diff options
author | Robert Bragg <robert@linux.intel.com> | 2014-02-08 13:14:40 +0000 |
---|---|---|
committer | Robert Bragg <robert@linux.intel.com> | 2014-03-05 19:25:05 +0000 |
commit | 41d3bdcb6b8c2ff14363de6e2ff9c5439a135976 (patch) | |
tree | 438b18bbf29de23d36b4a4bf12404ad3c98e1507 | |
parent | 9ead6be19cb4f397edc31ccde7dc199ac33b6f0e (diff) | |
download | cogl-41d3bdcb6b8c2ff14363de6e2ff9c5439a135976.tar.gz |
Add deps/eglib library from the mono project
This adds a deps/eglib api which is a small MIT licensed library that is
api compatible with enough of the glib api to run Cogl. This replaces
deps/glib and deps/gmodule for use when Cogl is built with
--enable-standalone.
This code is based on eglib from the mono project, with a few updates
and additions to handle apis that Cogl uses that mono doesn't.
As a reference point for monitoring eglib changes in the mono project,
this code is based on commit d50c836721f22df74a45185d51d0b9d37c370e33
193 files changed, 23443 insertions, 38604 deletions
@@ -7,16 +7,11 @@ A few exceptions are: This license is essentially identical to the MIT license with the option to refer to a web address for a copy of the notice in documentation. -- cogl-point-in-poly.c is under a 3 clause BSD license +- cogl-point-in-poly.c is under a permissive 3 clause BSD license - stb_image.c is public domain. Please see individual files for details. -deps/glib is licensed under the LGPL (please see individual files for -details and deps/glib/COPYING for a copy of the LGPL license) This -code is only referenced when building Cogl with the --standalone -configure option. - -- The MIT License @@ -25,7 +20,10 @@ Copyright (C) 2009-2014 Intel Corporation. Copyright (C) 2010,2012 Red Hat, Inc. Copyright (C) 1999-2005 Brian Paul All Rights Reserved. Copyright (C) 2011,2012 Collabora Ltd. -Copyright (c) 2008-2011 Kristian Høgsberg +Copyright (C) 2008-2011 Kristian Høgsberg +Copyright (C) 2006-2011 Novell, Inc. +Copyright (C) 2011-2012 Xamarin Inc. +Copyright (C) 2011 Jeffrey Stedfast Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -111,15 +111,17 @@ The experimental 2.0 API is documented here: LICENSE ------------------------------------------------------------------------------- -Most of Cogl is licensed under the terms of the MIT license. There are -also some files under the SGI Free Software License B, version 2.0, -cogl-point-in-poly.c is under a 3 clause BSD license and stb_image.c -is public domain. Please see individual files for details. - -deps/glib is licensed under the LGPL (please see individual files for -details and deps/glib/COPYING for a copy of the LGPL license) This -code is only referenced when building Cogl with the --standalone -configure option. +Most of Cogl is licensed under the terms of the MIT license. + +The tesselator used by cogl-path is under the SGI Free Software License B, +version 2.0 (basically identical to the MIT license except you can choose +to refer to a web address for a copy of the notice in documentation). + +cogl-point-in-poly.c is under a permissive 3 clause BSD license. + +stb_image.c is public domain. + +Please refer to the COPYING file and individual files for details. -- BUILDING AND INSTALLATION diff --git a/cogl-path/cogl-path.c b/cogl-path/cogl-path.c index a5287c4d..37f344d6 100644 --- a/cogl-path/cogl-path.c +++ b/cogl-path/cogl-path.c @@ -32,7 +32,12 @@ * Robert Bragg <robert@linux.intel.com> */ -#include "config.h" +#include <config.h> + +#include <glib.h> + +#include <string.h> +#include <math.h> #include "cogl-util.h" #include "cogl-object.h" @@ -49,8 +54,6 @@ #include "cogl-primitive-private.h" #include "tesselator/tesselator.h" -#include <string.h> -#include <math.h> #define _COGL_MAX_BEZ_RECURSE_DEPTH 16 diff --git a/cogl/Makefile.am b/cogl/Makefile.am index 9521b60b..a99ae04a 100644 --- a/cogl/Makefile.am +++ b/cogl/Makefile.am @@ -24,10 +24,6 @@ AM_CPPFLAGS = \ -I$(srcdir)/driver/gl/gles \ $(NULL) -if !USE_GLIB - AM_CPPFLAGS += -I$(top_builddir)/deps/glib -endif - AM_CPPFLAGS += \ -DG_LOG_DOMAIN=\"Cogl\" \ -DCOGL_COMPILATION \ @@ -490,8 +486,7 @@ lib_LTLIBRARIES += libcogl2.la libcogl2_la_LIBADD = $(LIBM) $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS) if !USE_GLIB -libcogl2_la_LIBADD += $(top_builddir)/deps/glib/libglib.la -libcogl2_la_LIBADD += $(top_builddir)/deps/gmodule/libgmodule.la +libcogl2_la_LIBADD += $(top_builddir)/deps/eglib/src/libeglib.la endif if UNIT_TESTS libcogl2_la_LIBADD += $(top_builddir)/test-fixtures/libtest-fixtures.la diff --git a/cogl/cogl-debug.c b/cogl/cogl-debug.c index 80a36695..e748a7ea 100644 --- a/cogl/cogl-debug.c +++ b/cogl/cogl-debug.c @@ -179,8 +179,7 @@ _cogl_parse_debug_string (const char *value, { g_printerr ("\n\n%28s\n", _("Supported debug values:")); #define OPT(MASK_NAME, GROUP, NAME, NAME_FORMATTED, DESCRIPTION) \ - g_printerr ("%28s %s\n", NAME ":", g_dgettext (GETTEXT_PACKAGE, \ - DESCRIPTION)); + g_printerr ("%28s %s\n", NAME ":", _(DESCRIPTION)); #include "cogl-debug-options.h" g_printerr ("\n%28s\n", _("Special debug values:")); OPT (IGNORED, "ignored", "all", "ignored", \ diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c index 062fa7ed..29c59286 100644 --- a/cogl/cogl-pipeline.c +++ b/cogl/cogl-pipeline.c @@ -53,7 +53,6 @@ #include "cogl-private.h" #include <glib.h> -#include <glib/gprintf.h> #include <string.h> static void _cogl_pipeline_free (CoglPipeline *tex); diff --git a/cogl/cogl-profile.c b/cogl/cogl-profile.c index ce687a20..3cab7838 100644 --- a/cogl/cogl-profile.c +++ b/cogl/cogl-profile.c @@ -93,12 +93,10 @@ _cogl_uprof_init (void) G_STMT_START { \ int shift = COGL_DEBUG_ ## MASK_NAME; \ uprof_context_add_boolean_option (_cogl_uprof_context, \ - g_dgettext (GETTEXT_PACKAGE, GROUP), \ + _(GROUP), \ NAME, \ - g_dgettext (GETTEXT_PACKAGE, \ - NAME_FORMATTED), \ - g_dgettext (GETTEXT_PACKAGE, \ - DESCRIPTION), \ + _(NAME_FORMATTED), \ + _(DESCRIPTION), \ debug_option_getter, \ debug_option_setter, \ GUINT_TO_POINTER (shift)); \ diff --git a/cogl/driver/gl/cogl-pipeline-fragend-fixed.c b/cogl/driver/gl/cogl-pipeline-fragend-fixed.c index d19430ef..12d14ff9 100644 --- a/cogl/driver/gl/cogl-pipeline-fragend-fixed.c +++ b/cogl/driver/gl/cogl-pipeline-fragend-fixed.c @@ -31,9 +31,7 @@ * Robert Bragg <robert@linux.intel.com> */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include <config.h> #include "cogl-context-private.h" #include "cogl-util-gl-private.h" @@ -51,7 +49,6 @@ #include "cogl-profile.h" #include <glib.h> -#include <glib/gprintf.h> #include <string.h> #ifndef GL_TEXTURE_RECTANGLE_ARB diff --git a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c index e90161be..7b2d67f3 100644 --- a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c +++ b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c @@ -31,9 +31,7 @@ * Robert Bragg <robert@linux.intel.com> */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif +#include <config.h> #include "cogl-debug.h" #include "cogl-context-private.h" @@ -54,7 +52,6 @@ #include "cogl-profile.h" #include <glib.h> -#include <glib/gprintf.h> #include <string.h> /* This might not be defined on GLES */ diff --git a/configure.ac b/configure.ac index a024234a..b2e2ed73 100644 --- a/configure.ac +++ b/configure.ac @@ -66,6 +66,10 @@ dnl ================================================================ # updating the version number in advance of a release. m4_define([cogl_release_status], [git]) + +dnl ================================================================ +dnl Setup autoconf +dnl ================================================================ AC_INIT(cogl, [cogl_version]) AC_CONFIG_SRCDIR(cogl/cogl.h) AC_CONFIG_AUX_DIR([build]) @@ -73,6 +77,9 @@ AC_CONFIG_MACRO_DIR([build/autotools]) AC_CONFIG_HEADERS(config.h) AC_GNU_SOURCE +AC_CANONICAL_SYSTEM +AC_CANONICAL_HOST + dnl ================================================================ dnl Required versions for dependencies dnl ================================================================ @@ -178,23 +185,93 @@ AC_SUBST(LIBM) dnl ================================================================ dnl See what platform we are building for dnl ================================================================ -AC_CANONICAL_HOST -AC_MSG_CHECKING([if building for some Win32 platform]) -AS_CASE([$host], - [*-*-mingw*|*-*-cygwin*], - [ - COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -no-undefined" - platform_win32=yes - ], - [platform_win32=no] -) -AC_MSG_RESULT([$platform_win32]) -AM_CONDITIONAL(OS_WIN32, [test "$platform_win32" = "yes"]) +AM_CONDITIONAL(CROSS_COMPILING, [test x$cross_compiling = xyes]) +AC_C_BIGENDIAN([ORDER=G_BIG_ENDIAN],[ORDER=G_LITTLE_ENDIAN]) + +platform_darwin=no +platform_android=no +platform_win32=no AC_CHECK_HEADER([OpenGL/gl.h], [platform_quartz=yes], [platform_quartz=no]) + +case $host in +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) + PATHSEP='\\' + SEARCHSEP=';' + OS="WIN32" + PIDTYPE='void *' + COGL_EXTRA_LDFLAGS="$COGL_EXTRA_LDFLAGS -no-undefined" + platform_win32=yes + ;; +*-*darwin*) + platform_darwin=yes + PATHSEP='/' + SEARCHSEP=':' + OS="UNIX" + PIDTYPE='int' + ;; +*-*-linux-android*) + platform_android=yes + AC_DEFINE(PLATFORM_ANDROID,1,[Targeting the Android platform]) + PATHSEP='/' + SEARCHSEP=':' + OS="UNIX" + PIDTYPE='int' + ;; +*) + PATHSEP='/' + SEARCHSEP=':' + OS="UNIX" + PIDTYPE='int' + ;; +esac + +AM_CONDITIONAL(OS_WIN32, [test "$platform_win32" = "yes"]) AM_CONDITIONAL(OS_QUARTZ, [test "$platform_quartz" = "yes"]) +case $target in +arm*-darwin*) + CFLAGS="$CFLAGS -U_FORTIFY_SOURCE" + ;; +i*86-*-darwin*) + ORDER=G_LITTLE_ENDIAN + ;; +esac + +target_osx=no +target_ios=no + +if test "x$platform_darwin" = "xyes"; then + AC_TRY_COMPILE([#include "TargetConditionals.h"],[ + #if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1 + #error fail this for ios + #endif + return 0; + ], [ + AC_DEFINE(TARGET_OSX,1,[The JIT/AOT targets OSX]) + target_osx=yes + ], [ + AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS]) + target_ios=yes + ]) + AC_DEFINE(TARGET_MACH,1,[The JIT/AOT targets Apple platforms]) +fi + +AC_SUBST(ORDER) +AC_SUBST(CFLAGS) +AC_SUBST(PATHSEP) +AC_SUBST(SEARCHSEP) +AC_SUBST(OS) +AC_SUBST(PIDTYPE) +AM_CONDITIONAL(HOST_WIN32, test x$OS = xWIN32) +AM_CONDITIONAL(TARGET_WIN32, test x$OS = xWIN32) +AM_CONDITIONAL(PLATFORM_DARWIN, test x$platform_darwin = xyes) +AM_CONDITIONAL(PLATFORM_ANDROID, test x$platform_android = xyes) + + + + dnl ================================================================ dnl Handle extra configure options dnl ================================================================ @@ -452,13 +529,8 @@ AS_IF([test "x$enable_glib" = "xyes"], COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gobject-2.0 gmodule-no-export-2.0" ], [ - AS_GLIBCONFIG([deps/glib]) - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_srcdir)/deps" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_builddir)/deps" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_srcdir)/deps/glib" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_builddir)/deps/glib" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_srcdir)/deps/gmodule" - COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_builddir)/deps/gmodule" + COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_srcdir)/deps/eglib/src" + COGL_EXTRA_CFLAGS="$COGL_EXTRA_CFLAGS -I\$(top_builddir)/deps/eglib/src" EXPERIMENTAL_CONFIG=yes EXPERIMENTAL_OPTIONS="$EXPERIMENTAL_OPTIONS --disable-glib," enable_nls=no @@ -1331,12 +1403,131 @@ AS_IF([test "x$enable_emscripten" = "xno"], dnl 'memmem' is a GNU extension but we have a simple fallback AC_CHECK_FUNCS([memmem]) + dnl This is used in the cogl-gles2-gears example but it is a GNU extension save_libs="$LIBS" LIBS="$LIBS $LIBM" AC_CHECK_FUNCS([sincos]) LIBS="$save_libs" + +dnl ================================================================ +dnl eglib checks. +dnl ================================================================ + +GNUC_PRETTY= +GNUC_UNUSED= +BREAKPOINT="G_STMT_START { raise (SIGTRAP); } G_STMT_END" +if test x$GCC = xyes; then + GNUC_UNUSED='__attribute__((__unused__))' + GNUC_NORETURN='__attribute__((__noreturn__))' + case $host_cpu in + i*86|x86_64) BREAKPOINT="G_STMT_START { __asm__ (\"int \$03\"); } G_STMT_END" ;; + esac +fi +AC_SUBST(GNUC_PRETTY) +AC_SUBST(GNUC_UNUSED) +AC_SUBST(GNUC_NORETURN) +AC_SUBST(BREAKPOINT) + +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(long long) +AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf) + +# +# iOS detection of strndup and getpwuid_r is faulty for some reason +# so let's simply avoid it +# +if test x$target_ios = xno; then +AC_CHECK_FUNCS(strndup getpwuid_r) +fi + +AM_CONDITIONAL(NEED_VASPRINTF, test x$have_vasprintf = x ) +AM_ICONV() +AC_SEARCH_LIBS(sqrtf, m) + +# nanosleep may not be part of libc, also search it in other libraries +AC_SEARCH_LIBS(nanosleep, rt) + +AC_SEARCH_LIBS(dlopen, dl) +old_ldflags="${LDFLAGS}" +LDFLAGS="${LDFLAGS} -Wl,-export-dynamic" +AC_TRY_LINK(, [int i;], found_export_dynamic=yes, found_export_dynamic=no) +if test $found_export_dynamic = no; then + LDFLAGS="${old_ldflags}" +fi + +AC_MSG_CHECKING(for varargs macros) +AC_TRY_COMPILE([],[ +int foo (int i, int j); +#define bar(...) foo (1, __VA_ARGS__) +void main () { + bar (2); +} +],have_iso_varargs=yes,have_iso_varargs=no) +AC_MSG_RESULT($have_iso_varargs) +G_HAVE_ISO_VARARGS=0 +if test "x$have_iso_varargs" = "xyes"; then + G_HAVE_ISO_VARARGS=1 +fi +AC_SUBST(G_HAVE_ISO_VARARGS) + +AC_CHECK_HEADERS(getopt.h sys/time.h sys/wait.h pwd.h langinfo.h iconv.h localcharset.h sys/types.h) +AC_CHECK_HEADER(alloca.h, [HAVE_ALLOCA_H=1], [HAVE_ALLOCA_H=0]) +AC_SUBST(HAVE_ALLOCA_H) + + +if test $ac_cv_sizeof_void_p = $ac_cv_sizeof_int; then + GPOINTER_TO_INT="((gint) (ptr))" + GPOINTER_TO_UINT="((guint) (ptr))" + GINT_TO_POINTER="((gpointer) (v))" + GUINT_TO_POINTER="((gpointer) (v))" + GSIZE="int" + GSIZE_FORMAT='"u"' + G_GUINT64_FORMAT='"llu"' + G_GINT64_FORMAT='"lld"' + G_GUINT32_FORMAT='"lu"' + G_GINT32_FORMAT='"ld"' +elif test $ac_cv_sizeof_void_p = $ac_cv_sizeof_long; then + GPOINTER_TO_INT="((gint)(long) (ptr))" + GPOINTER_TO_UINT="((guint)(long) (ptr))" + GINT_TO_POINTER="((gpointer)(glong) (v))" + GUINT_TO_POINTER="((gpointer)(gulong) (v))" + GSIZE="long" + GSIZE_FORMAT='"lu"' + G_GUINT64_FORMAT='"lu"' + G_GINT64_FORMAT='"ld"' + G_GUINT32_FORMAT='"u"' + G_GINT32_FORMAT='"d"' +elif test $ac_cv_sizeof_void_p = $ac_cv_sizeof_long_long; then + GPOINTER_TO_INT="((gint)(long long) (ptr))" + GPOINTER_TO_UINT="((guint)(unsigned long long) (ptr))" + GINT_TO_POINTER="((gpointer)(long long) (v))" + GUINT_TO_POINTER="((gpointer)(unsigned long long) (v))" + GSIZE="long long" + GSIZE_FORMAT='"I64u"' + G_GUINT64_FORMAT='"I64u"' + G_GINT64_FORMAT='"I64i"' + G_GUINT32_FORMAT='"I32u"' + G_GINT32_FORMAT='"I32i"' +else + AC_MSG_ERROR([unsupported pointer size]) +fi + +AC_SUBST(GPOINTER_TO_INT) +AC_SUBST(GPOINTER_TO_UINT) +AC_SUBST(GINT_TO_POINTER) +AC_SUBST(GUINT_TO_POINTER) +AC_SUBST(GSIZE) +AC_SUBST(GSIZE_FORMAT) +AC_SUBST(G_GUINT64_FORMAT) +AC_SUBST(G_GINT64_FORMAT) +AC_SUBST(G_GUINT32_FORMAT) +AC_SUBST(G_GINT32_FORMAT) + + dnl ================================================================ dnl Platform values dnl ================================================================ @@ -1439,9 +1630,11 @@ build/win32/Makefile build/win32/vs9/Makefile build/win32/vs10/Makefile deps/Makefile -deps/glib/Makefile -deps/gmodule/Makefile -deps/gmodule/gmoduleconf.h +deps/eglib/Makefile +deps/eglib/m4/Makefile +deps/eglib/src/Makefile +deps/eglib/src/eglib-config.h +deps/eglib/test/Makefile test-fixtures/Makefile cogl/Makefile cogl/cogl2.pc diff --git a/deps/Makefile.am b/deps/Makefile.am index 2cd3cb51..759c810d 100644 --- a/deps/Makefile.am +++ b/deps/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS = if !USE_GLIB -SUBDIRS += glib gmodule +SUBDIRS += eglib endif diff --git a/deps/eglib/.gitignore b/deps/eglib/.gitignore new file mode 100644 index 00000000..61e1af8f --- /dev/null +++ b/deps/eglib/.gitignore @@ -0,0 +1,22 @@ +/ +/depcomp +/config.guess +/config.sub +/ltmain.sh +/eglib-*.tar.gz +/missing +/install-sh +/compile +/Makefile +/Makefile.in +/stamp-h1 +/config.h.in +/libtool +/autom4te.cache +/aclocal.m4 +/config.log +/configure +/config.h +/config.status +/INSTALL +dolt* diff --git a/deps/eglib/AUTHORS b/deps/eglib/AUTHORS new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/deps/eglib/AUTHORS diff --git a/deps/eglib/COPYING b/deps/eglib/COPYING new file mode 100644 index 00000000..1bb5a443 --- /dev/null +++ b/deps/eglib/COPYING @@ -0,0 +1,17 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/deps/eglib/ChangeLog b/deps/eglib/ChangeLog new file mode 100644 index 00000000..de868165 --- /dev/null +++ b/deps/eglib/ChangeLog @@ -0,0 +1,7 @@ +Please refer to the Git history for a log of source code changes. + +This eglib api was originally copied from the mono project: + +https://github.com/mono/mono/tree/master/eglib + +Our inital snapshot was taken from commit d50c836721f22df7 diff --git a/deps/eglib/Makefile.am b/deps/eglib/Makefile.am new file mode 100644 index 00000000..b7e5cd63 --- /dev/null +++ b/deps/eglib/Makefile.am @@ -0,0 +1,17 @@ +ACLOCAL_AMFLAGS = -I m4 + +if HOST_WIN32 +SUBDIRS = m4 src +else +if PLATFORM_DARWIN +SUBDIRS = m4 src +else +if CROSS_COMPILING +SUBDIRS = m4 src +else +SUBDIRS = m4 src test +endif +endif +endif + +EXTRA_DIST = autogen.sh README NEWS AUTHORS ChangeLog winconfig.h diff --git a/deps/eglib/NEWS b/deps/eglib/NEWS new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/deps/eglib/NEWS diff --git a/deps/eglib/README b/deps/eglib/README new file mode 100644 index 00000000..ad04e326 --- /dev/null +++ b/deps/eglib/README @@ -0,0 +1,30 @@ + +The purpose of eglib is to be a small MIT licensed subset of glib. + +The implementation is done from the public documentation available here: + + http://developer.gnome.org/doc/API/2.0/glib/ + +Currently all the definitions go into a single file: glib.h, there are +no separate files, please try to follow the convetions in the source code + +* Tests + + Please read the README in tests/ + +* Features + + The source code is designed to allow for different operating + system builds of the eglib code. + + Files in src that: + + * Have a plain name: are cross platform, and should work on + every operating system. + + * That end in -unix.c: These files contain Unix specific code. + + * That end in -win32.c: These files contain Win32 specific code. + + * That end in -posix.c: Will work on both Windows and Unix, + but should not be included for other operating systems. diff --git a/deps/eglib/TODO b/deps/eglib/TODO new file mode 100644 index 00000000..bbbb49bb --- /dev/null +++ b/deps/eglib/TODO @@ -0,0 +1,33 @@ +* Missing code + + * Process launching + 3 g_shell_quote + 1 g_shell_unquote + +---------------------------------------------------------------------- + +* Should implement, for better performance: + +Macros: + 6 G_UNLIKELY + 4 G_LIKELY + +* Unimplemented, not supported currently: + + (none as yet.) + +* Dead Code + + The GMainLoop code was no longer in use in Mono. + +* Windows implementations needed + + Directory, File manipulation: + + g_dir_open, g_dir_close, g_dir_read_name + + We're missing a native windows implementation. The unix one is in place. + + * Information retrieval + 1 g_win32_getlocale + diff --git a/deps/eglib/acinclude.m4 b/deps/eglib/acinclude.m4 new file mode 100644 index 00000000..526d00c1 --- /dev/null +++ b/deps/eglib/acinclude.m4 @@ -0,0 +1,182 @@ +dnl dolt, a replacement for libtool +dnl Copyright © 2007-2008 Josh Triplett <josh@freedesktop.org> +dnl Copying and distribution of this file, with or without modification, +dnl are permitted in any medium without royalty provided the copyright +dnl notice and this notice are preserved. +dnl +dnl To use dolt, invoke the DOLT macro immediately after the libtool macros. +dnl Optionally, copy this file into acinclude.m4, to avoid the need to have it +dnl installed when running autoconf on your project. + +AC_DEFUN([DOLT], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +# dolt, a replacement for libtool +# Josh Triplett <josh@freedesktop.org> +AC_PATH_PROG(DOLT_BASH, bash) +AC_MSG_CHECKING([if dolt supports this host]) +dolt_supported=yes +if test x$DOLT_BASH = x; then + dolt_supported=no +fi +if test x$GCC != xyes; then + dolt_supported=no +fi +case $host in +i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ +|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*) + pic_options='-fPIC' + ;; +?86-pc-cygwin*|i?86-pc-cygwin*) + pic_options='-DDLL_EXPORT' + ;; +i?86-apple-darwin*|arm-apple-darwin*) + pic_options='-fno-common' + ;; +*) + dolt_supported=no + ;; +esac +if test x$dolt_supported = xno ; then + AC_MSG_RESULT([no, falling back to libtool]) + LTCOMPILE='$(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(COMPILE)' + LTCXXCOMPILE='$(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXXCOMPILE)' +else + AC_MSG_RESULT([yes, replacing libtool]) + +dnl Start writing out doltcompile. + cat <<__DOLTCOMPILE__EOF__ >doltcompile +#!$DOLT_BASH +__DOLTCOMPILE__EOF__ + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +args=("$[]@") +for ((arg=0; arg<${#args@<:@@@:>@}; arg++)) ; do + if test x"${args@<:@$arg@:>@}" = x-o ; then + objarg=$((arg+1)) + break + fi +done +if test x$objarg = x ; then + echo 'Error: no -o on compiler command line' 1>&2 + exit 1 +fi +lo="${args@<:@$objarg@:>@}" +obj="${lo%.lo}" +if test x"$lo" = x"$obj" ; then + echo "Error: libtool object file name \"$lo\" does not end in .lo" 1>&2 + exit 1 +fi +objbase="${obj##*/}" +__DOLTCOMPILE__EOF__ + +dnl Write out shared compilation code. + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +libobjdir="${obj%$objbase}.libs" +if test ! -d "$libobjdir" ; then + mkdir_out="$(mkdir "$libobjdir" 2>&1)" + mkdir_ret=$? + if test "$mkdir_ret" -ne 0 && test ! -d "$libobjdir" ; then + echo "$mkdir_out" 1>&2 + exit $mkdir_ret + fi +fi +pic_object="$libobjdir/$objbase.o" +args@<:@$objarg@:>@="$pic_object" +__DOLTCOMPILE__EOF__ + cat <<__DOLTCOMPILE__EOF__ >>doltcompile +"\${args@<:@@@:>@}" $pic_options -DPIC || exit \$? +__DOLTCOMPILE__EOF__ + fi + +dnl Write out static compilation code. +dnl Avoid duplicate compiler output if also building shared objects. + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +non_pic_object="$obj.o" +args@<:@$objarg@:>@="$non_pic_object" +__DOLTCOMPILE__EOF__ + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args@<:@@@:>@}" >/dev/null 2>&1 || exit $? +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +"${args@<:@@@:>@}" || exit $? +__DOLTCOMPILE__EOF__ + fi + fi + +dnl Write out the code to write the .lo file. +dnl The second line of the .lo file must match "^# Generated by .*libtool" + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +{ +echo "# $lo - a libtool object file" +echo "# Generated by doltcompile, not libtool" +__DOLTCOMPILE__EOF__ + + if test x$enable_shared = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "pic_object='.libs/${objbase}.o'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo pic_object=none +__DOLTCOMPILE__EOF__ + fi + + if test x$enable_static = xyes; then + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo "non_pic_object='${objbase}.o'" +__DOLTCOMPILE__EOF__ + else + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +echo non_pic_object=none +__DOLTCOMPILE__EOF__ + fi + + cat <<'__DOLTCOMPILE__EOF__' >>doltcompile +} > "$lo" +__DOLTCOMPILE__EOF__ + +dnl Done writing out doltcompile; substitute it for libtool compilation. + chmod +x doltcompile + LTCOMPILE='$(top_builddir)/doltcompile $(COMPILE)' + LTCXXCOMPILE='$(top_builddir)/doltcompile $(CXXCOMPILE)' + +dnl automake ignores LTCOMPILE and LTCXXCOMPILE when it has separate CFLAGS for +dnl a target, so write out a libtool wrapper to handle that case. +dnl Note that doltlibtool does not handle inferred tags or option arguments +dnl without '=', because automake does not use them. + cat <<__DOLTLIBTOOL__EOF__ > doltlibtool +#!$DOLT_BASH +__DOLTLIBTOOL__EOF__ + cat <<'__DOLTLIBTOOL__EOF__' >>doltlibtool +top_builddir_slash="${0%%doltlibtool}" +: ${top_builddir_slash:=./} +args=() +modeok=false +tagok=false +for arg in "$[]@"; do + case "$arg" in + --silent) ;; + --mode=compile) modeok=true ;; + --tag=CC|--tag=CXX) tagok=true ;; + --quiet) ;; + *) args@<:@${#args[@]}@:>@="$arg" ;; + esac +done +if $modeok && $tagok ; then + . ${top_builddir_slash}doltcompile "${args@<:@@@:>@}" +else + exec ${top_builddir_slash}libtool "$[]@" +fi +__DOLTLIBTOOL__EOF__ + +dnl Done writing out doltlibtool; substitute it for libtool. + chmod +x doltlibtool + LIBTOOL='$(top_builddir)/doltlibtool' +fi +AC_SUBST(LTCOMPILE) +AC_SUBST(LTCXXCOMPILE) +# end dolt +]) diff --git a/deps/eglib/autogen.sh b/deps/eglib/autogen.sh new file mode 100755 index 00000000..66f980a9 --- /dev/null +++ b/deps/eglib/autogen.sh @@ -0,0 +1,136 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +# Ripped off from GNOME macros version + +DIE=0 + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +if [ -n "$MONO_PATH" ]; then + # from -> /mono/lib:/another/mono/lib + # to -> /mono /another/mono + for i in `echo ${MONO_PATH} | tr ":" " "`; do + i=`dirname ${i}` + if [ -n "{i}" -a -d "${i}/share/aclocal" ]; then + ACLOCAL_FLAGS="-I ${i}/share/aclocal $ACLOCAL_FLAGS" + fi + if [ -n "{i}" -a -d "${i}/bin" ]; then + PATH="${i}/bin:$PATH" + fi + done + export PATH +fi + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`autoconf' installed to compile Mono." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +if [ -z "$LIBTOOL" ]; then + LIBTOOL=`which glibtool 2>/dev/null` + if [ ! -x "$LIBTOOL" ]; then + LIBTOOL=`which libtool` + fi +fi + +(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && { + ($LIBTOOL --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`libtool' installed to compile Mono." + echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + } +} + +grep "^AM_GNU_GETTEXT" $srcdir/configure.ac >/dev/null && { + grep "sed.*POTFILES" $srcdir/configure.ac >/dev/null || \ + (gettext --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`gettext' installed to compile Mono." + echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + } +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: You must have \`automake' installed to compile Mono." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 + NO_AUTOMAKE=yes +} + + +# if no automake, don't bother testing for aclocal +test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing \`aclocal'. The version of \`automake'" + echo "installed doesn't appear recent enough." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test x$NOCONFIGURE = x && test -z "$*"; then + echo "**Warning**: I am going to run \`configure' with no arguments." + echo "If you wish to pass any to it, please specify them on the" + echo \`$0\'" command line." + echo +fi + +case $CC in +xlc ) + am_opt=--include-deps;; +esac + + +if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then + if test -z "$NO_LIBTOOLIZE" ; then + echo "Running libtoolize..." + ${LIBTOOL}ize --force --copy + fi +fi + +echo "Running aclocal -I m4 $ACLOCAL_FLAGS ..." +aclocal -I m4 $ACLOCAL_FLAGS || { + echo + echo "**Error**: aclocal failed. This may mean that you have not" + echo "installed all of the packages you need, or you may need to" + echo "set ACLOCAL_FLAGS to include \"-I \$prefix/share/aclocal\"" + echo "for the prefix where you installed the packages whose" + echo "macros were not found" + exit 1 +} + +if grep "^AC_CONFIG_HEADERS" configure.ac >/dev/null; then + echo "Running autoheader..." + autoheader || { echo "**Error**: autoheader failed."; exit 1; } +fi + +echo "Running automake --gnu $am_opt ..." +automake --add-missing --gnu $am_opt || + { echo "**Error**: automake failed."; exit 1; } +echo "Running autoconf ..." +autoconf || { echo "**Error**: autoconf failed."; exit 1; } + + +conf_flags="--enable-maintainer-mode" #--enable-compile-warnings --enable-iso-c + +if test x$NOCONFIGURE = x; then + echo Running $srcdir/configure $conf_flags "$@" ... + $srcdir/configure $conf_flags "$@" \ + && echo Now type \`make\' to compile $PKG_NAME || exit 1 +else + echo Skipping configure process. +fi diff --git a/deps/eglib/config.rpath b/deps/eglib/config.rpath new file mode 100755 index 00000000..17298f23 --- /dev/null +++ b/deps/eglib/config.rpath @@ -0,0 +1,672 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2010 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + darwin*) + case $cc_basename in + xlc*) + wl='-Wl,' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + pgcc | pgf77 | pgf90) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we cannot use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if test "$GCC" = yes ; then + : + else + case $cc_basename in + xlc*) + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + library_names_spec='$libname.a' + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd1*) + ;; + freebsd* | dragonfly*) + case "$host_os" in + freebsd[123]*) + library_names_spec='$libname$shrext$versuffix' ;; + *) + library_names_spec='$libname$shrext' ;; + esac + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + nto-qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF + +# How to pass a linker flag through the compiler. +wl="$escaped_wl" + +# Static library suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally "so"). +shlibext="$shlibext" + +# Format of library name prefix. +libname_spec="$escaped_libname_spec" + +# Library names that the linker finds when passed -lNAME. +library_names_spec="$escaped_library_names_spec" + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec="$escaped_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" + +EOF diff --git a/deps/eglib/configure.ac b/deps/eglib/configure.ac new file mode 100644 index 00000000..fdbce134 --- /dev/null +++ b/deps/eglib/configure.ac @@ -0,0 +1,268 @@ +# +# Copyright 2012 Xamarin Inc +# +AC_INIT(eglib, [0.3], + [http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono]) + +AC_CONFIG_SRCDIR([README]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CANONICAL_SYSTEM +AC_CANONICAL_HOST + +AM_INIT_AUTOMAKE([1.9 dist-bzip2 tar-ustar no-dist-gzip foreign]) +AC_CONFIG_HEADERS([config.h]) +AM_MAINTAINER_MODE + +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +AC_PROG_CC +AM_PROG_LIBTOOL +# Use dolt (http://dolt.freedesktop.org/) instead of libtool for building. +DOLT +GNUC_PRETTY= +GNUC_UNUSED= +BREAKPOINT="G_STMT_START { raise (SIGTRAP); } G_STMT_END" +if test x$GCC = xyes; then + GNUC_UNUSED='__attribute__((__unused__))' + GNUC_NORETURN='__attribute__((__noreturn__))' + case $host_cpu in + i*86|x86_64) BREAKPOINT="G_STMT_START { __asm__ (\"int \$03\"); } G_STMT_END" ;; + esac +fi +AC_SUBST(GNUC_PRETTY) +AC_SUBST(GNUC_UNUSED) +AC_SUBST(GNUC_NORETURN) +AC_SUBST(BREAKPOINT) + +# We use a separate variable to pass down CPPFLAGS and CFLAGS from the main mono +# configure, because of autoconf brokeness +if test "x$CPPFLAGS_FOR_EGLIB" != "x"; then + CPPFLAGS=$CPPFLAGS_FOR_EGLIB +fi +if test "x$CFLAGS_FOR_EGLIB" != "x"; then + CFLAGS=$CFLAGS_FOR_EGLIB +fi + +CFLAGS="$CFLAGS -g -D_GNU_SOURCE" + +AM_CONDITIONAL(CROSS_COMPILING, [test x$cross_compiling = xyes]) +AC_C_BIGENDIAN([ORDER=G_BIG_ENDIAN],[ORDER=G_LITTLE_ENDIAN]) + +platform_darwin=no +platform_android=no + +case $host in +*-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) + PATHSEP='\\' + SEARCHSEP=';' + OS="WIN32" + PIDTYPE='void *' + ;; +*-*darwin*) + platform_darwin=yes + PATHSEP='/' + SEARCHSEP=':' + OS="UNIX" + PIDTYPE='int' + ;; +*-*-linux-android*) + platform_android=yes + AC_DEFINE(PLATFORM_ANDROID,1,[Targeting the Android platform]) + PATHSEP='/' + SEARCHSEP=':' + OS="UNIX" + PIDTYPE='int' + ;; +*) + PATHSEP='/' + SEARCHSEP=':' + OS="UNIX" + PIDTYPE='int' + ;; +esac + +case $host in + *-*-solaris*) + CFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS" + ;; +esac + +case $target in +arm*-darwin*) + CFLAGS="$CFLAGS -U_FORTIFY_SOURCE" + ;; +i*86-*-darwin*) + ORDER=G_LITTLE_ENDIAN + ;; +*-*-openbsd*) + CFLAGS="$CFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + ;; +esac + +target_osx=no +target_ios=no + +if test "x$platform_darwin" = "xyes"; then + AC_TRY_COMPILE([#include "TargetConditionals.h"],[ + #if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1 + #error fail this for ios + #endif + return 0; + ], [ + AC_DEFINE(TARGET_OSX,1,[The JIT/AOT targets OSX]) + target_osx=yes + ], [ + AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS]) + target_ios=yes + ]) + AC_DEFINE(TARGET_MACH,1,[The JIT/AOT targets Apple platforms]) +fi + +AC_SUBST(ORDER) +AC_SUBST(CFLAGS) +AC_SUBST(PATHSEP) +AC_SUBST(SEARCHSEP) +AC_SUBST(OS) +AC_SUBST(PIDTYPE) +AM_CONDITIONAL(HOST_WIN32, test x$OS = xWIN32) +AM_CONDITIONAL(TARGET_WIN32, test x$OS = xWIN32) +AM_CONDITIONAL(PLATFORM_DARWIN, test x$platform_darwin = xyes) +AM_CONDITIONAL(PLATFORM_ANDROID, test x$platform_android = xyes) + +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(long long) +AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf) + +# +# Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding +# the detection of strndup on OS X so Mono built on 10.7+ still runs on 10.6. This can be +# removed once support for 10.6 is dropped. +# +# iOS detection of strndup and getpwuid_r is faulty for some reason so let's simply avoid it +# +if test x$target_osx = xyes; then +AC_CHECK_FUNCS(getpwuid_r) +elif test x$target_ios = xno; then +AC_CHECK_FUNCS(strndup getpwuid_r) +fi + +AM_CONDITIONAL(NEED_VASPRINTF, test x$have_vasprintf = x ) +AM_ICONV() +AC_SEARCH_LIBS(sqrtf, m) + +# nanosleep may not be part of libc, also search it in other libraries +AC_SEARCH_LIBS(nanosleep, rt) + +AC_SEARCH_LIBS(dlopen, dl) +old_ldflags="${LDFLAGS}" +LDFLAGS="${LDFLAGS} -Wl,-export-dynamic" +AC_TRY_LINK(, [int i;], found_export_dynamic=yes, found_export_dynamic=no) +if test $found_export_dynamic = no; then + LDFLAGS="${old_ldflags}" +fi + +AC_MSG_CHECKING(for varargs macros) +AC_TRY_COMPILE([],[ +int foo (int i, int j); +#define bar(...) foo (1, __VA_ARGS__) +void main () { + bar (2); +} +],have_iso_varargs=yes,have_iso_varargs=no) +AC_MSG_RESULT($have_iso_varargs) +G_HAVE_ISO_VARARGS=0 +if test "x$have_iso_varargs" = "xyes"; then + G_HAVE_ISO_VARARGS=1 +fi +AC_SUBST(G_HAVE_ISO_VARARGS) + +AC_CHECK_HEADERS(getopt.h sys/time.h sys/wait.h pwd.h langinfo.h iconv.h localcharset.h sys/types.h) +AC_CHECK_HEADER(alloca.h, [HAVE_ALLOCA_H=1], [HAVE_ALLOCA_H=0]) +AC_SUBST(HAVE_ALLOCA_H) + +if test $ac_cv_sizeof_void_p = $ac_cv_sizeof_int; then + GPOINTER_TO_INT="((gint) (ptr))" + GPOINTER_TO_UINT="((guint) (ptr))" + GINT_TO_POINTER="((gpointer) (v))" + GUINT_TO_POINTER="((gpointer) (v))" + GSIZE="int" + GSIZE_FORMAT='"u"' + G_GUINT64_FORMAT='"llu"' + G_GINT64_FORMAT='"lld"' + G_GUINT32_FORMAT='"lu"' + G_GINT32_FORMAT='"ld"' +elif test $ac_cv_sizeof_void_p = $ac_cv_sizeof_long; then + GPOINTER_TO_INT="((gint)(long) (ptr))" + GPOINTER_TO_UINT="((guint)(long) (ptr))" + GINT_TO_POINTER="((gpointer)(glong) (v))" + GUINT_TO_POINTER="((gpointer)(gulong) (v))" + GSIZE="long" + GSIZE_FORMAT='"lu"' + G_GUINT64_FORMAT='"lu"' + G_GINT64_FORMAT='"ld"' + G_GUINT32_FORMAT='"u"' + G_GINT32_FORMAT='"d"' +elif test $ac_cv_sizeof_void_p = $ac_cv_sizeof_long_long; then + GPOINTER_TO_INT="((gint)(long long) (ptr))" + GPOINTER_TO_UINT="((guint)(unsigned long long) (ptr))" + GINT_TO_POINTER="((gpointer)(long long) (v))" + GUINT_TO_POINTER="((gpointer)(unsigned long long) (v))" + GSIZE="long long" + GSIZE_FORMAT='"I64u"' + G_GUINT64_FORMAT='"I64u"' + G_GINT64_FORMAT='"I64i"' + G_GUINT32_FORMAT='"I32u"' + G_GINT32_FORMAT='"I32i"' +else + AC_MSG_ERROR([unsupported pointer size]) +fi + +AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + +pkg_config_path= +AC_ARG_WITH(crosspkgdir, [ --with-crosspkgdir=/path/to/pkg-config/dir Change pkg-config dir to custom dir], + if test x$with_crosspkgdir = "x"; then + if test -s $PKG_CONFIG_PATH; then + pkg_config_path=$PKG_CONFIG_PATH + fi + else + pkg_config_path=$with_crosspkgdir + PKG_CONFIG_PATH=$pkg_config_path + export PKG_CONFIG_PATH + fi +) + +dnl +dnl No, you can not replace the call below with a pkg.m4 macro +dnl +have_glib=false +if test "x$PKG_CONFIG" != "xno"; then + if $PKG_CONFIG --atleast-version=$GLIB_REQUIRED_VERSION glib-2.0; then + have_glib=true; + else + have_glib=false; + fi +fi +AM_CONDITIONAL(HAVE_GLIB, $have_glib) + +AC_SUBST(GPOINTER_TO_INT) +AC_SUBST(GPOINTER_TO_UINT) +AC_SUBST(GINT_TO_POINTER) +AC_SUBST(GUINT_TO_POINTER) +AC_SUBST(GSIZE) +AC_SUBST(GSIZE_FORMAT) +AC_SUBST(G_GUINT64_FORMAT) +AC_SUBST(G_GINT64_FORMAT) +AC_SUBST(G_GUINT32_FORMAT) +AC_SUBST(G_GINT32_FORMAT) + +AC_OUTPUT([ +Makefile +m4/Makefile +src/Makefile +src/eglib-config.h +test/Makefile +]) diff --git a/deps/eglib/m4/.gitignore b/deps/eglib/m4/.gitignore new file mode 100644 index 00000000..7a0b214d --- /dev/null +++ b/deps/eglib/m4/.gitignore @@ -0,0 +1,7 @@ +Makefile +Makefile.in +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 diff --git a/deps/eglib/m4/Makefile.am b/deps/eglib/m4/Makefile.am new file mode 100644 index 00000000..af864e3b --- /dev/null +++ b/deps/eglib/m4/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST = $(wildcard *.m4) diff --git a/deps/eglib/m4/iconv.m4 b/deps/eglib/m4/iconv.m4 new file mode 100644 index 00000000..e2041b9b --- /dev/null +++ b/deps/eglib/m4/iconv.m4 @@ -0,0 +1,214 @@ +# iconv.m4 serial 11 (gettext-0.18.1) +dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + AC_TRY_RUN([ +#include <iconv.h> +#include <string.h> +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\263"; + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no], + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to +dnl avoid warnings like +dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required". +dnl This is tricky because of the way 'aclocal' is implemented: +dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN. +dnl Otherwise aclocal's initial scan pass would miss the macro definition. +dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions. +dnl Otherwise aclocal would emit many "Use of uninitialized value $1" +dnl warnings. +m4_define([gl_iconv_AC_DEFUN], + m4_version_prereq([2.64], + [[AC_DEFUN_ONCE( + [$1], [$2])]], + [[AC_DEFUN( + [$1], [$2])]])) +gl_iconv_AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_TRY_COMPILE([ +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/deps/eglib/m4/lib-ld.m4 b/deps/eglib/m4/lib-ld.m4 new file mode 100644 index 00000000..ebb30528 --- /dev/null +++ b/deps/eglib/m4/lib-ld.m4 @@ -0,0 +1,110 @@ +# lib-ld.m4 serial 4 (gettext-0.18) +dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes ;; +*) + acl_cv_prog_gnu_ld=no ;; +esac]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-1.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_ARG_WITH([gnu-ld], +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't 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 + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL([acl_cv_path_LD], +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_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. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/deps/eglib/m4/lib-link.m4 b/deps/eglib/m4/lib-link.m4 new file mode 100644 index 00000000..c73bd8e3 --- /dev/null +++ b/deps/eglib/m4/lib-link.m4 @@ -0,0 +1,774 @@ +# lib-link.m4 serial 21 (gettext-0.18) +dnl Copyright (C) 2001-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.54]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. The missing-message +dnl defaults to 'no' and may contain additional hints for the user. +dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} +dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, + dnl because these -l options might require -L options that are present in + dnl LIBS. -l options benefit only from the -L options listed before it. + dnl Otherwise, add it to the front of LIBS, because it may be a static + dnl library that depends on another static library that is present in LIBS. + dnl Static libraries benefit only from the static libraries listed after + dnl it. + case " $LIB[]NAME" in + *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; + *) LIBS="$LIB[]NAME $LIBS" ;; + esac + AC_TRY_LINK([$3], [$4], + [ac_cv_lib[]Name=yes], + [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/deps/eglib/m4/lib-prefix.m4 b/deps/eglib/m4/lib-prefix.m4 new file mode 100644 index 00000000..1601ceae --- /dev/null +++ b/deps/eglib/m4/lib-prefix.m4 @@ -0,0 +1,224 @@ +# lib-prefix.m4 serial 7 (gettext-0.18) +dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>. + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_EGREP_CPP([sixtyfour bits], [ +#ifdef _LP64 +sixtyfour bits +#endif + ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +]) diff --git a/deps/eglib/src/.gitignore b/deps/eglib/src/.gitignore new file mode 100644 index 00000000..6635df1a --- /dev/null +++ b/deps/eglib/src/.gitignore @@ -0,0 +1,11 @@ +/Makefile +/Makefile.in +/.libs +/.deps +/*.lo +/*.la +/*.o +/semantic.cache +/.project +/.cproject +/eglib-config.h diff --git a/deps/eglib/src/Makefile.am b/deps/eglib/src/Makefile.am new file mode 100644 index 00000000..2efca84d --- /dev/null +++ b/deps/eglib/src/Makefile.am @@ -0,0 +1,85 @@ +noinst_LTLIBRARIES = libeglib.la libeglib-static.la + +win_files = \ + eglib-config.hw \ + gdate-win32.c gdir-win32.c gfile-win32.c gmisc-win32.c \ + gmodule-win32.c gtimer-win32.c + +unix_files = \ + gdate-unix.c gdir-unix.c gfile-unix.c gmisc-unix.c \ + gmodule-unix.c gtimer-unix.c + +# some unices and windows do not have an implementation of vasprintf +# used by eglib, use provided implementation instead +if NEED_VASPRINTF +vasprintf_files = vasprintf.c +else +vaprinttf_files = foo.c +endif + +if HOST_WIN32 +os_files = $(win_files) +else +os_files = $(unix_files) +endif + +libeglib_la_SOURCES = \ + sort.frag.h \ + glib.h \ + gdebugkey.c \ + gquark.c \ + garray.c \ + gbytearray.c \ + gerror.c \ + ghashtable.c \ + giconv.c \ + gmem.c \ + gmodule.h \ + goutput.c \ + gqsort.c \ + gstr.c \ + gslist.c \ + gstring.c \ + gptrarray.c \ + glist.c \ + ghooklist.c \ + gqueue.c \ + gpath.c \ + gshell.c \ + gspawn.c \ + gfile.c \ + gfile-posix.c \ + gpattern.c \ + gmarkup.c \ + gutf8.c \ + gunicode.c \ + unicode-data.h \ + $(os_files) \ + $(vasprintf_files) + +AM_CPPFLAGS = \ + -I$(top_builddir) \ + -I$(top_srcdir) \ + -I$(srcdir) \ + -Wall \ + $(NULL) + +#libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2 +#libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2 +libeglib_static_la_SOURCES=$(libeglib_la_SOURCES) +libeglib_static_la_CFLAGS = $(libeglib_la_CFLAGS) + +if HOST_WIN32 +libeglib_la_LIBADD = -lm $(LIBICONV) -lpsapi +else +if PLATFORM_ANDROID +libeglib_la_LIBADD = -llog +endif +endif + +libeglib_static_la_LIBADD = $(libeglib_la_LIBADD) $(LIBICONV) +libeglib_static_la_LDFLAGS = -static + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = eglib-config.h.in $(win_files) $(unix_files) diff --git a/deps/eglib/src/eglib-config.h.in b/deps/eglib/src/eglib-config.h.in new file mode 100644 index 00000000..ba0f93f9 --- /dev/null +++ b/deps/eglib/src/eglib-config.h.in @@ -0,0 +1,46 @@ +#ifndef __EGLIB_CONFIG_H +#define __EGLIB_CONFIG_H + +/* + * System-dependent settings + */ +#define G_GNUC_PRETTY_FUNCTION @GNUC_PRETTY@ +#define G_GNUC_UNUSED @GNUC_UNUSED@ +#define G_BYTE_ORDER @ORDER@ +#define G_GNUC_NORETURN @GNUC_NORETURN@ +#define G_SEARCHPATH_SEPARATOR_S "@SEARCHSEP@" +#define G_SEARCHPATH_SEPARATOR '@SEARCHSEP@' +#define G_DIR_SEPARATOR '@PATHSEP@' +#define G_DIR_SEPARATOR_S "@PATHSEP@" +#define G_BREAKPOINT() @BREAKPOINT@ +#define G_OS_@OS@ +#define GPOINTER_TO_INT(ptr) @GPOINTER_TO_INT@ +#define GPOINTER_TO_UINT(ptr) @GPOINTER_TO_UINT@ +#define GINT_TO_POINTER(v) @GINT_TO_POINTER@ +#define GUINT_TO_POINTER(v) @GUINT_TO_POINTER@ + +#if @HAVE_ALLOCA_H@ == 1 +#define G_HAVE_ALLOCA_H +#endif + +typedef unsigned @GSIZE@ gsize; +typedef signed @GSIZE@ gssize; + +#define G_GSIZE_FORMAT @GSIZE_FORMAT@ +#define G_GUINT64_FORMAT @G_GUINT64_FORMAT@ +#define G_GINT64_FORMAT @G_GINT64_FORMAT@ +#define G_GUINT32_FORMAT @G_GUINT32_FORMAT@ +#define G_GINT32_FORMAT @G_GINT32_FORMAT@ + +#if @G_HAVE_ISO_VARARGS@ == 1 +#define G_HAVE_ISO_VARARGS +#endif + +#if defined (__native_client__) +#undef G_BREAKPOINT +#define G_BREAKPOINT() +#endif + +typedef @PIDTYPE@ GPid; + +#endif diff --git a/deps/eglib/src/eglib-config.hw b/deps/eglib/src/eglib-config.hw new file mode 100644 index 00000000..192d3936 --- /dev/null +++ b/deps/eglib/src/eglib-config.hw @@ -0,0 +1,76 @@ +#ifndef __EGLIB_CONFIG_H +#define __EGLIB_CONFIG_H + +/* + * System-dependent settings + */ +#define G_OS_WIN32 1 + +#ifdef _MSC_VER + +#include <io.h> + +#define G_GNUC_PRETTY_FUNCTION __FUNCTION__ +#define G_GNUC_UNUSED +#define G_BYTE_ORDER 1234 +#define G_GNUC_NORETURN +#define G_BREAKPOINT() __debugbreak() +#define MAXPATHLEN 242 + +typedef uintptr_t gsize; +typedef intptr_t gssize; +typedef int pid_t; + +#define G_DIR_SEPARATOR '\\' +#define G_DIR_SEPARATOR_S "\\" +#define G_SEARCHPATH_SEPARATOR_S ";" +#define G_SEARCHPATH_SEPARATOR ';' +#define G_GSIZE_FORMAT "d" +#define G_GUINT64_FORMAT "d" +#define G_GINT64_FORMAT "d" +#define GPOINTER_TO_INT(ptr) ((gint)(intptr_t) (ptr)) +#define GPOINTER_TO_UINT(ptr) ((guint)(intptr_t) (ptr)) +#define GINT_TO_POINTER(v) ((gpointer)(intptr_t) (v)) +#define GUINT_TO_POINTER(v) ((gpointer)(intptr_t) (v)) + +/* VS 2010 and later have stdint.h */ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#define INT32_MAX 2147483647 +#define INT32_MIN (~ INT32_MAX) +#define INT64_MAX 9223372036854775807i64 +#define INT64_MIN (~INT64_MAX) +#define UINT32_MAX 0xffffffffU +#define UINT64_MAX 0xffffffffffffffffULL +#endif + +#define STDOUT_FILENO (int)(intptr_t)stdout +#define STDERR_FILENO (int)(intptr_t)stderr + + +/* FIXME: what should this be ?*/ +#define X_OK 4 /* This is really read */ +#define WNOHANG 1 +#define F_SETFD 1 +#define FD_CLOEXEC 1 + +#undef inline +#define inline __inline + +#define strtok_r strtok_s + +#undef G_HAVE_UNISTD_H +#undef G_HAVE_SYS_TIME_H +#undef G_HAVE_SYS_WAIT_H +#undef G_HAVE_PWD_H +#undef G_HAVE_STRNDUP +#define G_HAVE_GETOPT_H 1 + +/* disable the following warnings + * C4100: The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored. + * C4127: conditional expression is constant +*/ +#pragma warning(disable:4100 4127) +#endif + +typedef void * GPid; +#endif diff --git a/deps/eglib/src/garray.c b/deps/eglib/src/garray.c new file mode 100644 index 00000000..0c8a8762 --- /dev/null +++ b/deps/eglib/src/garray.c @@ -0,0 +1,242 @@ +/* + * Arrays + * + * Author: + * Chris Toshok (toshok@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdlib.h> +#include <glib.h> + +#define INITIAL_CAPACITY 16 + +#define element_offset(p,i) ((p)->array.data + (i) * (p)->element_size) +#define element_length(p,i) ((i) * (p)->element_size) + +typedef struct { + GArray array; + gboolean clear_; + guint element_size; + gboolean zero_terminated; + guint capacity; +} GArrayPriv; + +static void +ensure_capacity (GArrayPriv *priv, guint capacity) +{ + guint new_capacity; + + if (capacity <= priv->capacity) + return; + + for (new_capacity = MAX (INITIAL_CAPACITY, priv->capacity * 2); + new_capacity < capacity; + new_capacity *= 2) + ; + + priv->array.data = g_realloc (priv->array.data, element_length (priv, new_capacity)); + + if (priv->clear_) { + memset (element_offset (priv, priv->capacity), + 0, + element_length (priv, new_capacity - priv->capacity)); + } + + priv->capacity = new_capacity; +} + +GArray * +g_array_new (gboolean zero_terminated, + gboolean clear_, + guint element_size) +{ + GArrayPriv *rv = g_new0 (GArrayPriv, 1); + rv->zero_terminated = zero_terminated; + rv->clear_ = clear_; + rv->element_size = element_size; + + ensure_capacity (rv, INITIAL_CAPACITY); + + return (GArray*)rv; +} + +GArray * +g_array_sized_new (gboolean zero_terminated, + gboolean clear_, + guint element_size, + guint reserved_size) +{ + GArrayPriv *rv = g_new0 (GArrayPriv, 1); + rv->zero_terminated = zero_terminated; + rv->clear_ = clear_; + rv->element_size = element_size; + + ensure_capacity (rv, reserved_size); + + return (GArray*)rv; +} + +gchar* +g_array_free (GArray *array, + gboolean free_segment) +{ + gchar* rv = NULL; + + g_return_val_if_fail (array != NULL, NULL); + + if (free_segment) + g_free (array->data); + else + rv = array->data; + + g_free (array); + + return rv; +} + +GArray * +g_array_append_vals (GArray *array, + gconstpointer data, + guint len) +{ + GArrayPriv *priv = (GArrayPriv*)array; + + g_return_val_if_fail (array != NULL, NULL); + + ensure_capacity (priv, priv->array.len + len + (priv->zero_terminated ? 1 : 0)); + + memmove (element_offset (priv, priv->array.len), + data, + element_length (priv, len)); + + priv->array.len += len; + + if (priv->zero_terminated) { + memset (element_offset (priv, priv->array.len), + 0, + priv->element_size); + } + + return array; +} + +GArray* +g_array_insert_vals (GArray *array, + guint index_, + gconstpointer data, + guint len) +{ + GArrayPriv *priv = (GArrayPriv*)array; + guint extra = (priv->zero_terminated ? 1 : 0); + + g_return_val_if_fail (array != NULL, NULL); + + ensure_capacity (priv, array->len + len + extra); + + /* first move the existing elements out of the way */ + memmove (element_offset (priv, index_ + len), + element_offset (priv, index_), + element_length (priv, array->len - index_)); + + /* then copy the new elements into the array */ + memmove (element_offset (priv, index_), + data, + element_length (priv, len)); + + array->len += len; + + if (priv->zero_terminated) { + memset (element_offset (priv, priv->array.len), + 0, + priv->element_size); + } + + return array; +} + +GArray* +g_array_remove_index (GArray *array, + guint index_) +{ + GArrayPriv *priv = (GArrayPriv*)array; + + g_return_val_if_fail (array != NULL, NULL); + + memmove (element_offset (priv, index_), + element_offset (priv, index_ + 1), + element_length (priv, array->len - index_)); + + array->len --; + + if (priv->zero_terminated) { + memset (element_offset (priv, priv->array.len), + 0, + priv->element_size); + } + + return array; +} + +GArray* +g_array_remove_index_fast (GArray *array, + guint index_) +{ + GArrayPriv *priv = (GArrayPriv*)array; + + g_return_val_if_fail (array != NULL, NULL); + + memmove (element_offset (priv, index_), + element_offset (priv, array->len - 1), + element_length (priv, 1)); + + array->len --; + + if (priv->zero_terminated) { + memset (element_offset (priv, priv->array.len), + 0, + priv->element_size); + } + + return array; +} + +GArray * +g_array_set_size (GArray *array, gint length) +{ + GArrayPriv *priv = (GArrayPriv*)array; + + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (length >= 0, NULL); + + if (length > priv->capacity) { + // grow the array + ensure_capacity (priv, length); + } + + array->len = length; + + return array; +} diff --git a/deps/eglib/src/gbytearray.c b/deps/eglib/src/gbytearray.c new file mode 100644 index 00000000..837e15eb --- /dev/null +++ b/deps/eglib/src/gbytearray.c @@ -0,0 +1,62 @@ +/* + * Arrays + * + * Author: + * Geoff Norton (gnorton@novell.com) + * + * (C) 2010 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include <config.h> + +#include <stdlib.h> +#include <glib.h> + +GByteArray * +g_byte_array_new () +{ + return (GByteArray *) g_array_new (FALSE, TRUE, 1); +} + +guint8* +g_byte_array_free (GByteArray *array, + gboolean free_segment) +{ + return (guint8*) g_array_free ((GArray *)array, free_segment); +} + +GByteArray * +g_byte_array_append (GByteArray *array, + const guint8 *data, + guint len) +{ + return (GByteArray *)g_array_append_vals ((GArray *)array, data, len); +} + +GByteArray * +g_byte_array_set_size (GByteArray *array, + guint len) +{ + g_array_set_size ((GArray*)array, len); + return array; +} diff --git a/deps/eglib/src/gdate-unix.c b/deps/eglib/src/gdate-unix.c new file mode 100644 index 00000000..5d3dfc82 --- /dev/null +++ b/deps/eglib/src/gdate-unix.c @@ -0,0 +1,58 @@ +/* + * gdate-unix.c: Date and time utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <glib.h> +#include <time.h> +#include <errno.h> +#include <sys/time.h> + +void +g_get_current_time (GTimeVal *result) +{ + struct timeval tv; + + g_return_if_fail (result != NULL); + gettimeofday (&tv, NULL); + result->tv_sec = tv.tv_sec; + result->tv_usec = tv.tv_usec; +} + +void +g_usleep (gulong microseconds) +{ + struct timespec req, rem; + + req.tv_sec = microseconds / 1000000; + req.tv_nsec = (microseconds % 1000000) * 1000; + + while (nanosleep (&req, &rem) == -1 && errno == EINTR) + req = rem; +} diff --git a/deps/eglib/src/gdate-win32.c b/deps/eglib/src/gdate-win32.c new file mode 100644 index 00000000..2b216988 --- /dev/null +++ b/deps/eglib/src/gdate-win32.c @@ -0,0 +1,52 @@ +/* + * gdate-win32.c: Date and time utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +#include <winsock2.h> + +void +g_get_current_time (GTimeVal *result) +{ + long int l; + + g_return_if_fail (result != NULL); + l = GetTickCount(); + + result->tv_sec = l / 1000; + result->tv_usec = (l % 1000) * 1000; +} + +void +g_usleep (gulong microseconds) +{ + Sleep (microseconds/1000); +} diff --git a/deps/eglib/src/gdebugkey.c b/deps/eglib/src/gdebugkey.c new file mode 100644 index 00000000..0cf79d4a --- /dev/null +++ b/deps/eglib/src/gdebugkey.c @@ -0,0 +1,71 @@ +/* + * ghooklist.c: API for manipulating a list of hook functions + * + * Copyright (C) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Robert Bragg <robert@linux.intel.com> + */ + +#include <config.h> + +#include <glib.h> + +guint +g_parse_debug_string (const gchar *string, + const GDebugKey *keys, + guint nkeys) +{ + char **strv = g_strsplit_set (string, ":;, \t", 0); + gboolean needs_invert = FALSE; + guint value = 0; + int i; + + if (strcasecmp (string, "help") == 0) + { + g_printerr ("Supported debug keys:\n"); + for (i = 0; strv[i]; i++) + { + g_printerr (" %s:\n", keys[i].key); + } + g_printerr (" all\n"); + g_printerr (" help\n"); + } + + for (i = 0; strv[i]; i++) + { + int j; + + for (j = 0; j < nkeys; j++) + if (strcasecmp (keys[j].key, strv[i]) == 0) + value |= keys[j].value; + else if (strcasecmp (keys[j].key, "all") == 0) + needs_invert = TRUE; + } + + if (needs_invert) + value = value ^ (~0); + + g_strfreev (strv); + + return value; +} diff --git a/deps/eglib/src/gdir-unix.c b/deps/eglib/src/gdir-unix.c new file mode 100644 index 00000000..5dfb275a --- /dev/null +++ b/deps/eglib/src/gdir-unix.c @@ -0,0 +1,151 @@ +/* + * Directory utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <dirent.h> + +struct _GDir { + DIR *dir; +#ifndef HAVE_REWINDDIR + char *path; +#endif +}; + +GDir * +g_dir_open (const gchar *path, guint flags, GError **error) +{ + GDir *dir; + + g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + (void) flags; /* this is not used */ + dir = g_new (GDir, 1); + dir->dir = opendir (path); + if (dir->dir == NULL) { + if (error) { + gint err = errno; + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (err), + g_strerror (err)); + } + g_free (dir); + return NULL; + } +#ifndef HAVE_REWINDDIR + dir->path = g_strdup (path); +#endif + return dir; +} + +const gchar * +g_dir_read_name (GDir *dir) +{ + struct dirent *entry; + + g_return_val_if_fail (dir != NULL && dir->dir != NULL, NULL); + do { + entry = readdir (dir->dir); + if (entry == NULL) + return NULL; + } while ((strcmp (entry->d_name, ".") == 0) || (strcmp (entry->d_name, "..") == 0)); + + return entry->d_name; +} + +void +g_dir_rewind (GDir *dir) +{ + g_return_if_fail (dir != NULL && dir->dir != NULL); +#ifndef HAVE_REWINDDIR + closedir (dir->dir); + dir->dir = opendir (dir->path); +#else + rewinddir (dir->dir); +#endif +} + +void +g_dir_close (GDir *dir) +{ + g_return_if_fail (dir != NULL && dir->dir != 0); + closedir (dir->dir); +#ifndef HAVE_REWINDDIR + g_free (dir->path); +#endif + dir->dir = NULL; + g_free (dir); +} + +int +g_mkdir_with_parents (const gchar *pathname, int mode) +{ + char *path, *d; + int rv; + + if (!pathname || *pathname == '\0') { + errno = EINVAL; + return -1; + } + + d = path = g_strdup (pathname); + if (*d == '/') + d++; + + while (TRUE) { + if (*d == '/' || *d == '\0') { + char orig = *d; + *d = '\0'; + rv = mkdir (path, mode); + if (rv == -1 && errno != EEXIST) { + g_free (path); + return -1; + } + + *d++ = orig; + while (orig == '/' && *d == '/') + d++; + if (orig == '\0') + break; + } else { + d++; + } + } + + g_free (path); + + return 0; +} diff --git a/deps/eglib/src/gdir-win32.c b/deps/eglib/src/gdir-win32.c new file mode 100644 index 00000000..1d61e34c --- /dev/null +++ b/deps/eglib/src/gdir-win32.c @@ -0,0 +1,148 @@ +/* + * Directory utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <io.h> + +#include <winsock2.h> + +struct _GDir { + HANDLE handle; + gchar* current; + gchar* next; +}; + +GDir * +g_dir_open (const gchar *path, guint flags, GError **error) +{ + GDir *dir; + gunichar2* path_utf16; + gunichar2* path_utf16_search; + WIN32_FIND_DATAW find_data; + + g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + dir = g_new0 (GDir, 1); + path_utf16 = u8to16 (path); + path_utf16_search = g_malloc ((wcslen((wchar_t *) path_utf16) + 3)*sizeof(gunichar2)); + wcscpy (path_utf16_search, path_utf16); + wcscat (path_utf16_search, L"\\*"); + + dir->handle = FindFirstFileW (path_utf16_search, &find_data); + if (dir->handle == INVALID_HANDLE_VALUE) { + if (error) { + gint err = errno; + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (err), + g_strerror (err)); + } + g_free (path_utf16_search); + g_free (path_utf16); + g_free (dir); + return NULL; + } + g_free (path_utf16_search); + g_free (path_utf16); + + while ((wcscmp ((wchar_t *) find_data.cFileName, L".") == 0) || (wcscmp ((wchar_t *) find_data.cFileName, L"..") == 0)) { + if (!FindNextFileW (dir->handle, &find_data)) { + if (error) { + gint err = errno; + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (err), + g_strerror (err)); + } + g_free (dir); + return NULL; + } + } + + dir->current = NULL; + dir->next = u16to8 (find_data.cFileName); + return dir; +} + +const gchar * +g_dir_read_name (GDir *dir) +{ + WIN32_FIND_DATAW find_data; + + g_return_val_if_fail (dir != NULL && dir->handle != 0, NULL); + + if (dir->current) + g_free (dir->current); + dir->current = NULL; + + dir->current = dir->next; + + if (!dir->current) + return NULL; + + dir->next = NULL; + + do { + if (!FindNextFileW (dir->handle, &find_data)) { + dir->next = NULL; + return dir->current; + } + } while ((wcscmp ((wchar_t *) find_data.cFileName, L".") == 0) || (wcscmp ((wchar_t *) find_data.cFileName, L"..") == 0)); + + dir->next = u16to8 (find_data.cFileName); + return dir->current; +} + +void +g_dir_rewind (GDir *dir) +{ +} + +void +g_dir_close (GDir *dir) +{ + g_return_if_fail (dir != NULL && dir->handle != 0); + + if (dir->current) + g_free (dir->current); + dir->current = NULL; + if (dir->next) + g_free (dir->next); + dir->next = NULL; + FindClose (dir->handle); + dir->handle = 0; + g_free (dir); +} + + diff --git a/deps/eglib/src/gerror.c b/deps/eglib/src/gerror.c new file mode 100644 index 00000000..927bb161 --- /dev/null +++ b/deps/eglib/src/gerror.c @@ -0,0 +1,127 @@ +/* + * gerror.c: Error support. + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <glib.h> + +GError * +g_error_new (GQuark domain, gint code, const char *format, ...) +{ + va_list args; + GError *err = g_new (GError, 1); + + err->domain = domain; + err->code = code; + + va_start (args, format); + if (vasprintf (&err->message, format, args) == -1) + err->message = g_strdup_printf ("internal: invalid format string %s", format); + va_end (args); + + return err; +} + +GError * +g_error_new_valist (GQuark domain, gint code, const char *format, va_list ap) +{ + GError *err = g_new (GError, 1); + + err->domain = domain; + err->code = code; + + err->message = g_strdup_vprintf (format, ap); + + return err; +} + +void +g_clear_error (GError **error) +{ + if (error && *error) { + g_error_free (*error); + *error = NULL; + } +} + +void +g_error_free (GError *error) +{ + g_return_if_fail (error != NULL); + + g_free (error->message); + g_free (error); +} + +void +g_set_error (GError **err, GQuark domain, gint code, const gchar *format, ...) +{ + va_list args; + + if (err) { + va_start (args, format); + *err = g_error_new_valist (domain, code, format, args); + va_end (args); + } +} + +void +g_propagate_error (GError **dest, GError *src) +{ + if (dest == NULL) { + if (src) + g_error_free (src); + } else { + *dest = src; + } +} + +GError * +g_error_copy (const GError *error) +{ + GError *copy = g_new (GError, 1); + copy->domain = error->domain; + copy->code = error->code; + copy->message = g_strdup (error->message); + return copy; +} + +gboolean +g_error_matches (const GError *error, GQuark domain, gint code) +{ + if (error) + { + if (error->domain == domain && error->code == code) + return TRUE; + return FALSE; + } + else + return FALSE; +} diff --git a/deps/eglib/src/gfile-posix.c b/deps/eglib/src/gfile-posix.c new file mode 100644 index 00000000..fdc89822 --- /dev/null +++ b/deps/eglib/src/gfile-posix.c @@ -0,0 +1,200 @@ +/* + * File utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <fcntl.h> +#include <errno.h> + +#ifdef _MSC_VER +#include <direct.h> +#endif +#ifdef G_OS_WIN32 +int mkstemp (char *tmp_template); +#endif + +#ifndef O_LARGEFILE +#define OPEN_FLAGS (O_RDONLY) +#else +#define OPEN_FLAGS (O_RDONLY | O_LARGEFILE) +#endif +gboolean +g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error) +{ + gchar *str; + int fd; + struct stat st; + long offset; + int nread; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (contents != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + *contents = NULL; + if (length) + *length = 0; + + fd = open (filename, OPEN_FLAGS); + if (fd == -1) { + if (error != NULL) { + int err = errno; + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (err), + "Error opening file '%s': %s", + filename, + g_strerror (err)); + } + return FALSE; + } + + if (fstat (fd, &st) != 0) { + if (error != NULL) { + int err = errno; + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (err), + "Error in fstat() for file '%s': %s", + filename, + g_strerror (err)); + } + close (fd); + return FALSE; + } + + str = g_malloc (st.st_size + 1); + offset = 0; + do { + nread = read (fd, str + offset, st.st_size - offset); + if (nread > 0) { + offset += nread; + } + } while ((nread > 0 && offset < st.st_size) || (nread == -1 && errno == EINTR)); + + close (fd); + str [st.st_size] = '\0'; + if (length) { + *length = st.st_size; + } + *contents = str; + return TRUE; +} + +gint +g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **error) +{ + const static gchar *default_tmpl = ".XXXXXX"; + gchar *t; + gint fd; + size_t len; + + g_return_val_if_fail (error == NULL || *error == NULL, -1); + + if (tmpl == NULL) + tmpl = default_tmpl; + + if (strchr (tmpl, G_DIR_SEPARATOR) != NULL) { + if (error) { + *error = g_error_new (G_FILE_ERROR, + G_FILE_ERROR_FAILED, + "Template should not have any " G_DIR_SEPARATOR_S); + } + return -1; + } + + len = strlen (tmpl); + if (len < 6 || strcmp (tmpl + len - 6, "XXXXXX")) { + if (error) { + *error = g_error_new (G_FILE_ERROR, + G_FILE_ERROR_FAILED, + "Template should end with XXXXXX"); + } + return -1; + } + + t = g_build_filename (g_get_tmp_dir (), tmpl, NULL); + + fd = mkstemp (t); + + if (fd == -1) { + if (error) { + int err = errno; + *error = g_error_new (G_FILE_ERROR, + g_file_error_from_errno (err), + "Error in mkstemp(): %s", + g_strerror (err)); + } + g_free (t); + return -1; + } + + if (name_used) { + *name_used = t; + } else { + g_free (t); + } + return fd; +} + +gchar * +g_get_current_dir (void) +{ +#ifdef __native_client__ + char *buffer; + if ((buffer = g_getenv("NACL_PWD"))) { + buffer = g_strdup(buffer); + } else { + buffer = g_strdup("."); + } + return buffer; +#else + int s = 32; + char *buffer = NULL, *r; + gboolean fail; + + do { + buffer = g_realloc (buffer, s); + r = getcwd (buffer, s); + fail = (r == NULL && errno == ERANGE); + if (fail) { + s <<= 1; + } + } while (fail); + + /* On amd64 sometimes the bottom 32-bits of r == the bottom 32-bits of buffer + * but the top 32-bits of r have overflown to 0xffffffff (seriously wtf getcwd + * so we return the buffer here since it has a pointer to the valid string + */ + return buffer; +#endif +} diff --git a/deps/eglib/src/gfile-unix.c b/deps/eglib/src/gfile-unix.c new file mode 100644 index 00000000..4e17a089 --- /dev/null +++ b/deps/eglib/src/gfile-unix.c @@ -0,0 +1,80 @@ +/* + * File utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +gboolean +g_file_test (const gchar *filename, GFileTest test) +{ + struct stat st; + gboolean have_stat; + + if (filename == NULL || test == 0) + return FALSE; + + have_stat = FALSE; + + if ((test & G_FILE_TEST_EXISTS) != 0) { + if (access (filename, F_OK) == 0) + return TRUE; + } + + if ((test & G_FILE_TEST_IS_EXECUTABLE) != 0) { + if (access (filename, X_OK) == 0) + return TRUE; + } + if ((test & G_FILE_TEST_IS_SYMLINK) != 0) { + have_stat = (lstat (filename, &st) == 0); + if (have_stat && S_ISLNK (st.st_mode)) + return TRUE; + } + + if ((test & G_FILE_TEST_IS_REGULAR) != 0) { + if (!have_stat) + have_stat = (stat (filename, &st) == 0); + if (have_stat && S_ISREG (st.st_mode)) + return TRUE; + } + if ((test & G_FILE_TEST_IS_DIR) != 0) { + if (!have_stat) + have_stat = (stat (filename, &st) == 0); + if (have_stat && S_ISDIR (st.st_mode)) + return TRUE; + } + return FALSE; +} diff --git a/deps/eglib/src/gfile-win32.c b/deps/eglib/src/gfile-win32.c new file mode 100644 index 00000000..a2e41ea9 --- /dev/null +++ b/deps/eglib/src/gfile-win32.c @@ -0,0 +1,120 @@ +/* + * File utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <windows.h> +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/types.h> + +#ifdef G_OS_WIN32 +#include <io.h> +#define open _open +#ifndef S_ISREG +#define S_ISREG(x) ((x & _S_IFMT) == _S_IFREG) +#endif +#ifndef S_ISDIR +#define S_ISDIR(x) ((x & _S_IFMT) == _S_IFDIR) +#endif +#endif + +int mkstemp (char *tmp_template) +{ + int fd; + gunichar2* utf16_template; + + utf16_template = u8to16 (tmp_template); + + fd = -1; + utf16_template = _wmktemp( utf16_template); + if (utf16_template && *utf16_template) { + /* FIXME: _O_TEMPORARY causes file to disappear on close causing a test to fail */ + fd = _wopen( utf16_template, _O_BINARY | _O_CREAT /*| _O_TEMPORARY*/ | _O_EXCL, _S_IREAD | _S_IWRITE); + } + + /* FIXME: this will crash if utf16_template == NULL */ + sprintf (tmp_template + strlen (tmp_template) - 6, "%S", utf16_template + wcslen (utf16_template) - 6); + + g_free (utf16_template); + return fd; +} + +#ifdef _MSC_VER +#pragma warning(disable:4701) +#endif + +gboolean +g_file_test (const gchar *filename, GFileTest test) +{ + gunichar2* utf16_filename = NULL; + DWORD attr; + + if (filename == NULL || test == 0) + return FALSE; + + utf16_filename = u8to16 (filename); + attr = GetFileAttributesW (utf16_filename); + g_free (utf16_filename); + + if (attr == INVALID_FILE_ATTRIBUTES) + return FALSE; + + if ((test & G_FILE_TEST_EXISTS) != 0) { + return TRUE; + } + + if ((test & G_FILE_TEST_IS_EXECUTABLE) != 0) { + size_t len = strlen (filename); + if (len > 4 && strcmp (filename + len-3, "exe")) + return TRUE; + + return FALSE; + } + + if ((test & G_FILE_TEST_IS_REGULAR) != 0) { + if (attr & (FILE_ATTRIBUTE_DEVICE|FILE_ATTRIBUTE_DIRECTORY)) + return FALSE; + return TRUE; + } + + if ((test & G_FILE_TEST_IS_DIR) != 0) { + if (attr & FILE_ATTRIBUTE_DIRECTORY) + return TRUE; + } + + /* make this last in case it is OR'd with something else */ + if ((test & G_FILE_TEST_IS_SYMLINK) != 0) { + return FALSE; + } + + return FALSE; +} diff --git a/deps/eglib/src/gfile.c b/deps/eglib/src/gfile.c new file mode 100644 index 00000000..ab0c9123 --- /dev/null +++ b/deps/eglib/src/gfile.c @@ -0,0 +1,155 @@ +/* + * File utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <stdio.h> +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <errno.h> + +GQuark +g_file_error_quark (void) +{ + return g_quark_from_static_string ("g-file-error-quark"); +} + +GFileError +g_file_error_from_errno (gint err_no) +{ + switch (err_no) { + case EEXIST: + return G_FILE_ERROR_EXIST; + case EISDIR: + return G_FILE_ERROR_ISDIR; + case EACCES: + return G_FILE_ERROR_ACCES; + case ENAMETOOLONG: + return G_FILE_ERROR_NAMETOOLONG; + case ENOENT: + return G_FILE_ERROR_NOENT; + case ENOTDIR: + return G_FILE_ERROR_NOTDIR; + case ENXIO: + return G_FILE_ERROR_NXIO; + case ENODEV: + return G_FILE_ERROR_NODEV; + case EROFS: + return G_FILE_ERROR_ROFS; +#ifdef ETXTBSY + case ETXTBSY: + return G_FILE_ERROR_TXTBSY; +#endif + case EFAULT: + return G_FILE_ERROR_FAULT; +#ifdef ELOOP + case ELOOP: + return G_FILE_ERROR_LOOP; +#endif + case ENOSPC: + return G_FILE_ERROR_NOSPC; + case ENOMEM: + return G_FILE_ERROR_NOMEM; + case EMFILE: + return G_FILE_ERROR_MFILE; + case ENFILE: + return G_FILE_ERROR_NFILE; + case EBADF: + return G_FILE_ERROR_BADF; + case EINVAL: + return G_FILE_ERROR_INVAL; + case EPIPE: + return G_FILE_ERROR_PIPE; + case EAGAIN: + return G_FILE_ERROR_AGAIN; + case EINTR: + return G_FILE_ERROR_INTR; + case EIO: + return G_FILE_ERROR_IO; + case EPERM: + return G_FILE_ERROR_PERM; + case ENOSYS: + return G_FILE_ERROR_NOSYS; + default: + return G_FILE_ERROR_FAILED; + } +} + +#ifdef G_OS_WIN32 +#define TMP_FILE_FORMAT "%.*s%s.tmp" +#else +#define TMP_FILE_FORMAT "%.*s.%s~" +#endif + +gboolean +g_file_set_contents (const gchar *filename, const gchar *contents, gssize length, GError **err) +{ + const char *name; + char *path; + FILE *fp; + + if (!(name = strrchr (filename, G_DIR_SEPARATOR))) + name = filename; + else + name++; + + path = g_strdup_printf (TMP_FILE_FORMAT, name - filename, filename, name); + if (!(fp = fopen (path, "wb"))) { + g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); + g_free (path); + return FALSE; + } + + if (length < 0) + length = strlen (contents); + + if (fwrite (contents, 1, length, fp) < length) { + g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (ferror (fp)), "%s", g_strerror (ferror (fp))); + g_unlink (path); + g_free (path); + fclose (fp); + + return FALSE; + } + + fclose (fp); + + if (g_rename (path, filename) != 0) { + g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", g_strerror (errno)); + g_unlink (path); + g_free (path); + return FALSE; + } + + g_free (path); + + return TRUE; +} diff --git a/deps/eglib/src/ghashtable.c b/deps/eglib/src/ghashtable.c new file mode 100644 index 00000000..35db6e62 --- /dev/null +++ b/deps/eglib/src/ghashtable.c @@ -0,0 +1,674 @@ +/* + * ghashtable.c: Hashtable implementation + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <math.h> +#include <glib.h> + +typedef struct _Slot Slot; + +struct _Slot { + gpointer key; + gpointer value; + Slot *next; +}; + +static gpointer KEYMARKER_REMOVED = &KEYMARKER_REMOVED; + +struct _GHashTable { + GHashFunc hash_func; + GEqualFunc key_equal_func; + + Slot **table; + int table_size; + int in_use; + int threshold; + int last_rehash; + GDestroyNotify value_destroy_func, key_destroy_func; +}; + +typedef struct { + GHashTable *ht; + int slot_index; + Slot *slot; +} Iter; + +static const guint prime_tbl[] = { + 11, 19, 37, 73, 109, 163, 251, 367, 557, 823, 1237, + 1861, 2777, 4177, 6247, 9371, 14057, 21089, 31627, + 47431, 71143, 106721, 160073, 240101, 360163, + 540217, 810343, 1215497, 1823231, 2734867, 4102283, + 6153409, 9230113, 13845163 +}; + +static gboolean +test_prime (int x) +{ + if ((x & 1) != 0) { + int n; + for (n = 3; n< (int)sqrt (x); n += 2) { + if ((x % n) == 0) + return FALSE; + } + return TRUE; + } + // There is only one even prime - 2. + return (x == 2); +} + +static int +calc_prime (int x) +{ + int i; + + for (i = (x & (~1))-1; i< G_MAXINT32; i += 2) { + if (test_prime (i)) + return i; + } + return x; +} + +guint +g_spaced_primes_closest (guint x) +{ + int i; + + for (i = 0; i < G_N_ELEMENTS (prime_tbl); i++) { + if (x <= prime_tbl [i]) + return prime_tbl [i]; + } + return calc_prime (x); +} + +GHashTable * +g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func) +{ + GHashTable *hash; + + if (hash_func == NULL) + hash_func = g_direct_hash; + if (key_equal_func == NULL) + key_equal_func = g_direct_equal; + hash = g_new0 (GHashTable, 1); + + hash->hash_func = hash_func; + hash->key_equal_func = key_equal_func; + + hash->table_size = g_spaced_primes_closest (1); + hash->table = g_new0 (Slot *, hash->table_size); + hash->last_rehash = hash->table_size; + + return hash; +} + +GHashTable * +g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func) +{ + GHashTable *hash = g_hash_table_new (hash_func, key_equal_func); + if (hash == NULL) + return NULL; + + hash->key_destroy_func = key_destroy_func; + hash->value_destroy_func = value_destroy_func; + + return hash; +} + +#if 0 +static void +dump_hash_table (GHashTable *hash) +{ + int i; + + for (i = 0; i < hash->table_size; i++) { + Slot *s; + + for (s = hash->table [i]; s != NULL; s = s->next){ + guint hashcode = (*hash->hash_func) (s->key); + guint slot = (hashcode) % hash->table_size; + printf ("key %p hash %x on slot %d correct slot %d tb size %d\n", s->key, hashcode, i, slot, hash->table_size); + } + } +} +#endif + +#ifdef SANITY_CHECK +static void +sanity_check (GHashTable *hash) +{ + int i; + + for (i = 0; i < hash->table_size; i++) { + Slot *s; + + for (s = hash->table [i]; s != NULL; s = s->next){ + guint hashcode = (*hash->hash_func) (s->key); + guint slot = (hashcode) % hash->table_size; + if (slot != i) { + dump_hashcode_func = 1; + hashcode = (*hash->hash_func) (s->key); + dump_hashcode_func = 0; + g_error ("Key %p (bucket %d) on invalid bucket %d (hashcode %x) (tb size %d)", s->key, slot, i, hashcode, hash->table_size); + } + } + } +} +#else + +#define sanity_check(HASH) do {}while(0) + +#endif + +static void +do_rehash (GHashTable *hash) +{ + int current_size, i; + Slot **table; + + /* printf ("Resizing diff=%d slots=%d\n", hash->in_use - hash->last_rehash, hash->table_size); */ + hash->last_rehash = hash->table_size; + current_size = hash->table_size; + hash->table_size = g_spaced_primes_closest (hash->in_use); + /* printf ("New size: %d\n", hash->table_size); */ + table = hash->table; + hash->table = g_new0 (Slot *, hash->table_size); + + for (i = 0; i < current_size; i++){ + Slot *s, *next; + + for (s = table [i]; s != NULL; s = next){ + guint hashcode = ((*hash->hash_func) (s->key)) % hash->table_size; + next = s->next; + + s->next = hash->table [hashcode]; + hash->table [hashcode] = s; + } + } + g_free (table); +} + +static void +rehash (GHashTable *hash) +{ + int diff = ABS (hash->last_rehash - hash->in_use); + + /* These are the factors to play with to change the rehashing strategy */ + /* I played with them with a large range, and could not really get */ + /* something that was too good, maybe the tests are not that great */ + if (!(diff * 0.75 > hash->table_size * 2)) + return; + do_rehash (hash); + sanity_check (hash); +} + +void +g_hash_table_insert_replace (GHashTable *hash, gpointer key, gpointer value, gboolean replace) +{ + guint hashcode; + Slot *s; + GEqualFunc equal; + + g_return_if_fail (hash != NULL); + sanity_check (hash); + + equal = hash->key_equal_func; + if (hash->in_use >= hash->threshold) + rehash (hash); + + hashcode = ((*hash->hash_func) (key)) % hash->table_size; + for (s = hash->table [hashcode]; s != NULL; s = s->next){ + if ((*equal) (s->key, key)){ + if (replace){ + if (hash->key_destroy_func != NULL) + (*hash->key_destroy_func)(s->key); + s->key = key; + } + if (hash->value_destroy_func != NULL) + (*hash->value_destroy_func) (s->value); + s->value = value; + sanity_check (hash); + return; + } + } + s = g_new (Slot, 1); + s->key = key; + s->value = value; + s->next = hash->table [hashcode]; + hash->table [hashcode] = s; + hash->in_use++; + sanity_check (hash); +} + +GList* +g_hash_table_get_keys (GHashTable *hash) +{ + GHashTableIter iter; + GList *rv = NULL; + gpointer key; + + g_hash_table_iter_init (&iter, hash); + + while (g_hash_table_iter_next (&iter, &key, NULL)) + rv = g_list_prepend (rv, key); + + return g_list_reverse (rv); +} + +GList* +g_hash_table_get_values (GHashTable *hash) +{ + GHashTableIter iter; + GList *rv = NULL; + gpointer value; + + g_hash_table_iter_init (&iter, hash); + + while (g_hash_table_iter_next (&iter, NULL, &value)) + rv = g_list_prepend (rv, value); + + return g_list_reverse (rv); +} + + +guint +g_hash_table_size (GHashTable *hash) +{ + g_return_val_if_fail (hash != NULL, 0); + + return hash->in_use; +} + +gpointer +g_hash_table_lookup (GHashTable *hash, gconstpointer key) +{ + gpointer orig_key, value; + + if (g_hash_table_lookup_extended (hash, key, &orig_key, &value)) + return value; + else + return NULL; +} + +gboolean +g_hash_table_lookup_extended (GHashTable *hash, gconstpointer key, gpointer *orig_key, gpointer *value) +{ + GEqualFunc equal; + Slot *s; + guint hashcode; + + g_return_val_if_fail (hash != NULL, FALSE); + sanity_check (hash); + equal = hash->key_equal_func; + + hashcode = ((*hash->hash_func) (key)) % hash->table_size; + + for (s = hash->table [hashcode]; s != NULL; s = s->next){ + if ((*equal)(s->key, key)){ + if (orig_key) + *orig_key = s->key; + if (value) + *value = s->value; + return TRUE; + } + } + return FALSE; +} + +void +g_hash_table_foreach (GHashTable *hash, GHFunc func, gpointer user_data) +{ + int i; + + g_return_if_fail (hash != NULL); + g_return_if_fail (func != NULL); + + for (i = 0; i < hash->table_size; i++){ + Slot *s; + + for (s = hash->table [i]; s != NULL; s = s->next) + (*func)(s->key, s->value, user_data); + } +} + +gpointer +g_hash_table_find (GHashTable *hash, GHRFunc predicate, gpointer user_data) +{ + int i; + + g_return_val_if_fail (hash != NULL, NULL); + g_return_val_if_fail (predicate != NULL, NULL); + + for (i = 0; i < hash->table_size; i++){ + Slot *s; + + for (s = hash->table [i]; s != NULL; s = s->next) + if ((*predicate)(s->key, s->value, user_data)) + return s->value; + } + return NULL; +} + +void +g_hash_table_remove_all (GHashTable *hash) +{ + int i; + + g_return_if_fail (hash != NULL); + + for (i = 0; i < hash->table_size; i++){ + Slot *s; + + while (hash->table [i]) { + s = hash->table [i]; + g_hash_table_remove (hash, s->key); + } + } +} + +gboolean +g_hash_table_remove (GHashTable *hash, gconstpointer key) +{ + GEqualFunc equal; + Slot *s, *last; + guint hashcode; + + g_return_val_if_fail (hash != NULL, FALSE); + sanity_check (hash); + equal = hash->key_equal_func; + + hashcode = ((*hash->hash_func)(key)) % hash->table_size; + last = NULL; + for (s = hash->table [hashcode]; s != NULL; s = s->next){ + if ((*equal)(s->key, key)){ + if (hash->key_destroy_func != NULL) + (*hash->key_destroy_func)(s->key); + if (hash->value_destroy_func != NULL) + (*hash->value_destroy_func)(s->value); + if (last == NULL) + hash->table [hashcode] = s->next; + else + last->next = s->next; + g_free (s); + hash->in_use--; + sanity_check (hash); + return TRUE; + } + last = s; + } + sanity_check (hash); + return FALSE; +} + +guint +g_hash_table_foreach_remove (GHashTable *hash, GHRFunc func, gpointer user_data) +{ + int i; + int count = 0; + + g_return_val_if_fail (hash != NULL, 0); + g_return_val_if_fail (func != NULL, 0); + + sanity_check (hash); + for (i = 0; i < hash->table_size; i++){ + Slot *s, *last; + + last = NULL; + for (s = hash->table [i]; s != NULL; ){ + if ((*func)(s->key, s->value, user_data)){ + Slot *n; + + if (hash->key_destroy_func != NULL) + (*hash->key_destroy_func)(s->key); + if (hash->value_destroy_func != NULL) + (*hash->value_destroy_func)(s->value); + if (last == NULL){ + hash->table [i] = s->next; + n = s->next; + } else { + last->next = s->next; + n = last->next; + } + g_free (s); + hash->in_use--; + count++; + s = n; + } else { + last = s; + s = s->next; + } + } + } + sanity_check (hash); + if (count > 0) + rehash (hash); + return count; +} + +gboolean +g_hash_table_steal (GHashTable *hash, gconstpointer key) +{ + GEqualFunc equal; + Slot *s, *last; + guint hashcode; + + g_return_val_if_fail (hash != NULL, FALSE); + sanity_check (hash); + equal = hash->key_equal_func; + + hashcode = ((*hash->hash_func)(key)) % hash->table_size; + last = NULL; + for (s = hash->table [hashcode]; s != NULL; s = s->next){ + if ((*equal)(s->key, key)) { + if (last == NULL) + hash->table [hashcode] = s->next; + else + last->next = s->next; + g_free (s); + hash->in_use--; + sanity_check (hash); + return TRUE; + } + last = s; + } + sanity_check (hash); + return FALSE; + +} + +guint +g_hash_table_foreach_steal (GHashTable *hash, GHRFunc func, gpointer user_data) +{ + int i; + int count = 0; + + g_return_val_if_fail (hash != NULL, 0); + g_return_val_if_fail (func != NULL, 0); + + sanity_check (hash); + for (i = 0; i < hash->table_size; i++){ + Slot *s, *last; + + last = NULL; + for (s = hash->table [i]; s != NULL; ){ + if ((*func)(s->key, s->value, user_data)){ + Slot *n; + + if (last == NULL){ + hash->table [i] = s->next; + n = s->next; + } else { + last->next = s->next; + n = last->next; + } + g_free (s); + hash->in_use--; + count++; + s = n; + } else { + last = s; + s = s->next; + } + } + } + sanity_check (hash); + if (count > 0) + rehash (hash); + return count; +} + +void +g_hash_table_destroy (GHashTable *hash) +{ + int i; + + g_return_if_fail (hash != NULL); + + for (i = 0; i < hash->table_size; i++){ + Slot *s, *next; + + for (s = hash->table [i]; s != NULL; s = next){ + next = s->next; + + if (hash->key_destroy_func != NULL) + (*hash->key_destroy_func)(s->key); + if (hash->value_destroy_func != NULL) + (*hash->value_destroy_func)(s->value); + g_free (s); + } + } + g_free (hash->table); + + g_free (hash); +} + +void +g_hash_table_print_stats (GHashTable *table) +{ + int i, max_chain_index, chain_size, max_chain_size; + Slot *node; + + max_chain_size = 0; + max_chain_index = -1; + for (i = 0; i < table->table_size; i++) { + chain_size = 0; + for (node = table->table [i]; node; node = node->next) + chain_size ++; + if (chain_size > max_chain_size) { + max_chain_size = chain_size; + max_chain_index = i; + } + } + + printf ("Size: %d Table Size: %d Max Chain Length: %d at %d\n", table->in_use, table->table_size, max_chain_size, max_chain_index); +} + +void +g_hash_table_iter_init (GHashTableIter *it, GHashTable *hash_table) +{ + Iter *iter = (Iter*)it; + + memset (iter, 0, sizeof (Iter)); + iter->ht = hash_table; + iter->slot_index = -1; +} + +gboolean g_hash_table_iter_next (GHashTableIter *it, gpointer *key, gpointer *value) +{ + Iter *iter = (Iter*)it; + + GHashTable *hash = iter->ht; + + g_assert (iter->slot_index != -2); + g_assert (sizeof (Iter) <= sizeof (GHashTableIter)); + + if (!iter->slot) { + while (TRUE) { + iter->slot_index ++; + if (iter->slot_index >= hash->table_size) { + iter->slot_index = -2; + return FALSE; + } + if (hash->table [iter->slot_index]) + break; + } + iter->slot = hash->table [iter->slot_index]; + } + + if (key) + *key = iter->slot->key; + if (value) + *value = iter->slot->value; + iter->slot = iter->slot->next; + + return TRUE; +} + +gboolean +g_direct_equal (gconstpointer v1, gconstpointer v2) +{ + return v1 == v2; +} + +guint +g_direct_hash (gconstpointer v1) +{ + return GPOINTER_TO_UINT (v1); +} + +gboolean +g_int_equal (gconstpointer v1, gconstpointer v2) +{ + return *(gint *)v1 == *(gint *)v2; +} + +guint +g_int_hash (gconstpointer v1) +{ + return *(guint *)v1; +} + +gboolean +g_str_equal (gconstpointer v1, gconstpointer v2) +{ + return strcmp (v1, v2) == 0; +} + +guint +g_str_hash (gconstpointer v1) +{ + guint hash = 0; + char *p = (char *) v1; + + while (*p++) + hash = (hash << 5) - (hash + *p); + + return hash; +} diff --git a/deps/eglib/src/ghooklist.c b/deps/eglib/src/ghooklist.c new file mode 100644 index 00000000..88eba730 --- /dev/null +++ b/deps/eglib/src/ghooklist.c @@ -0,0 +1,124 @@ +/* + * ghooklist.c: API for manipulating a list of hook functions + * + * Copyright (C) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Robert Bragg <robert@linux.intel.com> + */ + +#include <config.h> + +#include <glib.h> + +void +g_hook_list_init (GHookList *hook_list, + guint hook_size) +{ + hook_list->hooks = NULL; +} + +void +g_hook_list_invoke (GHookList *hook_list, + gboolean may_recurse) +{ + GHook *h; + + if (may_recurse) + { + for (h = hook_list->hooks; h; h = h->next) + { + GHookFunc func = h->func; + func (h->data); + } + } + else + { + for (h = hook_list->hooks; h && !h->in_call; h = h->next) + { + GHookFunc func = h->func; + h->in_call = TRUE; + func (h->data); + h->in_call = FALSE; + } + } +} + +void +g_hook_list_clear (GHookList *hook_list) +{ + while (hook_list->hooks) + g_hook_destroy_link (hook_list, hook_list->hooks); +} + +GHook * +g_hook_alloc (GHookList *hook_list) +{ + return g_new (GHook, 1); +} + +GHook * +g_hook_find_func_data (GHookList *hook_list, + gboolean need_valids, + gpointer func, + gpointer data) +{ + GHook *h; + + for (h = hook_list->hooks; h; h = h->next) + { + if (h->func == func && h->data == data) + return h; + } + + return NULL; +} + +void +g_hook_destroy_link (GHookList *hook_list, + GHook *hook) +{ + if (hook_list->hooks == hook) + hook_list->hooks = hook->next; + + if (hook->next) + hook->next->prev = hook->prev; + if (hook->prev) + hook->prev->next = hook->next; + + g_free (hook); +} + +void +g_hook_prepend (GHookList *hook_list, + GHook *hook) +{ + GHook *prev = hook_list->hooks ? hook_list->hooks->prev : NULL; + GHook *next = hook_list->hooks; + + hook->prev = prev; + hook->next = next; + if (prev) + prev->next = hook; + if (next) + next->prev = hook; +} diff --git a/deps/eglib/src/giconv.c b/deps/eglib/src/giconv.c new file mode 100644 index 00000000..f9da4a6b --- /dev/null +++ b/deps/eglib/src/giconv.c @@ -0,0 +1,1368 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2011 Jeffrey Stedfast + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <glib.h> +#include <string.h> +#ifdef HAVE_ICONV_H +#include <iconv.h> +#endif +#include <errno.h> + +#ifdef _MSC_VER +#define FORCE_INLINE(RET_TYPE) __forceinline RET_TYPE +#else +#define FORCE_INLINE(RET_TYPE) inline RET_TYPE __attribute__((always_inline)) +#endif + + +#define UNROLL_DECODE_UTF8 0 +#define UNROLL_ENCODE_UTF8 0 + +typedef int (* Decoder) (char *inbuf, size_t inleft, gunichar *outchar); +typedef int (* Encoder) (gunichar c, char *outbuf, size_t outleft); + +struct _GIConv { + Decoder decode; + Encoder encode; + gunichar c; +#ifdef HAVE_ICONV + iconv_t cd; +#endif +}; + +static int decode_utf32be (char *inbuf, size_t inleft, gunichar *outchar); +static int encode_utf32be (gunichar c, char *outbuf, size_t outleft); + +static int decode_utf32le (char *inbuf, size_t inleft, gunichar *outchar); +static int encode_utf32le (gunichar c, char *outbuf, size_t outleft); + +static int decode_utf16be (char *inbuf, size_t inleft, gunichar *outchar); +static int encode_utf16be (gunichar c, char *outbuf, size_t outleft); + +static int decode_utf16le (char *inbuf, size_t inleft, gunichar *outchar); +static int encode_utf16le (gunichar c, char *outbuf, size_t outleft); + +static FORCE_INLINE (int) decode_utf8 (char *inbuf, size_t inleft, gunichar *outchar); +static int encode_utf8 (gunichar c, char *outbuf, size_t outleft); + +static int decode_latin1 (char *inbuf, size_t inleft, gunichar *outchar); +static int encode_latin1 (gunichar c, char *outbuf, size_t outleft); + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define decode_utf32 decode_utf32le +#define encode_utf32 encode_utf32le +#define decode_utf16 decode_utf16le +#define encode_utf16 encode_utf16le +#else +#define decode_utf32 decode_utf32be +#define encode_utf32 encode_utf32be +#define decode_utf16 decode_utf16be +#define encode_utf16 encode_utf16be +#endif + +static struct { + const char *name; + Decoder decoder; + Encoder encoder; +} charsets[] = { + { "ISO-8859-1", decode_latin1, encode_latin1 }, + { "ISO8859-1", decode_latin1, encode_latin1 }, + { "UTF-32BE", decode_utf32be, encode_utf32be }, + { "UTF-32LE", decode_utf32le, encode_utf32le }, + { "UTF-16BE", decode_utf16be, encode_utf16be }, + { "UTF-16LE", decode_utf16le, encode_utf16le }, + { "UTF-32", decode_utf32, encode_utf32 }, + { "UTF-16", decode_utf16, encode_utf16 }, + { "UTF-8", decode_utf8, encode_utf8 }, + { "US-ASCII", decode_latin1, encode_latin1 }, + { "Latin1", decode_latin1, encode_latin1 }, + { "ASCII", decode_latin1, encode_latin1 }, + { "UTF32", decode_utf32, encode_utf32 }, + { "UTF16", decode_utf16, encode_utf16 }, + { "UTF8", decode_utf8, encode_utf8 }, +}; + + +GIConv +g_iconv_open (const char *to_charset, const char *from_charset) +{ +#ifdef HAVE_ICONV + iconv_t icd = (iconv_t) -1; +#endif + Decoder decoder = NULL; + Encoder encoder = NULL; + GIConv cd; + guint i; + + if (!to_charset || !from_charset || !to_charset[0] || !from_charset[0]) { + errno = EINVAL; + + return (GIConv) -1; + } + + for (i = 0; i < G_N_ELEMENTS (charsets); i++) { + if (!g_ascii_strcasecmp (charsets[i].name, from_charset)) + decoder = charsets[i].decoder; + + if (!g_ascii_strcasecmp (charsets[i].name, to_charset)) + encoder = charsets[i].encoder; + } + + if (!encoder || !decoder) { +#ifdef HAVE_ICONV + if ((icd = iconv_open (to_charset, from_charset)) == (iconv_t) -1) + return (GIConv) -1; +#else + errno = EINVAL; + + return (GIConv) -1; +#endif + } + + cd = (GIConv) g_malloc (sizeof (struct _GIConv)); + cd->decode = decoder; + cd->encode = encoder; + cd->c = -1; + +#ifdef HAVE_ICONV + cd->cd = icd; +#endif + + return cd; +} + +int +g_iconv_close (GIConv cd) +{ +#ifdef HAVE_ICONV + if (cd->cd != (iconv_t) -1) + iconv_close (cd->cd); +#endif + + g_free (cd); + + return 0; +} + +gsize +g_iconv (GIConv cd, gchar **inbytes, gsize *inbytesleft, + gchar **outbytes, gsize *outbytesleft) +{ + gsize inleft, outleft; + char *inptr, *outptr; + gunichar c; + int rc = 0; + +#ifdef HAVE_ICONV + if (cd->cd != (iconv_t) -1) { + /* Note: gsize may have a different size than size_t, so we need to + remap inbytesleft and outbytesleft to size_t's. */ + size_t *outleftptr, *inleftptr; + size_t n_outleft, n_inleft; + + if (inbytesleft) { + n_inleft = *inbytesleft; + inleftptr = &n_inleft; + } else { + inleftptr = NULL; + } + + if (outbytesleft) { + n_outleft = *outbytesleft; + outleftptr = &n_outleft; + } else { + outleftptr = NULL; + } + + return iconv (cd->cd, inbytes, inleftptr, outbytes, outleftptr); + } +#endif + + if (outbytes == NULL || outbytesleft == NULL) { + /* reset converter */ + cd->c = -1; + return 0; + } + + inleft = inbytesleft ? *inbytesleft : 0; + inptr = inbytes ? *inbytes : NULL; + outleft = *outbytesleft; + outptr = *outbytes; + + if ((c = cd->c) != (gunichar) -1) + goto encode; + + while (inleft > 0) { + if ((rc = cd->decode (inptr, inleft, &c)) < 0) + break; + + inleft -= rc; + inptr += rc; + + encode: + if ((rc = cd->encode (c, outptr, outleft)) < 0) + break; + + c = (gunichar) -1; + outleft -= rc; + outptr += rc; + } + + if (inbytesleft) + *inbytesleft = inleft; + + if (inbytes) + *inbytes = inptr; + + *outbytesleft = outleft; + *outbytes = outptr; + cd->c = c; + + return rc < 0 ? -1 : 0; +} + +/* + * Unicode encoders and decoders + */ + +static int +decode_utf32be (char *inbuf, size_t inleft, gunichar *outchar) +{ + unsigned char *inptr = (unsigned char *) inbuf; + gunichar c; + + if (inleft < 4) { + errno = EINVAL; + return -1; + } + + c = (inptr[0] << 24) | (inptr[1] << 16) | (inptr[2] << 8) | inptr[3]; + + if (c >= 0xd800 && c < 0xe000) { + errno = EILSEQ; + return -1; + } else if (c >= 0x110000) { + errno = EILSEQ; + return -1; + } + + *outchar = c; + + return 4; +} + +static int +decode_utf32le (char *inbuf, size_t inleft, gunichar *outchar) +{ + unsigned char *inptr = (unsigned char *) inbuf; + gunichar c; + + if (inleft < 4) { + errno = EINVAL; + return -1; + } + + c = (inptr[3] << 24) | (inptr[2] << 16) | (inptr[1] << 8) | inptr[0]; + + if (c >= 0xd800 && c < 0xe000) { + errno = EILSEQ; + return -1; + } else if (c >= 0x110000) { + errno = EILSEQ; + return -1; + } + + *outchar = c; + + return 4; +} + +static int +encode_utf32be (gunichar c, char *outbuf, size_t outleft) +{ + unsigned char *outptr = (unsigned char *) outbuf; + + if (outleft < 4) { + errno = E2BIG; + return -1; + } + + outptr[0] = (c >> 24) & 0xff; + outptr[1] = (c >> 16) & 0xff; + outptr[2] = (c >> 8) & 0xff; + outptr[3] = c & 0xff; + + return 4; +} + +static int +encode_utf32le (gunichar c, char *outbuf, size_t outleft) +{ + unsigned char *outptr = (unsigned char *) outbuf; + + if (outleft < 4) { + errno = E2BIG; + return -1; + } + + outptr[0] = c & 0xff; + outptr[1] = (c >> 8) & 0xff; + outptr[2] = (c >> 16) & 0xff; + outptr[3] = (c >> 24) & 0xff; + + return 4; +} + +static int +decode_utf16be (char *inbuf, size_t inleft, gunichar *outchar) +{ + unsigned char *inptr = (unsigned char *) inbuf; + gunichar2 c; + gunichar u; + + if (inleft < 2) { + errno = EINVAL; + return -1; + } + + u = (inptr[0] << 8) | inptr[1]; + + if (u < 0xd800) { + /* 0x0000 -> 0xd7ff */ + *outchar = u; + return 2; + } else if (u < 0xdc00) { + /* 0xd800 -> 0xdbff */ + if (inleft < 4) { + errno = EINVAL; + return -2; + } + + c = (inptr[2] << 8) | inptr[3]; + + if (c < 0xdc00 || c > 0xdfff) { + errno = EILSEQ; + return -2; + } + + u = ((u - 0xd800) << 10) + (c - 0xdc00) + 0x0010000UL; + *outchar = u; + + return 4; + } else if (u < 0xe000) { + /* 0xdc00 -> 0xdfff */ + errno = EILSEQ; + return -1; + } else { + /* 0xe000 -> 0xffff */ + *outchar = u; + return 2; + } +} + +static int +decode_utf16le (char *inbuf, size_t inleft, gunichar *outchar) +{ + unsigned char *inptr = (unsigned char *) inbuf; + gunichar2 c; + gunichar u; + + if (inleft < 2) { + errno = EINVAL; + return -1; + } + + u = (inptr[1] << 8) | inptr[0]; + + if (u < 0xd800) { + /* 0x0000 -> 0xd7ff */ + *outchar = u; + return 2; + } else if (u < 0xdc00) { + /* 0xd800 -> 0xdbff */ + if (inleft < 4) { + errno = EINVAL; + return -2; + } + + c = (inptr[3] << 8) | inptr[2]; + + if (c < 0xdc00 || c > 0xdfff) { + errno = EILSEQ; + return -2; + } + + u = ((u - 0xd800) << 10) + (c - 0xdc00) + 0x0010000UL; + *outchar = u; + + return 4; + } else if (u < 0xe000) { + /* 0xdc00 -> 0xdfff */ + errno = EILSEQ; + return -1; + } else { + /* 0xe000 -> 0xffff */ + *outchar = u; + return 2; + } +} + +static int +encode_utf16be (gunichar c, char *outbuf, size_t outleft) +{ + unsigned char *outptr = (unsigned char *) outbuf; + gunichar2 ch; + gunichar c2; + + if (c < 0x10000) { + if (outleft < 2) { + errno = E2BIG; + return -1; + } + + outptr[0] = (c >> 8) & 0xff; + outptr[1] = c & 0xff; + + return 2; + } else { + if (outleft < 4) { + errno = E2BIG; + return -1; + } + + c2 = c - 0x10000; + + ch = (gunichar2) ((c2 >> 10) + 0xd800); + outptr[0] = (ch >> 8) & 0xff; + outptr[1] = ch & 0xff; + + ch = (gunichar2) ((c2 & 0x3ff) + 0xdc00); + outptr[2] = (ch >> 8) & 0xff; + outptr[3] = ch & 0xff; + + return 4; + } +} + +static int +encode_utf16le (gunichar c, char *outbuf, size_t outleft) +{ + unsigned char *outptr = (unsigned char *) outbuf; + gunichar2 ch; + gunichar c2; + + if (c < 0x10000) { + if (outleft < 2) { + errno = E2BIG; + return -1; + } + + outptr[0] = c & 0xff; + outptr[1] = (c >> 8) & 0xff; + + return 2; + } else { + if (outleft < 4) { + errno = E2BIG; + return -1; + } + + c2 = c - 0x10000; + + ch = (gunichar2) ((c2 >> 10) + 0xd800); + outptr[0] = ch & 0xff; + outptr[1] = (ch >> 8) & 0xff; + + ch = (gunichar2) ((c2 & 0x3ff) + 0xdc00); + outptr[2] = ch & 0xff; + outptr[3] = (ch >> 8) & 0xff; + + return 4; + } +} + +static FORCE_INLINE (int) +decode_utf8 (char *inbuf, size_t inleft, gunichar *outchar) +{ + unsigned char *inptr = (unsigned char *) inbuf; + gunichar u; + int n, i; + + u = *inptr; + + if (u < 0x80) { + /* simple ascii case */ + *outchar = u; + return 1; + } else if (u < 0xc2) { + errno = EILSEQ; + return -1; + } else if (u < 0xe0) { + u &= 0x1f; + n = 2; + } else if (u < 0xf0) { + u &= 0x0f; + n = 3; + } else if (u < 0xf8) { + u &= 0x07; + n = 4; + } else if (u < 0xfc) { + u &= 0x03; + n = 5; + } else if (u < 0xfe) { + u &= 0x01; + n = 6; + } else { + errno = EILSEQ; + return -1; + } + + if (n > inleft) { + errno = EINVAL; + return -1; + } + +#if UNROLL_DECODE_UTF8 + switch (n) { + case 6: u = (u << 6) | (*++inptr ^ 0x80); + case 5: u = (u << 6) | (*++inptr ^ 0x80); + case 4: u = (u << 6) | (*++inptr ^ 0x80); + case 3: u = (u << 6) | (*++inptr ^ 0x80); + case 2: u = (u << 6) | (*++inptr ^ 0x80); + } +#else + for (i = 1; i < n; i++) + u = (u << 6) | (*++inptr ^ 0x80); +#endif + + *outchar = u; + + return n; +} + +static int +encode_utf8 (gunichar c, char *outbuf, size_t outleft) +{ + unsigned char *outptr = (unsigned char *) outbuf; + int base, n, i; + + if (c < 0x80) { + outptr[0] = c; + return 1; + } else if (c < 0x800) { + base = 192; + n = 2; + } else if (c < 0x10000) { + base = 224; + n = 3; + } else if (c < 0x200000) { + base = 240; + n = 4; + } else if (c < 0x4000000) { + base = 248; + n = 5; + } else { + base = 252; + n = 6; + } + + if (outleft < n) { + errno = E2BIG; + return -1; + } + +#if UNROLL_ENCODE_UTF8 + switch (n) { + case 6: outptr[5] = (c & 0x3f) | 0x80; c >>= 6; + case 5: outptr[4] = (c & 0x3f) | 0x80; c >>= 6; + case 4: outptr[3] = (c & 0x3f) | 0x80; c >>= 6; + case 3: outptr[2] = (c & 0x3f) | 0x80; c >>= 6; + case 2: outptr[1] = (c & 0x3f) | 0x80; c >>= 6; + case 1: outptr[0] = c | base; + } +#else + for (i = n - 1; i > 0; i--) { + outptr[i] = (c & 0x3f) | 0x80; + c >>= 6; + } + + outptr[0] = c | base; +#endif + + return n; +} + +static int +decode_latin1 (char *inbuf, size_t inleft, gunichar *outchar) +{ + *outchar = (unsigned char) *inbuf; + return 1; +} + +static int +encode_latin1 (gunichar c, char *outbuf, size_t outleft) +{ + if (outleft < 1) { + errno = E2BIG; + return -1; + } + + if (c > 0xff) { + errno = EILSEQ; + return -1; + } + + *outbuf = (char) c; + + return 1; +} + + +/* + * Simple conversion API + */ + +GQuark +g_convert_error_quark (void) +{ + return g_quark_from_static_string ("g-convert-error-quark"); +} + +gchar * +g_convert (const gchar *str, gssize len, const gchar *to_charset, const gchar *from_charset, + gsize *bytes_read, gsize *bytes_written, GError **err) +{ + gsize outsize, outused, outleft, inleft, grow, rc; + char *result, *outbuf, *inbuf; + gboolean flush = FALSE; + gboolean done = FALSE; + GIConv cd; + + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (to_charset != NULL, NULL); + g_return_val_if_fail (from_charset != NULL, NULL); + + if ((cd = g_iconv_open (to_charset, from_charset)) == (GIConv) -1) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, + "Conversion from %s to %s not supported.", + from_charset, to_charset); + + if (bytes_written) + *bytes_written = 0; + + if (bytes_read) + *bytes_read = 0; + + return NULL; + } + + inleft = len < 0 ? strlen (str) : len; + inbuf = (char *) str; + + outleft = outsize = MAX (inleft, 8); + outbuf = result = g_malloc (outsize + 4); + + do { + if (!flush) + rc = g_iconv (cd, &inbuf, &inleft, &outbuf, &outleft); + else + rc = g_iconv (cd, NULL, NULL, &outbuf, &outleft); + + if (rc == (gsize) -1) { + switch (errno) { + case E2BIG: + /* grow our result buffer */ + grow = MAX (inleft, 8) << 1; + outused = outbuf - result; + outsize += grow; + outleft += grow; + result = g_realloc (result, outsize + 4); + outbuf = result + outused; + break; + case EINVAL: + /* incomplete input, stop converting and terminate here */ + if (flush) + done = TRUE; + else + flush = TRUE; + break; + case EILSEQ: + /* illegal sequence in the input */ + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, "%s", g_strerror (errno)); + + if (bytes_read) { + /* save offset of the illegal input sequence */ + *bytes_read = (inbuf - str); + } + + if (bytes_written) + *bytes_written = 0; + + g_iconv_close (cd); + g_free (result); + return NULL; + default: + /* unknown errno */ + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, "%s", g_strerror (errno)); + + if (bytes_written) + *bytes_written = 0; + + if (bytes_read) + *bytes_read = 0; + + g_iconv_close (cd); + g_free (result); + return NULL; + } + } else if (flush) { + /* input has been converted and output has been flushed */ + break; + } else { + /* input has been converted, need to flush the output */ + flush = TRUE; + } + } while (!done); + + g_iconv_close (cd); + + /* Note: not all charsets can be null-terminated with a single + null byte. UCS2, for example, needs 2 null bytes and UCS4 + needs 4. I hope that 4 null bytes is enough to terminate all + multibyte charsets? */ + + /* null-terminate the result */ + memset (outbuf, 0, 4); + + if (bytes_written) + *bytes_written = outbuf - result; + + if (bytes_read) + *bytes_read = inbuf - str; + + return result; +} + + +/* + * Unicode conversion + */ + +/** + * from http://home.tiscali.nl/t876506/utf8tbl.html + * + * From Unicode UCS-4 to UTF-8: + * Start with the Unicode number expressed as a decimal number and call this ud. + * + * If ud <128 (7F hex) then UTF-8 is 1 byte long, the value of ud. + * + * If ud >=128 and <=2047 (7FF hex) then UTF-8 is 2 bytes long. + * byte 1 = 192 + (ud div 64) + * byte 2 = 128 + (ud mod 64) + * + * If ud >=2048 and <=65535 (FFFF hex) then UTF-8 is 3 bytes long. + * byte 1 = 224 + (ud div 4096) + * byte 2 = 128 + ((ud div 64) mod 64) + * byte 3 = 128 + (ud mod 64) + * + * If ud >=65536 and <=2097151 (1FFFFF hex) then UTF-8 is 4 bytes long. + * byte 1 = 240 + (ud div 262144) + * byte 2 = 128 + ((ud div 4096) mod 64) + * byte 3 = 128 + ((ud div 64) mod 64) + * byte 4 = 128 + (ud mod 64) + * + * If ud >=2097152 and <=67108863 (3FFFFFF hex) then UTF-8 is 5 bytes long. + * byte 1 = 248 + (ud div 16777216) + * byte 2 = 128 + ((ud div 262144) mod 64) + * byte 3 = 128 + ((ud div 4096) mod 64) + * byte 4 = 128 + ((ud div 64) mod 64) + * byte 5 = 128 + (ud mod 64) + * + * If ud >=67108864 and <=2147483647 (7FFFFFFF hex) then UTF-8 is 6 bytes long. + * byte 1 = 252 + (ud div 1073741824) + * byte 2 = 128 + ((ud div 16777216) mod 64) + * byte 3 = 128 + ((ud div 262144) mod 64) + * byte 4 = 128 + ((ud div 4096) mod 64) + * byte 5 = 128 + ((ud div 64) mod 64) + * byte 6 = 128 + (ud mod 64) + **/ +gint +g_unichar_to_utf8 (gunichar c, gchar *outbuf) +{ + int base, n, i; + + if (c < 0x80) { + base = 0; + n = 1; + } else if (c < 0x800) { + base = 192; + n = 2; + } else if (c < 0x10000) { + base = 224; + n = 3; + } else if (c < 0x200000) { + base = 240; + n = 4; + } else if (c < 0x4000000) { + base = 248; + n = 5; + } else if (c < 0x80000000) { + base = 252; + n = 6; + } else { + return -1; + } + + if (outbuf != NULL) { + for (i = n - 1; i > 0; i--) { + /* mask off 6 bits worth and add 128 */ + outbuf[i] = (c & 0x3f) | 0x80; + c >>= 6; + } + + /* first character has a different base */ + outbuf[0] = c | base; + } + + return n; +} + +static FORCE_INLINE (int) +g_unichar_to_utf16 (gunichar c, gunichar2 *outbuf) +{ + gunichar c2; + + if (c < 0xd800) { + if (outbuf) + *outbuf = (gunichar2) c; + + return 1; + } else if (c < 0xe000) { + return -1; + } else if (c < 0x10000) { + if (outbuf) + *outbuf = (gunichar2) c; + + return 1; + } else if (c < 0x110000) { + if (outbuf) { + c2 = c - 0x10000; + + outbuf[0] = (gunichar2) ((c2 >> 10) + 0xd800); + outbuf[1] = (gunichar2) ((c2 & 0x3ff) + 0xdc00); + } + + return 2; + } else { + return -1; + } +} + +gunichar * +g_utf8_to_ucs4_fast (const gchar *str, glong len, glong *items_written) +{ + gunichar *outbuf, *outptr; + char *inptr; + glong n, i; + + g_return_val_if_fail (str != NULL, NULL); + + n = g_utf8_strlen (str, len); + + if (items_written) + *items_written = n; + + outptr = outbuf = g_malloc ((n + 1) * sizeof (gunichar)); + inptr = (char *) str; + + for (i = 0; i < n; i++) { + *outptr++ = g_utf8_get_char (inptr); + inptr = g_utf8_next_char (inptr); + } + + *outptr = 0; + + return outbuf; +} + +static gunichar2 * +eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong *items_written, gboolean include_nuls, GError **err) +{ + gunichar2 *outbuf, *outptr; + size_t outlen = 0; + size_t inleft; + char *inptr; + gunichar c; + int u, n; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) { + if (include_nuls) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, "Conversions with embedded nulls must pass the string length"); + return NULL; + } + + len = strlen (str); + } + + inptr = (char *) str; + inleft = len; + + while (inleft > 0) { + if ((n = decode_utf8 (inptr, inleft, &c)) < 0) + goto error; + + if (c == 0 && !include_nuls) + break; + + if ((u = g_unichar_to_utf16 (c, NULL)) < 0) { + errno = EILSEQ; + goto error; + } + + outlen += u; + inleft -= n; + inptr += n; + } + + if (items_read) + *items_read = inptr - str; + + if (items_written) + *items_written = outlen; + + outptr = outbuf = g_malloc ((outlen + 1) * sizeof (gunichar2)); + inptr = (char *) str; + inleft = len; + + while (inleft > 0) { + if ((n = decode_utf8 (inptr, inleft, &c)) < 0) + break; + + if (c == 0 && !include_nuls) + break; + + outptr += g_unichar_to_utf16 (c, outptr); + inleft -= n; + inptr += n; + } + + *outptr = '\0'; + + return outbuf; + + error: + if (errno == EILSEQ) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + } else if (items_read) { + /* partial input is ok if we can let our caller know... */ + } else { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + "Partial byte sequence encountered in the input."); + } + + if (items_read) + *items_read = inptr - str; + + if (items_written) + *items_written = 0; + + return NULL; +} + +gunichar2 * +g_utf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, err); +} + +gunichar2 * +eg_utf8_to_utf16_with_nuls (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + return eg_utf8_to_utf16_general (str, len, items_read, items_written, TRUE, err); +} + +gunichar * +g_utf8_to_ucs4 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + gunichar *outbuf, *outptr; + size_t outlen = 0; + size_t inleft; + char *inptr; + gunichar c; + int n; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) + len = strlen (str); + + inptr = (char *) str; + inleft = len; + + while (inleft > 0) { + if ((n = decode_utf8 (inptr, inleft, &c)) < 0) { + if (errno == EILSEQ) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + } else if (items_read) { + /* partial input is ok if we can let our caller know... */ + break; + } else { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + "Partial byte sequence encountered in the input."); + } + + if (items_read) + *items_read = inptr - str; + + if (items_written) + *items_written = 0; + + return NULL; + } else if (c == 0) + break; + + outlen += 4; + inleft -= n; + inptr += n; + } + + if (items_written) + *items_written = outlen / 4; + + if (items_read) + *items_read = inptr - str; + + outptr = outbuf = g_malloc (outlen + 4); + inptr = (char *) str; + inleft = len; + + while (inleft > 0) { + if ((n = decode_utf8 (inptr, inleft, &c)) < 0) + break; + else if (c == 0) + break; + + *outptr++ = c; + inleft -= n; + inptr += n; + } + + *outptr = 0; + + return outbuf; +} + +gchar * +g_utf16_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + char *inptr, *outbuf, *outptr; + size_t outlen = 0; + size_t inleft; + gunichar c; + int n; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) { + len = 0; + while (str[len]) + len++; + } + + inptr = (char *) str; + inleft = len * 2; + + while (inleft > 0) { + if ((n = decode_utf16 (inptr, inleft, &c)) < 0) { + if (n == -2 && inleft > 2) { + /* This means that the first UTF-16 char was read, but second failed */ + inleft -= 2; + inptr += 2; + } + + if (errno == EILSEQ) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + } else if (items_read) { + /* partial input is ok if we can let our caller know... */ + break; + } else { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + "Partial byte sequence encountered in the input."); + } + + if (items_read) + *items_read = (inptr - (char *) str) / 2; + + if (items_written) + *items_written = 0; + + return NULL; + } else if (c == 0) + break; + + outlen += g_unichar_to_utf8 (c, NULL); + inleft -= n; + inptr += n; + } + + if (items_read) + *items_read = (inptr - (char *) str) / 2; + + if (items_written) + *items_written = outlen; + + outptr = outbuf = g_malloc (outlen + 1); + inptr = (char *) str; + inleft = len * 2; + + while (inleft > 0) { + if ((n = decode_utf16 (inptr, inleft, &c)) < 0) + break; + else if (c == 0) + break; + + outptr += g_unichar_to_utf8 (c, outptr); + inleft -= n; + inptr += n; + } + + *outptr = '\0'; + + return outbuf; +} + +gunichar * +g_utf16_to_ucs4 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + gunichar *outbuf, *outptr; + size_t outlen = 0; + size_t inleft; + char *inptr; + gunichar c; + int n; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) { + len = 0; + while (str[len]) + len++; + } + + inptr = (char *) str; + inleft = len * 2; + + while (inleft > 0) { + if ((n = decode_utf16 (inptr, inleft, &c)) < 0) { + if (n == -2 && inleft > 2) { + /* This means that the first UTF-16 char was read, but second failed */ + inleft -= 2; + inptr += 2; + } + + if (errno == EILSEQ) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + } else if (items_read) { + /* partial input is ok if we can let our caller know... */ + break; + } else { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + "Partial byte sequence encountered in the input."); + } + + if (items_read) + *items_read = (inptr - (char *) str) / 2; + + if (items_written) + *items_written = 0; + + return NULL; + } else if (c == 0) + break; + + outlen += 4; + inleft -= n; + inptr += n; + } + + if (items_read) + *items_read = (inptr - (char *) str) / 2; + + if (items_written) + *items_written = outlen / 4; + + outptr = outbuf = g_malloc (outlen + 4); + inptr = (char *) str; + inleft = len * 2; + + while (inleft > 0) { + if ((n = decode_utf16 (inptr, inleft, &c)) < 0) + break; + else if (c == 0) + break; + + *outptr++ = c; + inleft -= n; + inptr += n; + } + + *outptr = 0; + + return outbuf; +} + +gchar * +g_ucs4_to_utf8 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + char *outbuf, *outptr; + size_t outlen = 0; + glong i; + int n; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) { + for (i = 0; str[i] != 0; i++) { + if ((n = g_unichar_to_utf8 (str[i], NULL)) < 0) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + + if (items_written) + *items_written = 0; + + if (items_read) + *items_read = i; + + return NULL; + } + + outlen += n; + } + } else { + for (i = 0; i < len && str[i] != 0; i++) { + if ((n = g_unichar_to_utf8 (str[i], NULL)) < 0) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + + if (items_written) + *items_written = 0; + + if (items_read) + *items_read = i; + + return NULL; + } + + outlen += n; + } + } + + len = i; + + outptr = outbuf = g_malloc (outlen + 1); + for (i = 0; i < len; i++) + outptr += g_unichar_to_utf8 (str[i], outptr); + *outptr = 0; + + if (items_written) + *items_written = outlen; + + if (items_read) + *items_read = i; + + return outbuf; +} + +gunichar2 * +g_ucs4_to_utf16 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **err) +{ + gunichar2 *outbuf, *outptr; + size_t outlen = 0; + glong i; + int n; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) { + for (i = 0; str[i] != 0; i++) { + if ((n = g_unichar_to_utf16 (str[i], NULL)) < 0) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + + if (items_written) + *items_written = 0; + + if (items_read) + *items_read = i; + + return NULL; + } + + outlen += n; + } + } else { + for (i = 0; i < len && str[i] != 0; i++) { + if ((n = g_unichar_to_utf16 (str[i], NULL)) < 0) { + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + "Illegal byte sequence encounted in the input."); + + if (items_written) + *items_written = 0; + + if (items_read) + *items_read = i; + + return NULL; + } + + outlen += n; + } + } + + len = i; + + outptr = outbuf = g_malloc ((outlen + 1) * sizeof (gunichar2)); + for (i = 0; i < len; i++) + outptr += g_unichar_to_utf16 (str[i], outptr); + *outptr = 0; + + if (items_written) + *items_written = outlen; + + if (items_read) + *items_read = i; + + return outbuf; +} diff --git a/deps/eglib/src/glib.h b/deps/eglib/src/glib.h new file mode 100644 index 00000000..c717eedd --- /dev/null +++ b/deps/eglib/src/glib.h @@ -0,0 +1,1290 @@ +#ifndef __GLIB_H +#define __GLIB_H + +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stddef.h> +#include <ctype.h> +#include <limits.h> +#include <float.h> + +#ifdef _MSC_VER +#pragma include_alias(<eglib-config.h>, <eglib-config.hw>) +#endif + +/* VS 2010 and later have stdint.h */ +#if defined(_MSC_VER) && _MSC_VER < 1600 +#else +#include <stdint.h> +#endif + +#include <eglib-config.h> + +#ifdef G_HAVE_ALLOCA_H +#include <alloca.h> +#endif + +#ifdef WIN32 +/* For alloca */ +#include <malloc.h> +#endif + +#ifndef offsetof +# define offsetof(s_name,n_name) (size_t)(char *)&(((s_name*)0)->m_name) +#endif + +#define __EGLIB_X11 1 + +#ifdef __cplusplus +#define G_BEGIN_DECLS extern "C" { +#define G_END_DECLS } +#else +#define G_BEGIN_DECLS +#define G_END_DECLS +#endif + +G_BEGIN_DECLS + +#ifdef G_OS_WIN32 +/* MSC and Cross-compilatin will use this */ +int vasprintf (char **strp, const char *fmt, va_list ap); +#endif + + +/* + * Basic data types + */ +typedef int gint; +typedef unsigned int guint; +typedef short gshort; +typedef unsigned short gushort; +typedef long glong; +typedef unsigned long gulong; +typedef void * gpointer; +typedef const void * gconstpointer; +typedef char gchar; +typedef unsigned char guchar; + +/* VS 2010 and later have stdint.h */ +#if defined(_MSC_VER) && _MSC_VER < 1600 +typedef __int8 gint8; +typedef unsigned __int8 guint8; +typedef __int16 gint16; +typedef unsigned __int16 guint16; +typedef __int32 gint32; +typedef unsigned __int32 guint32; +typedef __int64 gint64; +typedef unsigned __int64 guint64; +typedef float gfloat; +typedef double gdouble; +typedef int gboolean; +#else +/* Types defined in terms of the stdint.h */ +typedef int8_t gint8; +typedef uint8_t guint8; +typedef int16_t gint16; +typedef uint16_t guint16; +typedef int32_t gint32; +typedef uint32_t guint32; +typedef int64_t gint64; +typedef uint64_t guint64; +typedef float gfloat; +typedef double gdouble; +typedef int32_t gboolean; +#endif + +typedef guint16 gunichar2; +typedef guint32 gunichar; + +/* + * Macros + */ +#define G_N_ELEMENTS(s) (sizeof(s) / sizeof ((s) [0])) +#define G_STRINGIFY_ARG(arg) #arg +#define G_STRINGIFY(arg) G_STRINGIFY_ARG(arg) +#define G_PASTE_ARGS(part0, part1) part0 ## part1 +#define G_PASTE(part0, part1) G_PASTE_ARGS (part0, part1) + +#define FALSE 0 +#define TRUE 1 + +#define G_MINSHORT SHRT_MIN +#define G_MAXSHORT SHRT_MAX +#define G_MAXUSHORT USHRT_MAX +#define G_MAXINT INT_MAX +#define G_MININT INT_MIN +#define G_MAXINT32 INT32_MAX +#define G_MAXUINT32 UINT32_MAX +#define G_MININT32 INT32_MIN +#define G_MININT64 INT64_MIN +#define G_MAXINT64 INT64_MAX +#define G_MAXUINT64 UINT64_MAX +#define G_MAXFLOAT FLT_MAX + +#define G_LITTLE_ENDIAN 1234 +#define G_BIG_ENDIAN 4321 +#define G_STMT_START do +#define G_STMT_END while (0) + +#define G_USEC_PER_SEC 1000000 +#define G_PI 3.141592653589793238462643383279502884L +#define G_PI_2 1.570796326794896619231321691639751442L + +#define G_GINT64_CONSTANT(val) (val##LL) +#define G_GUINT64_CONSTANT(val) (val##UL) + +#ifndef ABS +#define ABS(a) ((a) > 0 ? (a) : -(a)) +#endif + +#define G_STRUCT_OFFSET(p_type,field) offsetof(p_type,field) + +#define G_STRLOC __FILE__ ":" G_STRINGIFY(__LINE__) ":" + +#define G_CONST_RETURN const + +/* + * Allocation + */ +void g_free (void *ptr); +gpointer g_realloc (gpointer obj, gsize size); +gpointer g_malloc (gsize x); +gpointer g_malloc0 (gsize x); +gpointer g_try_malloc (gsize x); +gpointer g_try_realloc (gpointer obj, gsize size); +gpointer g_memdup (gconstpointer mem, guint byte_size); + +#define g_new(type,size) ((type *) g_malloc (sizeof (type) * (size))) +#define g_new0(type,size) ((type *) g_malloc0 (sizeof (type)* (size))) +#define g_newa(type,size) ((type *) alloca (sizeof (type) * (size))) + +#define g_memmove(dest,src,len) memmove (dest, src, len) +#define g_renew(struct_type, mem, n_structs) g_realloc (mem, sizeof (struct_type) * n_structs) +#define g_alloca(size) alloca (size) + +#define g_slice_new(type) ((type *) g_malloc (sizeof (type))) +#define g_slice_new0(type) ((type *) g_malloc0 (sizeof (type))) +#define g_slice_free(type, mem) g_free (mem) +#define g_slice_free1(size, mem) g_free (mem) +#define g_slice_alloc(size) g_malloc (size) +#define g_slice_alloc0(size) g_malloc0 (size) +#define g_slice_dup(type, mem) g_memdup (mem, sizeof (type)) +#define g_slice_copy(size, mem) g_memdup (mem, size) + +static inline gchar *g_strdup (const gchar *str) { if (str) {return strdup (str);} return NULL; } +gchar **g_strdupv (gchar **str_array); + +typedef struct { + gpointer (*malloc) (gsize n_bytes); + gpointer (*realloc) (gpointer mem, gsize n_bytes); + void (*free) (gpointer mem); + gpointer (*calloc) (gsize n_blocks, gsize n_block_bytes); + gpointer (*try_malloc) (gsize n_bytes); + gpointer (*try_realloc) (gpointer mem, gsize n_bytes); +} GMemVTable; + +#define g_mem_set_vtable(x) + +struct _GMemChunk { + guint alloc_size; +}; + +typedef struct _GMemChunk GMemChunk; +/* + * Misc. + */ +#define g_atexit(func) ((void) atexit (func)) + +const gchar * g_getenv(const gchar *variable); +gboolean g_setenv(const gchar *variable, const gchar *value, gboolean overwrite); +void g_unsetenv(const gchar *variable); + +gchar* g_win32_getlocale(void); + +/* + * Precondition macros + */ +#define g_warn_if_fail(x) G_STMT_START { if (!(x)) { g_warning ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); } } G_STMT_END +#define g_warn_if_reached() g_warning ("%s:%d: code should not be reached!", __FILE__, __LINE__) + +#define g_return_if_fail(x) G_STMT_START { if (!(x)) { g_critical ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return; } } G_STMT_END +#define g_return_val_if_fail(x,e) G_STMT_START { if (!(x)) { g_critical ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return (e); } } G_STMT_END +#define g_return_if_reached(e) G_STMT_START { g_warning ("%s:%d: code should not be reached, returning!", __FILE__, __LINE__); return; } G_STMT_END +#define g_return_val_if_reached(e) G_STMT_START { g_warning ("%s:%d: code should not be reached, returning!", __FILE__, __LINE__); return (e); } G_STMT_END + +/* + * DebugKeys + */ +typedef struct _GDebugKey { + const gchar *key; + guint value; +} GDebugKey; + +guint g_parse_debug_string (const gchar *string, const GDebugKey *keys, guint nkeys); + +/* + * Quark + */ + +typedef guint32 GQuark; + +GQuark +g_quark_from_static_string (const gchar *string); + +/* + * Errors + */ +typedef struct { + GQuark domain; + gint code; + gchar *message; +} GError; + +void g_clear_error (GError **error); +void g_error_free (GError *error); +GError *g_error_new (GQuark domain, gint code, const char *format, ...); +GError *g_error_new_valist (GQuark domain, gint code, const char *format, va_list ap); +void g_set_error (GError **err, GQuark domain, gint code, const gchar *format, ...); +void g_propagate_error (GError **dest, GError *src); +GError *g_error_copy (const GError *error); +gboolean g_error_matches (const GError *error, GQuark domain, gint code); + +/* + * Strings utility + */ +gchar *g_strdup_printf (const gchar *format, ...); +gchar *g_strdup_vprintf (const gchar *format, va_list args); +gchar *g_strndup (const gchar *str, gsize n); +const gchar *g_strerror (gint errnum); +gchar *g_strndup (const gchar *str, gsize n); +void g_strfreev (gchar **str_array); +gchar *g_strconcat (const gchar *first, ...); +gchar **g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens); +gchar **g_strsplit_set (const gchar *string, const gchar *delimiter, gint max_tokens); +gchar *g_strreverse (gchar *str); +gboolean g_str_has_prefix (const gchar *str, const gchar *prefix); +gboolean g_str_has_suffix (const gchar *str, const gchar *suffix); +guint g_strv_length (gchar **str_array); +gchar *g_strjoin (const gchar *separator, ...); +gchar *g_strjoinv (const gchar *separator, gchar **str_array); +gchar *g_strchug (gchar *str); +gchar *g_strchomp (gchar *str); +void g_strdown (gchar *string); +gchar *g_strnfill (gsize length, gchar fill_char); + +gchar *g_strdelimit (gchar *string, const gchar *delimiters, gchar new_delimiter); +gchar *g_strescape (const gchar *source, const gchar *exceptions); + +gchar *g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error); +gchar *g_filename_from_uri (const gchar *uri, gchar **hostname, GError **error); + +gint g_printf (gchar const *format, ...); +gint g_fprintf (FILE *file, gchar const *format, ...); +gint g_sprintf (gchar *string, gchar const *format, ...); +gint g_snprintf (gchar *string, gulong n, gchar const *format, ...); +#define g_vprintf vprintf +#define g_vfprintf vfprintf +#define g_vsprintf vsprintf +#define g_vsnprintf vsnprintf +#define g_vasprintf vasprintf + +gsize g_strlcpy (gchar *dest, const gchar *src, gsize dest_size); +gchar *g_stpcpy (gchar *dest, const char *src); + + +gchar g_ascii_tolower (gchar c); +gchar g_ascii_toupper (gchar c); +gchar *g_ascii_strdown (const gchar *str, gssize len); +gchar *g_ascii_strup (const gchar *str, gssize len); +gint g_ascii_strncasecmp (const gchar *s1, const gchar *s2, gsize n); +gint g_ascii_strcasecmp (const gchar *s1, const gchar *s2); +gint g_ascii_xdigit_value (gchar c); +#define g_ascii_isspace(c) (isspace (c) != 0) +#define g_ascii_isalpha(c) (isalpha (c) != 0) +#define g_ascii_isprint(c) (isprint (c) != 0) +#define g_ascii_isxdigit(c) (isxdigit (c) != 0) + +/* FIXME: g_strcasecmp supports utf8 unicode stuff */ +#ifdef _MSC_VER +#define g_strcasecmp stricmp +#define g_strncasecmp strnicmp +#define g_strstrip(a) g_strchug (g_strchomp (a)) +#else +#define g_strcasecmp strcasecmp +#define g_ascii_strtoull strtoull +#define g_strncasecmp strncasecmp +#define g_strstrip(a) g_strchug (g_strchomp (a)) +#endif +#define g_ascii_strdup strdup + + +#define G_STR_DELIMITERS "_-|> <." + +/* + * String type + */ +typedef struct { + char *str; + gsize len; + gsize allocated_len; +} GString; + +GString *g_string_new (const gchar *init); +GString *g_string_new_len (const gchar *init, gssize len); +GString *g_string_sized_new (gsize default_size); +gchar *g_string_free (GString *string, gboolean free_segment); +GString *g_string_assign (GString *string, const gchar *val); +GString *g_string_append (GString *string, const gchar *val); +void g_string_printf (GString *string, const gchar *format, ...); +void g_string_append_printf (GString *string, const gchar *format, ...); +void g_string_append_vprintf (GString *string, const gchar *format, va_list args); +GString *g_string_append_unichar (GString *string, gunichar c); +GString *g_string_append_c (GString *string, gchar c); +GString *g_string_append (GString *string, const gchar *val); +GString *g_string_append_len (GString *string, const gchar *val, gssize len); +GString *g_string_truncate (GString *string, gsize len); +GString *g_string_prepend (GString *string, const gchar *val); +GString *g_string_insert (GString *string, gssize pos, const gchar *val); +GString *g_string_set_size (GString *string, gsize len); +GString *g_string_erase (GString *string, gssize pos, gssize len); + +#define g_string_sprintfa g_string_append_printf + +typedef void (*GFunc) (gpointer data, gpointer user_data); +typedef gint (*GCompareFunc) (gconstpointer a, gconstpointer b); +typedef gint (*GCompareDataFunc) (gconstpointer a, gconstpointer b, gpointer user_data); +typedef void (*GHFunc) (gpointer key, gpointer value, gpointer user_data); +typedef gboolean (*GHRFunc) (gpointer key, gpointer value, gpointer user_data); +typedef void (*GDestroyNotify) (gpointer data); +typedef guint (*GHashFunc) (gconstpointer key); +typedef gboolean (*GEqualFunc) (gconstpointer a, gconstpointer b); +typedef void (*GFreeFunc) (gpointer data); + +/* + * Lists + */ +typedef struct _GSList GSList; +struct _GSList { + gpointer data; + GSList *next; +}; + +GSList *g_slist_alloc (void); +GSList *g_slist_append (GSList *list, + gpointer data); +GSList *g_slist_prepend (GSList *list, + gpointer data); +void g_slist_free (GSList *list); +void g_slist_free_1 (GSList *list); +GSList *g_slist_copy (GSList *list); +GSList *g_slist_concat (GSList *list1, + GSList *list2); +void g_slist_foreach (GSList *list, + GFunc func, + gpointer user_data); +GSList *g_slist_last (GSList *list); +GSList *g_slist_find (GSList *list, + gconstpointer data); +GSList *g_slist_find_custom (GSList *list, + gconstpointer data, + GCompareFunc func); +GSList *g_slist_remove (GSList *list, + gconstpointer data); +GSList *g_slist_remove_all (GSList *list, + gconstpointer data); +GSList *g_slist_reverse (GSList *list); +guint g_slist_length (GSList *list); +GSList *g_slist_remove_link (GSList *list, + GSList *link); +GSList *g_slist_delete_link (GSList *list, + GSList *link); +GSList *g_slist_insert_sorted (GSList *list, + gpointer data, + GCompareFunc func); +GSList *g_slist_insert_before (GSList *list, + GSList *sibling, + gpointer data); +GSList *g_slist_sort (GSList *list, + GCompareFunc func); +gint g_slist_index (GSList *list, + gconstpointer data); +GSList *g_slist_nth (GSList *list, + guint n); +gpointer g_slist_nth_data (GSList *list, + guint n); + +#define g_slist_next(slist) ((slist) ? (((GSList *) (slist))->next) : NULL) + + +typedef struct _GList GList; +struct _GList { + gpointer data; + GList *next; + GList *prev; +}; + +#define g_list_next(list) ((list) ? (((GList *) (list))->next) : NULL) +#define g_list_previous(list) ((list) ? (((GList *) (list))->prev) : NULL) + +GList *g_list_alloc (void); +GList *g_list_append (GList *list, + gpointer data); +GList *g_list_prepend (GList *list, + gpointer data); +void g_list_free (GList *list); +void g_list_free_full (GList *list, + GDestroyNotify free_func); +void g_list_free_1 (GList *list); +GList *g_list_copy (GList *list); +guint g_list_length (GList *list); +gint g_list_index (GList *list, + gconstpointer data); +GList *g_list_nth (GList *list, + guint n); +gpointer g_list_nth_data (GList *list, + guint n); +GList *g_list_last (GList *list); +GList *g_list_concat (GList *list1, + GList *list2); +void g_list_foreach (GList *list, + GFunc func, + gpointer user_data); +GList *g_list_first (GList *list); +GList *g_list_find (GList *list, + gconstpointer data); +GList *g_list_find_custom (GList *list, + gconstpointer data, + GCompareFunc func); +GList *g_list_remove (GList *list, + gconstpointer data); +GList *g_list_remove_all (GList *list, + gconstpointer data); +GList *g_list_reverse (GList *list); +GList *g_list_remove_link (GList *list, + GList *link); +GList *g_list_delete_link (GList *list, + GList *link); +GList *g_list_insert_sorted (GList *list, + gpointer data, + GCompareFunc func); +GList *g_list_insert_before (GList *list, + GList *sibling, + gpointer data); +GList *g_list_sort (GList *sort, + GCompareFunc func); + +/* + * HookLists + */ +typedef void (*GHookFunc) (gpointer data); + +typedef struct _GHook GHook; +typedef struct _GHookList GHookList; + +struct _GHook { + GHook *next; + GHook *prev; + gpointer data; + gpointer func; + gboolean in_call; +}; + +struct _GHookList { + GHook *hooks; +}; + +void +g_hook_list_init (GHookList *hook_list, + guint hook_size); + +void +g_hook_list_invoke (GHookList *hook_list, + gboolean may_recurse); + +void +g_hook_list_clear (GHookList *hook_list); + +GHook * +g_hook_alloc (GHookList *hook_list); + +GHook * +g_hook_find_func_data (GHookList *hook_list, + gboolean need_valids, + gpointer func, + gpointer data); + +void +g_hook_destroy_link (GHookList *hook_list, + GHook *hook); + +void +g_hook_prepend (GHookList *hook_list, + GHook *hook); + + +/* + * Hashtables + */ +typedef struct _GHashTable GHashTable; +typedef struct _GHashTableIter GHashTableIter; + +/* Private, but needed for stack allocation */ +struct _GHashTableIter +{ + gpointer dummy [8]; +}; + +GHashTable *g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func); +GHashTable *g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func); +void g_hash_table_insert_replace (GHashTable *hash, gpointer key, gpointer value, gboolean replace); +guint g_hash_table_size (GHashTable *hash); +GList *g_hash_table_get_keys (GHashTable *hash); +GList *g_hash_table_get_values (GHashTable *hash); +gpointer g_hash_table_lookup (GHashTable *hash, gconstpointer key); +gboolean g_hash_table_lookup_extended (GHashTable *hash, gconstpointer key, gpointer *orig_key, gpointer *value); +void g_hash_table_foreach (GHashTable *hash, GHFunc func, gpointer user_data); +gpointer g_hash_table_find (GHashTable *hash, GHRFunc predicate, gpointer user_data); +gboolean g_hash_table_remove (GHashTable *hash, gconstpointer key); +gboolean g_hash_table_steal (GHashTable *hash, gconstpointer key); +void g_hash_table_remove_all (GHashTable *hash); +guint g_hash_table_foreach_remove (GHashTable *hash, GHRFunc func, gpointer user_data); +guint g_hash_table_foreach_steal (GHashTable *hash, GHRFunc func, gpointer user_data); +void g_hash_table_destroy (GHashTable *hash); +void g_hash_table_print_stats (GHashTable *table); + +void g_hash_table_iter_init (GHashTableIter *iter, GHashTable *hash_table); +gboolean g_hash_table_iter_next (GHashTableIter *iter, gpointer *key, gpointer *value); + +guint g_spaced_primes_closest (guint x); + +#define g_hash_table_insert(h,k,v) g_hash_table_insert_replace ((h),(k),(v),FALSE) +#define g_hash_table_replace(h,k,v) g_hash_table_insert_replace ((h),(k),(v),TRUE) + +gboolean g_direct_equal (gconstpointer v1, gconstpointer v2); +guint g_direct_hash (gconstpointer v1); +gboolean g_int_equal (gconstpointer v1, gconstpointer v2); +guint g_int_hash (gconstpointer v1); +gboolean g_str_equal (gconstpointer v1, gconstpointer v2); +guint g_str_hash (gconstpointer v1); + +/* + * ByteArray + */ + +typedef struct _GByteArray GByteArray; +struct _GByteArray { + guint8 *data; + gint len; +}; + +GByteArray *g_byte_array_new (void); +GByteArray *g_byte_array_append (GByteArray *array, const guint8 *data, guint len); +GByteArray *g_byte_array_set_size (GByteArray *array, guint len); +guint8 *g_byte_array_free (GByteArray *array, gboolean free_segment); + +/* + * Array + */ + +typedef struct _GArray GArray; +struct _GArray { + gchar *data; + gint len; +}; + +GArray *g_array_new (gboolean zero_terminated, gboolean clear_, guint element_size); +GArray *g_array_sized_new (gboolean zero_terminated, gboolean clear_, guint element_size, guint reserved_size); +gchar* g_array_free (GArray *array, gboolean free_segment); +GArray *g_array_append_vals (GArray *array, gconstpointer data, guint len); +GArray* g_array_insert_vals (GArray *array, guint index_, gconstpointer data, guint len); +GArray* g_array_remove_index (GArray *array, guint index_); +GArray* g_array_remove_index_fast (GArray *array, guint index_); +GArray *g_array_set_size (GArray *array, gint length); + +#define g_array_append_val(a,v) (g_array_append_vals((a),&(v),1)) +#define g_array_insert_val(a,i,v) (g_array_insert_vals((a),(i),&(v),1)) +#define g_array_index(a,t,i) (((t*)(a)->data)[(i)]) + +/* + * QSort +*/ + +void g_qsort_with_data (gpointer base, size_t nmemb, size_t size, GCompareDataFunc compare, gpointer user_data); + +/* + * Pointer Array + */ + +typedef struct _GPtrArray GPtrArray; +struct _GPtrArray { + gpointer *pdata; + guint len; +}; + +GPtrArray *g_ptr_array_new (void); +GPtrArray *g_ptr_array_sized_new (guint reserved_size); +GPtrArray *g_ptr_array_new_with_free_func (GDestroyNotify element_free_func); +void g_ptr_array_add (GPtrArray *array, gpointer data); +gboolean g_ptr_array_remove (GPtrArray *array, gpointer data); +gpointer g_ptr_array_remove_index (GPtrArray *array, guint index); +gboolean g_ptr_array_remove_fast (GPtrArray *array, gpointer data); +gpointer g_ptr_array_remove_index_fast (GPtrArray *array, guint index); +void g_ptr_array_sort (GPtrArray *array, GCompareFunc compare_func); +void g_ptr_array_sort_with_data (GPtrArray *array, GCompareDataFunc compare_func, gpointer user_data); +void g_ptr_array_set_size (GPtrArray *array, gint length); +gpointer *g_ptr_array_free (GPtrArray *array, gboolean free_seg); +void g_ptr_array_foreach (GPtrArray *array, GFunc func, gpointer user_data); +#define g_ptr_array_index(array,index) (array)->pdata[(index)] + +/* + * Queues + */ +typedef struct { + GList *head; + GList *tail; + guint length; +} GQueue; + +#define G_QUEUE_INIT { NULL, NULL, 0 } + +void g_queue_init (GQueue *queue); +gpointer g_queue_peek_head (GQueue *queue); +gpointer g_queue_pop_head (GQueue *queue); +gpointer g_queue_peek_tail (GQueue *queue); +gpointer g_queue_pop_tail (GQueue *queue); +void g_queue_push_head (GQueue *queue, + gpointer data); +void g_queue_push_tail (GQueue *queue, + gpointer data); +gboolean g_queue_is_empty (GQueue *queue); +GQueue *g_queue_new (void); +void g_queue_free (GQueue *queue); +void g_queue_foreach (GQueue *queue, GFunc func, gpointer user_data); +GList *g_queue_find (GQueue *queue, gconstpointer data); +void g_queue_clear (GQueue *queue); + +/* + * Messages + */ +#ifndef G_LOG_DOMAIN +#define G_LOG_DOMAIN ((gchar*) 0) +#endif + +typedef enum { + G_LOG_FLAG_RECURSION = 1 << 0, + G_LOG_FLAG_FATAL = 1 << 1, + + G_LOG_LEVEL_ERROR = 1 << 2, + G_LOG_LEVEL_CRITICAL = 1 << 3, + G_LOG_LEVEL_WARNING = 1 << 4, + G_LOG_LEVEL_MESSAGE = 1 << 5, + G_LOG_LEVEL_INFO = 1 << 6, + G_LOG_LEVEL_DEBUG = 1 << 7, + + G_LOG_LEVEL_MASK = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL) +} GLogLevelFlags; + +void g_print (const gchar *format, ...); +void g_printerr (const gchar *format, ...); +GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask); +GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags fatal_mask); +void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args); +void g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...); +void g_assertion_message (const gchar *format, ...) G_GNUC_NORETURN; + +#ifdef HAVE_C99_SUPPORT +/* The for (;;) tells gc thats g_error () doesn't return, avoiding warnings */ +#define g_error(format, ...) do { g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, __VA_ARGS__); for (;;); } while (0) +#define g_critical(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, format, __VA_ARGS__) +#define g_warning(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, __VA_ARGS__) +#define g_message(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, __VA_ARGS__) +#define g_debug(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, __VA_ARGS__) +#else /* HAVE_C99_SUPPORT */ +#define g_error(...) do { g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, __VA_ARGS__); for (;;); } while (0) +#define g_critical(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, __VA_ARGS__) +#define g_warning(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, __VA_ARGS__) +#define g_message(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__) +#define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__) +#endif /* ndef HAVE_C99_SUPPORT */ +#define g_log_set_handler(a,b,c,d) + +#define G_GNUC_INTERNAL + +/* + * Conversions + */ + +GQuark g_convert_error_quark(void); + + +/* + * Unicode Manipulation: most of this is not used by Mono by default, it is + * only used if the old collation code is activated, so this is only the + * bare minimum to build. + */ + +typedef enum { + G_UNICODE_CONTROL, + G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, + G_UNICODE_PRIVATE_USE, + G_UNICODE_SURROGATE, + G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, + G_UNICODE_TITLECASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_COMBINING_MARK, + G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, + G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_LETTER_NUMBER, + G_UNICODE_OTHER_NUMBER, + G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, + G_UNICODE_LINE_SEPARATOR, + G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR +} GUnicodeType; + +typedef enum { + G_UNICODE_BREAK_MANDATORY, + G_UNICODE_BREAK_CARRIAGE_RETURN, + G_UNICODE_BREAK_LINE_FEED, + G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_SURROGATE, + G_UNICODE_BREAK_ZERO_WIDTH_SPACE, + G_UNICODE_BREAK_INSEPARABLE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_CONTINGENT, + G_UNICODE_BREAK_SPACE, + G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_BEFORE_AND_AFTER, + G_UNICODE_BREAK_HYPHEN, + G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_SYMBOL, + G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NEXT_LINE, + G_UNICODE_BREAK_WORD_JOINER, + G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE +} GUnicodeBreakType; + +gunichar g_unichar_toupper (gunichar c); +gunichar g_unichar_tolower (gunichar c); +gunichar g_unichar_totitle (gunichar c); +GUnicodeType g_unichar_type (gunichar c); +gboolean g_unichar_isspace (gunichar c); +gboolean g_unichar_isxdigit (gunichar c); +gint g_unichar_xdigit_value (gunichar c); +GUnicodeBreakType g_unichar_break_type (gunichar c); + +#ifndef MAX +#define MAX(a,b) (((a)>(b)) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) (((a)<(b)) ? (a) : (b)) +#endif + +#ifndef CLAMP +#define CLAMP(a,low,high) (((a) < (low)) ? (low) : (((a) > (high)) ? (high) : (a))) +#endif + +#if defined(__GNUC__) +# define G_LIKELY(expr) (__builtin_expect ((expr) != 0, 1)) +# define G_UNLIKELY(expr) (__builtin_expect ((expr) != 0, 0)) +# define G_GNUC_PRINTF(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#else +# define G_LIKELY(expr) (expr) +# define G_UNLIKELY(expr) (expr) +# define G_GNUC_PRINTF(format_idx, arg_idx) +#endif + +#if defined(__GNUC__) +# define G_STRFUNC ((const char *)(__PRETTY_FUNCTION__)) +#elif defined (_MSC_VER) +# define G_STRFUNC ((const char*) (__FUNCTION__)) +#else +# define G_STRFUNC ((const char*) (__func__)) +#endif + +#if defined (_MSC_VER) +# define G_VA_COPY(dest, src) ((dest) = (src)) +#else +# define G_VA_COPY(dest, src) va_copy (dest, src) +#endif + +#define g_assert(x) G_STMT_START { if (G_UNLIKELY (!(x))) g_assertion_message ("* Assertion at %s:%d, condition `%s' not met\n", __FILE__, __LINE__, #x); } G_STMT_END +#define g_assert_not_reached() G_STMT_START { g_assertion_message ("* Assertion: should not be reached at %s:%d\n", __FILE__, __LINE__); } G_STMT_END + +#define g_assert_cmpstr(s1, cmp, s2) \ + G_STMT_START { \ + const char *_s1 = s1; \ + const char *_s2 = s2; \ + if (!(strcmp (_s1, _s2) cmp 0)) \ + g_assertion_message ("* Assertion at %s:%d, condition \"%s\" " #cmp " \"%s\" failed\n", __FILE__, __LINE__, _s1, _s2); \ + } G_STMT_END +#define g_assert_cmpint(n1, cmp, n2) \ + G_STMT_START { \ + int _n1 = n1; \ + int _n2 = n2; \ + if (!(_n1 cmp _n2)) \ + g_assertion_message ("* Assertion at %s:%d, condition %d " #cmp " %d failed\n", __FILE__, __LINE__, _n1, _n2); \ + } G_STMT_END +#define g_assert_cmpuint(n1, cmp, n2) \ + G_STMT_START { \ + int _n1 = n1; \ + int _n2 = n2; \ + if (!(_n1 cmp _n2)) \ + g_assertion_message ("* Assertion at %s:%d, condition %u " #cmp " %u failed\n", __FILE__, __LINE__, _n1, _n2); \ + } G_STMT_END +#define g_assert_cmpfloat(n1, cmp, n2) \ + G_STMT_START { \ + float _n1 = n1; \ + float _n2 = n2; \ + if (!(_n1 cmp _n2)) \ + g_assertion_message ("* Assertion at %s:%d, condition %f " #cmp " %f failed\n", __FILE__, __LINE__, _n1, _n2); \ + } G_STMT_END + +/* + * Unicode conversion + */ + +#define G_CONVERT_ERROR g_convert_error_quark() + +typedef enum { + G_CONVERT_ERROR_NO_CONVERSION, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + G_CONVERT_ERROR_FAILED, + G_CONVERT_ERROR_PARTIAL_INPUT, + G_CONVERT_ERROR_BAD_URI, + G_CONVERT_ERROR_NOT_ABSOLUTE_PATH +} GConvertError; + +gchar *g_utf8_strup (const gchar *str, gssize len); +gchar *g_utf8_strdown (const gchar *str, gssize len); +gint g_unichar_to_utf8 (gunichar c, gchar *outbuf); +gunichar *g_utf8_to_ucs4_fast (const gchar *str, glong len, glong *items_written); +gunichar *g_utf8_to_ucs4 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err); +gunichar2 *g_utf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err); +gunichar2 *eg_utf8_to_utf16_with_nuls (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err); +gchar *g_utf16_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err); +gunichar *g_utf16_to_ucs4 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err); +gchar *g_ucs4_to_utf8 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **err); +gunichar2 *g_ucs4_to_utf16 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **err); + +#define u8to16(str) g_utf8_to_utf16(str, (glong)strlen(str), NULL, NULL, NULL) + +#ifdef G_OS_WIN32 +#define u16to8(str) g_utf16_to_utf8((gunichar2 *) (str), (glong)wcslen((wchar_t *) (str)), NULL, NULL, NULL) +#else +#define u16to8(str) g_utf16_to_utf8(str, (glong)strlen(str), NULL, NULL, NULL) +#endif + +/* + * Path + */ +gchar *g_build_path (const gchar *separator, const gchar *first_element, ...); +#define g_build_filename(x, ...) g_build_path(G_DIR_SEPARATOR_S, x, __VA_ARGS__) +gchar *g_path_get_dirname (const gchar *filename); +gchar *g_path_get_basename (const char *filename); +gchar *g_find_program_in_path (const gchar *program); +gchar *g_get_current_dir (void); +gboolean g_path_is_absolute (const char *filename); + +const gchar *g_get_home_dir (void); +const gchar *g_get_tmp_dir (void); +const gchar *g_get_user_name (void); +gchar *g_get_prgname (void); +void g_set_prgname (const gchar *prgname); + +/* + * Shell + */ + +GQuark g_shell_error_get_quark (void); + +#define G_SHELL_ERROR g_shell_error_get_quark () + +typedef enum { + G_SHELL_ERROR_BAD_QUOTING, + G_SHELL_ERROR_EMPTY_STRING, + G_SHELL_ERROR_FAILED +} GShellError; + + +gboolean g_shell_parse_argv (const gchar *command_line, gint *argcp, gchar ***argvp, GError **error); +gchar *g_shell_unquote (const gchar *quoted_string, GError **error); +gchar *g_shell_quote (const gchar *unquoted_string); + +/* + * Spawn + */ +GQuark g_shell_error_get_quark (void); + +#define G_SPAWN_ERROR g_shell_error_get_quark () + +typedef enum { + G_SPAWN_ERROR_FORK, + G_SPAWN_ERROR_READ, + G_SPAWN_ERROR_CHDIR, + G_SPAWN_ERROR_ACCES, + G_SPAWN_ERROR_PERM, + G_SPAWN_ERROR_TOO_BIG, + G_SPAWN_ERROR_NOEXEC, + G_SPAWN_ERROR_NAMETOOLONG, + G_SPAWN_ERROR_NOENT, + G_SPAWN_ERROR_NOMEM, + G_SPAWN_ERROR_NOTDIR, + G_SPAWN_ERROR_LOOP, + G_SPAWN_ERROR_TXTBUSY, + G_SPAWN_ERROR_IO, + G_SPAWN_ERROR_NFILE, + G_SPAWN_ERROR_MFILE, + G_SPAWN_ERROR_INVAL, + G_SPAWN_ERROR_ISDIR, + G_SPAWN_ERROR_LIBBAD, + G_SPAWN_ERROR_FAILED +} GSpawnError; + +typedef enum { + G_SPAWN_LEAVE_DESCRIPTORS_OPEN = 1, + G_SPAWN_DO_NOT_REAP_CHILD = 1 << 1, + G_SPAWN_SEARCH_PATH = 1 << 2, + G_SPAWN_STDOUT_TO_DEV_NULL = 1 << 3, + G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4, + G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5, + G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6 +} GSpawnFlags; + +typedef void (*GSpawnChildSetupFunc) (gpointer user_data); + +gboolean g_spawn_command_line_sync (const gchar *command_line, gchar **standard_output, gchar **standard_error, gint *exit_status, GError **error); +gboolean g_spawn_async_with_pipes (const gchar *working_directory, gchar **argv, gchar **envp, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, + gpointer user_data, GPid *child_pid, gint *standard_input, gint *standard_output, gint *standard_error, GError **error); + + +/* + * Timer + */ +typedef struct _GTimer GTimer; + +GTimer *g_timer_new (void); +void g_timer_destroy (GTimer *timer); +gdouble g_timer_elapsed (GTimer *timer, gulong *microseconds); +void g_timer_stop (GTimer *timer); +void g_timer_start (GTimer *timer); + +/* + * Date and time + */ +typedef struct { + glong tv_sec; + glong tv_usec; +} GTimeVal; + +void g_get_current_time (GTimeVal *result); +void g_usleep (gulong microseconds); + +/* + * File + */ + +GQuark g_file_error_quark (void); + +#define G_FILE_ERROR g_file_error_quark () + +typedef enum { + G_FILE_ERROR_EXIST, + G_FILE_ERROR_ISDIR, + G_FILE_ERROR_ACCES, + G_FILE_ERROR_NAMETOOLONG, + G_FILE_ERROR_NOENT, + G_FILE_ERROR_NOTDIR, + G_FILE_ERROR_NXIO, + G_FILE_ERROR_NODEV, + G_FILE_ERROR_ROFS, + G_FILE_ERROR_TXTBSY, + G_FILE_ERROR_FAULT, + G_FILE_ERROR_LOOP, + G_FILE_ERROR_NOSPC, + G_FILE_ERROR_NOMEM, + G_FILE_ERROR_MFILE, + G_FILE_ERROR_NFILE, + G_FILE_ERROR_BADF, + G_FILE_ERROR_INVAL, + G_FILE_ERROR_PIPE, + G_FILE_ERROR_AGAIN, + G_FILE_ERROR_INTR, + G_FILE_ERROR_IO, + G_FILE_ERROR_PERM, + G_FILE_ERROR_NOSYS, + G_FILE_ERROR_FAILED +} GFileError; + +typedef enum { + G_FILE_TEST_IS_REGULAR = 1 << 0, + G_FILE_TEST_IS_SYMLINK = 1 << 1, + G_FILE_TEST_IS_DIR = 1 << 2, + G_FILE_TEST_IS_EXECUTABLE = 1 << 3, + G_FILE_TEST_EXISTS = 1 << 4 +} GFileTest; + + +gboolean g_file_set_contents (const gchar *filename, const gchar *contents, gssize length, GError **error); +gboolean g_file_get_contents (const gchar *filename, gchar **contents, gsize *length, GError **error); +GFileError g_file_error_from_errno (gint err_no); +gint g_file_open_tmp (const gchar *tmpl, gchar **name_used, GError **error); +gboolean g_file_test (const gchar *filename, GFileTest test); + +#define g_open open +#define g_rename rename +#define g_stat stat +#define g_unlink unlink +#define g_fopen fopen +#define g_lstat lstat +#define g_rmdir rmdir +#define g_mkstemp mkstemp +#define g_ascii_isdigit isdigit +#define g_ascii_strtod strtod +#define g_ascii_isalnum isalnum + +/* + * Pattern matching + */ +typedef struct _GPatternSpec GPatternSpec; +GPatternSpec * g_pattern_spec_new (const gchar *pattern); +void g_pattern_spec_free (GPatternSpec *pspec); +gboolean g_pattern_match_string (GPatternSpec *pspec, const gchar *string); + +/* + * Directory + */ +typedef struct _GDir GDir; +GDir *g_dir_open (const gchar *path, guint flags, GError **error); +const gchar *g_dir_read_name (GDir *dir); +void g_dir_rewind (GDir *dir); +void g_dir_close (GDir *dir); + +int g_mkdir_with_parents (const gchar *pathname, int mode); +#define g_mkdir mkdir + +/* + * GMarkup + */ + +GQuark g_markup_error_quark (void); + +#define G_MARKUP_ERROR g_markup_error_quark() + +typedef enum { + G_MARKUP_ERROR_BAD_UTF8, + G_MARKUP_ERROR_EMPTY, + G_MARKUP_ERROR_PARSE, + G_MARKUP_ERROR_UNKNOWN_ELEMENT, + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, + G_MARKUP_ERROR_INVALID_CONTENT, + G_MARKUP_ERROR_MISSING_ATTRIBUTE +} GMarkupError; + +typedef struct _GMarkupParseContext GMarkupParseContext; + +typedef enum +{ + G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0, + G_MARKUP_TREAT_CDATA_AS_TEXT = 1 << 1 +} GMarkupParseFlags; + +typedef struct { + void (*start_element) (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error); + + void (*end_element) (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error); + + void (*text) (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error); + + void (*passthrough) (GMarkupParseContext *context, + const gchar *passthrough_text, + gsize text_len, + gpointer user_data, + GError **error); + void (*error) (GMarkupParseContext *context, + GError *error, + gpointer user_data); +} GMarkupParser; + +GMarkupParseContext *g_markup_parse_context_new (const GMarkupParser *parser, + GMarkupParseFlags flags, + gpointer user_data, + GDestroyNotify user_data_dnotify); +void g_markup_parse_context_free (GMarkupParseContext *context); +gboolean g_markup_parse_context_parse (GMarkupParseContext *context, + const gchar *text, gssize text_len, + GError **error); +gboolean g_markup_parse_context_end_parse (GMarkupParseContext *context, + GError **error); + +/* + * Character set conversion + */ +typedef struct _GIConv *GIConv; + +gsize g_iconv (GIConv cd, gchar **inbytes, gsize *inbytesleft, gchar **outbytes, gsize *outbytesleft); +GIConv g_iconv_open (const gchar *to_charset, const gchar *from_charset); +int g_iconv_close (GIConv cd); + +gboolean g_get_charset (G_CONST_RETURN char **charset); +gchar *g_locale_to_utf8 (const gchar *opsysstring, gssize len, + gsize *bytes_read, gsize *bytes_written, + GError **error); +gchar *g_locale_from_utf8 (const gchar *utf8string, gssize len, gsize *bytes_read, + gsize *bytes_written, GError **error); +gchar *g_filename_from_utf8 (const gchar *utf8string, gssize len, gsize *bytes_read, + gsize *bytes_written, GError **error); +gchar *g_convert (const gchar *str, gssize len, + const gchar *to_codeset, const gchar *from_codeset, + gsize *bytes_read, gsize *bytes_written, GError **error); + +/* + * Unicode manipulation + */ +extern const guchar g_utf8_jump_table[256]; + +gboolean g_utf8_validate (const gchar *str, gssize max_len, const gchar **end); +gunichar g_utf8_get_char_validated (const gchar *str, gssize max_len); +gchar *g_utf8_find_prev_char (const char *str, const char *p); +gchar *g_utf8_prev_char (const char *str); +#define g_utf8_next_char(p) ((p) + g_utf8_jump_table[(guchar)(*p)]) +gunichar g_utf8_get_char (const gchar *src); +glong g_utf8_strlen (const gchar *str, gssize max); +gchar *g_utf8_offset_to_pointer (const gchar *str, glong offset); +glong g_utf8_pointer_to_offset (const gchar *str, const gchar *pos); + +/* + * priorities + */ +#define G_PRIORITY_DEFAULT 0 +#define G_PRIORITY_DEFAULT_IDLE 200 + +/* + * Empty thread functions, not used by eglib + */ +#define g_thread_supported() TRUE +#define g_thread_init(x) G_STMT_START { if (x != NULL) { g_error ("No vtable supported in g_thread_init"); } } G_STMT_END + +#define G_LOCK_DEFINE(name) int name; +#define G_LOCK_DEFINE_STATIC(name) static int name; +#define G_LOCK_EXTERN(name) +#define G_LOCK(name) +#define G_TRYLOCK(name) +#define G_UNLOCK(name) + +#define GUINT16_SWAP_LE_BE_CONSTANT(x) ((((guint16) x) >> 8) | ((((guint16) x) << 8))) + +#define GUINT16_SWAP_LE_BE(x) ((guint16) (((guint16) x) >> 8) | ((((guint16)(x)) & 0xff) << 8)) +#define GUINT32_SWAP_LE_BE(x) ((guint32) \ + ( (((guint32) (x)) << 24)| \ + ((((guint32) (x)) & 0xff0000) >> 8) | \ + ((((guint32) (x)) & 0xff00) << 8) | \ + (((guint32) (x)) >> 24)) ) + +#define GUINT64_SWAP_LE_BE(x) ((guint64) (((guint64)(GUINT32_SWAP_LE_BE(((guint64)x) & 0xffffffff))) << 32) | \ + GUINT32_SWAP_LE_BE(((guint64)x) >> 32)) + + + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +# define GUINT64_FROM_BE(x) GUINT64_SWAP_LE_BE(x) +# define GUINT32_FROM_BE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT16_FROM_BE(x) GUINT16_SWAP_LE_BE(x) +# define GUINT_FROM_BE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT64_FROM_LE(x) (x) +# define GUINT32_FROM_LE(x) (x) +# define GUINT16_FROM_LE(x) (x) +# define GUINT_FROM_LE(x) (x) +# define GUINT64_TO_BE(x) GUINT64_SWAP_LE_BE(x) +# define GUINT32_TO_BE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT16_TO_BE(x) GUINT16_SWAP_LE_BE(x) +# define GUINT_TO_BE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT64_TO_LE(x) (x) +# define GUINT32_TO_LE(x) (x) +# define GUINT16_TO_LE(x) (x) +# define GUINT_TO_LE(x) (x) +#else +# define GUINT64_FROM_BE(x) (x) +# define GUINT32_FROM_BE(x) (x) +# define GUINT16_FROM_BE(x) (x) +# define GUINT_FROM_BE(x) (x) +# define GUINT64_FROM_LE(x) GUINT64_SWAP_LE_BE(x) +# define GUINT32_FROM_LE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT16_FROM_LE(x) GUINT16_SWAP_LE_BE(x) +# define GUINT_FROM_LE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT64_TO_BE(x) (x) +# define GUINT32_TO_BE(x) (x) +# define GUINT16_TO_BE(x) (x) +# define GUINT_TO_BE(x) (x) +# define GUINT64_TO_LE(x) GUINT64_SWAP_LE_BE(x) +# define GUINT32_TO_LE(x) GUINT32_SWAP_LE_BE(x) +# define GUINT16_TO_LE(x) GUINT16_SWAP_LE_BE(x) +# define GUINT_TO_LE(x) GUINT32_SWAP_LE_BE(x) +#endif + +#define GINT64_FROM_BE(x) (GUINT64_TO_BE (x)) +#define GINT32_FROM_BE(x) (GUINT32_TO_BE (x)) +#define GINT16_FROM_BE(x) (GUINT16_TO_BE (x)) +#define GINT64_FROM_LE(x) (GUINT64_TO_LE (x)) +#define GINT32_FROM_LE(x) (GUINT32_TO_LE (x)) +#define GINT16_FROM_LE(x) (GUINT16_TO_LE (x)) + +#define _EGLIB_MAJOR 2 +#define _EGLIB_MIDDLE 4 +#define _EGLIB_MINOR 0 + +#define GLIB_CHECK_VERSION(a,b,c) ((a < _EGLIB_MAJOR) || (a == _EGLIB_MAJOR && (b < _EGLIB_MIDDLE || (b == _EGLIB_MIDDLE && c <= _EGLIB_MINOR)))) + +G_END_DECLS + +#endif + + + diff --git a/deps/eglib/src/glist.c b/deps/eglib/src/glist.c new file mode 100644 index 00000000..0bf21133 --- /dev/null +++ b/deps/eglib/src/glist.c @@ -0,0 +1,359 @@ +/* + * glist.c: Doubly-linked list implementation + * + * Authors: + * Duncan Mak (duncan@novell.com) + * Raja R Harinath (rharinath@novell.com) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * (C) 2006 Novell, Inc. + */ + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +GList* +g_list_alloc () +{ + return g_new0 (GList, 1); +} + +static inline GList* +new_node (GList *prev, gpointer data, GList *next) +{ + GList *node = g_list_alloc (); + node->data = data; + node->prev = prev; + node->next = next; + if (prev) + prev->next = node; + if (next) + next->prev = node; + return node; +} + +static inline GList* +disconnect_node (GList *node) +{ + if (node->next) + node->next->prev = node->prev; + if (node->prev) + node->prev->next = node->next; + return node; +} + +GList * +g_list_prepend (GList *list, gpointer data) +{ + return new_node (list ? list->prev : NULL, data, list); +} + +void +g_list_free_1 (GList *list) +{ + g_free (list); +} + +void +g_list_free (GList *list) +{ + while (list){ + GList *next = list->next; + g_list_free_1 (list); + list = next; + } +} + +void +g_list_free_full (GList *list, GDestroyNotify free_func) +{ + while (list){ + GList *next = list->next; + free_func (list->data); + g_list_free_1 (list); + list = next; + } +} + +GList* +g_list_append (GList *list, gpointer data) +{ + GList *node = new_node (g_list_last (list), data, NULL); + return list ? list : node; +} + +GList * +g_list_concat (GList *list1, GList *list2) +{ + if (list1 && list2) { + list2->prev = g_list_last (list1); + list2->prev->next = list2; + } + return list1 ? list1 : list2; +} + +guint +g_list_length (GList *list) +{ + guint length = 0; + + while (list) { + length ++; + list = list->next; + } + + return length; +} + +GList* +g_list_remove (GList *list, gconstpointer data) +{ + GList *current = g_list_find (list, data); + if (!current) + return list; + + if (current == list) + list = list->next; + g_list_free_1 (disconnect_node (current)); + + return list; +} + +GList* +g_list_remove_all (GList *list, gconstpointer data) +{ + GList *current = g_list_find (list, data); + + if (!current) + return list; + + while (current) { + if (current == list) + list = list->next; + g_list_free_1 (disconnect_node (current)); + + current = g_list_find (list, data); + } + + return list; +} + +GList* +g_list_remove_link (GList *list, GList *link) +{ + if (list == link) + list = list->next; + + disconnect_node (link); + link->next = NULL; + link->prev = NULL; + + return list; +} + +GList* +g_list_delete_link (GList *list, GList *link) +{ + list = g_list_remove_link (list, link); + g_list_free_1 (link); + + return list; +} + +GList* +g_list_find (GList *list, gconstpointer data) +{ + while (list){ + if (list->data == data) + return list; + + list = list->next; + } + + return NULL; +} + +GList* +g_list_find_custom (GList *list, gconstpointer data, GCompareFunc func) +{ + if (!func) + return NULL; + + while (list) { + if (func (list->data, data) == 0) + return list; + + list = list->next; + } + + return NULL; +} + +GList* +g_list_reverse (GList *list) +{ + GList *reverse = NULL; + + while (list) { + reverse = list; + list = reverse->next; + + reverse->next = reverse->prev; + reverse->prev = list; + } + + return reverse; +} + +GList* +g_list_first (GList *list) +{ + if (!list) + return NULL; + + while (list->prev) + list = list->prev; + + return list; +} + +GList* +g_list_last (GList *list) +{ + if (!list) + return NULL; + + while (list->next) + list = list->next; + + return list; +} + +GList* +g_list_insert_sorted (GList *list, gpointer data, GCompareFunc func) +{ + GList *prev = NULL; + GList *current; + GList *node; + + if (!func) + return list; + + /* Invariant: !prev || func (prev->data, data) <= 0) */ + for (current = list; current; current = current->next) { + if (func (current->data, data) > 0) + break; + prev = current; + } + + node = new_node (prev, data, current); + return list == current ? node : list; +} + +GList* +g_list_insert_before (GList *list, GList *sibling, gpointer data) +{ + if (sibling) { + GList *node = new_node (sibling->prev, data, sibling); + return list == sibling ? node : list; + } + return g_list_append (list, data); +} + +void +g_list_foreach (GList *list, GFunc func, gpointer user_data) +{ + while (list){ + (*func) (list->data, user_data); + list = list->next; + } +} + +gint +g_list_index (GList *list, gconstpointer data) +{ + gint index = 0; + + while (list){ + if (list->data == data) + return index; + + index ++; + list = list->next; + } + + return -1; +} + +GList* +g_list_nth (GList *list, guint n) +{ + for (; list; list = list->next) { + if (n == 0) + break; + n--; + } + return list; +} + +gpointer +g_list_nth_data (GList *list, guint n) +{ + GList *node = g_list_nth (list, n); + return node ? node->data : NULL; +} + +GList* +g_list_copy (GList *list) +{ + GList *copy = NULL; + + if (list) { + GList *tmp = new_node (NULL, list->data, NULL); + copy = tmp; + + for (list = list->next; list; list = list->next) + tmp = new_node (tmp, list->data, NULL); + } + + return copy; +} + +typedef GList list_node; +#include "sort.frag.h" + +GList* +g_list_sort (GList *list, GCompareFunc func) +{ + GList *current; + if (!list || !list->next) + return list; + list = do_sort (list, func); + + /* Fixup: do_sort doesn't update 'prev' pointers */ + list->prev = NULL; + for (current = list; current->next; current = current->next) + current->next->prev = current; + + return list; +} diff --git a/deps/eglib/src/gmarkup.c b/deps/eglib/src/gmarkup.c new file mode 100644 index 00000000..7a1c0964 --- /dev/null +++ b/deps/eglib/src/gmarkup.c @@ -0,0 +1,487 @@ +/* + * gmakrup.c: Minimal XML markup reader. + * + * Unlike the GLib one, this can not be restarted with more text + * as the Mono use does not require it. + * + * Actually, with further thought, I think that this could be made + * to restart very easily. The pos == end condition would mean + * "return to caller" and only at end parse this would be a fatal + * error. + * + * Not that it matters to Mono, but it is very simple to change, there + * is a tricky situation: there are a few places where we check p+n + * in the source, and that would have to change to be progressive, instead + * of depending on the string to be complete at that point, so we would + * have to introduce extra states to cope with that. + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <ctype.h> +#include <glib.h> + +GQuark +g_markup_error_quark (void) +{ + return g_quark_from_static_string ("g-markup-error-quark"); +} + +#define set_error(code, msg, ...) do { \ + if (error != NULL) *error = \ + g_error_new (g_markup_error_quark (), \ + G_MARKUP_ERROR_ ## code, msg, __VA_ARGS__); \ +} while (0); + +typedef enum { + START, + START_ELEMENT, + TEXT, + FLUSH_TEXT, + CLOSING_ELEMENT, + COMMENT, + SKIP_XML_DECLARATION +} ParseState; + +struct _GMarkupParseContext { + GMarkupParser parser; + gpointer user_data; + GDestroyNotify user_data_dnotify; + ParseState state; + + /* Stores the name of the current element, so we can issue the end_element */ + GSList *level; + + GString *text; +}; + +GMarkupParseContext * +g_markup_parse_context_new (const GMarkupParser *parser, + GMarkupParseFlags flags, + gpointer user_data, + GDestroyNotify user_data_dnotify) +{ + GMarkupParseContext *context = g_new0 (GMarkupParseContext, 1); + + context->parser = *parser; + context->user_data = user_data; + context->user_data_dnotify = user_data_dnotify; + + return context; +} + +void +g_markup_parse_context_free (GMarkupParseContext *context) +{ + GSList *l; + + g_return_if_fail (context != NULL); + + if (context->user_data_dnotify != NULL) + (context->user_data_dnotify) (context->user_data); + + if (context->text != NULL) + g_string_free (context->text, TRUE); + for (l = context->level; l; l = l->next) + g_free (l->data); + g_slist_free (context->level); + g_free (context); +} + +static gboolean +my_isspace (char c) +{ + if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v') + return TRUE; + return FALSE; +} + +static gboolean +my_isalnum (char c) +{ + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + return TRUE; + if (c >= '0' && c <= '9') + return TRUE; + + return FALSE; +} + +static gboolean +my_isalpha (char c) +{ + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + return TRUE; + return FALSE; +} + +static const char * +skip_space (const char *p, const char *end) +{ + for (; p < end && my_isspace (*p); p++) + ; + return p; +} + +static const char * +parse_value (const char *p, const char *end, char **value, GError **error) +{ + const char *start; + int l; + + if (*p != '"'){ + set_error (PARSE, "%s", "Expected the attribute value to start with a quote"); + return end; + } + start = ++p; + for (; p < end && *p != '"'; p++) + ; + if (p == end) + return end; + l = (int)(p - start); + p++; + *value = g_malloc (l + 1); + if (*value == NULL) + return end; + strncpy (*value, start, l); + (*value) [l] = 0; + return p; +} + +static const char * +parse_name (const char *p, const char *end, char **value) +{ + const char *start = p; + int l; + + for (; p < end && my_isalnum (*p); p++) + ; + if (p == end) + return end; + + l = (int)(p - start); + *value = g_malloc (l + 1); + if (*value == NULL) + return end; + strncpy (*value, start, l); + (*value) [l] = 0; + return p; +} + +static const char * +parse_attributes (const char *p, const char *end, char ***names, char ***values, GError **error, int *full_stop, int state) +{ + int nnames = 0; + + while (TRUE){ + p = skip_space (p, end); + if (p == end) + return end; + + if (*p == '>'){ + *full_stop = 0; + return p; + } + if (state == SKIP_XML_DECLARATION && *p == '?' && ((p+1) < end) && *(p+1) == '>'){ + *full_stop = 0; + return p+1; + } + + if (*p == '/' && ((p+1) < end && *(p+1) == '>')){ + *full_stop = 1; + return p+1; + } else { + char *name, *value; + + p = parse_name (p, end, &name); + if (p == end) + return p; + + p = skip_space (p, end); + if (p == end){ + g_free (name); + return p; + } + if (*p != '='){ + set_error (PARSE, "Expected an = after the attribute name `%s'", name); + g_free (name); + return end; + } + p++; + p = skip_space (p, end); + if (p == end){ + g_free (name); + return end; + } + + p = parse_value (p, end, &value, error); + if (p == end){ + g_free (name); + return p; + } + + ++nnames; + *names = g_realloc (*names, sizeof (char **) * (nnames+1)); + *values = g_realloc (*values, sizeof (char **) * (nnames+1)); + (*names) [nnames-1] = name; + (*values) [nnames-1] = value; + (*names) [nnames] = NULL; + (*values) [nnames] = NULL; + } + } +} + +static void +destroy_parse_state (GMarkupParseContext *context) +{ + GSList *p; + + for (p = context->level; p != NULL; p = p->next) + g_free (p->data); + + g_slist_free (context->level); + if (context->text != NULL) + g_string_free (context->text, TRUE); + context->text = NULL; + context->level = NULL; +} + +gboolean +g_markup_parse_context_parse (GMarkupParseContext *context, + const gchar *text, gssize text_len, + GError **error) +{ + const char *p, *end; + + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (text != NULL, FALSE); + g_return_val_if_fail (text_len >= 0, FALSE); + + end = text + text_len; + + for (p = text; p < end; p++){ + char c = *p; + + switch (context->state){ + case START: + if (c == ' ' || c == '\t' || c == '\f' || c == '\n' || (c & 0x80)) + continue; + if (c == '<'){ + if (p+1 < end && p [1] == '?'){ + context->state = SKIP_XML_DECLARATION; + p++; + } else + context->state = START_ELEMENT; + continue; + } + set_error (PARSE, "%s", "Expected < to start the document"); + goto fail; + + case SKIP_XML_DECLARATION: + case START_ELEMENT: { + const char *element_start = p, *element_end; + char *ename = NULL; + int full_stop = 0, l; + gchar **names = NULL, **values = NULL; + + for (; p < end && my_isspace (*p); p++) + ; + if (p == end){ + set_error (PARSE, "%s", "Unfinished element"); + goto fail; + } + + if (*p == '!' && (p+2 < end) && (p [1] == '-') && (p [2] == '-')){ + context->state = COMMENT; + p += 2; + break; + } + + if (!my_isalpha (*p)){ + set_error (PARSE, "%s", "Expected an element name"); + goto fail; + } + + for (++p; p < end && (my_isalnum (*p) || (*p == '.')); p++) + ; + if (p == end){ + set_error (PARSE, "%s", "Expected an element"); + goto fail; + } + element_end = p; + + for (; p < end && my_isspace (*p); p++) + ; + if (p == end){ + set_error (PARSE, "%s", "Unfinished element"); + goto fail; + } + p = parse_attributes (p, end, &names, &values, error, &full_stop, context->state); + if (p == end){ + if (names != NULL) { + g_strfreev (names); + g_strfreev (values); + } + /* Only set the error if parse_attributes did not */ + if (error != NULL && *error == NULL) + set_error (PARSE, "%s", "Unfinished sequence"); + goto fail; + } + l = (int)(element_end - element_start); + ename = g_malloc (l + 1); + if (ename == NULL) + goto fail; + strncpy (ename, element_start, l); + ename [l] = 0; + + if (context->state == START_ELEMENT) + if (context->parser.start_element != NULL) + context->parser.start_element (context, ename, + (const gchar **) names, + (const gchar **) values, + context->user_data, error); + + if (names != NULL){ + g_strfreev (names); + g_strfreev (values); + } + + if (error != NULL && *error != NULL){ + g_free (ename); + goto fail; + } + + if (full_stop){ + if (context->parser.end_element != NULL && context->state == START_ELEMENT){ + context->parser.end_element (context, ename, context->user_data, error); + if (error != NULL && *error != NULL){ + free (ename); + goto fail; + } + } + g_free (ename); + } else { + context->level = g_slist_prepend (context->level, ename); + } + + context->state = TEXT; + break; + } /* case START_ELEMENT */ + + case TEXT: { + if (c == '<'){ + context->state = FLUSH_TEXT; + break; + } + if (context->parser.text != NULL){ + if (context->text == NULL) + context->text = g_string_new (""); + g_string_append_c (context->text, c); + } + break; + } + + case COMMENT: + if (*p != '-') + break; + if (p+2 < end && (p [1] == '-') && (p [2] == '>')){ + context->state = TEXT; + p += 2; + break; + } + break; + + case FLUSH_TEXT: + if (context->parser.text != NULL && context->text != NULL){ + context->parser.text (context, context->text->str, context->text->len, + context->user_data, error); + if (error != NULL && *error != NULL) + goto fail; + } + + if (c == '/') + context->state = CLOSING_ELEMENT; + else { + p--; + context->state = START_ELEMENT; + } + break; + + case CLOSING_ELEMENT: { + GSList *current = context->level; + char *text; + + if (context->level == NULL){ + set_error (PARSE, "%s", "Too many closing tags, not enough open tags"); + goto fail; + } + + text = current->data; + if (context->parser.end_element != NULL){ + context->parser.end_element (context, text, context->user_data, error); + if (error != NULL && *error != NULL){ + g_free (text); + goto fail; + } + } + g_free (text); + + while (p < end && *p != '>') + p++; + + context->level = context->level->next; + g_slist_free_1 (current); + context->state = TEXT; + break; + } /* case CLOSING_ELEMENT */ + + } /* switch */ + } + + + return TRUE; + fail: + if (context->parser.error && error != NULL && *error) + context->parser.error (context, *error, context->user_data); + + destroy_parse_state (context); + return FALSE; +} + +gboolean +g_markup_parse_context_end_parse (GMarkupParseContext *context, GError **error) +{ + g_return_val_if_fail (context != NULL, FALSE); + + /* + * In our case, we always signal errors during parse, not at the end + * see the notes at the top of this file for details on how this + * could be moved here + */ + return TRUE; +} diff --git a/deps/eglib/src/gmem.c b/deps/eglib/src/gmem.c new file mode 100644 index 00000000..a59a4388 --- /dev/null +++ b/deps/eglib/src/gmem.c @@ -0,0 +1,108 @@ +/* + * gmem.c: memory utility functions + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <string.h> +#include <glib.h> + +void +g_free (void *ptr) +{ + if (ptr != NULL) + free (ptr); +} + +gpointer +g_memdup (gconstpointer mem, guint byte_size) +{ + gpointer ptr; + + if (mem == NULL) + return NULL; + + ptr = g_malloc (byte_size); + if (ptr != NULL) + memcpy (ptr, mem, byte_size); + + return ptr; +} + +gpointer g_realloc (gpointer obj, gsize size) +{ + gpointer ptr; + if (!size) { + g_free (obj); + return 0; + } + ptr = realloc (obj, size); + if (ptr) + return ptr; + g_error ("Could not allocate %i bytes", size); +} + +gpointer +g_malloc (gsize x) +{ + gpointer ptr; + if (!x) + return 0; + ptr = malloc (x); + if (ptr) + return ptr; + g_error ("Could not allocate %i bytes", x); +} + +gpointer g_malloc0 (gsize x) +{ + gpointer ptr; + if (!x) + return 0; + ptr = calloc(1,x); + if (ptr) + return ptr; + g_error ("Could not allocate %i bytes", x); +} + +gpointer g_try_malloc (gsize x) +{ + if (x) + return malloc (x); + return 0; +} + + +gpointer g_try_realloc (gpointer obj, gsize size) +{ + if (!size) { + g_free (obj); + return 0; + } + return realloc (obj, size); +} diff --git a/deps/eglib/src/gmisc-unix.c b/deps/eglib/src/gmisc-unix.c new file mode 100644 index 00000000..860b9304 --- /dev/null +++ b/deps/eglib/src/gmisc-unix.c @@ -0,0 +1,152 @@ +/* + * gmisc.c: Misc functions with no place to go (right now) + * + * Author: + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> +#include <stdlib.h> +#include <glib.h> +#include <pthread.h> + +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + + +const gchar * +g_getenv(const gchar *variable) +{ + return getenv(variable); +} + +gboolean +g_setenv(const gchar *variable, const gchar *value, gboolean overwrite) +{ + return setenv(variable, value, overwrite) == 0; +} + +void +g_unsetenv(const gchar *variable) +{ + unsetenv(variable); +} + +gchar* +g_win32_getlocale(void) +{ + return NULL; +} + +gboolean +g_path_is_absolute (const char *filename) +{ + g_return_val_if_fail (filename != NULL, FALSE); + + return (*filename == '/'); +} + +static pthread_mutex_t pw_lock = PTHREAD_MUTEX_INITIALIZER; +static const gchar *home_dir; +static const gchar *user_name; + +static void +get_pw_data (void) +{ +#ifdef HAVE_GETPWUID_R + struct passwd pw; + struct passwd *result; + char buf [4096]; +#endif + + if (user_name != NULL) + return; + + pthread_mutex_lock (&pw_lock); + if (user_name != NULL) { + pthread_mutex_unlock (&pw_lock); + return; + } +#ifdef HAVE_GETPWUID_R + if (getpwuid_r (getuid (), &pw, buf, 4096, &result) == 0) { + home_dir = g_strdup (pw.pw_dir); + user_name = g_strdup (pw.pw_name); + } +#endif + if (home_dir == NULL) + home_dir = g_getenv ("HOME"); + + if (user_name == NULL) { + user_name = g_getenv ("USER"); + if (user_name == NULL) + user_name = "somebody"; + } + pthread_mutex_unlock (&pw_lock); +} + +/* Give preference to /etc/passwd than HOME */ +const gchar * +g_get_home_dir (void) +{ + get_pw_data (); + return home_dir; +} + +const char * +g_get_user_name (void) +{ + get_pw_data (); + return user_name; +} + +static const char *tmp_dir; + +static pthread_mutex_t tmp_lock = PTHREAD_MUTEX_INITIALIZER; + +const gchar * +g_get_tmp_dir (void) +{ + if (tmp_dir == NULL){ + pthread_mutex_lock (&tmp_lock); + if (tmp_dir == NULL){ + tmp_dir = g_getenv ("TMPDIR"); + if (tmp_dir == NULL){ + tmp_dir = g_getenv ("TMP"); + if (tmp_dir == NULL){ + tmp_dir = g_getenv ("TEMP"); + if (tmp_dir == NULL) + tmp_dir = "/tmp"; + } + } + } + pthread_mutex_unlock (&tmp_lock); + } + return tmp_dir; +} + diff --git a/deps/eglib/src/gmisc-win32.c b/deps/eglib/src/gmisc-win32.c new file mode 100644 index 00000000..35bb43de --- /dev/null +++ b/deps/eglib/src/gmisc-win32.c @@ -0,0 +1,166 @@ +/* + * gmisc.c: Misc functions with no place to go (right now) + * + * Author: + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include <config.h> + +#include <stdlib.h> +#include <glib.h> + +#include <windows.h> +#include <direct.h> +#include <io.h> + +const gchar * +g_getenv(const gchar *variable) +{ + gunichar2 *var, *buffer; + gchar* val = NULL; + gint32 buffer_size = 1024; + gint32 retval; + var = u8to16(variable); + buffer = g_malloc(buffer_size*sizeof(gunichar2)); + retval = GetEnvironmentVariableW (var, buffer, buffer_size); + if (retval != 0) { + if (retval > buffer_size) { + g_free (buffer); + buffer_size = retval; + buffer = g_malloc(buffer_size*sizeof(gunichar2)); + retval = GetEnvironmentVariableW (var, buffer, buffer_size); + } + val = u16to8 (buffer); + } else { + if (GetLastError () != ERROR_ENVVAR_NOT_FOUND){ + val = g_malloc (1); + *val = 0; + } + } + g_free(var); + g_free(buffer); + return val; +} + +gboolean +g_setenv(const gchar *variable, const gchar *value, gboolean overwrite) +{ + gunichar2 *var, *val; + gboolean result; + var = u8to16(variable); + val = u8to16(value); + result = (SetEnvironmentVariableW(var, val) != 0) ? TRUE : FALSE; + g_free(var); + g_free(val); + return result; +} + +void +g_unsetenv(const gchar *variable) +{ + gunichar2 *var; + var = u8to16(variable); + SetEnvironmentVariableW(var, L""); + g_free(var); +} + +gchar* +g_win32_getlocale(void) +{ + LCID lcid = GetThreadLocale(); + gchar buf[19]; + gint ccBuf = GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, 9); + buf[ccBuf - 1] = '-'; + ccBuf += GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, buf + ccBuf, 9); + return strdup(buf); +} + +gboolean +g_path_is_absolute (const char *filename) +{ + g_return_val_if_fail (filename != NULL, FALSE); + + if (filename[0] != '\0' && filename[1] != '\0') { + if (filename[1] == ':' && filename[2] != '\0' && + (filename[2] == '\\' || filename[2] == '/')) + return TRUE; + /* UNC paths */ + else if (filename[0] == '\\' && filename[1] == '\\' && + filename[2] != '\0') + return TRUE; + } + + return FALSE; +} + +const gchar * +g_get_home_dir (void) +{ + /* FIXME */ + const gchar *drive = g_getenv ("HOMEDRIVE"); + const gchar *path = g_getenv ("HOMEPATH"); + gchar *home_dir = NULL; + + if (drive && path) { + home_dir = g_malloc(strlen(drive) + strlen(path) +1); + if (home_dir) { + sprintf(home_dir, "%s%s", drive, path); + } + } + + return home_dir; +} + +const char * +g_get_user_name (void) +{ + const char * retName = g_getenv ("USER"); + if (!retName) + retName = g_getenv ("USERNAME"); + return retName; +} + +static const char *tmp_dir; + +const gchar * +g_get_tmp_dir (void) +{ + if (tmp_dir == NULL){ + if (tmp_dir == NULL){ + tmp_dir = g_getenv ("TMPDIR"); + if (tmp_dir == NULL){ + tmp_dir = g_getenv ("TMP"); + if (tmp_dir == NULL){ + tmp_dir = g_getenv ("TEMP"); + if (tmp_dir == NULL) + tmp_dir = "C:\\temp"; + } + } + } + } + return tmp_dir; +} + diff --git a/deps/eglib/src/gmodule-unix.c b/deps/eglib/src/gmodule-unix.c new file mode 100644 index 00000000..9dd5eaa3 --- /dev/null +++ b/deps/eglib/src/gmodule-unix.c @@ -0,0 +1,290 @@ +/* + * gmodule.c: dl* functions, glib style + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * Jonathan Chambers (joncham@gmail.com) + * Robert Jordan (robertj@gmx.net) + * + * (C) 2006 Novell, Inc. + * (C) 2006 Jonathan Chambers + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> + +#include <glib.h> +#include <gmodule.h> + +#if defined(G_OS_UNIX) && defined(HAVE_DLFCN_H) +#include <dlfcn.h> + +/* For Linux and Solaris, need to add others as we port this */ +#define LIBPREFIX "lib" +#define LIBSUFFIX ".so" + +struct _GModule { + void *handle; +}; + +GModule * +g_module_open (const gchar *file, GModuleFlags flags) +{ + int f = 0; + GModule *module; + void *handle; + + flags &= G_MODULE_BIND_MASK; + if ((flags & G_MODULE_BIND_LAZY) != 0) + f |= RTLD_LAZY; + if ((flags & G_MODULE_BIND_LOCAL) != 0) + f |= RTLD_LOCAL; + + handle = dlopen (file, f); + if (handle == NULL) + return NULL; + + module = g_new (GModule,1); + module->handle = handle; + + return module; +} + +gboolean +g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol) +{ + if (symbol_name == NULL || symbol == NULL) + return FALSE; + + if (module == NULL || module->handle == NULL) + return FALSE; + + *symbol = dlsym (module->handle, symbol_name); + return (*symbol != NULL); +} + +const gchar * +g_module_error (void) +{ + return dlerror (); +} + +gboolean +g_module_close (GModule *module) +{ + void *handle; + if (module == NULL || module->handle == NULL) + return FALSE; + + handle = module->handle; + module->handle = NULL; + g_free (module); + return (0 == dlclose (handle)); +} + +#elif defined (G_OS_WIN32) +#include <windows.h> +#include <psapi.h> + +#define LIBSUFFIX ".dll" +#define LIBPREFIX "" + +struct _GModule { + HMODULE handle; + int main_module; +}; + +GModule * +g_module_open (const gchar *file, GModuleFlags flags) +{ + GModule *module; + module = g_malloc (sizeof (GModule)); + if (module == NULL) + return NULL; + + if (file != NULL) { + gunichar2 *file16; + file16 = u8to16(file); + module->main_module = FALSE; + module->handle = LoadLibrary (file16); + g_free(file16); + if (!module->handle) { + g_free (module); + return NULL; + } + + } else { + module->main_module = TRUE; + module->handle = GetModuleHandle (NULL); + } + + return module; +} + +static gpointer +w32_find_symbol (const gchar *symbol_name) +{ + HMODULE *modules; + DWORD buffer_size = sizeof (HMODULE) * 1024; + DWORD needed, i; + + modules = (HMODULE *) g_malloc (buffer_size); + + if (modules == NULL) + return NULL; + + if (!EnumProcessModules (GetCurrentProcess (), modules, + buffer_size, &needed)) { + g_free (modules); + return NULL; + } + + /* check whether the supplied buffer was too small, realloc, retry */ + if (needed > buffer_size) { + g_free (modules); + + buffer_size = needed; + modules = (HMODULE *) g_malloc (buffer_size); + + if (modules == NULL) + return NULL; + + if (!EnumProcessModules (GetCurrentProcess (), modules, + buffer_size, &needed)) { + g_free (modules); + return NULL; + } + } + + for (i = 0; i < needed / sizeof (HANDLE); i++) { + gpointer proc = (gpointer)(intptr_t)GetProcAddress (modules [i], symbol_name); + if (proc != NULL) { + g_free (modules); + return proc; + } + } + + g_free (modules); + return NULL; +} + +gboolean +g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol) +{ + if (module == NULL || symbol_name == NULL || symbol == NULL) + return FALSE; + + if (module->main_module) { + *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name); + if (*symbol != NULL) + return TRUE; + + *symbol = w32_find_symbol (symbol_name); + return *symbol != NULL; + } else { + *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name); + return *symbol != NULL; + } +} + +const gchar * +g_module_error (void) +{ + gchar* ret = NULL; + TCHAR* buf = NULL; + DWORD code = GetLastError (); + + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, + code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL); + + ret = u16to8 (buf); + LocalFree(buf); + + return ret; +} + +gboolean +g_module_close (GModule *module) +{ + HMODULE handle; + int main_module; + + if (module == NULL || module->handle == NULL) + return FALSE; + + handle = module->handle; + main_module = module->main_module; + module->handle = NULL; + g_free (module); + return (main_module ? 1 : (0 == FreeLibrary (handle))); +} + +#else + +#define LIBSUFFIX "" +#define LIBPREFIX "" + +GModule * +g_module_open (const gchar *file, GModuleFlags flags) +{ + g_error ("%s", "g_module_open not implemented on this platform"); + return NULL; +} + +gboolean +g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol) +{ + g_error ("%s", "g_module_open not implemented on this platform"); + return FALSE; +} + +const gchar * +g_module_error (void) +{ + g_error ("%s", "g_module_open not implemented on this platform"); + return NULL; +} + +gboolean +g_module_close (GModule *module) +{ + g_error ("%s", "g_module_open not implemented on this platform"); + return FALSE; +} +#endif + +gchar * +g_module_build_path (const gchar *directory, const gchar *module_name) +{ + char *lib_prefix = ""; + + if (module_name == NULL) + return NULL; + + if (strncmp (module_name, "lib", 3) != 0) + lib_prefix = LIBPREFIX; + + if (directory && *directory){ + + return g_strdup_printf ("%s/%s%s" LIBSUFFIX, directory, lib_prefix, module_name); + } + return g_strdup_printf ("%s%s" LIBSUFFIX, lib_prefix, module_name); +} + diff --git a/deps/eglib/src/gmodule-win32.c b/deps/eglib/src/gmodule-win32.c new file mode 100644 index 00000000..7dcaa05d --- /dev/null +++ b/deps/eglib/src/gmodule-win32.c @@ -0,0 +1,189 @@ +/* + * gmodule.c: dl* functions, glib style + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * Jonathan Chambers (joncham@gmail.com) + * Robert Jordan (robertj@gmx.net) + * + * (C) 2006 Novell, Inc. + * (C) 2006 Jonathan Chambers + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <gmodule.h> +#include <windows.h> +#include <psapi.h> + +#define LIBSUFFIX ".dll" +#define LIBPREFIX "" + +struct _GModule { + HMODULE handle; + int main_module; +}; + +GModule * +g_module_open (const gchar *file, GModuleFlags flags) +{ + GModule *module; + module = g_malloc (sizeof (GModule)); + if (module == NULL) + return NULL; + + if (file != NULL) { + gunichar2 *file16; + file16 = u8to16(file); + module->main_module = FALSE; + module->handle = LoadLibraryW (file16); + g_free(file16); + if (!module->handle) { + g_free (module); + return NULL; + } + + } else { + module->main_module = TRUE; + module->handle = GetModuleHandle (NULL); + } + + return module; +} + +static gpointer +w32_find_symbol (const gchar *symbol_name) +{ + HMODULE *modules; + DWORD buffer_size = sizeof (HMODULE) * 1024; + DWORD needed, i; + + modules = (HMODULE *) g_malloc (buffer_size); + + if (modules == NULL) + return NULL; + + if (!EnumProcessModules (GetCurrentProcess (), modules, + buffer_size, &needed)) { + g_free (modules); + return NULL; + } + + /* check whether the supplied buffer was too small, realloc, retry */ + if (needed > buffer_size) { + g_free (modules); + + buffer_size = needed; + modules = (HMODULE *) g_malloc (buffer_size); + + if (modules == NULL) + return NULL; + + if (!EnumProcessModules (GetCurrentProcess (), modules, + buffer_size, &needed)) { + g_free (modules); + return NULL; + } + } + + for (i = 0; i < needed / sizeof (HANDLE); i++) { + gpointer proc = (gpointer)(intptr_t)GetProcAddress (modules [i], symbol_name); + if (proc != NULL) { + g_free (modules); + return proc; + } + } + + g_free (modules); + return NULL; +} + +gboolean +g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol) +{ + if (module == NULL || symbol_name == NULL || symbol == NULL) + return FALSE; + + if (module->main_module) { + *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name); + if (*symbol != NULL) + return TRUE; + + *symbol = w32_find_symbol (symbol_name); + return *symbol != NULL; + } else { + *symbol = (gpointer)(intptr_t)GetProcAddress (module->handle, symbol_name); + return *symbol != NULL; + } +} + +const gchar * +g_module_error (void) +{ + gchar* ret = NULL; + TCHAR* buf = NULL; + DWORD code = GetLastError (); + + /* FIXME: buf must not be NULL! */ + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, + code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 0, NULL); + + ret = u16to8 (buf); + LocalFree(buf); + + return ret; +} + +gboolean +g_module_close (GModule *module) +{ + HMODULE handle; + int main_module; + + if (module == NULL || module->handle == NULL) + return FALSE; + + handle = module->handle; + main_module = module->main_module; + module->handle = NULL; + g_free (module); + return (main_module ? 1 : (0 == FreeLibrary (handle))); +} + +gchar * +g_module_build_path (const gchar *directory, const gchar *module_name) +{ + char *lib_prefix = ""; + + if (module_name == NULL) + return NULL; + + if (strncmp (module_name, "lib", 3) != 0) + lib_prefix = LIBPREFIX; + + if (directory && *directory){ + + return g_strdup_printf ("%s/%s%s" LIBSUFFIX, directory, lib_prefix, module_name); + } + return g_strdup_printf ("%s%s" LIBSUFFIX, lib_prefix, module_name); +} diff --git a/deps/eglib/src/gmodule.h b/deps/eglib/src/gmodule.h new file mode 100644 index 00000000..ee89683f --- /dev/null +++ b/deps/eglib/src/gmodule.h @@ -0,0 +1,37 @@ +#ifndef __GLIB_GMODULE_H +#define __GLIB_GMODULE_H + +#include <glib.h> + +#define G_MODULE_IMPORT extern +#ifdef G_OS_WIN32 +#define G_MODULE_EXPORT __declspec(dllexport) +#else +#define G_MODULE_EXPORT +#endif + +G_BEGIN_DECLS + +/* + * Modules + */ +typedef enum { + G_MODULE_BIND_LAZY = 0x01, + G_MODULE_BIND_LOCAL = 0x02, + G_MODULE_BIND_MASK = 0x03 +} GModuleFlags; +typedef struct _GModule GModule; + +GModule *g_module_open (const gchar *file, GModuleFlags flags); +gboolean g_module_symbol (GModule *module, const gchar *symbol_name, + gpointer *symbol); +const gchar *g_module_error (void); +gboolean g_module_close (GModule *module); +gchar * g_module_build_path (const gchar *directory, const gchar *module_name); + +extern char *gmodule_libprefix; +extern char *gmodule_libsuffix; + +G_END_DECLS + +#endif diff --git a/deps/eglib/src/goutput.c b/deps/eglib/src/goutput.c new file mode 100644 index 00000000..aff9f460 --- /dev/null +++ b/deps/eglib/src/goutput.c @@ -0,0 +1,199 @@ +/* + * Output and debugging functions + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * Copyright 2011 Xamarin Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <glib.h> + +/* The current fatal levels, error is always fatal */ +static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; + +#if PLATFORM_ANDROID +#include <android/log.h> + +static android_LogPriority +to_android_priority (GLogLevelFlags log_level) +{ + switch (log_level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: return ANDROID_LOG_FATAL; + case G_LOG_LEVEL_CRITICAL: return ANDROID_LOG_ERROR; + case G_LOG_LEVEL_WARNING: return ANDROID_LOG_WARN; + case G_LOG_LEVEL_MESSAGE: return ANDROID_LOG_INFO; + case G_LOG_LEVEL_INFO: return ANDROID_LOG_DEBUG; + case G_LOG_LEVEL_DEBUG: return ANDROID_LOG_VERBOSE; + } + return ANDROID_LOG_UNKNOWN; +} + +static void +out_vfprintf (FILE *ignore, const gchar *format, va_list args) +{ + /* TODO: provide a proper app name */ + __android_log_vprint (ANDROID_LOG_ERROR, "mono", format, args); +} +#elif MONOTOUCH && defined(__arm__) +#include <asl.h> + +static int +to_asl_priority (GLogLevelFlags log_level) +{ + switch (log_level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: return ASL_LEVEL_CRIT; + case G_LOG_LEVEL_CRITICAL: return ASL_LEVEL_ERR; + case G_LOG_LEVEL_WARNING: return ASL_LEVEL_WARNING; + case G_LOG_LEVEL_MESSAGE: return ASL_LEVEL_NOTICE; + case G_LOG_LEVEL_INFO: return ASL_LEVEL_INFO; + case G_LOG_LEVEL_DEBUG: return ASL_LEVEL_DEBUG; + } + return ASL_LEVEL_ERR; +} + +static void +out_vfprintf (FILE *ignore, const gchar *format, va_list args) +{ + asl_vlog (NULL, NULL, ASL_LEVEL_WARNING, format, args); +} + +#else +static void +out_vfprintf (FILE *file, const gchar *format, va_list args) +{ + vfprintf (file, format, args); +} +#endif + +void +g_print (const gchar *format, ...) +{ + va_list args; + + va_start (args, format); + + out_vfprintf (stdout, format, args); + + va_end (args); +} + +void +g_printerr (const gchar *format, ...) +{ + va_list args; + + va_start (args, format); + + out_vfprintf (stderr, format, args); + + va_end (args); +} + +GLogLevelFlags +g_log_set_always_fatal (GLogLevelFlags fatal_mask) +{ + GLogLevelFlags old_fatal = fatal; + + fatal |= fatal_mask; + + return old_fatal; +} + +GLogLevelFlags +g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags fatal_mask) +{ + /* + * Mono does not use a G_LOG_DOMAIN currently, so we just assume things are fatal + * if we decide to set G_LOG_DOMAIN (we probably should) we should implement + * this. + */ + return fatal_mask; +} + +void +g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args) +{ +#if PLATFORM_ANDROID + __android_log_vprint (to_android_priority (log_level), log_domain, format, args); +#elif MONOTOUCH && defined(__arm__) + asl_vlog (NULL, NULL, to_asl_priority (log_level), format, args); +#else + char *msg; + + if (vasprintf (&msg, format, args) < 0) + return; + +#ifdef G_OS_WIN32 + printf ("%s%s%s\n", + log_domain != NULL ? log_domain : "", + log_domain != NULL ? ": " : "", + msg); +#else +#if MONOTOUCH + FILE *target = stderr; +#else + FILE *target = stdout; +#endif + + fprintf (target, "%s%s%s\n", + log_domain != NULL ? log_domain : "", + log_domain != NULL ? ": " : "", + msg); +#endif + free (msg); + if (log_level & fatal){ + fflush (stdout); + fflush (stderr); + } +#endif + if (log_level & fatal){ + abort (); + } +} + +void +g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...) +{ + va_list args; + + va_start (args, format); + g_logv (log_domain, log_level, format, args); + va_end (args); +} + +void +g_assertion_message (const gchar *format, ...) +{ + va_list args; + + va_start (args, format); + g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args); + va_end (args); + abort (); +} + diff --git a/deps/eglib/src/gpath.c b/deps/eglib/src/gpath.c new file mode 100644 index 00000000..5302f427 --- /dev/null +++ b/deps/eglib/src/gpath.c @@ -0,0 +1,296 @@ +/* + * Portable Utility Functions + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <stdio.h> +#include <glib.h> +#include <errno.h> + +#ifdef G_OS_WIN32 +#include <direct.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +gchar * +g_build_path (const gchar *separator, const gchar *first_element, ...) +{ + const char *elem, *next, *endptr; + gboolean trimmed; + GString *path; + va_list args; + size_t slen; + + g_return_val_if_fail (separator != NULL, NULL); + + path = g_string_sized_new (48); + slen = strlen (separator); + + va_start (args, first_element); + for (elem = first_element; elem != NULL; elem = next) { + /* trim any trailing separators from @elem */ + endptr = elem + strlen (elem); + trimmed = FALSE; + + while (endptr >= elem + slen) { + if (strncmp (endptr - slen, separator, slen) != 0) + break; + + endptr -= slen; + trimmed = TRUE; + } + + /* append elem, not including any trailing separators */ + if (endptr > elem) + g_string_append_len (path, elem, endptr - elem); + + /* get the next element */ + do { + if (!(next = va_arg (args, char *))) + break; + + /* remove leading separators */ + while (!strncmp (next, separator, slen)) + next += slen; + } while (*next == '\0'); + + if (next || trimmed) + g_string_append_len (path, separator, slen); + } + va_end (args); + + return g_string_free (path, FALSE); +} + +static gchar* +strrchr_seperator (const gchar* filename) +{ +#ifdef G_OS_WIN32 + char *p2; +#endif + char *p; + + p = strrchr (filename, G_DIR_SEPARATOR); +#ifdef G_OS_WIN32 + p2 = strrchr (filename, '/'); + if (p2 > p) + p = p2; +#endif + + return p; +} + +gchar * +g_path_get_dirname (const gchar *filename) +{ + char *p, *r; + size_t count; + g_return_val_if_fail (filename != NULL, NULL); + + p = strrchr_seperator (filename); + if (p == NULL) + return g_strdup ("."); + if (p == filename) + return g_strdup ("/"); + count = p - filename; + r = g_malloc (count + 1); + strncpy (r, filename, count); + r [count] = 0; + + return r; +} + +gchar * +g_path_get_basename (const char *filename) +{ + char *r; + g_return_val_if_fail (filename != NULL, NULL); + + /* Empty filename -> . */ + if (!*filename) + return g_strdup ("."); + + /* No separator -> filename */ + r = strrchr_seperator (filename); + if (r == NULL) + return g_strdup (filename); + + /* Trailing slash, remove component */ + if (r [1] == 0){ + char *copy = g_strdup (filename); + copy [r-filename] = 0; + r = strrchr_seperator (copy); + + if (r == NULL){ + g_free (copy); + return g_strdup ("/"); + } + r = g_strdup (&r[1]); + g_free (copy); + return r; + } + + return g_strdup (&r[1]); +} + +#ifndef HAVE_STRTOK_R +// This is from BSD's strtok_r + +char * +strtok_r(char *s, const char *delim, char **last) +{ + char *spanp; + int c, sc; + char *tok; + + if (s == NULL && (s = *last) == NULL) + return NULL; + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0; ){ + if (c == sc) + goto cont; + } + + if (c == 0){ /* no non-delimiter characters */ + *last = NULL; + return NULL; + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;){ + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else { + char *w = s - 1; + *w = '\0'; + } + *last = s; + return tok; + } + } + while (sc != 0); + } + /* NOTREACHED */ +} +#endif + +gchar * +g_find_program_in_path (const gchar *program) +{ + char *p; + char *x, *l; + gchar *curdir = NULL; + char *save = NULL; +#ifdef G_OS_WIN32 + char *program_exe; + char *suffix_list[5] = {".exe",".cmd",".bat",".com",NULL}; + int listx; + gboolean hasSuffix; +#endif + + g_return_val_if_fail (program != NULL, NULL); + x = p = g_strdup (g_getenv ("PATH")); + + if (x == NULL || *x == '\0') { + curdir = g_get_current_dir (); + x = curdir; + } + +#ifdef G_OS_WIN32 + /* see if program already has a suffix */ + listx = 0; + hasSuffix = FALSE; + while (!hasSuffix && suffix_list[listx]) { + hasSuffix = g_str_has_suffix(program,suffix_list[listx++]); + } +#endif + + while ((l = strtok_r (x, G_SEARCHPATH_SEPARATOR_S, &save)) != NULL){ + char *probe_path; + + x = NULL; + probe_path = g_build_path (G_DIR_SEPARATOR_S, l, program, NULL); + if (access (probe_path, X_OK) == 0){ /* FIXME: on windows this is just a read permissions test */ + g_free (curdir); + g_free (p); + return probe_path; + } + g_free (probe_path); + +#ifdef G_OS_WIN32 + /* check for program with a suffix attached */ + if (!hasSuffix) { + listx = 0; + while (suffix_list[listx]) { + program_exe = g_strjoin(NULL,program,suffix_list[listx],NULL); + probe_path = g_build_path (G_DIR_SEPARATOR_S, l, program_exe, NULL); + if (access (probe_path, X_OK) == 0){ /* FIXME: on windows this is just a read permissions test */ + g_free (curdir); + g_free (p); + g_free (program_exe); + return probe_path; + } + listx++; + g_free (probe_path); + g_free (program_exe); + } + } +#endif + } + g_free (curdir); + g_free (p); + return NULL; +} + +static char *name; + +void +g_set_prgname (const gchar *prgname) +{ + name = g_strdup (prgname); +} + +gchar * +g_get_prgname (void) +{ + return name; +} diff --git a/deps/eglib/src/gpattern.c b/deps/eglib/src/gpattern.c new file mode 100644 index 00000000..aef45ded --- /dev/null +++ b/deps/eglib/src/gpattern.c @@ -0,0 +1,216 @@ +/* + * Simple pattern matching + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#ifndef _MSC_VER +#include <unistd.h> +#endif + +typedef enum { + MATCH_LITERAL, + MATCH_ANYCHAR, + MATCH_ANYTHING, + MATCH_ANYTHING_END, + MATCH_INVALID = -1 +} MatchType; + +typedef struct { + MatchType type; + gchar *str; +} PData; + +struct _GPatternSpec { + GSList *pattern; +}; + +static GSList * +compile_pattern (const gchar *pattern) +{ + GSList *list; + size_t i, len; + PData *data; + gchar c; + MatchType last = MATCH_INVALID; + GString *str; + gboolean free_str; + + if (pattern == NULL) + return NULL; + + data = NULL; + list = NULL; + free_str = TRUE; + str = g_string_new (""); + for (i = 0, len = strlen (pattern); i < len; i++) { + c = pattern [i]; + if (c == '*' || c == '?') { + if (str->len > 0) { + data = g_new0 (PData, 1); + data->type = MATCH_LITERAL; + data->str = g_string_free (str, FALSE); + list = g_slist_append (list, data); + str = g_string_new (""); + } + + if (last == MATCH_ANYTHING && c == '*') + continue; + + data = g_new0 (PData, 1); + data->type = (c == '*') ? MATCH_ANYTHING : MATCH_ANYCHAR; + list = g_slist_append (list, data); + last = data->type; + } else { + g_string_append_c (str, c); + last = MATCH_LITERAL; + } + } + + if (last == MATCH_ANYTHING && str->len == 0) { + data->type = MATCH_ANYTHING_END; + free_str = TRUE; + } else if (str->len > 0) { + data = g_new0 (PData, 1); + data->type = MATCH_LITERAL; + data->str = str->str; + free_str = FALSE; + list = g_slist_append (list, data); + } + g_string_free (str, free_str); + return list; +} + +#ifdef DEBUG_PATTERN +static void +print_pattern (gpointer data, gpointer user_data) +{ + PData *d = (PData *) data; + + printf ("Type: %s", d->type == MATCH_LITERAL ? "literal" : d->type == MATCH_ANYCHAR ? "any char" : "anything"); + if (d->type == MATCH_LITERAL) + printf (" String: %s", d->str); + printf ("\n"); +} +#endif + +GPatternSpec * +g_pattern_spec_new (const gchar *pattern) +{ + GPatternSpec *spec; + + g_return_val_if_fail (pattern != NULL, NULL); + spec = g_new0 (GPatternSpec, 1); + if (pattern) { + spec->pattern = compile_pattern (pattern); +#ifdef DEBUG_PATTERN + g_slist_foreach (spec->pattern, print_pattern, NULL); + printf ("\n"); +#endif + } + return spec; +} + +static void +free_pdata (gpointer data, gpointer user_data) +{ + PData *d = (PData *) data; + + if (d->str) + g_free (d->str); + g_free (d); +} + +void +g_pattern_spec_free (GPatternSpec *pspec) +{ + if (pspec) { + g_slist_foreach (pspec->pattern, free_pdata, NULL); + g_slist_free (pspec->pattern); + pspec->pattern = NULL; + } + g_free (pspec); +} + +static gboolean +match_string (GSList *list, const gchar *str, size_t idx, size_t max) +{ + size_t len; + + while (list && idx < max) { + PData *data = (PData *) list->data; + + if (data->type == MATCH_ANYTHING_END) + return TRUE; + + if (data->type == MATCH_LITERAL) { + len = strlen (data->str); + if (strncmp (&str [idx], data->str, len) != 0) + return FALSE; + idx += len; + list = list->next; + if (list) { + /* + * When recursing, we need this to avoid returning FALSE + * because 'list' will not be NULL + */ + data = (PData *) list->data; + if (data->type == MATCH_ANYTHING_END) + return TRUE; + } + } else if (data->type == MATCH_ANYCHAR) { + idx++; + list = list->next; + } else if (data->type == MATCH_ANYTHING) { + while (idx < max) { + if (match_string (list->next, str, idx++, max)) + return TRUE; + } + return FALSE; + } else { + g_assert_not_reached (); + } + } + + return (list == NULL && idx >= max); +} +gboolean +g_pattern_match_string (GPatternSpec *pspec, const gchar *string) +{ + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + if (pspec->pattern == NULL) + return FALSE; + return match_string (pspec->pattern, string, 0, strlen (string)); +} + + diff --git a/deps/eglib/src/gptrarray.c b/deps/eglib/src/gptrarray.c new file mode 100644 index 00000000..1caa354c --- /dev/null +++ b/deps/eglib/src/gptrarray.c @@ -0,0 +1,248 @@ +/* + * Pointer Array + * + * Author: + * Aaron Bockover (abockover@novell.com) + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * Jeffrey Stedfast (fejj@novell.com) + * + * (C) 2006,2011 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include <config.h> + +#include <stdlib.h> +#include <glib.h> + +typedef struct _GPtrArrayPriv { + gpointer *pdata; + guint len; + guint size; + GDestroyNotify element_free_func; +} GPtrArrayPriv; + +static void +g_ptr_array_grow(GPtrArrayPriv *array, guint length) +{ + guint new_length = array->len + length; + + g_return_if_fail(array != NULL); + + if(new_length <= array->size) { + return; + } + + array->size = 1; + + while(array->size < new_length) { + array->size <<= 1; + } + + array->size = MAX(array->size, 16); + array->pdata = g_realloc(array->pdata, array->size * sizeof(gpointer)); +} + +GPtrArray * +g_ptr_array_new(void) +{ + return g_ptr_array_sized_new(0); +} + +GPtrArray * +g_ptr_array_sized_new(guint reserved_size) +{ + GPtrArrayPriv *array = g_new0(GPtrArrayPriv, 1); + + array->pdata = NULL; + array->len = 0; + array->size = 0; + + if(reserved_size > 0) { + g_ptr_array_grow(array, reserved_size); + } + + return (GPtrArray *)array; +} + +GPtrArray * +g_ptr_array_new_with_free_func(GDestroyNotify element_free_func) +{ + GPtrArrayPriv *array = (GPtrArrayPriv *)g_ptr_array_sized_new (0); + array->element_free_func = element_free_func; + return (GPtrArray *)array; +} + +gpointer * +g_ptr_array_free(GPtrArray *array, gboolean free_seg) +{ + gpointer *data = NULL; + + g_return_val_if_fail(array != NULL, NULL); + + if(free_seg) { + GPtrArrayPriv *priv = (GPtrArrayPriv *)array; + gpointer *pdata = priv->pdata; + + if (priv->element_free_func) { + GDestroyNotify free_func = priv->element_free_func; + int i; + + for (i = priv->len - 1; i > 0; i--) + free_func (pdata[i]); + } + g_free(pdata); + } else { + data = array->pdata; + } + + g_free(array); + + return data; +} + +void +g_ptr_array_set_size(GPtrArray *array, gint length) +{ + g_return_if_fail(array != NULL); + + if((size_t)length > array->len) { + g_ptr_array_grow((GPtrArrayPriv *)array, length); + memset(array->pdata + array->len, 0, (length - array->len) + * sizeof(gpointer)); + } + + array->len = length; +} + +void +g_ptr_array_add(GPtrArray *array, gpointer data) +{ + g_return_if_fail(array != NULL); + g_ptr_array_grow((GPtrArrayPriv *)array, 1); + array->pdata[array->len++] = data; +} + +gpointer +g_ptr_array_remove_index(GPtrArray *array, guint index) +{ + gpointer removed_node; + + g_return_val_if_fail(array != NULL, NULL); + g_return_val_if_fail(index >= 0 || index < array->len, NULL); + + removed_node = array->pdata[index]; + + if(index != array->len - 1) { + g_memmove(array->pdata + index, array->pdata + index + 1, + (array->len - index - 1) * sizeof(gpointer)); + } + + array->len--; + array->pdata[array->len] = NULL; + + return removed_node; +} + +gpointer +g_ptr_array_remove_index_fast(GPtrArray *array, guint index) +{ + gpointer removed_node; + + g_return_val_if_fail(array != NULL, NULL); + g_return_val_if_fail(index >= 0 || index < array->len, NULL); + + removed_node = array->pdata[index]; + + if(index != array->len - 1) { + g_memmove(array->pdata + index, array->pdata + array->len - 1, + sizeof(gpointer)); + } + + array->len--; + array->pdata[array->len] = NULL; + + return removed_node; +} + +gboolean +g_ptr_array_remove(GPtrArray *array, gpointer data) +{ + guint i; + + g_return_val_if_fail(array != NULL, FALSE); + + for(i = 0; i < array->len; i++) { + if(array->pdata[i] == data) { + g_ptr_array_remove_index(array, i); + return TRUE; + } + } + + return FALSE; +} + +gboolean +g_ptr_array_remove_fast(GPtrArray *array, gpointer data) +{ + guint i; + + g_return_val_if_fail(array != NULL, FALSE); + + for(i = 0; i < array->len; i++) { + if(array->pdata[i] == data) { + array->len--; + if (array->len > 0) + array->pdata [i] = array->pdata [array->len]; + else + array->pdata [i] = NULL; + return TRUE; + } + } + + return FALSE; +} + +void +g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data) +{ + guint i; + + for(i = 0; i < array->len; i++) { + func(g_ptr_array_index(array, i), user_data); + } +} + +void +g_ptr_array_sort(GPtrArray *array, GCompareFunc compare) +{ + g_return_if_fail(array != NULL); + qsort(array->pdata, array->len, sizeof(gpointer), compare); +} + +void +g_ptr_array_sort_with_data (GPtrArray *array, GCompareDataFunc compare, gpointer user_data) +{ + g_return_if_fail (array != NULL); + + g_qsort_with_data (array->pdata, array->len, sizeof (gpointer), compare, user_data); +} diff --git a/deps/eglib/src/gqsort.c b/deps/eglib/src/gqsort.c new file mode 100644 index 00000000..771edb8b --- /dev/null +++ b/deps/eglib/src/gqsort.c @@ -0,0 +1,168 @@ +/* + * QuickSort + * + * Author: Jeffrey Stedfast <fejj@novell.com> + * + * (C) 2011 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include <config.h> + +#include <stdlib.h> +#include <glib.h> + +/* Any segment <= this threshold will be sorted using insertion + * sort. OpenBSD seems to use a value of 7 so we'll go with that for + * now... */ +#define MAX_THRESHOLD 7 + +#define STACK_SIZE (8 * sizeof (size_t)) + +typedef struct _QSortStack { + char *array; + size_t count; +} QSortStack; + +#define QSORT_PUSH(sp, a, c) (sp->array = a, sp->count = c, sp++) +#define QSORT_POP(sp, a, c) (sp--, a = sp->array, c = sp->count) + +#define SWAPTYPE(TYPE, a, b) { \ + long __n = size / sizeof (TYPE); \ + register TYPE *__a = (TYPE *) (a); \ + register TYPE *__b = (TYPE *) (b); \ + register TYPE t; \ + \ + do { \ + t = *__a; \ + *__a++ = *__b; \ + *__b++ = t; \ + } while (--__n > 0); \ +} + +#define SWAPBYTE(a, b) SWAPTYPE(char, (a), (b)) +#define SWAPLONG(a, b) SWAPTYPE(long, (a), (b)) +#define SWAP(a, b) if (swaplong) SWAPLONG((a), (b)) else SWAPBYTE((a), (b)) + +/* check if we can swap by longs rather than bytes by making sure that + * memory is properly aligned and that the element size is a multiple + * of sizeof (long) */ +#define SWAP_INIT() swaplong = (((char *) base) - ((char *) 0)) % sizeof (long) == 0 && (size % sizeof (long)) == 0 + +void +g_qsort_with_data (gpointer base, size_t nmemb, size_t size, GCompareDataFunc compare, gpointer user_data) +{ + QSortStack stack[STACK_SIZE], *sp; + register char *i, *k, *mid; + size_t n, n1, n2; + char *lo, *hi; + int swaplong; + + if (nmemb <= 1) + return; + + SWAP_INIT (); + + /* initialize our stack */ + sp = stack; + QSORT_PUSH (sp, base, nmemb); + + do { + QSORT_POP (sp, lo, n); + + hi = lo + (n - 1) * size; + + if (n < MAX_THRESHOLD) { + /* switch to insertion sort */ + for (i = lo + size; i <= hi; i += size) + for (k = i; k > lo && compare (k - size, k, user_data) > 0; k -= size) + SWAP (k - size, k); + + continue; + } + + /* calculate the middle element */ + mid = lo + (n / 2) * size; + + /* once we re-order the lo, mid, and hi elements to be in + * ascending order, we'll use mid as our pivot. */ + if (compare (mid, lo, user_data) < 0) { + SWAP (mid, lo); + } + + if (compare (hi, mid, user_data) < 0) { + SWAP (mid, hi); + if (compare (mid, lo, user_data) < 0) { + SWAP (mid, lo); + } + } + + /* since we've already guaranteed that lo <= mid and mid <= hi, + * we can skip comparing them again */ + i = lo + size; + k = hi - size; + + do { + /* find the first element with a value > pivot value */ + while (i < k && compare (i, mid, user_data) <= 0) + i += size; + + /* find the last element with a value <= pivot value */ + while (k >= i && compare (mid, k, user_data) < 0) + k -= size; + + if (k <= i) + break; + + SWAP (i, k); + + /* make sure we keep track of our pivot element */ + if (mid == i) { + mid = k; + } else if (mid == k) { + mid = i; + } + + i += size; + k -= size; + } while (1); + + if (k != mid) { + /* swap the pivot with the last element in the first partition */ + SWAP (mid, k); + } + + /* calculate segment sizes */ + n2 = (hi - k) / size; + n1 = (k - lo) / size; + + /* push our partitions onto the stack, largest first + * (to make sure we don't run out of stack space) */ + if (n2 > n1) { + if (n2 > 1) QSORT_PUSH (sp, k + size, n2); + if (n1 > 1) QSORT_PUSH (sp, lo, n1); + } else { + if (n1 > 1) QSORT_PUSH (sp, lo, n1); + if (n2 > 1) QSORT_PUSH (sp, k + size, n2); + } + } while (sp > stack); +} diff --git a/deps/eglib/src/gquark.c b/deps/eglib/src/gquark.c new file mode 100644 index 00000000..7a888853 --- /dev/null +++ b/deps/eglib/src/gquark.c @@ -0,0 +1,57 @@ +/* + * ghooklist.c: API for manipulating a list of hook functions + * + * Copyright (C) 2014 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Robert Bragg <robert@linux.intel.com> + */ + +#include <config.h> + +#include <glib.h> + +static GHashTable *_quark_hash_table; +static guint32 _next_quark; + +GQuark +g_quark_from_static_string (const gchar *string) +{ + void *quark_ptr; + + if (G_UNLIKELY (_quark_hash_table == NULL)) + { + _quark_hash_table = g_hash_table_new (g_str_hash, g_str_equal); + _next_quark++; + } + + quark_ptr = g_hash_table_lookup (_quark_hash_table, string); + if (!quark_ptr) + { + GQuark new_quark = _next_quark++; + g_hash_table_insert (_quark_hash_table, + (gpointer)string, GUINT_TO_POINTER (new_quark)); + return new_quark; + } + else + return GPOINTER_TO_UINT (quark_ptr); +} diff --git a/deps/eglib/src/gqueue.c b/deps/eglib/src/gqueue.c new file mode 100644 index 00000000..68302c45 --- /dev/null +++ b/deps/eglib/src/gqueue.c @@ -0,0 +1,187 @@ +/* + * gqueue.c: Queue + * + * Author: + * Duncan Mak (duncan@novell.com) + * Gonzalo Paniagua Javier (gonzalo@novell.com) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2006-2009 Novell, Inc. + * + */ + + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +void +g_queue_init (GQueue *queue) +{ + queue->head = NULL; + queue->tail = NULL; + queue->length = 0; +} + +gpointer +g_queue_peek_head (GQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + return queue->head ? queue->head->data : NULL; +} + +gpointer +g_queue_pop_head (GQueue *queue) +{ + gpointer result; + GList *old_head; + + g_return_val_if_fail (queue, NULL); + + if (!queue->head) + return NULL; + + result = queue->head->data; + old_head = queue->head; + queue->head = old_head->next; + g_list_free_1 (old_head); + + if (--queue->length) + queue->head->prev = NULL; + else + queue->tail = NULL; + + return result; +} + +gpointer +g_queue_peek_tail (GQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + return queue->tail ? queue->tail->data : NULL; +} + +gpointer +g_queue_pop_tail (GQueue *queue) +{ + gpointer result; + GList *old_tail; + + g_return_val_if_fail (queue, NULL); + + if (!queue->tail) + return NULL; + + result = queue->tail->data; + old_tail = queue->tail; + queue->tail = old_tail->prev; + + if (old_tail->prev) + old_tail->prev->next = NULL; + else + queue->head = NULL; + + queue->length--; + g_list_free_1 (old_tail); + + return result; +} + +gboolean +g_queue_is_empty (GQueue *queue) +{ + g_return_val_if_fail (queue, TRUE); + return queue->length == 0; +} + +void +g_queue_push_head (GQueue *queue, gpointer head) +{ + g_return_if_fail (queue); + + queue->head = g_list_prepend (queue->head, head); + + if (!queue->tail) + queue->tail = queue->head; + + queue->length ++; +} + +void +g_queue_push_tail (GQueue *queue, gpointer data) +{ + g_return_if_fail (queue); + + queue->tail = g_list_append (queue->tail, data); + if (queue->head == NULL) + queue->head = queue->tail; + else + queue->tail = queue->tail->next; + queue->length++; +} + +GQueue * +g_queue_new (void) +{ + return g_new0 (GQueue, 1); +} + +void +g_queue_free (GQueue *queue) +{ + g_return_if_fail (queue); + + g_list_free (queue->head); + g_free (queue); +} + +void +g_queue_foreach (GQueue *queue, GFunc func, gpointer user_data) +{ + g_return_if_fail (queue); + g_return_if_fail (func); + + g_list_foreach (queue->head, func, user_data); +} + +GList * +g_queue_find (GQueue *queue, gconstpointer data) +{ + GList *l; + + for (l = queue->head; l; l = l->next) + if (l->data == data) + return l; + + return NULL; +} + +void +g_queue_clear (GQueue *queue) +{ + g_return_if_fail (queue); + + g_list_free (queue->head); + queue->length = 0; + queue->head = NULL; + queue->tail = NULL; +} diff --git a/deps/eglib/src/gshell.c b/deps/eglib/src/gshell.c new file mode 100644 index 00000000..c2ea5b52 --- /dev/null +++ b/deps/eglib/src/gshell.c @@ -0,0 +1,304 @@ +/* + * Shell utility functions. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +GQuark +g_shell_error_get_quark (void) +{ + return g_quark_from_static_string ("g-shell-error-quark"); +} + +static int +split_cmdline (const gchar *cmdline, GPtrArray *array, GError **error) +{ + gchar *ptr; + gchar c; + gboolean escaped = FALSE, fresh = TRUE; + gchar quote_char = '\0'; + GString *str; + + str = g_string_new (""); + ptr = (gchar *) cmdline; + while ((c = *ptr++) != '\0') { + if (escaped) { + /* + * \CHAR is only special inside a double quote if CHAR is + * one of: $`"\ and newline + */ + if (quote_char == '\"'){ + if (!(c == '$' || c == '`' || c == '"' || c == '\\')) + g_string_append_c (str, '\\'); + g_string_append_c (str, c); + } else { + if (!g_ascii_isspace (c)) + g_string_append_c (str, c); + } + escaped = FALSE; + } else if (quote_char) { + if (c == quote_char) { + quote_char = '\0'; + if (fresh && (g_ascii_isspace (*ptr) || *ptr == '\0')){ + g_ptr_array_add (array, g_string_free (str, FALSE)); + str = g_string_new (""); + } + } else if (c == '\\'){ + escaped = TRUE; + } else + g_string_append_c (str, c); + } else if (g_ascii_isspace (c)) { + if (str->len > 0) { + g_ptr_array_add (array, g_string_free (str, FALSE)); + str = g_string_new (""); + } + } else if (c == '\\') { + escaped = TRUE; + } else if (c == '\'' || c == '"') { + fresh = str->len == 0; + quote_char = c; + } else { + g_string_append_c (str, c); + } + } + + if (escaped) { + if (error) + *error = g_error_new (G_SHELL_ERROR, + G_SHELL_ERROR_BAD_QUOTING, + "Unfinished escape."); + g_string_free (str, TRUE); + return -1; + } + + if (quote_char) { + if (error) + *error = g_error_new (G_SHELL_ERROR, + G_SHELL_ERROR_BAD_QUOTING, + "Unfinished quote."); + g_string_free (str, TRUE); + return -1; + } + + if (str->len > 0) { + g_ptr_array_add (array, g_string_free (str, FALSE)); + } else { + g_string_free (str, TRUE); + } + g_ptr_array_add (array, NULL); + return 0; +} + +gboolean +g_shell_parse_argv (const gchar *command_line, gint *argcp, gchar ***argvp, GError **error) +{ + GPtrArray *array; + gint argc; + gchar **argv; + + g_return_val_if_fail (command_line, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + array = g_ptr_array_new(); + if (split_cmdline (command_line, array, error)) { + g_ptr_array_add (array, NULL); + g_strfreev ((gchar **) array->pdata); + g_ptr_array_free (array, FALSE); + return FALSE; + } + + argc = array->len; + argv = (gchar **) array->pdata; + + if (argc == 1) { + g_strfreev (argv); + g_ptr_array_free (array, FALSE); + return FALSE; + } + + if (argcp) { + *argcp = array->len - 1; + } + + if (argvp) { + *argvp = argv; + } else { + g_strfreev (argv); + } + + g_ptr_array_free (array, FALSE); + return TRUE; +} + +gchar * +g_shell_quote (const gchar *unquoted_string) +{ + GString *result = g_string_new ("'"); + const gchar *p; + + for (p = unquoted_string; *p; p++){ + if (*p == '\'') + g_string_append (result, "'\\'"); + g_string_append_c (result, *p); + } + g_string_append_c (result, '\''); + return g_string_free (result, FALSE); +} + +gchar * +g_shell_unquote (const gchar *quoted_string, GError **error) +{ + GString *result; + const char *p; + int do_unquote = 0; + + if (quoted_string == NULL) + return NULL; + + /* Quickly try to determine if we need to unquote or not */ + for (p = quoted_string; *p; p++){ + if (*p == '\'' || *p == '"' || *p == '\\'){ + do_unquote = 1; + break; + } + } + + if (!do_unquote) + return g_strdup (quoted_string); + + /* We do need to unquote */ + result = g_string_new (""); + for (p = quoted_string; *p; p++){ + + if (*p == '\''){ + /* Process single quote, not even \ is processed by glib's version */ + for (p++; *p; p++){ + if (*p == '\'') + break; + g_string_append_c (result, *p); + } + if (!*p){ + g_set_error (error, 0, 0, "Open quote"); + return NULL; + } + } else if (*p == '"'){ + /* Process double quote, allows some escaping */ + for (p++; *p; p++){ + if (*p == '"') + break; + if (*p == '\\'){ + p++; + if (*p == 0){ + g_set_error (error, 0, 0, "Open quote"); + return NULL; + } + switch (*p){ + case '$': + case '"': + case '\\': + case '`': + break; + default: + g_string_append_c (result, '\\'); + break; + } + } + g_string_append_c (result, *p); + } + if (!*p){ + g_set_error (error, 0, 0, "Open quote"); + return NULL; + } + } else if (*p == '\\'){ + char c = *(++p); + if (!(c == '$' || c == '"' || c == '\\' || c == '`' || c == '\'' || c == 0 )) + g_string_append_c (result, '\\'); + if (c == 0) + break; + else + g_string_append_c (result, c); + } else + g_string_append_c (result, *p); + } + return g_string_free (result, FALSE); +} + +#if JOINT_TEST +/* + * This test is designed to be built with the 2 glib/eglib to compare + */ + +char *args [] = { + "\\", + "\"Foo'bar\"", + "'foo'", + "'fo\'b'", + "'foo\"bar'", + "'foo' dingus bar", + "'foo' 'bar' 'baz'", + "\"foo\" 'bar' \"baz\"", + "\"f\\$\\\'", + "\"\\", + "\\\\", + "'\\\\'", + "\"f\\$\"\\\"\\\\", // /\\\"\\\\" + "'f\\$'\\\"\\\\", + "'f\\$\\\\'", + NULL +}; + + +int +main () +{ + char **s = args; + int i; + + while (*s){ + char *r1 = g_shell_unquote (*s, NULL); + char *r2 = g2_shell_unquote (*s, NULL); + char *ok = r1 == r2 ? "ok" : (r1 != NULL && r2 != NULL && strcmp (r1, r2) == 0) ? "ok" : "fail"; + + printf ("%s [%s] -> [%s] - [%s]\n", ok, *s, r1, r2); + s++; + } + return; + char buffer [10]; + buffer [0] = '\"'; + buffer [1] = '\\'; + buffer [3] = '\"'; + buffer [4] = 0; + + for (i = 32; i < 255; i++){ + buffer [2] = i; + printf ("%d [%s] -> [%s]\n", i, buffer, g_shell_unquote (buffer, NULL)); + } +} +#endif diff --git a/deps/eglib/src/gslist.c b/deps/eglib/src/gslist.c new file mode 100644 index 00000000..1b12e474 --- /dev/null +++ b/deps/eglib/src/gslist.c @@ -0,0 +1,365 @@ +/* + * gslist.c: Singly-linked list implementation + * + * Authors: + * Duncan Mak (duncan@novell.com) + * Raja R Harinath (rharinath@novell.com) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * (C) 2006 Novell, Inc. + */ + + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +GSList* +g_slist_alloc (void) +{ + return g_new0 (GSList, 1); +} + +void +g_slist_free_1 (GSList *list) +{ + g_free (list); +} + +GSList* +g_slist_append (GSList *list, gpointer data) +{ + return g_slist_concat (list, g_slist_prepend (NULL, data)); +} + +/* This is also a list node constructor. */ +GSList* +g_slist_prepend (GSList *list, gpointer data) +{ + GSList *head = g_slist_alloc (); + head->data = data; + head->next = list; + + return head; +} + +/* + * Insert the given data in a new node after the current node. + * Return new node. + */ +static inline GSList * +insert_after (GSList *list, gpointer data) +{ + list->next = g_slist_prepend (list->next, data); + return list->next; +} + +/* + * Return the node prior to the node containing 'data'. + * If the list is empty, or the first node contains 'data', return NULL. + * If no node contains 'data', return the last node. + */ +static inline GSList* +find_prev (GSList *list, gconstpointer data) +{ + GSList *prev = NULL; + while (list) { + if (list->data == data) + break; + prev = list; + list = list->next; + } + return prev; +} + +/* like 'find_prev', but searches for node 'link' */ +static inline GSList* +find_prev_link (GSList *list, GSList *link) +{ + GSList *prev = NULL; + while (list) { + if (list == link) + break; + prev = list; + list = list->next; + } + return prev; +} + +GSList* +g_slist_insert_before (GSList *list, GSList *sibling, gpointer data) +{ + GSList *prev = find_prev_link (list, sibling); + + if (!prev) + return g_slist_prepend (list, data); + + insert_after (prev, data); + return list; +} + +void +g_slist_free (GSList *list) +{ + while (list) { + GSList *next = list->next; + g_slist_free_1 (list); + list = next; + } +} + +GSList* +g_slist_copy (GSList *list) +{ + GSList *copy, *tmp; + + if (!list) + return NULL; + + copy = g_slist_prepend (NULL, list->data); + tmp = copy; + + for (list = list->next; list; list = list->next) + tmp = insert_after (tmp, list->data); + + return copy; +} + +GSList* +g_slist_concat (GSList *list1, GSList *list2) +{ + if (!list1) + return list2; + + g_slist_last (list1)->next = list2; + return list1; +} + +void +g_slist_foreach (GSList *list, GFunc func, gpointer user_data) +{ + while (list) { + (*func) (list->data, user_data); + list = list->next; + } +} + +GSList* +g_slist_last (GSList *list) +{ + if (!list) + return NULL; + + while (list->next) + list = list->next; + + return list; +} + +GSList* +g_slist_find (GSList *list, gconstpointer data) +{ + for (; list; list = list->next) + if (list->data == data) + return list; + return NULL; +} + +GSList * +g_slist_find_custom (GSList *list, gconstpointer data, GCompareFunc func) +{ + if (!func) + return NULL; + + while (list) { + if (func (list->data, data) == 0) + return list; + + list = list->next; + } + + return NULL; +} + +guint +g_slist_length (GSList *list) +{ + guint length = 0; + + while (list) { + length ++; + list = list->next; + } + + return length; +} + +GSList* +g_slist_remove (GSList *list, gconstpointer data) +{ + GSList *prev = find_prev (list, data); + GSList *current = prev ? prev->next : list; + + if (current) { + if (prev) + prev->next = current->next; + else + list = current->next; + g_slist_free_1 (current); + } + + return list; +} + +GSList* +g_slist_remove_all (GSList *list, gconstpointer data) +{ + GSList *next = list; + GSList *prev = NULL; + GSList *current; + + while (next) { + GSList *tmp_prev = find_prev (next, data); + if (tmp_prev) + prev = tmp_prev; + current = prev ? prev->next : list; + + if (!current) + break; + + next = current->next; + + if (prev) + prev->next = next; + else + list = next; + g_slist_free_1 (current); + } + + return list; +} + +GSList* +g_slist_remove_link (GSList *list, GSList *link) +{ + GSList *prev = find_prev_link (list, link); + GSList *current = prev ? prev->next : list; + + if (current) { + if (prev) + prev->next = current->next; + else + list = current->next; + current->next = NULL; + } + + return list; +} + +GSList* +g_slist_delete_link (GSList *list, GSList *link) +{ + list = g_slist_remove_link (list, link); + g_slist_free_1 (link); + + return list; +} + +GSList* +g_slist_reverse (GSList *list) +{ + GSList *prev = NULL; + while (list){ + GSList *next = list->next; + list->next = prev; + prev = list; + list = next; + } + + return prev; +} + +GSList* +g_slist_insert_sorted (GSList *list, gpointer data, GCompareFunc func) +{ + GSList *prev = NULL; + + if (!func) + return list; + + if (!list || func (list->data, data) > 0) + return g_slist_prepend (list, data); + + /* Invariant: func (prev->data, data) <= 0) */ + for (prev = list; prev->next; prev = prev->next) + if (func (prev->next->data, data) > 0) + break; + + /* ... && (prev->next == 0 || func (prev->next->data, data) > 0)) */ + insert_after (prev, data); + return list; +} + +gint +g_slist_index (GSList *list, gconstpointer data) +{ + gint index = 0; + + while (list) { + if (list->data == data) + return index; + + index++; + list = list->next; + } + + return -1; +} + +GSList* +g_slist_nth (GSList *list, guint n) +{ + for (; list; list = list->next) { + if (n == 0) + break; + n--; + } + return list; +} + +gpointer +g_slist_nth_data (GSList *list, guint n) +{ + GSList *node = g_slist_nth (list, n); + return node ? node->data : NULL; +} + +typedef GSList list_node; +#include "sort.frag.h" + +GSList* +g_slist_sort (GSList *list, GCompareFunc func) +{ + if (!list || !list->next) + return list; + return do_sort (list, func); +} diff --git a/deps/eglib/src/gspawn.c b/deps/eglib/src/gspawn.c new file mode 100644 index 00000000..3bb93908 --- /dev/null +++ b/deps/eglib/src/gspawn.c @@ -0,0 +1,495 @@ +/* + * Spawning processes. + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> + +#include <glib.h> + +#ifdef HAVE_UNISTD_H +#ifndef __USE_GNU +#define __USE_GNU +#endif +#include <unistd.h> +#endif + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +#ifdef G_OS_WIN32 +#include <io.h> +#include <winsock2.h> +#define open _open +#define close _close +#define read _read +#define write _write +/* windows pipe api details: http://msdn2.microsoft.com/en-us/library/edze9h7e(VS.80).aspx */ +#define pipe(x) _pipe(x, 256, 0) +#endif + +#define set_error(msg, ...) do { if (error != NULL) *error = g_error_new (G_SPAWN_ERROR, 1, msg, __VA_ARGS__); } while (0) +#define set_error_cond(cond,msg, ...) do { if ((cond) && error != NULL) *error = g_error_new (G_SPAWN_ERROR, 1, msg, __VA_ARGS__); } while (0) +#define set_error_status(status,msg, ...) do { if (error != NULL) *error = g_error_new (G_SPAWN_ERROR, status, msg, __VA_ARGS__); } while (0) +#define NO_INTR(var,cmd) do { (var) = (cmd); } while ((var) == -1 && errno == EINTR) +#define CLOSE_PIPE(p) do { close (p [0]); close (p [1]); } while (0) + +#if defined(__APPLE__) && !defined (__arm__) +/* Apple defines this in crt_externs.h but doesn't provide that header for + * arm-apple-darwin9. We'll manually define the symbol on Apple as it does + * in fact exist on all implementations (so far) + */ +gchar ***_NSGetEnviron(); +#define environ (*_NSGetEnviron()) +#elif defined(_MSC_VER) +/* MS defines this in stdlib.h */ +#else +extern char **environ; +#endif + +GQuark +g_spawn_error_get_quark (void) +{ + return g_quark_from_static_string ("g-spawn-error-quark"); +} + + +#ifndef G_OS_WIN32 +static int +safe_read (int fd, gchar *buffer, gint count, GError **error) +{ + int res; + + NO_INTR (res, read (fd, buffer, count)); + set_error_cond (res == -1, "%s", "Error reading from pipe."); + return res; +} + +static int +read_pipes (int outfd, gchar **out_str, int errfd, gchar **err_str, GError **error) +{ + fd_set rfds; + int res; + gboolean out_closed; + gboolean err_closed; + GString *out = NULL; + GString *err = NULL; + gchar *buffer = NULL; + gint nread; + + out_closed = (outfd < 0); + err_closed = (errfd < 0); + if (out_str) { + *out_str = NULL; + out = g_string_new (""); + } + + if (err_str) { + *err_str = NULL; + err = g_string_new (""); + } + + do { + if (out_closed && err_closed) + break; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4389) +#endif + + FD_ZERO (&rfds); + if (!out_closed && outfd >= 0) + FD_SET (outfd, &rfds); + if (!err_closed && errfd >= 0) + FD_SET (errfd, &rfds); + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + res = select (MAX (outfd, errfd) + 1, &rfds, NULL, NULL, NULL); + if (res > 0) { + if (buffer == NULL) + buffer = g_malloc (1024); + if (!out_closed && FD_ISSET (outfd, &rfds)) { + nread = safe_read (outfd, buffer, 1024, error); + if (nread < 0) { + close (errfd); + close (outfd); + return -1; + } + g_string_append_len (out, buffer, nread); + if (nread <= 0) { + out_closed = TRUE; + close (outfd); + } + } + + if (!err_closed && FD_ISSET (errfd, &rfds)) { + nread = safe_read (errfd, buffer, 1024, error); + if (nread < 0) { + close (errfd); + close (outfd); + return -1; + } + g_string_append_len (err, buffer, nread); + if (nread <= 0) { + err_closed = TRUE; + close (errfd); + } + } + } + } while (res > 0 || (res == -1 && errno == EINTR)); + + g_free (buffer); + if (out_str) + *out_str = g_string_free (out, FALSE); + + if (err_str) + *err_str = g_string_free (err, FALSE); + + return 0; +} + +static gboolean +create_pipe (int *fds, GError **error) +{ + if (pipe (fds) == -1) { + set_error ("%s", "Error creating pipe."); + return FALSE; + } + return TRUE; +} +#endif /* G_OS_WIN32 */ + +static int +write_all (int fd, const void *vbuf, size_t n) +{ + const char *buf = (const char *) vbuf; + size_t nwritten = 0; + int w; + + do { + do { + w = write (fd, buf + nwritten, n - nwritten); + } while (w == -1 && errno == EINTR); + + if (w == -1) + return -1; + + nwritten += w; + } while (nwritten < n); + + return nwritten; +} + +gboolean +g_spawn_command_line_sync (const gchar *command_line, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ +#ifdef G_OS_WIN32 +#else + pid_t pid; + gchar **argv; + gint argc; + int stdout_pipe [2] = { -1, -1 }; + int stderr_pipe [2] = { -1, -1 }; + int status; + int res; + + if (!g_shell_parse_argv (command_line, &argc, &argv, error)) + return FALSE; + + if (standard_output && !create_pipe (stdout_pipe, error)) + return FALSE; + + if (standard_error && !create_pipe (stderr_pipe, error)) { + if (standard_output) { + CLOSE_PIPE (stdout_pipe); + } + return FALSE; + } + + pid = fork (); + if (pid == 0) { + gint i; + + if (standard_output) { + close (stdout_pipe [0]); + dup2 (stdout_pipe [1], STDOUT_FILENO); + } + + if (standard_error) { + close (stderr_pipe [0]); + dup2 (stderr_pipe [1], STDERR_FILENO); + } + for (i = getdtablesize () - 1; i >= 3; i--) + close (i); + + /* G_SPAWN_SEARCH_PATH is always enabled for g_spawn_command_line_sync */ + if (!g_path_is_absolute (argv [0])) { + gchar *arg0; + + arg0 = g_find_program_in_path (argv [0]); + if (arg0 == NULL) { + exit (1); + } + //g_free (argv [0]); + argv [0] = arg0; + } + execv (argv [0], argv); + exit (1); /* TODO: What now? */ + } + + g_strfreev (argv); + if (standard_output) + close (stdout_pipe [1]); + + if (standard_error) + close (stderr_pipe [1]); + + if (standard_output || standard_error) { + res = read_pipes (stdout_pipe [0], standard_output, stderr_pipe [0], standard_error, error); + if (res) { + waitpid (pid, &status, WNOHANG); /* avoid zombie */ + return FALSE; + } + } + + NO_INTR (res, waitpid (pid, &status, 0)); + + /* TODO: What if error? */ + if (WIFEXITED (status) && exit_status) { + *exit_status = WEXITSTATUS (status); + } +#endif + return TRUE; +} + +/* + * This is the only use we have in mono/metadata +!g_spawn_async_with_pipes (NULL, (char**)addr_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &child_pid, &ch_in, &ch_out, NULL, NULL) +*/ +gboolean +g_spawn_async_with_pipes (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) +{ +#ifdef G_OS_WIN32 +#else + pid_t pid; + int info_pipe [2]; + int in_pipe [2] = { -1, -1 }; + int out_pipe [2] = { -1, -1 }; + int err_pipe [2] = { -1, -1 }; + int status; + + g_return_val_if_fail (argv != NULL, FALSE); /* Only mandatory arg */ + + if (!create_pipe (info_pipe, error)) + return FALSE; + + if (standard_output && !create_pipe (out_pipe, error)) { + CLOSE_PIPE (info_pipe); + return FALSE; + } + + if (standard_error && !create_pipe (err_pipe, error)) { + CLOSE_PIPE (info_pipe); + CLOSE_PIPE (out_pipe); + return FALSE; + } + + if (standard_input && !create_pipe (in_pipe, error)) { + CLOSE_PIPE (info_pipe); + CLOSE_PIPE (out_pipe); + CLOSE_PIPE (err_pipe); + return FALSE; + } + + pid = fork (); + if (pid == -1) { + CLOSE_PIPE (info_pipe); + CLOSE_PIPE (out_pipe); + CLOSE_PIPE (err_pipe); + CLOSE_PIPE (in_pipe); + set_error ("%s", "Error in fork ()"); + return FALSE; + } + + if (pid == 0) { + /* No zombie left behind */ + if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) { + pid = fork (); + } + + if (pid != 0) { + exit (pid == -1 ? 1 : 0); + } else { + gint i; + int fd; + gchar *arg0; + gchar **actual_args; + gint unused; + + close (info_pipe [0]); + close (in_pipe [1]); + close (out_pipe [0]); + close (err_pipe [0]); + + /* when exec* succeeds, we want to close this fd, which will return + * a 0 read on the parent. We're not supposed to keep it open forever. + * If exec fails, we still can write the error to it before closing. + */ + fcntl (info_pipe [1], F_SETFD, FD_CLOEXEC); + + if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) { + pid = getpid (); + NO_INTR (unused, write_all (info_pipe [1], &pid, sizeof (pid_t))); + } + + if (working_directory && chdir (working_directory) == -1) { + int err = errno; + NO_INTR (unused, write_all (info_pipe [1], &err, sizeof (int))); + exit (0); + } + + if (standard_output) { + dup2 (out_pipe [1], STDOUT_FILENO); + } else if ((flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0) { + fd = open ("/dev/null", O_WRONLY); + dup2 (fd, STDOUT_FILENO); + } + + if (standard_error) { + dup2 (err_pipe [1], STDERR_FILENO); + } else if ((flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0) { + fd = open ("/dev/null", O_WRONLY); + dup2 (fd, STDERR_FILENO); + } + + if (standard_input) { + dup2 (in_pipe [0], STDIN_FILENO); + } else if ((flags & G_SPAWN_CHILD_INHERITS_STDIN) == 0) { + fd = open ("/dev/null", O_RDONLY); + dup2 (fd, STDIN_FILENO); + } + + if ((flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN) != 0) { + for (i = getdtablesize () - 1; i >= 3; i--) + close (i); + } + + actual_args = ((flags & G_SPAWN_FILE_AND_ARGV_ZERO) == 0) ? argv : argv + 1; + if (envp == NULL) + envp = environ; + + if (child_setup) + child_setup (user_data); + + arg0 = argv [0]; + if (!g_path_is_absolute (arg0) || (flags & G_SPAWN_SEARCH_PATH) != 0) { + arg0 = g_find_program_in_path (argv [0]); + if (arg0 == NULL) { + int err = ENOENT; + write_all (info_pipe [1], &err, sizeof (int)); + exit (0); + } + } + + execve (arg0, actual_args, envp); + write_all (info_pipe [1], &errno, sizeof (int)); + exit (0); + } + } else if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) { + int w; + /* Wait for the first child if two are created */ + NO_INTR (w, waitpid (pid, &status, 0)); + if (status == 1 || w == -1) { + CLOSE_PIPE (info_pipe); + CLOSE_PIPE (out_pipe); + CLOSE_PIPE (err_pipe); + CLOSE_PIPE (in_pipe); + set_error ("Error in fork (): %d", status); + return FALSE; + } + } + close (info_pipe [1]); + close (in_pipe [0]); + close (out_pipe [1]); + close (err_pipe [1]); + + if ((flags & G_SPAWN_DO_NOT_REAP_CHILD) == 0) { + int x; + NO_INTR (x, read (info_pipe [0], &pid, sizeof (pid_t))); /* if we read < sizeof (pid_t)... */ + } + + if (child_pid) { + *child_pid = pid; + } + + if (read (info_pipe [0], &status, sizeof (int)) != 0) { + close (info_pipe [0]); + close (in_pipe [0]); + close (out_pipe [1]); + close (err_pipe [1]); + set_error_status (status, "Error in exec (%d -> %s)", status, strerror (status)); + return FALSE; + } + + close (info_pipe [0]); + if (standard_input) + *standard_input = in_pipe [1]; + if (standard_output) + *standard_output = out_pipe [0]; + if (standard_error) + *standard_error = err_pipe [0]; +#endif + return TRUE; +} + + diff --git a/deps/eglib/src/gstr.c b/deps/eglib/src/gstr.c new file mode 100644 index 00000000..e8e449c6 --- /dev/null +++ b/deps/eglib/src/gstr.c @@ -0,0 +1,932 @@ +/* + * gstr.c: String Utility Functions. + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include <config.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <glib.h> + +/* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */ +gchar * +g_strndup (const gchar *str, gsize n) +{ +#ifdef HAVE_STRNDUP + return strndup (str, n); +#else + if (str) { + char *retval = g_malloc(n+1); + if (retval) { + strncpy(retval, str, n)[n] = 0; + } + return retval; + } + return NULL; +#endif +} + +void +g_strfreev (gchar **str_array) +{ + gchar **orig = str_array; + if (str_array == NULL) + return; + while (*str_array != NULL){ + g_free (*str_array); + str_array++; + } + g_free (orig); +} + +gchar ** +g_strdupv (gchar **str_array) +{ + guint length; + gchar **ret; + guint i; + + if (!str_array) + return NULL; + + length = g_strv_length(str_array); + ret = g_new0(gchar *, length + 1); + for (i = 0; str_array[i]; i++) { + ret[i] = g_strdup(str_array[i]); + } + ret[length] = NULL; + return ret; +} + +guint +g_strv_length(gchar **str_array) +{ + gint length = 0; + g_return_val_if_fail(str_array != NULL, 0); + for(length = 0; str_array[length] != NULL; length++); + return length; +} + +gboolean +g_str_has_suffix(const gchar *str, const gchar *suffix) +{ + size_t str_length; + size_t suffix_length; + + g_return_val_if_fail(str != NULL, FALSE); + g_return_val_if_fail(suffix != NULL, FALSE); + + str_length = strlen(str); + suffix_length = strlen(suffix); + + return suffix_length <= str_length ? + strncmp(str + str_length - suffix_length, suffix, suffix_length) == 0 : + FALSE; +} + +gboolean +g_str_has_prefix(const gchar *str, const gchar *prefix) +{ + size_t str_length; + size_t prefix_length; + + g_return_val_if_fail(str != NULL, FALSE); + g_return_val_if_fail(prefix != NULL, FALSE); + + str_length = strlen(str); + prefix_length = strlen(prefix); + + return prefix_length <= str_length ? + strncmp(str, prefix, prefix_length) == 0 : + FALSE; +} + +gchar * +g_strdup_vprintf (const gchar *format, va_list args) +{ + int n; + char *ret; + + n = vasprintf (&ret, format, args); + if (n == -1) + return NULL; + + return ret; +} + +gchar * +g_strdup_printf (const gchar *format, ...) +{ + gchar *ret; + va_list args; + int n; + + va_start (args, format); + n = vasprintf (&ret, format, args); + va_end (args); + if (n == -1) + return NULL; + + return ret; +} + +const gchar * +g_strerror (gint errnum) +{ + return strerror (errnum); +} + +gchar * +g_strconcat (const gchar *first, ...) +{ + va_list args; + size_t total = 0; + char *s, *ret; + g_return_val_if_fail (first != NULL, NULL); + + total += strlen (first); + va_start (args, first); + for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){ + total += strlen (s); + } + va_end (args); + + ret = g_malloc (total + 1); + if (ret == NULL) + return NULL; + + ret [total] = 0; + strcpy (ret, first); + va_start (args, first); + for (s = va_arg (args, char *); s != NULL; s = va_arg(args, char *)){ + strcat (ret, s); + } + va_end (args); + + return ret; +} + +static void +add_to_vector (gchar ***vector, int size, gchar *token) +{ + *vector = *vector == NULL ? + (gchar **)g_malloc(2 * sizeof(*vector)) : + (gchar **)g_realloc(*vector, (size + 1) * sizeof(*vector)); + + (*vector)[size - 1] = token; +} + +gchar ** +g_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens) +{ + const gchar *c; + gchar *token, **vector; + gint size = 1; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != 0, NULL); + + if (strncmp (string, delimiter, strlen (delimiter)) == 0) { + vector = (gchar **)g_malloc (2 * sizeof(vector)); + vector[0] = g_strdup (""); + size++; + string += strlen (delimiter); + } else { + vector = NULL; + } + + while (*string && !(max_tokens > 0 && size >= max_tokens)) { + c = string; + if (strncmp (string, delimiter, strlen (delimiter)) == 0) { + token = g_strdup (""); + string += strlen (delimiter); + } else { + while (*string && strncmp (string, delimiter, strlen (delimiter)) != 0) { + string++; + } + + if (*string) { + gsize toklen = (string - c); + token = g_strndup (c, toklen); + + /* Need to leave a trailing empty + * token if the delimiter is the last + * part of the string + */ + if (strcmp (string, delimiter) != 0) { + string += strlen (delimiter); + } + } else { + token = g_strdup (c); + } + } + + add_to_vector (&vector, size, token); + size++; + } + + if (*string) { + if (strcmp (string, delimiter) == 0) + add_to_vector (&vector, size, g_strdup ("")); + else { + /* Add the rest of the string as the last element */ + add_to_vector (&vector, size, g_strdup (string)); + } + size++; + } + + if (vector == NULL) { + vector = (gchar **) g_malloc (2 * sizeof (vector)); + vector [0] = NULL; + } else if (size > 0) { + vector[size - 1] = NULL; + } + + return vector; +} + +static gboolean +charcmp (gchar testchar, const gchar *compare) +{ + while(*compare) { + if (*compare == testchar) { + return TRUE; + } + compare++; + } + + return FALSE; +} + +gchar ** +g_strsplit_set (const gchar *string, const gchar *delimiter, gint max_tokens) +{ + const gchar *c; + gchar *token, **vector; + gint size = 1; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != 0, NULL); + + if (charcmp (*string, delimiter)) { + vector = (gchar **)g_malloc (2 * sizeof(vector)); + vector[0] = g_strdup (""); + size++; + string++; + } else { + vector = NULL; + } + + c = string; + while (*string && !(max_tokens > 0 && size >= max_tokens)) { + if (charcmp (*string, delimiter)) { + gsize toklen = (string - c); + if (toklen == 0) { + token = g_strdup (""); + } else { + token = g_strndup (c, toklen); + } + + c = string + 1; + + add_to_vector (&vector, size, token); + size++; + } + + string++; + } + + if (max_tokens > 0 && size >= max_tokens) { + if (*string) { + /* Add the rest of the string as the last element */ + add_to_vector (&vector, size, g_strdup (string)); + size++; + } + } else { + if (*c) { + /* Fill in the trailing last token */ + add_to_vector (&vector, size, g_strdup (c)); + size++; + } else { + /* Need to leave a trailing empty token if the + * delimiter is the last part of the string + */ + add_to_vector (&vector, size, g_strdup ("")); + size++; + } + } + + if (vector == NULL) { + vector = (gchar **) g_malloc (2 * sizeof (vector)); + vector [0] = NULL; + } else if (size > 0) { + vector[size - 1] = NULL; + } + + return vector; +} + +gchar * +g_strreverse (gchar *str) +{ + size_t i, j; + gchar c; + + if (str == NULL) + return NULL; + + if (*str == 0) + return str; + + for (i = 0, j = strlen (str) - 1; i < j; i++, j--) { + c = str [i]; + str [i] = str [j]; + str [j] = c; + } + + return str; +} + +gchar * +g_strjoin (const gchar *separator, ...) +{ + va_list args; + char *res, *s, *r; + size_t len, slen; + + if (separator != NULL) + slen = strlen (separator); + else + slen = 0; + + len = 0; + va_start (args, separator); + for (s = va_arg (args, char *); s != NULL; s = va_arg (args, char *)){ + len += strlen (s); + len += slen; + } + va_end (args); + + if (len == 0) + return g_strdup (""); + + /* Remove the last separator */ + if (slen > 0 && len > 0) + len -= slen; + + res = g_malloc (len + 1); + va_start (args, separator); + s = va_arg (args, char *); + r = g_stpcpy (res, s); + for (s = va_arg (args, char *); s != NULL; s = va_arg (args, char *)){ + if (separator != NULL) + r = g_stpcpy (r, separator); + r = g_stpcpy (r, s); + } + va_end (args); + + return res; +} + +gchar * +g_strjoinv (const gchar *separator, gchar **str_array) +{ + char *res, *r; + size_t slen, len, i; + + if (separator != NULL) + slen = strlen (separator); + else + slen = 0; + + len = 0; + for (i = 0; str_array [i] != NULL; i++){ + len += strlen (str_array [i]); + len += slen; + } + + if (len == 0) + return g_strdup (""); + + if (slen > 0 && len > 0) + len -= slen; + + res = g_malloc (len + 1); + r = g_stpcpy (res, str_array [0]); + for (i = 1; str_array [i] != NULL; i++){ + if (separator != NULL) + r = g_stpcpy (r, separator); + r = g_stpcpy (r, str_array [i]); + } + + return res; +} + +gchar * +g_strchug (gchar *str) +{ + size_t len; + gchar *tmp; + + if (str == NULL) + return NULL; + + tmp = str; + while (*tmp && isspace (*tmp)) tmp++; + if (str != tmp) { + len = strlen (str) - (tmp - str - 1); + memmove (str, tmp, len); + } + return str; +} + +gchar * +g_strchomp (gchar *str) +{ + gchar *tmp; + + if (str == NULL) + return NULL; + + tmp = str + strlen (str) - 1; + while (*tmp && isspace (*tmp)) tmp--; + *(tmp + 1) = '\0'; + return str; +} + +gint +g_printf(gchar const *format, ...) +{ + va_list args; + gint ret; + + va_start(args, format); + ret = vprintf(format, args); + va_end(args); + + return ret; +} + +gint +g_fprintf(FILE *file, gchar const *format, ...) +{ + va_list args; + gint ret; + + va_start(args, format); + ret = vfprintf(file, format, args); + va_end(args); + + return ret; +} + +gint +g_sprintf(gchar *string, gchar const *format, ...) +{ + va_list args; + gint ret; + + va_start(args, format); + ret = vsprintf(string, format, args); + va_end(args); + + return ret; +} + +gint +g_snprintf(gchar *string, gulong n, gchar const *format, ...) +{ + va_list args; + gint ret; + + va_start(args, format); + ret = vsnprintf(string, n, format, args); + va_end(args); + + return ret; +} + +static const char hx [] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +static gboolean +char_needs_encoding (char c) +{ + if (((unsigned char)c) >= 0x80) + return TRUE; + + if ((c >= '@' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '&' && c < 0x3b) || + (c == '!') || (c == '$') || (c == '_') || (c == '=') || (c == '~')) + return FALSE; + return TRUE; +} + +gchar * +g_filename_to_uri (const gchar *filename, const gchar *hostname, GError **error) +{ + size_t n; + char *ret, *rp; + const char *p; +#ifdef G_OS_WIN32 + const char *uriPrefix = "file:///"; +#else + const char *uriPrefix = "file://"; +#endif + + g_return_val_if_fail (filename != NULL, NULL); + + if (hostname != NULL) + g_warning ("%s", "eglib: g_filename_to_uri: hostname not handled"); + + if (!g_path_is_absolute (filename)){ + if (error != NULL) { + *error = g_error_new (G_CONVERT_ERROR, + G_CONVERT_ERROR_NOT_ABSOLUTE_PATH, + "Not an absolute filename"); + } + + return NULL; + } + + n = strlen (uriPrefix) + 1; + for (p = filename; *p; p++){ +#ifdef G_OS_WIN32 + if (*p == '\\') { + n++; + continue; + } +#endif + if (char_needs_encoding (*p)) + n += 3; + else + n++; + } + ret = g_malloc (n); + strcpy (ret, uriPrefix); + for (p = filename, rp = ret + strlen (ret); *p; p++){ +#ifdef G_OS_WIN32 + if (*p == '\\') { + *rp++ = '/'; + continue; + } +#endif + if (char_needs_encoding (*p)){ + *rp++ = '%'; + *rp++ = hx [((unsigned char)(*p)) >> 4]; + *rp++ = hx [((unsigned char)(*p)) & 0xf]; + } else + *rp++ = *p; + } + *rp = 0; + return ret; +} + +static int +decode (char p) +{ + if (p >= '0' && p <= '9') + return p - '0'; + if (p >= 'A' && p <= 'F') + return p - 'A'; + if (p >= 'a' && p <= 'f') + return p - 'a'; + g_assert_not_reached (); + return 0; +} + +gchar * +g_filename_from_uri (const gchar *uri, gchar **hostname, GError **error) +{ + const char *p; + char *r, *result; + int flen = 0; + + g_return_val_if_fail (uri != NULL, NULL); + + if (hostname != NULL) + g_warning ("%s", "eglib: g_filename_from_uri: hostname not handled"); + + if (strncmp (uri, "file:///", 8) != 0){ + if (error != NULL) { + *error = g_error_new (G_CONVERT_ERROR, + G_CONVERT_ERROR_BAD_URI, + "URI does not start with the file: scheme"); + } + return NULL; + } + + for (p = uri + 8; *p; p++){ + if (*p == '%'){ + if (p [1] && p [2] && isxdigit (p [1]) && isxdigit (p [2])){ + p += 2; + } else { + if (error != NULL) { + *error = g_error_new (G_CONVERT_ERROR, + G_CONVERT_ERROR_BAD_URI, + "URI contains an invalid escape sequence"); + } + return NULL; + } + } + flen++; + } +#ifndef G_OS_WIN32 + flen++; +#endif + + result = g_malloc (flen + 1); + result [flen] = 0; + +#ifndef G_OS_WIN32 + *result = '/'; + r = result + 1; +#else + r = result; +#endif + + for (p = uri + 8; *p; p++){ + if (*p == '%'){ + *r++ = (char)((decode (p [1]) << 4) | decode (p [2])); + p += 2; + } else + *r++ = *p; + flen++; + } + return result; +} + +void +g_strdown (gchar *string) +{ + g_return_if_fail (string != NULL); + + while (*string){ + *string = (gchar)tolower (*string); + string++; + } +} + +gchar +g_ascii_tolower (gchar c) +{ + return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; +} + +gchar * +g_ascii_strdown (const gchar *str, gssize len) +{ + char *ret; + int i; + + g_return_val_if_fail (str != NULL, NULL); + + if (len == -1) + len = strlen (str); + + ret = g_malloc (len + 1); + for (i = 0; i < len; i++) + ret [i] = (guchar) g_ascii_tolower (str [i]); + ret [i] = 0; + + return ret; +} + +gchar +g_ascii_toupper (gchar c) +{ + return c >= 'a' && c <= 'z' ? c + ('A' - 'a') : c; +} + +gchar * +g_ascii_strup (const gchar *str, gssize len) +{ + char *ret; + int i; + + g_return_val_if_fail (str != NULL, NULL); + + if (len == -1) + len = strlen (str); + + ret = g_malloc (len + 1); + for (i = 0; i < len; i++) + ret [i] = (guchar) g_ascii_toupper (str [i]); + ret [i] = 0; + + return ret; +} + +gint +g_ascii_strncasecmp (const gchar *s1, const gchar *s2, gsize n) +{ + gsize i; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + for (i = 0; i < n; i++) { + gchar c1 = g_ascii_tolower (*s1++); + gchar c2 = g_ascii_tolower (*s2++); + + if (c1 != c2) + return c1 - c2; + } + + return 0; +} + +gint +g_ascii_strcasecmp (const gchar *s1, const gchar *s2) +{ + const char *sp1 = s1; + const char *sp2 = s2; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + while (*sp1 != '\0') { + char c1 = g_ascii_tolower (*sp1++); + char c2 = g_ascii_tolower (*sp2++); + + if (c1 != c2) + return c1 - c2; + } + + return (*sp1) - (*sp2); +} + +gchar * +g_strdelimit (gchar *string, const gchar *delimiters, gchar new_delimiter) +{ + gchar *ptr; + + g_return_val_if_fail (string != NULL, NULL); + + if (delimiters == NULL) + delimiters = G_STR_DELIMITERS; + + for (ptr = string; *ptr; ptr++) { + if (strchr (delimiters, *ptr)) + *ptr = new_delimiter; + } + + return string; +} + +gsize +g_strlcpy (gchar *dest, const gchar *src, gsize dest_size) +{ +#ifdef HAVE_STRLCPY + return strlcpy (dest, src, dest_size); +#else + gchar *d; + const gchar *s; + gchar c; + gsize len; + + g_return_val_if_fail (src != NULL, 0); + g_return_val_if_fail (dest != NULL, 0); + + len = dest_size; + if (len == 0) + return 0; + + s = src; + d = dest; + while (--len) { + c = *s++; + *d++ = c; + if (c == '\0') + return (dest_size - len - 1); + } + + /* len is 0 i we get here */ + *d = '\0'; + /* we need to return the length of src here */ + while (*s++) ; /* instead of a plain strlen, we use 's' */ + return s - src - 1; +#endif +} + +gchar * +g_stpcpy (gchar *dest, const char *src) +{ + g_return_val_if_fail (dest != NULL, dest); + g_return_val_if_fail (src != NULL, dest); + +#if HAVE_STPCPY + return stpcpy (dest, src); +#else + while (*src) + *dest++ = *src++; + + *dest = '\0'; + + return dest; +#endif +} + +static const gchar escaped_dflt [256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 'b', 't', 'n', 1, 'f', 'r', 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +gchar * +g_strescape (const gchar *source, const gchar *exceptions) +{ + gchar escaped [256]; + const gchar *ptr; + gchar c; + gchar op; + gchar *result; + gchar *res_ptr; + + g_return_val_if_fail (source != NULL, NULL); + + memcpy (escaped, escaped_dflt, 256); + if (exceptions != NULL) { + for (ptr = exceptions; *ptr; ptr++) + escaped [(int) *ptr] = 0; + } + result = g_malloc (strlen (source) * 4 + 1); /* Worst case: everything octal. */ + res_ptr = result; + for (ptr = source; *ptr; ptr++) { + c = *ptr; + op = escaped [(int) c]; + if (op == 0) { + *res_ptr++ = c; + } else { + *res_ptr++ = '\\'; + if (op != 1) { + *res_ptr++ = op; + } else { + *res_ptr++ = '0' + ((c >> 6) & 3); + *res_ptr++ = '0' + ((c >> 3) & 7); + *res_ptr++ = '0' + (c & 7); + } + } + } + *res_ptr = '\0'; + return result; +} + +gint +g_ascii_xdigit_value (gchar c) +{ + return ((isxdigit (c) == 0) ? -1 : + ((c >= '0' && c <= '9') ? (c - '0') : + ((c >= 'a' && c <= 'f') ? (c - 'a' + 10) : + (c - 'A' + 10)))); +} + +gchar * +g_strnfill (gsize length, gchar fill_char) +{ + gchar *ret = g_new (gchar, length + 1); + + memset (ret, fill_char, length); + ret [length] = 0; + return ret; +} diff --git a/deps/eglib/src/gstring.c b/deps/eglib/src/gstring.c new file mode 100644 index 00000000..38dfc457 --- /dev/null +++ b/deps/eglib/src/gstring.c @@ -0,0 +1,293 @@ +/* + * String functions + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +#define GROW_IF_NECESSARY(s,l) { \ + if(s->len + l >= s->allocated_len) { \ + s->allocated_len = (s->allocated_len + l + 16) * 2; \ + s->str = g_realloc(s->str, s->allocated_len); \ + } \ +} + +GString * +g_string_new_len (const gchar *init, gssize len) +{ + GString *ret = g_new (GString, 1); + + if (init == NULL) + ret->len = 0; + else + ret->len = len < 0 ? strlen(init) : len; + ret->allocated_len = MAX(ret->len + 1, 16); + ret->str = g_malloc(ret->allocated_len); + if (init) + memcpy(ret->str, init, ret->len); + ret->str[ret->len] = 0; + + return ret; +} + +GString * +g_string_new (const gchar *init) +{ + return g_string_new_len(init, -1); +} + +GString * +g_string_sized_new (gsize default_size) +{ + GString *ret = g_new (GString, 1); + + ret->str = g_malloc (default_size); + ret->str [0] = 0; + ret->len = 0; + ret->allocated_len = default_size; + + return ret; +} + +gchar * +g_string_free (GString *string, gboolean free_segment) +{ + gchar *data; + + g_return_val_if_fail (string != NULL, NULL); + + data = string->str; + g_free(string); + + if(!free_segment) { + return data; + } + + g_free(data); + return NULL; +} + +GString * +g_string_assign (GString *string, const gchar *val) +{ + g_return_val_if_fail(string != NULL, NULL); + g_return_val_if_fail(val != NULL, string); + + if (string->str == val) + return string; + + g_string_truncate (string, 0); + g_string_append (string, val); + return string; +} + +GString * +g_string_append_len (GString *string, const gchar *val, gssize len) +{ + g_return_val_if_fail(string != NULL, NULL); + g_return_val_if_fail(val != NULL, string); + + if(len < 0) { + len = strlen(val); + } + + GROW_IF_NECESSARY(string, len); + memcpy(string->str + string->len, val, len); + string->len += len; + string->str[string->len] = 0; + + return string; +} + +GString * +g_string_append (GString *string, const gchar *val) +{ + g_return_val_if_fail(string != NULL, NULL); + g_return_val_if_fail(val != NULL, string); + + return g_string_append_len(string, val, -1); +} + +GString * +g_string_append_c (GString *string, gchar c) +{ + g_return_val_if_fail(string != NULL, NULL); + + GROW_IF_NECESSARY(string, 1); + + string->str[string->len] = c; + string->str[string->len + 1] = 0; + string->len++; + + return string; +} + +GString * +g_string_append_unichar (GString *string, gunichar c) +{ + gchar utf8[6]; + gint len; + + g_return_val_if_fail (string != NULL, NULL); + + if ((len = g_unichar_to_utf8 (c, utf8)) <= 0) + return string; + + return g_string_append_len (string, utf8, len); +} + +GString * +g_string_prepend (GString *string, const gchar *val) +{ + gssize len; + + g_return_val_if_fail (string != NULL, string); + g_return_val_if_fail (val != NULL, string); + + len = strlen (val); + + GROW_IF_NECESSARY(string, len); + memmove(string->str + len, string->str, string->len + 1); + memcpy(string->str, val, len); + + return string; +} + +GString * +g_string_insert (GString *string, gssize pos, const gchar *val) +{ + gssize len; + + g_return_val_if_fail (string != NULL, string); + g_return_val_if_fail (val != NULL, string); + g_return_val_if_fail (pos <= string->len, string); + + len = strlen (val); + + GROW_IF_NECESSARY(string, len); + memmove(string->str + pos + len, string->str + pos, string->len - pos - len + 1); + memcpy(string->str + pos, val, len); + + return string; +} + +void +g_string_append_printf (GString *string, const gchar *format, ...) +{ + char *ret; + va_list args; + + g_return_if_fail (string != NULL); + g_return_if_fail (format != NULL); + + va_start (args, format); + ret = g_strdup_vprintf (format, args); + va_end (args); + g_string_append (string, ret); + + g_free (ret); +} + +void +g_string_append_vprintf (GString *string, const gchar *format, va_list args) +{ + char *ret; + + g_return_if_fail (string != NULL); + g_return_if_fail (format != NULL); + + ret = g_strdup_vprintf (format, args); + g_string_append (string, ret); + g_free (ret); +} + +void +g_string_printf (GString *string, const gchar *format, ...) +{ + va_list args; + + g_return_if_fail (string != NULL); + g_return_if_fail (format != NULL); + + g_free (string->str); + + va_start (args, format); + string->str = g_strdup_vprintf (format, args); + va_end (args); + + string->len = strlen (string->str); + string->allocated_len = string->len+1; +} + +GString * +g_string_truncate (GString *string, gsize len) +{ + g_return_val_if_fail (string != NULL, string); + + /* Silent return */ + if (len >= string->len) + return string; + + string->len = len; + string->str[len] = 0; + return string; +} + +GString * +g_string_set_size (GString *string, gsize len) +{ + g_return_val_if_fail (string != NULL, string); + + GROW_IF_NECESSARY(string, len); + + string->len = len; + string->str[len] = 0; + return string; +} + +GString * +g_string_erase (GString *string, gssize pos, gssize len) +{ + g_return_val_if_fail (string != NULL, string); + + /* Silent return */ + if (pos >= string->len) + return string; + + if (len == -1 || (pos + len) >= string->len) { + string->str[pos] = 0; + } + else { + memmove (string->str + pos, string->str + pos + len, string->len - (pos + len) + 1); + string->len -= len; + } + + return string; +} diff --git a/deps/eglib/src/gtimer-unix.c b/deps/eglib/src/gtimer-unix.c new file mode 100644 index 00000000..901f9216 --- /dev/null +++ b/deps/eglib/src/gtimer-unix.c @@ -0,0 +1,99 @@ +/* + * Timer + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <sys/time.h> + +struct _GTimer { + struct timeval start; + struct timeval stop; +}; + +GTimer *g_timer_new (void) +{ + GTimer *timer; + + timer = g_new0 (GTimer, 1); + g_timer_start (timer); + return timer; +} + +void +g_timer_destroy (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + g_free (timer); +} + +void +g_timer_start (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + gettimeofday (&timer->start, NULL); + memset (&timer->stop, 0, sizeof (struct timeval)); +} + +void +g_timer_stop (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + gettimeofday (&timer->stop, NULL); +} + +gdouble +g_timer_elapsed (GTimer *timer, gulong *microseconds) +{ + struct timeval tv; + gulong seconds; + long usec; + gdouble result; + + g_return_val_if_fail (timer != NULL, 0.0); + + if (timer->stop.tv_sec == 0 && timer->stop.tv_usec == 0) { + gettimeofday (&tv, NULL); + } else { + tv = timer->stop; + } + + usec = (tv.tv_usec) - (timer->start.tv_usec); + seconds = tv.tv_sec - timer->start.tv_sec; + if (microseconds) { + if (usec < 0) { + usec += 1000000; + seconds--; + } + *microseconds = usec; + } + result = seconds * 1000000 + usec; + return (result / 1000000); +} + + diff --git a/deps/eglib/src/gtimer-win32.c b/deps/eglib/src/gtimer-win32.c new file mode 100644 index 00000000..2025eeee --- /dev/null +++ b/deps/eglib/src/gtimer-win32.c @@ -0,0 +1,97 @@ +/* + * Timer + * + * Author: + * Gonzalo Paniagua Javier (gonzalo@novell.com + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> + +#include <glib.h> +#include <windows.h> + +struct _GTimer { + guint64 start; + guint64 stop; +}; + +GTimer *g_timer_new (void) +{ + GTimer *timer; + + timer = g_new0 (GTimer, 1); + g_timer_start (timer); + return timer; +} + +void +g_timer_destroy (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + g_free (timer); +} + +void +g_timer_start (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + + QueryPerformanceCounter ((LARGE_INTEGER*)&timer->start); +} + +void +g_timer_stop (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + + QueryPerformanceCounter ((LARGE_INTEGER*)&timer->stop); +} + +gdouble +g_timer_elapsed (GTimer *timer, gulong *microseconds) +{ + static guint64 freq = 0; + guint64 delta, stop; + + if (freq == 0) { + if (!QueryPerformanceFrequency ((LARGE_INTEGER *)&freq)) + freq = 1; + } + + if (timer->stop == 0) { + QueryPerformanceCounter ((LARGE_INTEGER*)&stop); + } + else { + stop = timer->stop; + } + + delta = stop - timer->start; + + if (microseconds) + *microseconds = (gulong) (delta * (1000000.0 / freq)); + + return (gdouble) delta / (gdouble) freq; +} + + diff --git a/deps/eglib/src/gunicode.c b/deps/eglib/src/gunicode.c new file mode 100644 index 00000000..c3a9000f --- /dev/null +++ b/deps/eglib/src/gunicode.c @@ -0,0 +1,253 @@ +/* + * gunicode.c: Some Unicode routines + * + * Author: + * Miguel de Icaza (miguel@novell.com) + * + * (C) 2006 Novell, Inc. + * + * utf8 validation code came from: + * libxml2-2.6.26 licensed under the MIT X11 license + * + * Authors credit in libxml's string.c: + * William Brack <wbrack@mmm.com.hk> + * daniel@veillard.com + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include <config.h> +#include <stdio.h> +#include <glib.h> +#include <unicode-data.h> +#include <errno.h> + +#if defined(_MSC_VER) || defined(G_OS_WIN32) +/* FIXME */ +# define CODESET 1 +# include <windows.h> +#else +# ifdef HAVE_LANGINFO_H +# include <langinfo.h> +# endif +# ifdef HAVE_LOCALCHARSET_H +# include <localcharset.h> +# endif +#endif + +static const char *my_charset; +static gboolean is_utf8; + +/* + * Character set conversion + */ + +GUnicodeType +g_unichar_type (gunichar c) +{ + int i; + + guint16 cp = (guint16) c; + for (i = 0; i < unicode_category_ranges_count; i++) { + if (cp < unicode_category_ranges [i].start) + continue; + if (unicode_category_ranges [i].end <= cp) + continue; + return unicode_category [i] [cp - unicode_category_ranges [i].start]; + } + + /* + // 3400-4DB5: OtherLetter + // 4E00-9FC3: OtherLetter + // AC00-D7A3: OtherLetter + // D800-DFFF: OtherSurrogate + // E000-F8FF: OtherPrivateUse + // 20000-2A6D6 OtherLetter + // F0000-FFFFD OtherPrivateUse + // 100000-10FFFD OtherPrivateUse + */ + if (0x3400 <= cp && cp < 0x4DB5) + return G_UNICODE_OTHER_LETTER; + if (0x4E00 <= cp && cp < 0x9FC3) + return G_UNICODE_OTHER_LETTER; + if (0xAC00<= cp && cp < 0xD7A3) + return G_UNICODE_OTHER_LETTER; + if (0xD800 <= cp && cp < 0xDFFF) + return G_UNICODE_SURROGATE; + if (0xE000 <= cp && cp < 0xF8FF) + return G_UNICODE_PRIVATE_USE; + /* since the argument is UTF-16, we cannot check beyond FFFF */ + + /* It should match any of above */ + return 0; +} + +GUnicodeBreakType +g_unichar_break_type (gunichar c) +{ + // MOONLIGHT_FIXME + return G_UNICODE_BREAK_UNKNOWN; +} + +gunichar +g_unichar_case (gunichar c, gboolean upper) +{ + gint8 i, i2; + guint32 cp = (guint32) c, v; + + for (i = 0; i < simple_case_map_ranges_count; i++) { + if (cp < simple_case_map_ranges [i].start) + return c; + if (simple_case_map_ranges [i].end <= cp) + continue; + if (c < 0x10000) { + const guint16 *tab = upper ? simple_upper_case_mapping_lowarea [i] : simple_lower_case_mapping_lowarea [i]; + v = tab [cp - simple_case_map_ranges [i].start]; + } else { + const guint32 *tab; + i2 = (gint8)(i - (upper ? simple_upper_case_mapping_lowarea_table_count : simple_lower_case_mapping_lowarea_table_count)); + tab = upper ? simple_upper_case_mapping_higharea [i2] : simple_lower_case_mapping_higharea [i2]; + v = tab [cp - simple_case_map_ranges [i].start]; + } + return v != 0 ? (gunichar) v : c; + } + return c; +} + +gunichar +g_unichar_toupper (gunichar c) +{ + return g_unichar_case (c, TRUE); +} + +gunichar +g_unichar_tolower (gunichar c) +{ + return g_unichar_case (c, FALSE); +} + +gunichar +g_unichar_totitle (gunichar c) +{ + guint8 i; + guint32 cp; + + cp = (guint32) c; + for (i = 0; i < simple_titlecase_mapping_count; i++) { + if (simple_titlecase_mapping [i].codepoint == cp) + return simple_titlecase_mapping [i].title; + if (simple_titlecase_mapping [i].codepoint > cp) + /* it is ordered, hence no more match */ + break; + } + return g_unichar_toupper (c); +} + +gboolean +g_unichar_isxdigit (gunichar c) +{ + return (g_unichar_xdigit_value (c) != -1); + +} + +gint +g_unichar_xdigit_value (gunichar c) +{ + if (c >= 0x30 && c <= 0x39) /*0-9*/ + return (c - 0x30); + if (c >= 0x41 && c <= 0x46) /*A-F*/ + return (c - 0x37); + if (c >= 0x61 && c <= 0x66) /*a-f*/ + return (c - 0x57); + return -1; +} + +gboolean +g_unichar_isspace (gunichar c) +{ + GUnicodeType type = g_unichar_type (c); + if (type == G_UNICODE_LINE_SEPARATOR || + type == G_UNICODE_PARAGRAPH_SEPARATOR || + type == G_UNICODE_SPACE_SEPARATOR) + return TRUE; + + return FALSE; +} + + +/* + * This is broken, and assumes an UTF8 system, but will do for eglib's first user + */ +gchar * +g_filename_from_utf8 (const gchar *utf8string, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error) +{ + char *res; + + if (len == -1) + len = strlen (utf8string); + + res = g_malloc (len + 1); + g_strlcpy (res, utf8string, len + 1); + return res; +} + +gboolean +g_get_charset (G_CONST_RETURN char **charset) +{ + if (my_charset == NULL) { +#ifdef G_OS_WIN32 + static char buf [14]; + sprintf (buf, "CP%u", GetACP ()); + my_charset = buf; + is_utf8 = FALSE; +#else + /* These shouldn't be heap allocated */ +#if HAVE_LOCALCHARSET_H + my_charset = locale_charset (); +#elif defined(HAVE_LANGINFO_H) + my_charset = nl_langinfo (CODESET); +#else + my_charset = "UTF-8"; +#endif + is_utf8 = strcmp (my_charset, "UTF-8") == 0; +#endif + } + + if (charset != NULL) + *charset = my_charset; + + return is_utf8; +} + +gchar * +g_locale_to_utf8 (const gchar *opsysstring, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error) +{ + g_get_charset (NULL); + + return g_convert (opsysstring, len, "UTF-8", my_charset, bytes_read, bytes_written, error); +} + +gchar * +g_locale_from_utf8 (const gchar *utf8string, gssize len, gsize *bytes_read, gsize *bytes_written, GError **error) +{ + g_get_charset (NULL); + + return g_convert (utf8string, len, my_charset, "UTF-8", bytes_read, bytes_written, error); +} diff --git a/deps/eglib/src/gutf8.c b/deps/eglib/src/gutf8.c new file mode 100644 index 00000000..e6a47ac2 --- /dev/null +++ b/deps/eglib/src/gutf8.c @@ -0,0 +1,376 @@ +/* + * gutf8.c: UTF-8 conversion + * + * Author: + * Atsushi Enomoto <atsushi@ximian.com> + * + * (C) 2006 Novell, Inc. + * Copyright 2012 Xamarin Inc + */ + + +#include <config.h> + +#include <stdio.h> +#include <glib.h> + +/* + * Index into the table below with the first byte of a UTF-8 sequence to get + * the number of bytes that are supposed to follow it to complete the sequence. + * + * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is left + * as-is for anyone who may want to do such conversion, which was allowed in + * earlier algorithms. +*/ +const guchar g_utf8_jump_table[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; + +static gchar * +utf8_case_conv (const gchar *str, gssize len, gboolean upper) +{ + gunichar *ustr; + glong i, ulen; + gchar *utf8; + + ustr = g_utf8_to_ucs4_fast (str, (glong) len, &ulen); + for (i = 0; i < ulen; i++) + ustr[i] = upper ? g_unichar_toupper (ustr[i]) : g_unichar_tolower (ustr[i]); + utf8 = g_ucs4_to_utf8 (ustr, ulen, NULL, NULL, NULL); + g_free (ustr); + + return utf8; +} + +gchar * +g_utf8_strup (const gchar *str, gssize len) +{ + return utf8_case_conv (str, len, TRUE); +} + +gchar * +g_utf8_strdown (const gchar *str, gssize len) +{ + return utf8_case_conv (str, len, FALSE); +} + +static gboolean +utf8_validate (const unsigned char *inptr, size_t len) +{ + const unsigned char *ptr = inptr + len; + unsigned char c; + + /* Everything falls through when TRUE... */ + switch (len) { + default: + return FALSE; + case 4: + if ((c = (*--ptr)) < 0x80 || c > 0xBF) + return FALSE; + + if ((c == 0xBF || c == 0xBE) && ptr[-1] == 0xBF) { + if (ptr[-2] == 0x8F || ptr[-2] == 0x9F || + ptr[-2] == 0xAF || ptr[-2] == 0xBF) + return FALSE; + } + case 3: + if ((c = (*--ptr)) < 0x80 || c > 0xBF) + return FALSE; + case 2: + if ((c = (*--ptr)) < 0x80 || c > 0xBF) + return FALSE; + + /* no fall-through in this inner switch */ + switch (*inptr) { + case 0xE0: if (c < 0xA0) return FALSE; break; + case 0xED: if (c > 0x9F) return FALSE; break; + case 0xEF: if (c == 0xB7 && (ptr[1] > 0x8F && ptr[1] < 0xB0)) return FALSE; + if (c == 0xBF && (ptr[1] == 0xBE || ptr[1] == 0xBF)) return FALSE; + break; + case 0xF0: if (c < 0x90) return FALSE; break; + case 0xF4: if (c > 0x8F) return FALSE; break; + default: if (c < 0x80) return FALSE; break; + } + case 1: if (*inptr >= 0x80 && *inptr < 0xC2) return FALSE; + } + + if (*inptr > 0xF4) + return FALSE; + + return TRUE; +} + +/** + * g_utf8_validate: + * @str: a utf-8 encoded string + * @max_len: max number of bytes to validate (or -1 to validate the entire null-terminated string) + * @end: output parameter to mark the end of the valid input + * + * Checks @utf for being valid UTF-8. @str is assumed to be + * null-terminated. This function is not super-strict, as it will + * allow longer UTF-8 sequences than necessary. Note that Java is + * capable of producing these sequences if provoked. Also note, this + * routine checks for the 4-byte maximum size, but does not check for + * 0x10ffff maximum value. + * + * Return value: %TRUE if @str is valid or %FALSE otherwise. + **/ +gboolean +g_utf8_validate (const gchar *str, gssize max_len, const gchar **end) +{ + guchar *inptr = (guchar *) str; + gboolean valid = TRUE; + guint length, min; + gssize n = 0; + + if (max_len == 0) + return FALSE; + + if (max_len < 0) { + while (*inptr != 0) { + length = g_utf8_jump_table[*inptr]; + if (!utf8_validate (inptr, length)) { + valid = FALSE; + break; + } + + inptr += length; + } + } else { + while (n < max_len) { + if (*inptr == 0) { + /* Note: return FALSE if we encounter nul-byte + * before max_len is reached. */ + valid = FALSE; + break; + } + + length = g_utf8_jump_table[*inptr]; + min = MIN (length, max_len - n); + + if (!utf8_validate (inptr, min)) { + valid = FALSE; + break; + } + + if (min < length) { + valid = FALSE; + break; + } + + inptr += length; + n += length; + } + } + + if (end != NULL) + *end = (gchar *) inptr; + + return valid; +} + +gunichar +g_utf8_get_char_validated (const gchar *str, gssize max_len) +{ + unsigned char *inptr = (unsigned char *) str; + gunichar u = *inptr; + int n, i; + + if (max_len == 0) + return -2; + + if (u < 0x80) { + /* simple ascii case */ + return u; + } else if (u < 0xc2) { + return -1; + } else if (u < 0xe0) { + u &= 0x1f; + n = 2; + } else if (u < 0xf0) { + u &= 0x0f; + n = 3; + } else if (u < 0xf8) { + u &= 0x07; + n = 4; + } else if (u < 0xfc) { + u &= 0x03; + n = 5; + } else if (u < 0xfe) { + u &= 0x01; + n = 6; + } else { + return -1; + } + + if (max_len > 0) { + if (!utf8_validate (inptr, MIN (max_len, n))) + return -1; + + if (max_len < n) + return -2; + } else { + if (!utf8_validate (inptr, n)) + return -1; + } + + for (i = 1; i < n; i++) + u = (u << 6) | (*++inptr ^ 0x80); + + return u; +} + +glong +g_utf8_strlen (const gchar *str, gssize max_len) +{ + const guchar *inptr = (const guchar *) str; + glong clen = 0, len = 0, n; + + if (max_len == 0) + return 0; + + if (max_len < 0) { + while (*inptr) { + inptr += g_utf8_jump_table[*inptr]; + len++; + } + } else { + while (len < max_len && *inptr) { + n = g_utf8_jump_table[*inptr]; + if ((clen + n) > max_len) + break; + + inptr += n; + clen += n; + len++; + } + } + + return len; +} + +gunichar +g_utf8_get_char (const gchar *src) +{ + unsigned char *inptr = (unsigned char *) src; + gunichar u = *inptr; + int n, i; + + if (u < 0x80) { + /* simple ascii case */ + return u; + } else if (u < 0xe0) { + u &= 0x1f; + n = 2; + } else if (u < 0xf0) { + u &= 0x0f; + n = 3; + } else if (u < 0xf8) { + u &= 0x07; + n = 4; + } else if (u < 0xfc) { + u &= 0x03; + n = 5; + } else { + u &= 0x01; + n = 6; + } + + for (i = 1; i < n; i++) + u = (u << 6) | (*++inptr ^ 0x80); + + return u; +} + +gchar * +g_utf8_find_prev_char (const gchar *str, const gchar *p) +{ + while (p > str) { + p--; + if ((*p & 0xc0) != 0xb0) + return (gchar *)p; + } + return NULL; +} + +gchar * +g_utf8_prev_char (const gchar *str) +{ + const gchar *p = str; + do { + p--; + } while ((*p & 0xc0) == 0xb0); + + return (gchar *)p; +} + +gchar * +g_utf8_offset_to_pointer (const gchar *str, glong offset) +{ + const gchar *p = str; + + if (offset > 0) { + do { + p = g_utf8_next_char (p); + offset --; + } while (offset > 0); + } + else if (offset < 0) { + const gchar *jump = str; + do { + // since the minimum size of a character is 1 + // we know we can step back at least offset bytes + jump = jump + offset; + + // if we land in the middle of a character + // walk to the beginning + while ((*jump & 0xc0) == 0xb0) + jump --; + + // count how many characters we've actually walked + // by going forward + p = jump; + do { + p = g_utf8_next_char (p); + offset ++; + } while (p < jump); + + } while (offset < 0); + } + + return (gchar *)p; +} + +glong +g_utf8_pointer_to_offset (const gchar *str, const gchar *pos) +{ + const gchar *inptr, *inend; + glong offset = 0; + glong sign = 1; + + if (pos == str) + return 0; + + if (str < pos) { + inptr = str; + inend = pos; + } else { + inptr = pos; + inend = str; + sign = -1; + } + + do { + inptr = g_utf8_next_char (inptr); + offset++; + } while (inptr < inend); + + return offset * sign; +} diff --git a/deps/eglib/src/sort.frag.h b/deps/eglib/src/sort.frag.h new file mode 100644 index 00000000..2cf5a9ba --- /dev/null +++ b/deps/eglib/src/sort.frag.h @@ -0,0 +1,184 @@ +/* + * sort.frag.h: Common implementation of linked-list sorting + * + * Author: + * Raja R Harinath (rharinath@novell.com) + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * (C) 2006 Novell, Inc. + */ + +/* + * This code requires a typedef named 'list_node' for the list node. It + * is assumed that the list type is the type of a pointer to a list + * node, and that the node has a field named 'next' that implements to + * the linked list. No additional invariant is maintained (e.g. the + * 'prev' pointer of a doubly-linked list node is _not_ updated). Any + * invariant would require a post-processing pass to fix matters if + * necessary. + */ +typedef list_node *digit; + +/* + * The maximum possible depth of the merge tree + * = ceiling (log2 (maximum number of list nodes)) + * = ceiling (log2 (maximum possible memory size/size of each list node)) + * = number of bits in 'size_t' - floor (log2 (sizeof digit)) + * Also, each list in sort_info is at least 2 nodes long: we can reduce the depth by 1 + */ +#define FLOOR_LOG2(x) (((x)>=2) + ((x)>=4) + ((x)>=8) + ((x)>=16) + ((x)>=32) + ((x)>=64) + ((x)>=128)) +#define MAX_RANKS ((sizeof (size_t) * 8) - FLOOR_LOG2(sizeof (list_node)) - 1) + +struct sort_info +{ + int min_rank, n_ranks; + GCompareFunc func; + + /* Invariant: ranks[i] == NULL || length(ranks[i]) >= 2**(i+1) */ + list_node *ranks [MAX_RANKS]; /* ~ 128 bytes on 32bit, ~ 512 bytes on 64bit */ +}; + +static inline void +init_sort_info (struct sort_info *si, GCompareFunc func) +{ + si->min_rank = si->n_ranks = 0; + si->func = func; + /* we don't need to initialize si->ranks, since we never lookup past si->n_ranks. */ +} + +static inline list_node * +merge_lists (list_node *first, list_node *second, GCompareFunc func) +{ + /* merge the two lists */ + list_node *list = NULL; + list_node **pos = &list; + while (first && second) { + if (func (first->data, second->data) > 0) { + *pos = second; + second = second->next; + } else { + *pos = first; + first = first->next; + } + pos = &((*pos)->next); + } + *pos = first ? first : second; + return list; +} + +/* Pre-condition: upto <= si->n_ranks, list == NULL || length(list) == 1 */ +static inline list_node * +sweep_up (struct sort_info *si, list_node *list, int upto) +{ + int i; + for (i = si->min_rank; i < upto; ++i) { + list = merge_lists (si->ranks [i], list, si->func); + si->ranks [i] = NULL; + } + return list; +} + +/* + * The 'ranks' array essentially captures the recursion stack of a mergesort. + * The merge tree is built in a bottom-up manner. The control loop for + * updating the 'ranks' array is analogous to incrementing a binary integer, + * and the O(n) time for counting upto n translates to O(n) merges when + * inserting rank-0 lists. When we plug in the sizes of the lists involved in + * those merges, we get the O(n log n) time for the sort. + * + * Inserting higher-ranked lists reduce the height of the merge tree, and also + * eliminate a lot of redundant comparisons when merging two lists that would've + * been part of the same run. Adding a rank-i list is analogous to incrementing + * a binary integer by 2**i in one operation, thus sharing a similar speedup. + * + * When inserting higher-ranked lists, we choose to clear out the lower ranks + * in the interests of keeping the sort stable, but this makes analysis harder. + * Note that clearing the lower-ranked lists is O(length(list))-- thus it + * shouldn't affect the O(n log n) behaviour. IOW, inserting one rank-i list + * is equivalent to inserting 2**i rank-0 lists, thus even if we do i additional + * merges in the clearing-out (taking at most 2**i time) we are still fine. + */ + +#define stringify2(x) #x +#define stringify(x) stringify2(x) + +/* Pre-condition: 2**(rank+1) <= length(list) < 2**(rank+2) (therefore: length(list) >= 2) */ +static inline void +insert_list (struct sort_info *si, list_node* list, int rank) +{ + int i; + + if (rank > si->n_ranks) { + if (rank > MAX_RANKS) { + g_warning ("Rank '%d' should not exceed " stringify (MAX_RANKS), rank); + rank = MAX_RANKS; + } + list = merge_lists (sweep_up (si, NULL, si->n_ranks), list, si->func); + for (i = si->n_ranks; i < rank; ++i) + si->ranks [i] = NULL; + } else { + if (rank) + list = merge_lists (sweep_up (si, NULL, rank), list, si->func); + for (i = rank; i < si->n_ranks && si->ranks [i]; ++i) { + list = merge_lists (si->ranks [i], list, si->func); + si->ranks [i] = NULL; + } + } + + if (i == MAX_RANKS) /* Will _never_ happen: so we can just devolve into quadratic ;-) */ + --i; + if (i >= si->n_ranks) + si->n_ranks = i + 1; + si->min_rank = i; + si->ranks [i] = list; +} + +#undef stringify2 +#undef stringify +#undef MAX_RANKS +#undef FLOOR_LOG2 + +/* A non-recursive mergesort */ +static inline digit +do_sort (list_node* list, GCompareFunc func) +{ + struct sort_info si; + + init_sort_info (&si, func); + + while (list && list->next) { + list_node* next = list->next; + list_node* tail = next->next; + + if (func (list->data, next->data) > 0) { + next->next = list; + next = list; + list = list->next; + } + next->next = NULL; + + insert_list (&si, list, 0); + + list = tail; + } + + return sweep_up (&si, list, si.n_ranks); +} diff --git a/deps/eglib/src/unicode-data.h b/deps/eglib/src/unicode-data.h new file mode 100644 index 00000000..1cd75f3a --- /dev/null +++ b/deps/eglib/src/unicode-data.h @@ -0,0 +1,2152 @@ +/* +This file is automatically generated by ucd.exe. +The source for this generator should be in Mono repository +(mcs/class/corlib/Mono.Globalization.Unicode directory). +*/ + +#ifndef __UNICODE_DATA_H +#define __UNICODE_DATA_H + +#include <glib.h> + + +/* ======== Structures ======== */ +typedef struct { + guint32 codepoint; + guint32 upper; + guint32 title; +} SimpleTitlecaseMapping; +typedef struct { + guint32 start; + guint32 end; +} CodePointRange; +typedef struct { + guint32 upper; + guint32 lower; +} SimpleCaseMapping; + +/* ======== Unicode Categories ======== */ +static const guint8 unicode_category_ranges_count = 11; +static const CodePointRange unicode_category_ranges [] = { +{0x000000, 0x003400}, +{0x004DC0, 0x004E00}, +{0x00A000, 0x00AA80}, +{0x00F900, 0x010000}, +{0x010000, 0x0104C0}, +{0x010800, 0x010A80}, +{0x012000, 0x012480}, +{0x01D000, 0x01D800}, +{0x01F000, 0x01F0C0}, +{0x02F800, 0x02FA40}, +{0x0E0000, 0x0E0200}, +{0, 0}}; +static const guint8 unicode_category_table0 [] = { + /* ==== 0-3400 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 29,21,21,21,23,21,21,21,22,18,21,25,21,17,21,21, + 13,13,13,13,13,13,13,13,13,13,21,21,25,25,25,21, + 21,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,22,21,18,24,16, + 24,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,22,25,18,25,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 29,21,23,23,23,23,26,26,24,26,5,20,25,1,26,24, + 26,25,15,15,24,5,26,21,24,15,5,19,15,15,15,21, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,25,9,9,9,9,9,9,9,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,25,5,5,5,5,5,5,5,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,5,9,5,9,5,9,5,9, + 5,9,5,9,5,9,5,9,5,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,9,5,9,5,9,5,5, + 5,9,9,5,9,5,9,9,5,9,9,9,5,5,9,9, + 9,9,5,9,9,5,9,9,9,5,5,5,9,9,5,9, + 9,5,9,5,9,5,9,9,5,9,5,5,9,5,9,9, + 5,9,9,9,5,9,5,9,9,5,5,7,9,5,5,5, + 7,7,7,7,9,8,5,9,8,5,9,8,5,9,5,9, + 5,9,5,9,5,9,5,9,5,9,5,9,5,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 5,9,8,5,9,5,9,9,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,5,5,5,5,5,5,9,9,5,9,9,5, + 5,9,5,9,9,9,9,5,9,5,9,5,9,5,9,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,7,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,24,24,24,24,6,6,6,6,6,6,6,6,6,6, + 6,6,24,24,24,24,24,24,24,24,24,24,24,24,24,24, + 6,6,6,6,6,24,24,24,24,24,24,24,6,24,6,24, + 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 9,5,9,5,6,24,9,5,0,0,6,5,5,5,21,0, + 0,0,0,0,24,24,9,21,9,9,9,0,9,0,9,9, + 5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,0,9,9,9,9,9,9,9,9,9,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,9, + 5,5,9,9,9,5,5,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 5,5,5,5,9,5,25,9,5,9,9,5,5,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,26,12,12,12,12,12,11,11,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,9,5,9,5,9,5,9,5,9,5,9,5,9,5,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,0,0,0,0,0,0,0,0,0,0,0,0, + 0,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,0,0,6,21,21,21,21,21,21, + 0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,0,21,17,0,0,0,0,0, + 0,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,17,12, + 21,12,12,21,12,12,21,12,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, + 7,7,7,21,21,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,0,0,25,25,25,21,21,23,21,21,26,26, + 12,12,12,12,12,12,12,12,12,12,12,21,0,0,21,21, + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 6,7,7,7,7,7,7,7,7,7,7,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,0, + 13,13,13,13,13,13,13,13,13,13,21,21,21,21,7,7, + 12,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,21,7,12,12,12,12,12,12,12,1,11,12, + 12,12,12,12,12,6,6,12,12,26,12,12,12,12,7,7, + 13,13,13,13,13,13,13,13,13,13,7,7,7,26,26,7, + 21,21,21,21,21,21,21,21,21,21,21,21,21,21,0,1, + 7,12,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,0,0,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,12,12,12,12,12,12,12,12,12,12, + 12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 13,13,13,13,13,13,13,13,13,13,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,12,12,12,12,12, + 12,12,12,12,6,6,26,21,21,21,6,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,12,12,10,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,12,7,10,10, + 10,12,12,12,12,12,12,12,12,10,10,10,10,12,0,0, + 7,12,12,12,12,0,0,0,7,7,7,7,7,7,7,7, + 7,7,12,12,21,21,13,13,13,13,13,13,13,13,13,13, + 21,6,7,0,0,0,0,0,0,0,0,7,7,7,7,7, + 0,12,10,10,0,7,7,7,7,7,7,7,7,0,0,7, + 7,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,0,7,0,0,0,7,7,7,7,0,0,12,7,10,10, + 10,12,12,12,12,0,0,10,10,0,0,10,10,12,7,0, + 0,0,0,0,0,0,0,10,0,0,0,0,7,7,0,7, + 7,7,12,12,0,0,13,13,13,13,13,13,13,13,13,13, + 7,7,23,23,15,15,15,15,15,15,26,0,0,0,0,0, + 0,12,12,10,0,7,7,7,7,7,7,0,0,0,0,7, + 7,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,0,7,7,0,7,7,0,7,7,0,0,12,0,10,10, + 10,12,12,0,0,0,0,12,12,0,0,12,12,12,0,0, + 0,12,0,0,0,0,0,0,0,7,7,7,7,0,7,0, + 0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13, + 12,12,7,7,7,12,0,0,0,0,0,0,0,0,0,0, + 0,12,12,10,0,7,7,7,7,7,7,7,7,7,0,7, + 7,7,0,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,0,7,7,0,7,7,7,7,7,0,0,12,7,10,10, + 10,12,12,12,12,12,0,12,12,10,0,10,10,12,0,0, + 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,12,12,0,0,13,13,13,13,13,13,13,13,13,13, + 0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,12,10,10,0,7,7,7,7,7,7,7,7,0,0,7, + 7,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,0,7,7,0,7,7,7,7,7,0,0,12,7,10,12, + 10,12,12,12,12,0,0,10,10,0,0,10,10,12,0,0, + 0,0,0,0,0,0,12,10,0,0,0,0,7,7,0,7, + 7,7,12,12,0,0,13,13,13,13,13,13,13,13,13,13, + 26,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,12,7,0,7,7,7,7,7,7,0,0,0,7,7, + 7,0,7,7,7,7,0,0,0,7,7,0,7,0,7,7, + 0,0,0,7,7,0,0,0,7,7,7,0,0,0,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,10,10, + 12,10,10,0,0,0,10,10,10,0,10,10,10,12,0,0, + 7,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,13,13,13,13,13,13,13,13,13,13, + 15,15,15,26,26,26,26,26,26,23,26,0,0,0,0,0, + 0,10,10,10,0,7,7,7,7,7,7,7,7,0,7,7, + 7,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,7,7,7,0,7,7,7,7,7,0,0,0,7,12,12, + 12,10,10,10,10,0,12,12,12,0,12,12,12,12,0,0, + 0,0,0,0,0,12,12,0,7,7,0,0,0,0,0,0, + 7,7,12,12,0,0,13,13,13,13,13,13,13,13,13,13, + 0,0,0,0,0,0,0,0,15,15,15,15,15,15,15,26, + 0,0,10,10,0,7,7,7,7,7,7,7,7,0,7,7, + 7,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,7,7,7,0,7,7,7,7,7,0,0,12,7,10,12, + 10,10,10,10,10,0,12,10,10,0,10,10,12,12,0,0, + 0,0,0,0,0,10,10,0,0,0,0,0,0,0,7,0, + 7,7,12,12,0,0,13,13,13,13,13,13,13,13,13,13, + 0,26,26,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,10,10,0,7,7,7,7,7,7,7,7,0,7,7, + 7,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,7,10,10, + 10,12,12,12,12,0,10,10,10,0,10,10,10,12,0,0, + 0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0, + 7,7,12,12,0,0,13,13,13,13,13,13,13,13,13,13, + 15,15,15,15,15,15,0,0,0,26,7,7,7,7,7,7, + 0,0,10,10,0,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,0,0,0,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,0,7,7,7,7,7,7,7,7,7,0,7,0,0, + 7,7,7,7,7,7,7,0,0,0,12,0,0,0,0,10, + 10,10,12,12,12,0,12,0,10,10,10,10,10,10,10,10, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,10,10,21,0,0,0,0,0,0,0,0,0,0,0, + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,12,7,7,12,12,12,12,12,12,12,0,0,0,0,23, + 7,7,7,7,7,7,6,12,12,12,12,12,12,12,12,21, + 13,13,13,13,13,13,13,13,13,13,21,21,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,7,7,0,7,0,0,7,7,0,7,0,0,7,0,0, + 0,0,0,0,7,7,7,7,0,7,7,7,7,7,7,7, + 0,7,7,7,0,7,0,7,0,0,7,7,0,7,7,7, + 7,12,7,7,12,12,12,12,12,12,0,12,12,7,0,0, + 7,7,7,7,7,0,6,0,12,12,12,12,12,12,0,0, + 13,13,13,13,13,13,13,13,13,13,0,0,7,7,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,26,26,26,21,21,21,21,21,21,21,21,21,21,21,21, + 21,21,21,26,26,26,26,26,12,12,26,26,26,26,26,26, + 13,13,13,13,13,13,13,13,13,13,15,15,15,15,15,15, + 15,15,15,15,26,12,26,12,26,12,22,18,22,18,10,10, + 7,7,7,7,7,7,7,7,0,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0, + 0,12,12,12,12,12,12,12,12,12,12,12,12,12,12,10, + 12,12,12,12,12,21,12,12,7,7,7,7,0,0,0,0, + 12,12,12,12,12,12,12,12,0,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,0,26,26, + 26,26,26,26,26,26,12,26,26,26,26,26,26,0,26,26, + 21,21,21,21,21,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,10,10,12,12,12, + 12,10,12,12,12,12,12,12,10,12,12,10,10,12,12,7, + 13,13,13,13,13,13,13,13,13,13,21,21,21,21,21,21, + 7,7,7,7,7,7,10,10,12,12,7,7,7,7,12,12, + 12,7,10,10,10,7,7,10,10,10,10,10,10,10,7,7, + 7,12,12,12,12,7,7,7,7,7,7,7,7,7,7,7, + 7,7,12,10,10,12,12,10,10,10,10,10,10,12,7,10, + 13,13,13,13,13,13,13,13,13,13,0,0,0,0,26,26, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,21,6,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,0,0,0,0,0,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,0,0, + 7,7,7,7,7,7,7,0,7,0,7,7,7,7,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,0,7,7,7,7,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,0,7,7,7,7,0,0,7,7,7,7,7,7,7,0, + 7,0,7,7,7,7,0,0,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,0,7,7,7,7,0,0,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,12, + 26,21,21,21,21,21,21,21,21,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 26,26,26,26,26,26,26,26,26,26,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0, + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,21,21,7, + 7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0, + 29,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,22,18,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,21,21,21,14,14, + 14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,7,7, + 7,7,12,12,12,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,12,12,12,21,21,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,12,12,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,7,7, + 7,0,12,12,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,1,1,10,12,12,12,12,12,12,12,10,10, + 10,10,10,10,10,10,12,10,10,12,12,12,12,12,12,12, + 12,12,12,12,21,21,21,6,21,21,21,23,7,12,0,0, + 13,13,13,13,13,13,13,13,13,13,0,0,0,0,0,0, + 15,15,15,15,15,15,15,15,15,15,0,0,0,0,0,0, + 21,21,21,21,21,21,17,21,21,21,21,12,12,12,29,0, + 13,13,13,13,13,13,13,13,13,13,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,6,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,12,7,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0, + 12,12,12,10,10,10,10,12,12,10,10,10,0,0,0,0, + 10,10,12,10,10,10,10,10,10,12,12,12,0,0,0,0, + 26,0,0,0,21,21,13,13,13,13,13,13,13,13,13,13, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0, + 7,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, + 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, + 10,7,7,7,7,7,7,7,10,10,0,0,0,0,0,0, + 13,13,13,13,13,13,13,13,13,13,0,0,0,0,21,21, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,12,12,10,10,10,0,0,21,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,12,12,12,10,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,12,10,12,12,12,12,12,10,12,10,10,10, + 10,10,12,10,10,7,7,7,7,7,7,7,0,0,0,0, + 13,13,13,13,13,13,13,13,13,13,21,21,21,21,21,21, + 21,26,26,26,26,26,26,26,26,26,26,12,12,12,12,12, + 12,12,12,12,26,26,26,26,26,26,26,26,26,0,0,0, + 12,12,10,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,10,12,12,12,12,10,10,12,12,10,0,0,0,7,7, + 13,13,13,13,13,13,13,13,13,13,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,10,10,10,10,10,10,10,10,12,12,12,12, + 12,12,12,12,10,10,12,12,0,0,0,21,21,21,21,21, + 13,13,13,13,13,13,13,13,13,13,0,0,0,7,7,7, + 13,13,13,13,13,13,13,13,13,13,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,6,6,6,6,6,6,21,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,6,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,12, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,5,5,5,5,5,5,5,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 5,5,5,5,5,5,5,5,9,9,9,9,9,9,9,9, + 5,5,5,5,5,5,0,0,9,9,9,9,9,9,0,0, + 5,5,5,5,5,5,5,5,9,9,9,9,9,9,9,9, + 5,5,5,5,5,5,5,5,9,9,9,9,9,9,9,9, + 5,5,5,5,5,5,0,0,9,9,9,9,9,9,0,0, + 5,5,5,5,5,5,5,5,0,9,0,9,0,9,0,9, + 5,5,5,5,5,5,5,5,9,9,9,9,9,9,9,9, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0, + 5,5,5,5,5,5,5,5,8,8,8,8,8,8,8,8, + 5,5,5,5,5,5,5,5,8,8,8,8,8,8,8,8, + 5,5,5,5,5,5,5,5,8,8,8,8,8,8,8,8, + 5,5,5,5,5,0,5,5,9,9,9,9,8,24,5,24, + 24,24,5,5,5,0,5,5,9,9,9,9,8,24,24,24, + 5,5,5,5,0,0,5,5,9,9,9,9,0,24,24,24, + 5,5,5,5,5,5,5,5,9,9,9,9,9,24,24,24, + 0,0,5,5,5,0,5,5,9,9,9,9,8,24,24,0, + 29,29,29,29,29,29,29,29,29,29,29,1,1,1,1,1, + 17,17,17,17,17,17,21,21,20,19,22,20,20,19,22,20, + 21,21,21,21,21,21,21,21,27,28,1,1,1,1,1,29, + 21,21,21,21,21,21,21,21,21,20,19,21,21,21,21,16, + 16,21,21,21,25,22,18,21,21,21,21,21,21,21,21,21, + 21,21,25,21,16,21,21,21,21,21,21,21,21,21,21,29, + 1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,1, + 15,5,0,0,15,15,15,15,15,15,25,25,25,22,18,5, + 15,15,15,15,15,15,15,15,15,15,25,25,25,22,18,0, + 6,6,6,6,6,0,0,0,0,0,0,0,0,0,0,0, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,12,12,12,12,12,12,12,12,12,12,12,12,11,11,11, + 11,12,11,11,11,12,12,12,12,12,12,12,12,12,12,12, + 12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,9,26,26,26,26,9,26,26,5,9,9,9,5,5, + 9,9,9,5,26,9,26,26,26,9,9,9,9,9,26,26, + 26,26,26,26,9,26,9,26,9,26,9,9,9,9,26,5, + 9,9,9,9,5,7,7,7,7,5,26,26,5,5,9,9, + 25,25,25,25,25,9,5,5,5,5,26,25,26,26,5,26, + 0,0,0,15,15,15,15,15,15,15,15,15,15,15,15,15, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,9,5,14,14,14,14,0,0,0,0,0,0,0, + 25,25,25,25,25,26,26,26,26,26,25,25,26,26,26,26, + 25,26,26,25,26,26,25,26,26,26,26,26,26,26,25,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,25,25, + 26,26,25,26,25,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 26,26,26,26,26,26,26,26,25,25,25,25,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 25,25,26,26,26,26,26,26,26,22,18,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,25,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,25,25,25,25, + 25,25,26,26,26,26,26,26,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,25,26,26,26,26,26,26,26,26, + 26,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,25,25,25,25,25,25,25,25, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,25, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,0,0,0, + 26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,26,26,26,26,0,26,26,26,26,0,0,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,0,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,0,26,0,26, + 26,26,26,0,0,0,26,0,26,26,26,26,26,26,26,0, + 0,26,26,26,26,26,26,26,22,18,22,18,22,18,22,18, + 22,18,22,18,22,18,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,26,0,0,0,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0, + 25,25,25,25,25,22,18,25,25,25,25,0,25,0,0,0, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,22,18,22,18,22,18,22,18,22,18, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,22,18,22,18,22,18,22,18,22,18,22,18,22, + 18,22,18,22,18,22,18,22,18,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,22,18,22,18,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,22,18,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25, + 25,25,25,25,25,26,26,25,25,25,25,25,25,0,0,0, + 26,26,26,26,26,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0, + 9,5,9,9,9,5,5,9,5,9,5,9,5,9,9,9, + 0,5,9,5,5,9,5,5,5,5,5,5,5,6,0,0, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,5,26,26,26,26,26,26,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,21,21,21,21,15,21,21, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,0,0,0,0,0,0,0,0,0,6, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,0, + 7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,0, + 7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,0, + 7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,0, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 21,21,20,19,20,19,21,21,21,20,19,21,20,19,21,21, + 21,21,21,21,21,21,21,17,21,21,17,21,20,19,21,21, + 20,19,22,18,22,18,22,18,22,18,21,21,21,21,21,6, + 21,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,0,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0, + 29,21,21,21,26,6,7,14,22,18,22,18,22,18,22,18, + 22,18,26,26,22,18,22,18,22,18,22,18,17,22,18,18, + 26,14,14,14,14,14,14,14,14,14,12,12,12,12,12,12, + 17,6,6,6,6,6,26,26,14,14,14,6,7,21,26,26, + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,0,0,12,12,24,24,6,6,7, + 17,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,21,6,6,6,7, + 0,0,0,0,0,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0, + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0, + 26,26,15,15,15,15,26,26,26,26,26,26,26,26,26,26, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0, + 15,15,15,15,15,15,15,15,15,15,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,0,0,0,0,0,0,0,0,0,0,0,0, + 26,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 15,15,15,15,15,15,15,15,15,15,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 0}; +static const guint8 unicode_category_table1 [] = { + /* ==== 4DC0-4E00 ==== */ + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 0}; +static const guint8 unicode_category_table2 [] = { + /* ==== A000-AA80 ==== */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,6,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,6,21,21,21, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 13,13,13,13,13,13,13,13,13,13,7,7,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 0,0,9,5,9,5,9,5,9,5,9,5,9,5,7,12, + 11,11,11,21,0,0,0,0,0,0,0,0,12,12,21,6, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, + 24,24,24,24,24,24,24,6,6,6,6,6,6,6,6,6, + 24,24,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 5,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 9,5,9,5,9,5,9,5,9,5,9,5,9,5,9,5, + 6,5,5,5,5,5,5,5,5,9,5,9,5,9,9,5, + 9,5,9,5,9,5,9,5,6,24,24,9,5,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,7,7,7,7,7, + 7,7,12,7,7,7,12,7,7,7,7,12,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,10,10,12,12,10,26,26,26,26,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,21,21,21,21,0,0,0,0,0,0,0,0, + 10,10,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,10,10,10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,12,0,0,0,0,0,0,0,0,0,21,21, + 13,13,13,13,13,13,13,13,13,13,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 13,13,13,13,13,13,13,13,13,13,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,12,12,12,12,12,12,12,12,21,21, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,12,12,12,12,12,12,12,12,12, + 12,12,10,10,0,0,0,0,0,0,0,0,0,0,0,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,12,12,12,12,12,12,10, + 10,12,12,10,10,12,12,0,0,0,0,0,0,0,0,0, + 7,7,7,12,7,7,7,7,7,7,7,7,12,10,0,0, + 13,13,13,13,13,13,13,13,13,13,0,0,21,21,21,21, + 0}; +static const guint8 unicode_category_table3 [] = { + /* ==== F900-10000 ==== */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0, + 0,0,0,5,5,5,5,5,0,0,0,0,0,7,12,7, + 7,7,7,7,7,7,7,7,7,25,7,7,7,7,7,7, + 7,7,7,7,7,7,7,0,7,7,7,7,7,0,7,0, + 7,7,0,7,7,0,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,22,18, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 0,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,23,26,0,0, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 21,21,21,21,21,21,21,22,18,21,0,0,0,0,0,0, + 12,12,12,12,12,12,12,0,0,0,0,0,0,0,0,0, + 21,17,17,16,16,22,18,22,18,22,18,22,18,22,18,22, + 18,22,18,22,18,21,21,22,18,21,21,21,21,16,16,16, + 21,21,21,0,21,21,21,21,17,22,18,22,18,22,18,21, + 21,21,25,17,25,25,25,0,21,23,21,21,0,0,0,0, + 7,7,7,7,7,0,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,1, + 0,21,21,21,23,21,21,21,22,18,21,25,21,17,21,21, + 13,13,13,13,13,13,13,13,13,13,21,21,25,25,25,21, + 21,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,22,21,18,24,16, + 24,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,22,25,18,25,22, + 18,21,22,18,21,21,7,7,7,7,7,7,7,7,7,7, + 6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0, + 0,0,7,7,7,7,7,7,0,0,7,7,7,7,7,7, + 0,0,7,7,7,7,7,7,0,0,7,7,7,0,0,0, + 23,23,25,24,26,23,23,0,26,25,25,25,25,26,26,0, + 0,0,0,0,0,0,0,0,0,1,1,1,26,26,0}; +static const guint8 unicode_category_table4 [] = { + /* ==== 10000-104C0 ==== */ + 7,7,7,7,7,7,7,7,7,7,7,7,0,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,0,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,0,7,7,0,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, + 21,21,26,0,0,0,0,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,0,0,0,26,26,26,26,26,26,26,26,26, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,15,15,15,15,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,15,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,12,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0, + 15,15,15,15,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,14,7,7,7,7,7,7,7,7,14,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,21, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,0,0,0,0,7,7,7,7,7,7,7,7, + 21,14,14,14,14,14,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0, + 13,13,13,13,13,13,13,13,13,13,0}; +static const guint8 unicode_category_table5 [] = { + /* ==== 10800-10A80 ==== */ + 7,7,7,7,7,7,0,0,7,0,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,0,7,7,0,0,0,7,0,0,7, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,15,15,15,15,0,0,0,0,0,21, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,21, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 7,12,12,12,0,12,12,0,0,0,0,0,12,12,12,12, + 7,7,7,7,0,7,7,7,0,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,0,0,0,0,12,12,12,0,0,0,0,12, + 15,15,15,15,15,15,15,15,0,0,0,0,0,0,0,0, + 21,21,21,21,21,21,21,21,21,0}; +static const guint8 unicode_category_table6 [] = { + /* ==== 12000-12480 ==== */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,0,0,0,0,0,0,0,0,0,0,0,0,0, + 21,21,21,21,0}; +static const guint8 unicode_category_table7 [] = { + /* ==== 1D000-1D800 ==== */ + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,0,0,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,10,10,12,12,12,26,26,26,10,10,10, + 10,10,10,1,1,1,1,1,1,1,1,12,12,12,12,12, + 12,12,12,26,26,12,12,12,12,12,12,12,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,12,12,12,12,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,12,12,12,26,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,0,0,0,0,0,0,0,0,0, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,5,5, + 5,5,5,5,5,0,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,9,0,9,9, + 0,0,9,0,0,9,9,0,0,9,9,9,9,0,9,9, + 9,9,9,9,9,9,5,5,5,5,0,5,0,5,5,5, + 5,5,5,5,0,5,5,5,5,5,5,5,5,5,5,5, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,9,9,0,9,9,9,9,0,0,9,9,9, + 9,9,9,9,9,0,9,9,9,9,9,9,9,0,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,9,9,0,9,9,9,9,0, + 9,9,9,9,9,0,9,0,0,0,9,9,9,9,9,9, + 9,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,0,0,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,25,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,25,5,5,5,5, + 5,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,25,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,25,5,5,5,5,5,5,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,25,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,25, + 5,5,5,5,5,5,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,25, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,25,5,5,5,5,5,5, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,25,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,25,5,5,5,5,5,5,9,5,0,0,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 0}; +static const guint8 unicode_category_table8 [] = { + /* ==== 1F000-1F0C0 ==== */ + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,0,0,0,0, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,0}; +static const guint8 unicode_category_table9 [] = { + /* ==== 2F800-2FA40 ==== */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,0}; +static const guint8 unicode_category_table10 [] = { + /* ==== E0000-E0200 ==== */ + 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 0}; +static const guint8 *unicode_category [11] = { + unicode_category_table0, + unicode_category_table1, + unicode_category_table2, + unicode_category_table3, + unicode_category_table4, + unicode_category_table5, + unicode_category_table6, + unicode_category_table7, + unicode_category_table8, + unicode_category_table9, + unicode_category_table10 +}; + +static const guint8 simple_case_map_ranges_count = 9; +static const CodePointRange simple_case_map_ranges [] = { +{0x000040, 0x000600}, +{0x001000, 0x0010D0}, +{0x001D00, 0x002000}, +{0x002100, 0x0021C0}, +{0x002480, 0x002500}, +{0x002C00, 0x002D80}, +{0x00A640, 0x00A7C0}, +{0x00FF20, 0x00FF80}, +{0x010400, 0x010480}, +{0, 0}}; +static const guint16 simple_upper_case_mapping_lowarea_table0 [] = { + /* ==== 40-600 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0x39C,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, + 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0x178, + 0,0x100,0,0x102,0,0x104,0,0x106,0,0x108,0,0x10A,0,0x10C,0,0x10E, + 0,0x110,0,0x112,0,0x114,0,0x116,0,0x118,0,0x11A,0,0x11C,0,0x11E, + 0,0x120,0,0x122,0,0x124,0,0x126,0,0x128,0,0x12A,0,0x12C,0,0x12E, + 0,0x49,0,0x132,0,0x134,0,0x136,0,0,0x139,0,0x13B,0,0x13D,0, + 0x13F,0,0x141,0,0x143,0,0x145,0,0x147,0,0,0x14A,0,0x14C,0,0x14E, + 0,0x150,0,0x152,0,0x154,0,0x156,0,0x158,0,0x15A,0,0x15C,0,0x15E, + 0,0x160,0,0x162,0,0x164,0,0x166,0,0x168,0,0x16A,0,0x16C,0,0x16E, + 0,0x170,0,0x172,0,0x174,0,0x176,0,0,0x179,0,0x17B,0,0x17D,0x53, + 0x243,0,0,0x182,0,0x184,0,0,0x187,0,0,0,0x18B,0,0,0, + 0,0,0x191,0,0,0x1F6,0,0,0,0x198,0x23D,0,0,0,0x220,0, + 0,0x1A0,0,0x1A2,0,0x1A4,0,0,0x1A7,0,0,0,0,0x1AC,0,0, + 0x1AF,0,0,0,0x1B3,0,0x1B5,0,0,0x1B8,0,0,0,0x1BC,0,0x1F7, + 0,0,0,0,0,0x1C4,0x1C4,0,0x1C7,0x1C7,0,0x1CA,0x1CA,0,0x1CD,0, + 0x1CF,0,0x1D1,0,0x1D3,0,0x1D5,0,0x1D7,0,0x1D9,0,0x1DB,0x18E,0,0x1DE, + 0,0x1E0,0,0x1E2,0,0x1E4,0,0x1E6,0,0x1E8,0,0x1EA,0,0x1EC,0,0x1EE, + 0,0,0x1F1,0x1F1,0,0x1F4,0,0,0,0x1F8,0,0x1FA,0,0x1FC,0,0x1FE, + 0,0x200,0,0x202,0,0x204,0,0x206,0,0x208,0,0x20A,0,0x20C,0,0x20E, + 0,0x210,0,0x212,0,0x214,0,0x216,0,0x218,0,0x21A,0,0x21C,0,0x21E, + 0,0,0,0x222,0,0x224,0,0x226,0,0x228,0,0x22A,0,0x22C,0,0x22E, + 0,0x230,0,0x232,0,0,0,0,0,0,0,0,0x23B,0,0,0, + 0,0,0x241,0,0,0,0,0x246,0,0x248,0,0x24A,0,0x24C,0,0x24E, + 0x2C6F,0x2C6D,0,0x181,0x186,0,0x189,0x18A,0,0x18F,0,0x190,0,0,0,0, + 0x193,0,0,0x194,0,0,0,0,0x197,0x196,0,0x2C62,0,0,0,0x19C, + 0,0x2C6E,0x19D,0,0,0x19F,0,0,0,0,0,0,0,0x2C64,0,0, + 0x1A6,0,0,0x1A9,0,0,0,0,0x1AE,0x244,0x1B1,0x1B2,0x245,0,0,0, + 0,0,0x1B7,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0x399,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0x370,0,0x372,0,0,0,0x376,0,0,0,0x3FD,0x3FE,0x3FF,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0x386,0x388,0x389,0x38A, + 0,0x391,0x392,0x393,0x394,0x395,0x396,0x397,0x398,0x399,0x39A,0x39B,0x39C,0x39D,0x39E,0x39F, + 0x3A0,0x3A1,0x3A3,0x3A3,0x3A4,0x3A5,0x3A6,0x3A7,0x3A8,0x3A9,0x3AA,0x3AB,0x38C,0x38E,0x38F,0, + 0x392,0x398,0,0,0,0x3A6,0x3A0,0x3CF,0,0x3D8,0,0x3DA,0,0x3DC,0,0x3DE, + 0,0x3E0,0,0x3E2,0,0x3E4,0,0x3E6,0,0x3E8,0,0x3EA,0,0x3EC,0,0x3EE, + 0x39A,0x3A1,0x3F9,0,0,0x395,0,0,0x3F7,0,0,0x3FA,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x410,0x411,0x412,0x413,0x414,0x415,0x416,0x417,0x418,0x419,0x41A,0x41B,0x41C,0x41D,0x41E,0x41F, + 0x420,0x421,0x422,0x423,0x424,0x425,0x426,0x427,0x428,0x429,0x42A,0x42B,0x42C,0x42D,0x42E,0x42F, + 0x400,0x401,0x402,0x403,0x404,0x405,0x406,0x407,0x408,0x409,0x40A,0x40B,0x40C,0x40D,0x40E,0x40F, + 0,0x460,0,0x462,0,0x464,0,0x466,0,0x468,0,0x46A,0,0x46C,0,0x46E, + 0,0x470,0,0x472,0,0x474,0,0x476,0,0x478,0,0x47A,0,0x47C,0,0x47E, + 0,0x480,0,0,0,0,0,0,0,0,0,0x48A,0,0x48C,0,0x48E, + 0,0x490,0,0x492,0,0x494,0,0x496,0,0x498,0,0x49A,0,0x49C,0,0x49E, + 0,0x4A0,0,0x4A2,0,0x4A4,0,0x4A6,0,0x4A8,0,0x4AA,0,0x4AC,0,0x4AE, + 0,0x4B0,0,0x4B2,0,0x4B4,0,0x4B6,0,0x4B8,0,0x4BA,0,0x4BC,0,0x4BE, + 0,0,0x4C1,0,0x4C3,0,0x4C5,0,0x4C7,0,0x4C9,0,0x4CB,0,0x4CD,0x4C0, + 0,0x4D0,0,0x4D2,0,0x4D4,0,0x4D6,0,0x4D8,0,0x4DA,0,0x4DC,0,0x4DE, + 0,0x4E0,0,0x4E2,0,0x4E4,0,0x4E6,0,0x4E8,0,0x4EA,0,0x4EC,0,0x4EE, + 0,0x4F0,0,0x4F2,0,0x4F4,0,0x4F6,0,0x4F8,0,0x4FA,0,0x4FC,0,0x4FE, + 0,0x500,0,0x502,0,0x504,0,0x506,0,0x508,0,0x50A,0,0x50C,0,0x50E, + 0,0x510,0,0x512,0,0x514,0,0x516,0,0x518,0,0x51A,0,0x51C,0,0x51E, + 0,0x520,0,0x522,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0x531,0x532,0x533,0x534,0x535,0x536,0x537,0x538,0x539,0x53A,0x53B,0x53C,0x53D,0x53E,0x53F, + 0x540,0x541,0x542,0x543,0x544,0x545,0x546,0x547,0x548,0x549,0x54A,0x54B,0x54C,0x54D,0x54E,0x54F, + 0x550,0x551,0x552,0x553,0x554,0x555,0x556,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0}; +static const guint16 simple_upper_case_mapping_lowarea_table1 [] = { + /* ==== 1000-10D0 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0}; +static const guint16 simple_upper_case_mapping_lowarea_table2 [] = { + /* ==== 1D00-2000 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0xA77D,0,0,0,0x2C63,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0x1E00,0,0x1E02,0,0x1E04,0,0x1E06,0,0x1E08,0,0x1E0A,0,0x1E0C,0,0x1E0E, + 0,0x1E10,0,0x1E12,0,0x1E14,0,0x1E16,0,0x1E18,0,0x1E1A,0,0x1E1C,0,0x1E1E, + 0,0x1E20,0,0x1E22,0,0x1E24,0,0x1E26,0,0x1E28,0,0x1E2A,0,0x1E2C,0,0x1E2E, + 0,0x1E30,0,0x1E32,0,0x1E34,0,0x1E36,0,0x1E38,0,0x1E3A,0,0x1E3C,0,0x1E3E, + 0,0x1E40,0,0x1E42,0,0x1E44,0,0x1E46,0,0x1E48,0,0x1E4A,0,0x1E4C,0,0x1E4E, + 0,0x1E50,0,0x1E52,0,0x1E54,0,0x1E56,0,0x1E58,0,0x1E5A,0,0x1E5C,0,0x1E5E, + 0,0x1E60,0,0x1E62,0,0x1E64,0,0x1E66,0,0x1E68,0,0x1E6A,0,0x1E6C,0,0x1E6E, + 0,0x1E70,0,0x1E72,0,0x1E74,0,0x1E76,0,0x1E78,0,0x1E7A,0,0x1E7C,0,0x1E7E, + 0,0x1E80,0,0x1E82,0,0x1E84,0,0x1E86,0,0x1E88,0,0x1E8A,0,0x1E8C,0,0x1E8E, + 0,0x1E90,0,0x1E92,0,0x1E94,0,0,0,0,0,0x1E60,0,0,0,0, + 0,0x1EA0,0,0x1EA2,0,0x1EA4,0,0x1EA6,0,0x1EA8,0,0x1EAA,0,0x1EAC,0,0x1EAE, + 0,0x1EB0,0,0x1EB2,0,0x1EB4,0,0x1EB6,0,0x1EB8,0,0x1EBA,0,0x1EBC,0,0x1EBE, + 0,0x1EC0,0,0x1EC2,0,0x1EC4,0,0x1EC6,0,0x1EC8,0,0x1ECA,0,0x1ECC,0,0x1ECE, + 0,0x1ED0,0,0x1ED2,0,0x1ED4,0,0x1ED6,0,0x1ED8,0,0x1EDA,0,0x1EDC,0,0x1EDE, + 0,0x1EE0,0,0x1EE2,0,0x1EE4,0,0x1EE6,0,0x1EE8,0,0x1EEA,0,0x1EEC,0,0x1EEE, + 0,0x1EF0,0,0x1EF2,0,0x1EF4,0,0x1EF6,0,0x1EF8,0,0x1EFA,0,0x1EFC,0,0x1EFE, + 0x1F08,0x1F09,0x1F0A,0x1F0B,0x1F0C,0x1F0D,0x1F0E,0x1F0F,0,0,0,0,0,0,0,0, + 0x1F18,0x1F19,0x1F1A,0x1F1B,0x1F1C,0x1F1D,0,0,0,0,0,0,0,0,0,0, +0x1F28,0x1F29,0x1F2A,0x1F2B,0x1F2C,0x1F2D,0x1F2E,0x1F2F,0,0,0,0,0,0,0,0, + 0x1F38,0x1F39,0x1F3A,0x1F3B,0x1F3C,0x1F3D,0x1F3E,0x1F3F,0,0,0,0,0,0,0,0, + 0x1F48,0x1F49,0x1F4A,0x1F4B,0x1F4C,0x1F4D,0,0,0,0,0,0,0,0,0,0, +0,0x1F59,0,0x1F5B,0,0x1F5D,0,0x1F5F,0,0,0,0,0,0,0,0, + 0x1F68,0x1F69,0x1F6A,0x1F6B,0x1F6C,0x1F6D,0x1F6E,0x1F6F,0,0,0,0,0,0,0,0, + 0x1FBA,0x1FBB,0x1FC8,0x1FC9,0x1FCA,0x1FCB,0x1FDA,0x1FDB,0x1FF8,0x1FF9,0x1FEA,0x1FEB,0x1FFA,0x1FFB,0,0, +0x1F88,0x1F89,0x1F8A,0x1F8B,0x1F8C,0x1F8D,0x1F8E,0x1F8F,0,0,0,0,0,0,0,0, + 0x1F98,0x1F99,0x1F9A,0x1F9B,0x1F9C,0x1F9D,0x1F9E,0x1F9F,0,0,0,0,0,0,0,0, + 0x1FA8,0x1FA9,0x1FAA,0x1FAB,0x1FAC,0x1FAD,0x1FAE,0x1FAF,0,0,0,0,0,0,0,0, + 0x1FB8,0x1FB9,0,0x1FBC,0,0,0,0,0,0,0,0,0,0,0x399,0, + 0,0,0,0x1FCC,0,0,0,0,0,0,0,0,0,0,0,0, + 0x1FD8,0x1FD9,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x1FE8,0x1FE9,0,0,0,0x1FEC,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0x1FFC,0,0,0,0,0,0,0,0,0,0,0,0}; +static const guint16 simple_upper_case_mapping_lowarea_table3 [] = { + /* ==== 2100-21C0 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x2132,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,0x2168,0x2169,0x216A,0x216B,0x216C,0x216D,0x216E,0x216F, + 0,0,0,0,0x2183,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 simple_upper_case_mapping_lowarea_table4 [] = { + /* ==== 2480-2500 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x24B6,0x24B7,0x24B8,0x24B9,0x24BA,0x24BB,0x24BC,0x24BD,0x24BE,0x24BF,0x24C0,0x24C1,0x24C2,0x24C3,0x24C4,0x24C5, + 0x24C6,0x24C7,0x24C8,0x24C9,0x24CA,0x24CB,0x24CC,0x24CD,0x24CE,0x24CF,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 simple_upper_case_mapping_lowarea_table5 [] = { + /* ==== 2C00-2D80 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0x2C00,0x2C01,0x2C02,0x2C03,0x2C04,0x2C05,0x2C06,0x2C07,0x2C08,0x2C09,0x2C0A,0x2C0B,0x2C0C,0x2C0D,0x2C0E,0x2C0F, + 0x2C10,0x2C11,0x2C12,0x2C13,0x2C14,0x2C15,0x2C16,0x2C17,0x2C18,0x2C19,0x2C1A,0x2C1B,0x2C1C,0x2C1D,0x2C1E,0x2C1F, + 0x2C20,0x2C21,0x2C22,0x2C23,0x2C24,0x2C25,0x2C26,0x2C27,0x2C28,0x2C29,0x2C2A,0x2C2B,0x2C2C,0x2C2D,0x2C2E,0, +0,0x2C60,0,0,0,0x23A,0x23E,0,0x2C67,0,0x2C69,0,0x2C6B,0,0,0, + 0,0,0,0x2C72,0,0,0x2C75,0,0,0,0,0,0,0,0,0, +0,0x2C80,0,0x2C82,0,0x2C84,0,0x2C86,0,0x2C88,0,0x2C8A,0,0x2C8C,0,0x2C8E, + 0,0x2C90,0,0x2C92,0,0x2C94,0,0x2C96,0,0x2C98,0,0x2C9A,0,0x2C9C,0,0x2C9E, + 0,0x2CA0,0,0x2CA2,0,0x2CA4,0,0x2CA6,0,0x2CA8,0,0x2CAA,0,0x2CAC,0,0x2CAE, + 0,0x2CB0,0,0x2CB2,0,0x2CB4,0,0x2CB6,0,0x2CB8,0,0x2CBA,0,0x2CBC,0,0x2CBE, + 0,0x2CC0,0,0x2CC2,0,0x2CC4,0,0x2CC6,0,0x2CC8,0,0x2CCA,0,0x2CCC,0,0x2CCE, + 0,0x2CD0,0,0x2CD2,0,0x2CD4,0,0x2CD6,0,0x2CD8,0,0x2CDA,0,0x2CDC,0,0x2CDE, + 0,0x2CE0,0,0x2CE2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x10A0,0x10A1,0x10A2,0x10A3,0x10A4,0x10A5,0x10A6,0x10A7,0x10A8,0x10A9,0x10AA,0x10AB,0x10AC,0x10AD,0x10AE,0x10AF, + 0x10B0,0x10B1,0x10B2,0x10B3,0x10B4,0x10B5,0x10B6,0x10B7,0x10B8,0x10B9,0x10BA,0x10BB,0x10BC,0x10BD,0x10BE,0x10BF, + 0x10C0,0x10C1,0x10C2,0x10C3,0x10C4,0x10C5,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 simple_upper_case_mapping_lowarea_table6 [] = { + /* ==== A640-A7C0 ==== */ + 0,0xA640,0,0xA642,0,0xA644,0,0xA646,0,0xA648,0,0xA64A,0,0xA64C,0,0xA64E, + 0,0xA650,0,0xA652,0,0xA654,0,0xA656,0,0xA658,0,0xA65A,0,0xA65C,0,0xA65E, + 0,0,0,0xA662,0,0xA664,0,0xA666,0,0xA668,0,0xA66A,0,0xA66C,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0xA680,0,0xA682,0,0xA684,0,0xA686,0,0xA688,0,0xA68A,0,0xA68C,0,0xA68E, + 0,0xA690,0,0xA692,0,0xA694,0,0xA696,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0xA722,0,0xA724,0,0xA726,0,0xA728,0,0xA72A,0,0xA72C,0,0xA72E, + 0,0,0,0xA732,0,0xA734,0,0xA736,0,0xA738,0,0xA73A,0,0xA73C,0,0xA73E, + 0,0xA740,0,0xA742,0,0xA744,0,0xA746,0,0xA748,0,0xA74A,0,0xA74C,0,0xA74E, + 0,0xA750,0,0xA752,0,0xA754,0,0xA756,0,0xA758,0,0xA75A,0,0xA75C,0,0xA75E, + 0,0xA760,0,0xA762,0,0xA764,0,0xA766,0,0xA768,0,0xA76A,0,0xA76C,0,0xA76E, + 0,0,0,0,0,0,0,0,0,0,0xA779,0,0xA77B,0,0,0xA77E, + 0,0xA780,0,0xA782,0,0xA784,0,0xA786,0,0,0,0,0xA78B,0}; +static const guint16 simple_upper_case_mapping_lowarea_table7 [] = { + /* ==== FF20-FF80 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0xFF21,0xFF22,0xFF23,0xFF24,0xFF25,0xFF26,0xFF27,0xFF28,0xFF29,0xFF2A,0xFF2B,0xFF2C,0xFF2D,0xFF2E,0xFF2F, + 0xFF30,0xFF31,0xFF32,0xFF33,0xFF34,0xFF35,0xFF36,0xFF37,0xFF38,0xFF39,0xFF3A,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 *simple_upper_case_mapping_lowarea [] = { + simple_upper_case_mapping_lowarea_table0, + simple_upper_case_mapping_lowarea_table1, + simple_upper_case_mapping_lowarea_table2, + simple_upper_case_mapping_lowarea_table3, + simple_upper_case_mapping_lowarea_table4, + simple_upper_case_mapping_lowarea_table5, + simple_upper_case_mapping_lowarea_table6, + simple_upper_case_mapping_lowarea_table7}; +static const int simple_upper_case_mapping_lowarea_table_count = 8; + +static const guint32 simple_upper_case_mapping_higharea_table0 [] = { + /* ==== 10400-10480 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0x10400,0x10401,0x10402,0x10403,0x10404,0x10405,0x10406,0x10407, + 0x10408,0x10409,0x1040A,0x1040B,0x1040C,0x1040D,0x1040E,0x1040F,0x10410,0x10411,0x10412,0x10413,0x10414,0x10415,0x10416,0x10417, + 0x10418,0x10419,0x1041A,0x1041B,0x1041C,0x1041D,0x1041E,0x1041F,0x10420,0x10421,0x10422,0x10423,0x10424,0x10425,0x10426,0x10427, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint32 *simple_upper_case_mapping_higharea [] = { + simple_upper_case_mapping_higharea_table0}; + +static const guint16 simple_lower_case_mapping_lowarea_table0 [] = { + /* ==== 40-600 ==== */ + 0,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x101,0,0x103,0,0x105,0,0x107,0,0x109,0,0x10B,0,0x10D,0,0x10F,0, + 0x111,0,0x113,0,0x115,0,0x117,0,0x119,0,0x11B,0,0x11D,0,0x11F,0, + 0x121,0,0x123,0,0x125,0,0x127,0,0x129,0,0x12B,0,0x12D,0,0x12F,0, + 0x69,0,0x133,0,0x135,0,0x137,0,0,0x13A,0,0x13C,0,0x13E,0,0x140, + 0,0x142,0,0x144,0,0x146,0,0x148,0,0,0x14B,0,0x14D,0,0x14F,0, + 0x151,0,0x153,0,0x155,0,0x157,0,0x159,0,0x15B,0,0x15D,0,0x15F,0, + 0x161,0,0x163,0,0x165,0,0x167,0,0x169,0,0x16B,0,0x16D,0,0x16F,0, + 0x171,0,0x173,0,0x175,0,0x177,0,0xFF,0x17A,0,0x17C,0,0x17E,0,0, + 0,0x253,0x183,0,0x185,0,0x254,0x188,0,0x256,0x257,0x18C,0,0,0x1DD,0x259, + 0x25B,0x192,0,0x260,0x263,0,0x269,0x268,0x199,0,0,0,0x26F,0x272,0,0x275, + 0x1A1,0,0x1A3,0,0x1A5,0,0x280,0x1A8,0,0x283,0,0,0x1AD,0,0x288,0x1B0, + 0,0x28A,0x28B,0x1B4,0,0x1B6,0,0x292,0x1B9,0,0,0,0x1BD,0,0,0, + 0,0,0,0,0x1C6,0x1C6,0,0x1C9,0x1C9,0,0x1CC,0x1CC,0,0x1CE,0,0x1D0, + 0,0x1D2,0,0x1D4,0,0x1D6,0,0x1D8,0,0x1DA,0,0x1DC,0,0,0x1DF,0, + 0x1E1,0,0x1E3,0,0x1E5,0,0x1E7,0,0x1E9,0,0x1EB,0,0x1ED,0,0x1EF,0, + 0,0x1F3,0x1F3,0,0x1F5,0,0x195,0x1BF,0x1F9,0,0x1FB,0,0x1FD,0,0x1FF,0, + 0x201,0,0x203,0,0x205,0,0x207,0,0x209,0,0x20B,0,0x20D,0,0x20F,0, + 0x211,0,0x213,0,0x215,0,0x217,0,0x219,0,0x21B,0,0x21D,0,0x21F,0, + 0x19E,0,0x223,0,0x225,0,0x227,0,0x229,0,0x22B,0,0x22D,0,0x22F,0, + 0x231,0,0x233,0,0,0,0,0,0,0,0x2C65,0x23C,0,0x19A,0x2C66,0, + 0,0x242,0,0x180,0x289,0x28C,0x247,0,0x249,0,0x24B,0,0x24D,0,0x24F,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x371,0,0x373,0,0,0,0x377,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0x3AC,0,0x3AD,0x3AE,0x3AF,0,0x3CC,0,0x3CD,0x3CE, + 0,0x3B1,0x3B2,0x3B3,0x3B4,0x3B5,0x3B6,0x3B7,0x3B8,0x3B9,0x3BA,0x3BB,0x3BC,0x3BD,0x3BE,0x3BF, + 0x3C0,0x3C1,0,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CA,0x3CB,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x3D7, + 0,0,0,0,0,0,0,0,0x3D9,0,0x3DB,0,0x3DD,0,0x3DF,0, + 0x3E1,0,0x3E3,0,0x3E5,0,0x3E7,0,0x3E9,0,0x3EB,0,0x3ED,0,0x3EF,0, + 0,0,0,0,0x3B8,0,0,0x3F8,0,0x3F2,0x3FB,0,0,0x37B,0x37C,0x37D, + 0x450,0x451,0x452,0x453,0x454,0x455,0x456,0x457,0x458,0x459,0x45A,0x45B,0x45C,0x45D,0x45E,0x45F, + 0x430,0x431,0x432,0x433,0x434,0x435,0x436,0x437,0x438,0x439,0x43A,0x43B,0x43C,0x43D,0x43E,0x43F, + 0x440,0x441,0x442,0x443,0x444,0x445,0x446,0x447,0x448,0x449,0x44A,0x44B,0x44C,0x44D,0x44E,0x44F, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x461,0,0x463,0,0x465,0,0x467,0,0x469,0,0x46B,0,0x46D,0,0x46F,0, + 0x471,0,0x473,0,0x475,0,0x477,0,0x479,0,0x47B,0,0x47D,0,0x47F,0, + 0x481,0,0,0,0,0,0,0,0,0,0x48B,0,0x48D,0,0x48F,0, + 0x491,0,0x493,0,0x495,0,0x497,0,0x499,0,0x49B,0,0x49D,0,0x49F,0, + 0x4A1,0,0x4A3,0,0x4A5,0,0x4A7,0,0x4A9,0,0x4AB,0,0x4AD,0,0x4AF,0, + 0x4B1,0,0x4B3,0,0x4B5,0,0x4B7,0,0x4B9,0,0x4BB,0,0x4BD,0,0x4BF,0, + 0x4CF,0x4C2,0,0x4C4,0,0x4C6,0,0x4C8,0,0x4CA,0,0x4CC,0,0x4CE,0,0, + 0x4D1,0,0x4D3,0,0x4D5,0,0x4D7,0,0x4D9,0,0x4DB,0,0x4DD,0,0x4DF,0, + 0x4E1,0,0x4E3,0,0x4E5,0,0x4E7,0,0x4E9,0,0x4EB,0,0x4ED,0,0x4EF,0, + 0x4F1,0,0x4F3,0,0x4F5,0,0x4F7,0,0x4F9,0,0x4FB,0,0x4FD,0,0x4FF,0, + 0x501,0,0x503,0,0x505,0,0x507,0,0x509,0,0x50B,0,0x50D,0,0x50F,0, + 0x511,0,0x513,0,0x515,0,0x517,0,0x519,0,0x51B,0,0x51D,0,0x51F,0, + 0x521,0,0x523,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0x561,0x562,0x563,0x564,0x565,0x566,0x567,0x568,0x569,0x56A,0x56B,0x56C,0x56D,0x56E,0x56F, + 0x570,0x571,0x572,0x573,0x574,0x575,0x576,0x577,0x578,0x579,0x57A,0x57B,0x57C,0x57D,0x57E,0x57F, + 0x580,0x581,0x582,0x583,0x584,0x585,0x586,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0}; +static const guint16 simple_lower_case_mapping_lowarea_table1 [] = { + /* ==== 1000-10D0 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x2D00,0x2D01,0x2D02,0x2D03,0x2D04,0x2D05,0x2D06,0x2D07,0x2D08,0x2D09,0x2D0A,0x2D0B,0x2D0C,0x2D0D,0x2D0E,0x2D0F, + 0x2D10,0x2D11,0x2D12,0x2D13,0x2D14,0x2D15,0x2D16,0x2D17,0x2D18,0x2D19,0x2D1A,0x2D1B,0x2D1C,0x2D1D,0x2D1E,0x2D1F, + 0x2D20,0x2D21,0x2D22,0x2D23,0x2D24,0x2D25,0}; +static const guint16 simple_lower_case_mapping_lowarea_table2 [] = { + /* ==== 1D00-2000 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x1E01,0,0x1E03,0,0x1E05,0,0x1E07,0,0x1E09,0,0x1E0B,0,0x1E0D,0,0x1E0F,0, + 0x1E11,0,0x1E13,0,0x1E15,0,0x1E17,0,0x1E19,0,0x1E1B,0,0x1E1D,0,0x1E1F,0, + 0x1E21,0,0x1E23,0,0x1E25,0,0x1E27,0,0x1E29,0,0x1E2B,0,0x1E2D,0,0x1E2F,0, + 0x1E31,0,0x1E33,0,0x1E35,0,0x1E37,0,0x1E39,0,0x1E3B,0,0x1E3D,0,0x1E3F,0, + 0x1E41,0,0x1E43,0,0x1E45,0,0x1E47,0,0x1E49,0,0x1E4B,0,0x1E4D,0,0x1E4F,0, + 0x1E51,0,0x1E53,0,0x1E55,0,0x1E57,0,0x1E59,0,0x1E5B,0,0x1E5D,0,0x1E5F,0, + 0x1E61,0,0x1E63,0,0x1E65,0,0x1E67,0,0x1E69,0,0x1E6B,0,0x1E6D,0,0x1E6F,0, + 0x1E71,0,0x1E73,0,0x1E75,0,0x1E77,0,0x1E79,0,0x1E7B,0,0x1E7D,0,0x1E7F,0, + 0x1E81,0,0x1E83,0,0x1E85,0,0x1E87,0,0x1E89,0,0x1E8B,0,0x1E8D,0,0x1E8F,0, + 0x1E91,0,0x1E93,0,0x1E95,0,0,0,0,0,0,0,0,0,0xDF,0, + 0x1EA1,0,0x1EA3,0,0x1EA5,0,0x1EA7,0,0x1EA9,0,0x1EAB,0,0x1EAD,0,0x1EAF,0, + 0x1EB1,0,0x1EB3,0,0x1EB5,0,0x1EB7,0,0x1EB9,0,0x1EBB,0,0x1EBD,0,0x1EBF,0, + 0x1EC1,0,0x1EC3,0,0x1EC5,0,0x1EC7,0,0x1EC9,0,0x1ECB,0,0x1ECD,0,0x1ECF,0, + 0x1ED1,0,0x1ED3,0,0x1ED5,0,0x1ED7,0,0x1ED9,0,0x1EDB,0,0x1EDD,0,0x1EDF,0, + 0x1EE1,0,0x1EE3,0,0x1EE5,0,0x1EE7,0,0x1EE9,0,0x1EEB,0,0x1EED,0,0x1EEF,0, + 0x1EF1,0,0x1EF3,0,0x1EF5,0,0x1EF7,0,0x1EF9,0,0x1EFB,0,0x1EFD,0,0x1EFF,0, + 0,0,0,0,0,0,0,0,0x1F00,0x1F01,0x1F02,0x1F03,0x1F04,0x1F05,0x1F06,0x1F07, + 0,0,0,0,0,0,0,0,0x1F10,0x1F11,0x1F12,0x1F13,0x1F14,0x1F15,0,0, +0,0,0,0,0,0,0,0,0x1F20,0x1F21,0x1F22,0x1F23,0x1F24,0x1F25,0x1F26,0x1F27, + 0,0,0,0,0,0,0,0,0x1F30,0x1F31,0x1F32,0x1F33,0x1F34,0x1F35,0x1F36,0x1F37, + 0,0,0,0,0,0,0,0,0x1F40,0x1F41,0x1F42,0x1F43,0x1F44,0x1F45,0,0, +0,0,0,0,0,0,0,0,0,0x1F51,0,0x1F53,0,0x1F55,0,0x1F57, + 0,0,0,0,0,0,0,0,0x1F60,0x1F61,0x1F62,0x1F63,0x1F64,0x1F65,0x1F66,0x1F67, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0x1F80,0x1F81,0x1F82,0x1F83,0x1F84,0x1F85,0x1F86,0x1F87, + 0,0,0,0,0,0,0,0,0x1F90,0x1F91,0x1F92,0x1F93,0x1F94,0x1F95,0x1F96,0x1F97, + 0,0,0,0,0,0,0,0,0x1FA0,0x1FA1,0x1FA2,0x1FA3,0x1FA4,0x1FA5,0x1FA6,0x1FA7, + 0,0,0,0,0,0,0,0,0x1FB0,0x1FB1,0x1F70,0x1F71,0x1FB3,0,0,0, + 0,0,0,0,0,0,0,0,0x1F72,0x1F73,0x1F74,0x1F75,0x1FC3,0,0,0, + 0,0,0,0,0,0,0,0,0x1FD0,0x1FD1,0x1F76,0x1F77,0,0,0,0, + 0,0,0,0,0,0,0,0,0x1FE0,0x1FE1,0x1F7A,0x1F7B,0x1FE5,0,0,0, + 0,0,0,0,0,0,0,0,0x1F78,0x1F79,0x1F7C,0x1F7D,0x1FF3,0,0,0}; +static const guint16 simple_lower_case_mapping_lowarea_table3 [] = { + /* ==== 2100-21C0 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0x3C9,0,0,0,0x6B,0xE5,0,0,0,0, + 0,0,0x214E,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,0x2178,0x2179,0x217A,0x217B,0x217C,0x217D,0x217E,0x217F, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0x2184,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 simple_lower_case_mapping_lowarea_table4 [] = { + /* ==== 2480-2500 ==== */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0x24D0,0x24D1,0x24D2,0x24D3,0x24D4,0x24D5,0x24D6,0x24D7,0x24D8,0x24D9, + 0x24DA,0x24DB,0x24DC,0x24DD,0x24DE,0x24DF,0x24E0,0x24E1,0x24E2,0x24E3,0x24E4,0x24E5,0x24E6,0x24E7,0x24E8,0x24E9, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 simple_lower_case_mapping_lowarea_table5 [] = { + /* ==== 2C00-2D80 ==== */ + 0x2C30,0x2C31,0x2C32,0x2C33,0x2C34,0x2C35,0x2C36,0x2C37,0x2C38,0x2C39,0x2C3A,0x2C3B,0x2C3C,0x2C3D,0x2C3E,0x2C3F, + 0x2C40,0x2C41,0x2C42,0x2C43,0x2C44,0x2C45,0x2C46,0x2C47,0x2C48,0x2C49,0x2C4A,0x2C4B,0x2C4C,0x2C4D,0x2C4E,0x2C4F, + 0x2C50,0x2C51,0x2C52,0x2C53,0x2C54,0x2C55,0x2C56,0x2C57,0x2C58,0x2C59,0x2C5A,0x2C5B,0x2C5C,0x2C5D,0x2C5E,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0x2C61,0,0x26B,0x1D7D,0x27D,0,0,0x2C68,0,0x2C6A,0,0x2C6C,0,0x251,0x271,0x250, + 0,0,0x2C73,0,0,0x2C76,0,0,0,0,0,0,0,0,0,0, +0x2C81,0,0x2C83,0,0x2C85,0,0x2C87,0,0x2C89,0,0x2C8B,0,0x2C8D,0,0x2C8F,0, + 0x2C91,0,0x2C93,0,0x2C95,0,0x2C97,0,0x2C99,0,0x2C9B,0,0x2C9D,0,0x2C9F,0, + 0x2CA1,0,0x2CA3,0,0x2CA5,0,0x2CA7,0,0x2CA9,0,0x2CAB,0,0x2CAD,0,0x2CAF,0, + 0x2CB1,0,0x2CB3,0,0x2CB5,0,0x2CB7,0,0x2CB9,0,0x2CBB,0,0x2CBD,0,0x2CBF,0, + 0x2CC1,0,0x2CC3,0,0x2CC5,0,0x2CC7,0,0x2CC9,0,0x2CCB,0,0x2CCD,0,0x2CCF,0, + 0x2CD1,0,0x2CD3,0,0x2CD5,0,0x2CD7,0,0x2CD9,0,0x2CDB,0,0x2CDD,0,0x2CDF,0, + 0x2CE1,0,0x2CE3,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 simple_lower_case_mapping_lowarea_table6 [] = { + /* ==== A640-A7C0 ==== */ + 0xA641,0,0xA643,0,0xA645,0,0xA647,0,0xA649,0,0xA64B,0,0xA64D,0,0xA64F,0, + 0xA651,0,0xA653,0,0xA655,0,0xA657,0,0xA659,0,0xA65B,0,0xA65D,0,0xA65F,0, + 0,0,0xA663,0,0xA665,0,0xA667,0,0xA669,0,0xA66B,0,0xA66D,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0xA681,0,0xA683,0,0xA685,0,0xA687,0,0xA689,0,0xA68B,0,0xA68D,0,0xA68F,0, + 0xA691,0,0xA693,0,0xA695,0,0xA697,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0xA723,0,0xA725,0,0xA727,0,0xA729,0,0xA72B,0,0xA72D,0,0xA72F,0, + 0,0,0xA733,0,0xA735,0,0xA737,0,0xA739,0,0xA73B,0,0xA73D,0,0xA73F,0, + 0xA741,0,0xA743,0,0xA745,0,0xA747,0,0xA749,0,0xA74B,0,0xA74D,0,0xA74F,0, + 0xA751,0,0xA753,0,0xA755,0,0xA757,0,0xA759,0,0xA75B,0,0xA75D,0,0xA75F,0, + 0xA761,0,0xA763,0,0xA765,0,0xA767,0,0xA769,0,0xA76B,0,0xA76D,0,0xA76F,0, + 0,0,0,0,0,0,0,0,0,0xA77A,0,0xA77C,0,0x1D79,0xA77F,0, + 0xA781,0,0xA783,0,0xA785,0,0xA787,0,0,0,0,0xA78C,0,0}; +static const guint16 simple_lower_case_mapping_lowarea_table7 [] = { + /* ==== FF20-FF80 ==== */ + 0,0xFF41,0xFF42,0xFF43,0xFF44,0xFF45,0xFF46,0xFF47,0xFF48,0xFF49,0xFF4A,0xFF4B,0xFF4C,0xFF4D,0xFF4E,0xFF4F, + 0xFF50,0xFF51,0xFF52,0xFF53,0xFF54,0xFF55,0xFF56,0xFF57,0xFF58,0xFF59,0xFF5A,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint16 *simple_lower_case_mapping_lowarea [] = { + simple_lower_case_mapping_lowarea_table0, + simple_lower_case_mapping_lowarea_table1, + simple_lower_case_mapping_lowarea_table2, + simple_lower_case_mapping_lowarea_table3, + simple_lower_case_mapping_lowarea_table4, + simple_lower_case_mapping_lowarea_table5, + simple_lower_case_mapping_lowarea_table6, + simple_lower_case_mapping_lowarea_table7}; +static const int simple_lower_case_mapping_lowarea_table_count = 8; + +static const guint32 simple_lower_case_mapping_higharea_table0 [] = { + /* ==== 10400-10480 ==== */ + 0x10428,0x10429,0x1042A,0x1042B,0x1042C,0x1042D,0x1042E,0x1042F,0x10430,0x10431,0x10432,0x10433,0x10434,0x10435,0x10436,0x10437, + 0x10438,0x10439,0x1043A,0x1043B,0x1043C,0x1043D,0x1043E,0x1043F,0x10440,0x10441,0x10442,0x10443,0x10444,0x10445,0x10446,0x10447, + 0x10448,0x10449,0x1044A,0x1044B,0x1044C,0x1044D,0x1044E,0x1044F,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0}; +static const guint32 *simple_lower_case_mapping_higharea [] = { + simple_lower_case_mapping_higharea_table0}; + + +static const SimpleTitlecaseMapping simple_titlecase_mapping [] = { + {0x0001C4, 0x000000, 0x0001C5}, + {0x0001C5, 0x0001C4, 0x0001C5}, + {0x0001C6, 0x0001C4, 0x0001C5}, + {0x0001C7, 0x000000, 0x0001C8}, + {0x0001C8, 0x0001C7, 0x0001C8}, + {0x0001C9, 0x0001C7, 0x0001C8}, + {0x0001CA, 0x000000, 0x0001CB}, + {0x0001CB, 0x0001CA, 0x0001CB}, + {0x0001CC, 0x0001CA, 0x0001CB}, + {0x0001F1, 0x000000, 0x0001F2}, + {0x0001F2, 0x0001F1, 0x0001F2}, + {0x0001F3, 0x0001F1, 0x0001F2} +}; +static const guint8 simple_titlecase_mapping_count = 12; + +#endif + diff --git a/deps/eglib/src/vasprintf.c b/deps/eglib/src/vasprintf.c new file mode 100644 index 00000000..297afbe0 --- /dev/null +++ b/deps/eglib/src/vasprintf.c @@ -0,0 +1,34 @@ +#include <stdarg.h> + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +int vasprintf(char **ret, const char *fmt, va_list ap) +{ + char *buf; + int len; + size_t buflen; + va_list ap2; + +#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) + ap2 = ap; + len = _vscprintf(fmt, ap2); // NOTE MS specific extension ( :-( ) +#else + va_copy(ap2, ap); + len = vsnprintf(NULL, 0, fmt, ap2); +#endif + + if (len >= 0 && (buf = malloc ((buflen = (size_t) (len + 1)))) != NULL) { + len = vsnprintf(buf, buflen, fmt, ap); + *ret = buf; + } else { + *ret = NULL; + len = -1; + } + + va_end(ap2); + return len; +} + diff --git a/deps/eglib/test/.gitignore b/deps/eglib/test/.gitignore new file mode 100644 index 00000000..2d669e10 --- /dev/null +++ b/deps/eglib/test/.gitignore @@ -0,0 +1,12 @@ +/Makefile +/Makefile.in +/.libs +/.deps +/*.lo +/*.la +/*.o +/semantic.cache +/.project +/.cproject +/test-eglib +/test-glib diff --git a/deps/eglib/test/Makefile.am b/deps/eglib/test/Makefile.am new file mode 100644 index 00000000..14aa233e --- /dev/null +++ b/deps/eglib/test/Makefile.am @@ -0,0 +1,51 @@ +EXTRA_DIST = UTF-8.txt UTF-16BE.txt UTF-16LE.txt UTF-32BE.txt UTF-32LE.txt + +SOURCES = \ + test.c \ + test.h \ + tests.h \ + driver.c \ + hashtable.c \ + string-util.c \ + string.c \ + slist.c \ + sizes.c \ + ptrarray.c \ + list.c \ + array.c \ + fake.c \ + path.c \ + queue.c \ + shell.c \ + spawn.c \ + timer.c \ + file.c \ + pattern.c \ + dir.c \ + markup.c \ + unicode.c \ + utf8.c \ + endian.c \ + module.c \ + memory.c + +AM_CPPFLAGS = \ + -I$(top_builddir) \ + -I$(top_srcdir) \ + -I$(srcdir) \ + -Wall \ + $(NULL) + +test_eglib_SOURCES = $(SOURCES) + +test_eglib_CFLAGS = -DEGLIB_TESTS=1 -I$(srcdir)/../src -I../src -DDRIVER_NAME=\"EGlib\" +test_eglib_LDADD = ../src/libeglib.la $(LIBICONV) + +run-eglib: all + srcdir=`readlink -f $(srcdir)` ./test-eglib + +noinst_PROGRAMS = test-eglib + +run-both: run-eglib + +MAINTAINERCLEANFILES = Makefile.in diff --git a/deps/eglib/test/README b/deps/eglib/test/README new file mode 100644 index 00000000..7c28d03e --- /dev/null +++ b/deps/eglib/test/README @@ -0,0 +1,113 @@ +EGlib Unit Testing +=============================================================================== + + 1. Writing new tests + 2. Using the test driver + +=============================================================================== +1. Writing new tests +=============================================================================== + +Tests are easy to write, but must be grouped in to logical cases. For instance, +the GPtrArray group has a number of tests that cover the entire GPtrArray +implementation. + +These logical case groups should be in a single C file, and must have +three elements: + + #include <glib.h> + #include "test.h" + + ... + <define test implementations> + ... + + static Test groupname_tests [] = { + {"groupname_test1", groupname_test1}, + {"groupname_test1", groupname_test2}, + {NULL, NULL} + }; + + DEFINE_TEST_GROUP_INIT(groupname_tests_init, groupname_tests) + +A test implementation should look like: + + RESULT groupname_test1() + { + <perform the test> + + if(test_failed) { + return FAILED("reason: %s", "this works like printf"); + } + + return OK; /* just NULL, but OK is cute */ + } + +Once a test group is written, it needs to be added to the groups table +in tests.h: + + DEFINE_TEST_GROUP_INIT_H(groupname_tests_init) // same as in impl + + static Group test_groups [] = { + ... + {"groupname", groupname_tests_init} + ... + }; + +=============================================================================== +2. Using the test driver +=============================================================================== + +When tests are written, they are rebuilt with make. Two programs will be +built: + + test-eglib: the test driver and tests linked against eglib + test-glib: the test driver and tests linked against system glib-2.0 + +Each driver program works exactly the same. Running test-eglib will run +the tests against eglib, and test-glib against glib-2.0. + +The test driver supports a few options to allow for performance measuring: + + --help show all options and available test groups + --time time the overall run and report it, even if --quiet is set + --quiet do not print test results, useful for timing + --iterations N run all or specified test groups N times + +Run "test-eglib --help" for more details. + +Example: run the ptrarray test group 100000 times and only print the time + it took to perform all iterations + + ./test-eglib -tqi 100000 ptrarray + +Example: show single iteration of test output for two groups + + ./test-eglib ptrarray hashtable + +Example: show test output of all available groups + + ./test-eglib + +The 'test-both' script can be used to run both test-eglib and test-glib +with the same options back to back: + + $ ./test-both -tqi 100000 ptrarray + EGlib Total Time: 1.1961s + GLib Total Time: 0.955957s + +test-both also has a nice --speed-compare mode that shows comparison +information about EGlib vs GLib. It can run all tests or specific tests +with a configurable number of iterations. --speed-compare mode always runs +the drivers with -qtni + +The syntax for --speed-compare is: + + ./test-both --speed-compare [ITERATIONS] [GROUPS...] + + $ ./test-both --speed-compare Runs all tests with default iterations + $ ./test-both --speed-compare 500 Runs all tests with 500 iterations + $ ./test-both --speed-compare ptrarray Runs ptrarray test with default + iterations + + diff --git a/deps/eglib/test/UTF-16BE.txt b/deps/eglib/test/UTF-16BE.txt Binary files differnew file mode 100644 index 00000000..b7e494cb --- /dev/null +++ b/deps/eglib/test/UTF-16BE.txt diff --git a/deps/eglib/test/UTF-16LE.txt b/deps/eglib/test/UTF-16LE.txt Binary files differnew file mode 100644 index 00000000..30fe7b06 --- /dev/null +++ b/deps/eglib/test/UTF-16LE.txt diff --git a/deps/eglib/test/UTF-32BE.txt b/deps/eglib/test/UTF-32BE.txt Binary files differnew file mode 100644 index 00000000..a1fd5437 --- /dev/null +++ b/deps/eglib/test/UTF-32BE.txt diff --git a/deps/eglib/test/UTF-32LE.txt b/deps/eglib/test/UTF-32LE.txt Binary files differnew file mode 100644 index 00000000..043afc99 --- /dev/null +++ b/deps/eglib/test/UTF-32LE.txt diff --git a/deps/eglib/test/UTF-8.txt b/deps/eglib/test/UTF-8.txt new file mode 100644 index 00000000..4363f27b --- /dev/null +++ b/deps/eglib/test/UTF-8.txt @@ -0,0 +1,212 @@ + +UTF-8 encoded sample plain-text file +‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ + +Markus Kuhn [ˈmaʳkʊs kuːn] <http://www.cl.cam.ac.uk/~mgk25/> — 2002-07-25 + + +The ASCII compatible UTF-8 encoding used in this plain-text file +is defined in Unicode, ISO 10646-1, and RFC 2279. + + +Using Unicode/UTF-8, you can write in emails and source code things such as + +Mathematics and sciences: + + ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i), ⎧⎡⎛┌─────┐⎞⎤⎫ + ⎪⎢⎜│a²+b³ ⎟⎥⎪ + ∀x∈ℝ: ⌈x⌉ = −⌊−x⌋, α ∧ ¬β = ¬(¬α ∨ β), ⎪⎢⎜│───── ⎟⎥⎪ + ⎪⎢⎜⎷ c₈ ⎟⎥⎪ + ℕ ⊆ ℕ₀ ⊂ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ, ⎨⎢⎜ ⎟⎥⎬ + ⎪⎢⎜ ∞ ⎟⎥⎪ + ⊥ < a ≠ b ≡ c ≤ d ≪ ⊤ ⇒ (⟦A⟧ ⇔ ⟪B⟫), ⎪⎢⎜ ⎲ ⎟⎥⎪ + ⎪⎢⎜ ⎳aⁱ-bⁱ⎟⎥⎪ + 2H₂ + O₂ ⇌ 2H₂O, R = 4.7 kΩ, ⌀ 200 mm ⎩⎣⎝i=1 ⎠⎦⎭ + +Linguistics and dictionaries: + + ði ıntəˈnæʃənəl fəˈnɛtık əsoʊsiˈeıʃn + Y [ˈʏpsilɔn], Yen [jɛn], Yoga [ˈjoːgɑ] + +APL: + + ((V⍳V)=⍳⍴V)/V←,V ⌷←⍳→⍴∆∇⊃‾⍎⍕⌈ + +Nicer typography in plain text files: + + ╔══════════════════════════════════════════╗ + ║ ║ + ║ • ‘single’ and “double” quotes ║ + ║ ║ + ║ • Curly apostrophes: “We’ve been here” ║ + ║ ║ + ║ • Latin-1 apostrophe and accents: '´` ║ + ║ ║ + ║ • ‚deutsche‘ „Anführungszeichen“ ║ + ║ ║ + ║ • †, ‡, ‰, •, 3–4, —, −5/+5, ™, … ║ + ║ ║ + ║ • ASCII safety test: 1lI|, 0OD, 8B ║ + ║ ╭─────────╮ ║ + ║ • the euro symbol: │ 14.95 € │ ║ + ║ ╰─────────╯ ║ + ╚══════════════════════════════════════════╝ + +Combining characters: + + STARGΛ̊TE SG-1, a = v̇ = r̈, a⃑ ⊥ b⃑ + +Greek (in Polytonic): + + The Greek anthem: + + Σὲ γνωρίζω ἀπὸ τὴν κόψη + τοῦ σπαθιοῦ τὴν τρομερή, + σὲ γνωρίζω ἀπὸ τὴν ὄψη + ποὺ μὲ βία μετράει τὴ γῆ. + + ᾿Απ᾿ τὰ κόκκαλα βγαλμένη + τῶν ῾Ελλήνων τὰ ἱερά + καὶ σὰν πρῶτα ἀνδρειωμένη + χαῖρε, ὦ χαῖρε, ᾿Ελευθεριά! + + From a speech of Demosthenes in the 4th century BC: + + Οὐχὶ ταὐτὰ παρίσταταί μοι γιγνώσκειν, ὦ ἄνδρες ᾿Αθηναῖοι, + ὅταν τ᾿ εἰς τὰ πράγματα ἀποβλέψω καὶ ὅταν πρὸς τοὺς + λόγους οὓς ἀκούω· τοὺς μὲν γὰρ λόγους περὶ τοῦ + τιμωρήσασθαι Φίλιππον ὁρῶ γιγνομένους, τὰ δὲ πράγματ᾿ + εἰς τοῦτο προήκοντα, ὥσθ᾿ ὅπως μὴ πεισόμεθ᾿ αὐτοὶ + πρότερον κακῶς σκέψασθαι δέον. οὐδέν οὖν ἄλλο μοι δοκοῦσιν + οἱ τὰ τοιαῦτα λέγοντες ἢ τὴν ὑπόθεσιν, περὶ ἧς βουλεύεσθαι, + οὐχὶ τὴν οὖσαν παριστάντες ὑμῖν ἁμαρτάνειν. ἐγὼ δέ, ὅτι μέν + ποτ᾿ ἐξῆν τῇ πόλει καὶ τὰ αὑτῆς ἔχειν ἀσφαλῶς καὶ Φίλιππον + τιμωρήσασθαι, καὶ μάλ᾿ ἀκριβῶς οἶδα· ἐπ᾿ ἐμοῦ γάρ, οὐ πάλαι + γέγονεν ταῦτ᾿ ἀμφότερα· νῦν μέντοι πέπεισμαι τοῦθ᾿ ἱκανὸν + προλαβεῖν ἡμῖν εἶναι τὴν πρώτην, ὅπως τοὺς συμμάχους + σώσομεν. ἐὰν γὰρ τοῦτο βεβαίως ὑπάρξῃ, τότε καὶ περὶ τοῦ + τίνα τιμωρήσεταί τις καὶ ὃν τρόπον ἐξέσται σκοπεῖν· πρὶν δὲ + τὴν ἀρχὴν ὀρθῶς ὑποθέσθαι, μάταιον ἡγοῦμαι περὶ τῆς + τελευτῆς ὁντινοῦν ποιεῖσθαι λόγον. + + Δημοσθένους, Γ´ ᾿Ολυνθιακὸς + +Georgian: + + From a Unicode conference invitation: + + გთხოვთ ახლავე გაიაროთ რეგისტრაცია Unicode-ის მეათე საერთაშორისო + კონფერენციაზე დასასწრებად, რომელიც გაიმართება 10-12 მარტს, + ქ. მაინცში, გერმანიაში. კონფერენცია შეჰკრებს ერთად მსოფლიოს + ექსპერტებს ისეთ დარგებში როგორიცაა ინტერნეტი და Unicode-ი, + ინტერნაციონალიზაცია და ლოკალიზაცია, Unicode-ის გამოყენება + ოპერაციულ სისტემებსა, და გამოყენებით პროგრამებში, შრიფტებში, + ტექსტების დამუშავებასა და მრავალენოვან კომპიუტერულ სისტემებში. + +Russian: + + From a Unicode conference invitation: + + Зарегистрируйтесь сейчас на Десятую Международную Конференцию по + Unicode, которая состоится 10-12 марта 1997 года в Майнце в Германии. + Конференция соберет широкий круг экспертов по вопросам глобального + Интернета и Unicode, локализации и интернационализации, воплощению и + применению Unicode в различных операционных системах и программных + приложениях, шрифтах, верстке и многоязычных компьютерных системах. + +Thai (UCS Level 2): + + Excerpt from a poetry on The Romance of The Three Kingdoms (a Chinese + classic 'San Gua'): + + [----------------------------|------------------------] + ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่ + สิบสองกษัตริย์ก่อนหน้าแลถัดไป สององค์ไซร้โง่เขลาเบาปัญญา + ทรงนับถือขันทีเป็นที่พึ่ง บ้านเมืองจึงวิปริตเป็นนักหนา + โฮจิ๋นเรียกทัพทั่วหัวเมืองมา หมายจะฆ่ามดชั่วตัวสำคัญ + เหมือนขับไสไล่เสือจากเคหา รับหมาป่าเข้ามาเลยอาสัญ + ฝ่ายอ้องอุ้นยุแยกให้แตกกัน ใช้สาวนั้นเป็นชนวนชื่นชวนใจ + พลันลิฉุยกุยกีกลับก่อเหตุ ช่างอาเพศจริงหนาฟ้าร้องไห้ + ต้องรบราฆ่าฟันจนบรรลัย ฤๅหาใครค้ำชูกู้บรรลังก์ ฯ + + (The above is a two-column text. If combining characters are handled + correctly, the lines of the second column should be aligned with the + | character above.) + +Ethiopian: + + Proverbs in the Amharic language: + + ሰማይ አይታረስ ንጉሥ አይከሰስ። + ብላ ካለኝ እንደአባቴ በቆመጠኝ። + ጌጥ ያለቤቱ ቁምጥና ነው። + ደሀ በሕልሙ ቅቤ ባይጠጣ ንጣት በገደለው። + የአፍ ወለምታ በቅቤ አይታሽም። + አይጥ በበላ ዳዋ ተመታ። + ሲተረጉሙ ይደረግሙ። + ቀስ በቀስ፥ ዕንቁላል በእግሩ ይሄዳል። + ድር ቢያብር አንበሳ ያስር። + ሰው እንደቤቱ እንጅ እንደ ጉረቤቱ አይተዳደርም። + እግዜር የከፈተውን ጉሮሮ ሳይዘጋው አይድርም። + የጎረቤት ሌባ፥ ቢያዩት ይስቅ ባያዩት ያጠልቅ። + ሥራ ከመፍታት ልጄን ላፋታት። + ዓባይ ማደሪያ የለው፥ ግንድ ይዞ ይዞራል። + የእስላም አገሩ መካ የአሞራ አገሩ ዋርካ። + ተንጋሎ ቢተፉ ተመልሶ ባፉ። + ወዳጅህ ማር ቢሆን ጨርስህ አትላሰው። + እግርህን በፍራሽህ ልክ ዘርጋ። + +Runes: + + ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ + + (Old English, which transcribed into Latin reads 'He cwaeth that he + bude thaem lande northweardum with tha Westsae.' and means 'He said + that he lived in the northern land near the Western Sea.') + +Braille: + + ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌ + + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠙⠑⠁⠙⠒ ⠞⠕ ⠃⠑⠛⠔ ⠺⠊⠹⠲ ⡹⠻⠑ ⠊⠎ ⠝⠕ ⠙⠳⠃⠞ + ⠱⠁⠞⠑⠧⠻ ⠁⠃⠳⠞ ⠹⠁⠞⠲ ⡹⠑ ⠗⠑⠛⠊⠌⠻ ⠕⠋ ⠙⠊⠎ ⠃⠥⠗⠊⠁⠇ ⠺⠁⠎ + ⠎⠊⠛⠝⠫ ⠃⠹ ⠹⠑ ⠊⠇⠻⠛⠹⠍⠁⠝⠂ ⠹⠑ ⠊⠇⠻⠅⠂ ⠹⠑ ⠥⠝⠙⠻⠞⠁⠅⠻⠂ + ⠁⠝⠙ ⠹⠑ ⠡⠊⠑⠋ ⠍⠳⠗⠝⠻⠲ ⡎⠊⠗⠕⠕⠛⠑ ⠎⠊⠛⠝⠫ ⠊⠞⠲ ⡁⠝⠙ + ⡎⠊⠗⠕⠕⠛⠑⠰⠎ ⠝⠁⠍⠑ ⠺⠁⠎ ⠛⠕⠕⠙ ⠥⠏⠕⠝ ⠰⡡⠁⠝⠛⠑⠂ ⠋⠕⠗ ⠁⠝⠹⠹⠔⠛ ⠙⠑ + ⠡⠕⠎⠑ ⠞⠕ ⠏⠥⠞ ⠙⠊⠎ ⠙⠁⠝⠙ ⠞⠕⠲ + + ⡕⠇⠙ ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + ⡍⠔⠙⠖ ⡊ ⠙⠕⠝⠰⠞ ⠍⠑⠁⠝ ⠞⠕ ⠎⠁⠹ ⠹⠁⠞ ⡊ ⠅⠝⠪⠂ ⠕⠋ ⠍⠹ + ⠪⠝ ⠅⠝⠪⠇⠫⠛⠑⠂ ⠱⠁⠞ ⠹⠻⠑ ⠊⠎ ⠏⠜⠞⠊⠊⠥⠇⠜⠇⠹ ⠙⠑⠁⠙ ⠁⠃⠳⠞ + ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ ⡊ ⠍⠊⠣⠞ ⠙⠁⠧⠑ ⠃⠑⠲ ⠔⠊⠇⠔⠫⠂ ⠍⠹⠎⠑⠇⠋⠂ ⠞⠕ + ⠗⠑⠛⠜⠙ ⠁ ⠊⠕⠋⠋⠔⠤⠝⠁⠊⠇ ⠁⠎ ⠹⠑ ⠙⠑⠁⠙⠑⠌ ⠏⠊⠑⠊⠑ ⠕⠋ ⠊⠗⠕⠝⠍⠕⠝⠛⠻⠹ + ⠔ ⠹⠑ ⠞⠗⠁⠙⠑⠲ ⡃⠥⠞ ⠹⠑ ⠺⠊⠎⠙⠕⠍ ⠕⠋ ⠳⠗ ⠁⠝⠊⠑⠌⠕⠗⠎ + ⠊⠎ ⠔ ⠹⠑ ⠎⠊⠍⠊⠇⠑⠆ ⠁⠝⠙ ⠍⠹ ⠥⠝⠙⠁⠇⠇⠪⠫ ⠙⠁⠝⠙⠎ + ⠩⠁⠇⠇ ⠝⠕⠞ ⠙⠊⠌⠥⠗⠃ ⠊⠞⠂ ⠕⠗ ⠹⠑ ⡊⠳⠝⠞⠗⠹⠰⠎ ⠙⠕⠝⠑ ⠋⠕⠗⠲ ⡹⠳ + ⠺⠊⠇⠇ ⠹⠻⠑⠋⠕⠗⠑ ⠏⠻⠍⠊⠞ ⠍⠑ ⠞⠕ ⠗⠑⠏⠑⠁⠞⠂ ⠑⠍⠏⠙⠁⠞⠊⠊⠁⠇⠇⠹⠂ ⠹⠁⠞ + ⡍⠜⠇⠑⠹ ⠺⠁⠎ ⠁⠎ ⠙⠑⠁⠙ ⠁⠎ ⠁ ⠙⠕⠕⠗⠤⠝⠁⠊⠇⠲ + + (The first couple of paragraphs of "A Christmas Carol" by Dickens) + +Compact font selection example text: + + ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789 + abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ + –—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд + ∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა + +Greetings in various languages: + + Hello world, Καλημέρα κόσμε, コンニチハ + +Box drawing alignment tests: █ + ▉ + ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓ ┎┒┏┑ ╷ ╻ ┏┯┓ ┌┰┐ ▊ ╱╲╱╲╳╳╳ + ║┌─╨─┐║ │╔═╧═╗│ │╒═╪═╕│ │╓─╁─╖│ ┃┌─╂─┐┃ ┗╃╄┙ ╶┼╴╺╋╸┠┼┨ ┝╋┥ ▋ ╲╱╲╱╳╳╳ + ║│╲ ╱│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╿ │┃ ┍╅╆┓ ╵ ╹ ┗┷┛ └┸┘ ▌ ╱╲╱╲╳╳╳ + ╠╡ ╳ ╞╣ ├╢ ╟┤ ├┼─┼─┼┤ ├╫─╂─╫┤ ┣┿╾┼╼┿┫ ┕┛┖┚ ┌┄┄┐ ╎ ┏┅┅┓ ┋ ▍ ╲╱╲╱╳╳╳ + ║│╱ ╲│║ │║ ║│ ││ │ ││ │║ ┃ ║│ ┃│ ╽ │┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▎ + ║└─╥─┘║ │╚═╤═╝│ │╘═╪═╛│ │╙─╀─╜│ ┃└─╂─┘┃ ░░▒▒▓▓██ ┊ ┆ ╎ ╏ ┇ ┋ ▏ + ╚══╩══╝ └──┴──┘ ╰──┴──╯ ╰──┴──╯ ┗━━┻━━┛ ▗▄▖▛▀▜ └╌╌┘ ╎ ┗╍╍┛ ┋ ▁▂▃▄▅▆▇█ + ▝▀▘▙▄▟ diff --git a/deps/eglib/test/array.c b/deps/eglib/test/array.c new file mode 100644 index 00000000..37d5486a --- /dev/null +++ b/deps/eglib/test/array.c @@ -0,0 +1,163 @@ +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include "test.h" + +/* example from glib documentation */ +RESULT +test_array_big () +{ + GArray *garray; + gint i; + + /* We create a new array to store gint values. + We don't want it zero-terminated or cleared to 0's. */ + garray = g_array_new (FALSE, FALSE, sizeof (gint)); + for (i = 0; i < 10000; i++) + g_array_append_val (garray, i); + + for (i = 0; i < 10000; i++) + if (g_array_index (garray, gint, i) != i) + return FAILED ("array value didn't match"); + + g_array_free (garray, TRUE); + + return NULL; +} + +RESULT +test_array_index () +{ + GArray *array = g_array_new (FALSE, FALSE, sizeof (int)); + int v; + + v = 27; + g_array_append_val (array, v); + + if (27 != g_array_index (array, int, 0)) + return FAILED (""); + + g_array_free (array, TRUE); + + return NULL; +} + +RESULT +test_array_append_zero_terminated () +{ + GArray *array = g_array_new (TRUE, FALSE, sizeof (int)); + int v; + + v = 27; + g_array_append_val (array, v); + + if (27 != g_array_index (array, int, 0)) + return FAILED ("g_array_append_val failed"); + + if (0 != g_array_index (array, int, 1)) + return FAILED ("zero_terminated didn't append a zero element"); + + g_array_free (array, TRUE); + + return NULL; +} + +RESULT +test_array_append () +{ + GArray *array = g_array_new (FALSE, FALSE, sizeof (int)); + int v; + + if (0 != array->len) + return FAILED ("initial array length not zero"); + + v = 27; + + g_array_append_val (array, v); + + if (1 != array->len) + return FAILED ("array append failed"); + + g_array_free (array, TRUE); + + return NULL; +} + +RESULT +test_array_insert_val () +{ + GArray *array = g_array_new (FALSE, FALSE, sizeof (gpointer)); + gpointer ptr0, ptr1, ptr2, ptr3; + + g_array_insert_val (array, 0, array); + + if (array != g_array_index (array, gpointer, 0)) + return FAILED ("1 The value in the array is incorrect"); + + g_array_insert_val (array, 1, array); + if (array != g_array_index (array, gpointer, 1)) + return FAILED ("2 The value in the array is incorrect"); + + g_array_insert_val (array, 2, array); + if (array != g_array_index (array, gpointer, 2)) + return FAILED ("3 The value in the array is incorrect"); + + g_array_free (array, TRUE); + array = g_array_new (FALSE, FALSE, sizeof (gpointer)); + ptr0 = array; + ptr1 = array + 1; + ptr2 = array + 2; + ptr3 = array + 3; + + g_array_insert_val (array, 0, ptr0); + g_array_insert_val (array, 1, ptr1); + g_array_insert_val (array, 2, ptr2); + g_array_insert_val (array, 1, ptr3); + if (ptr0 != g_array_index (array, gpointer, 0)) + return FAILED ("4 The value in the array is incorrect"); + if (ptr3 != g_array_index (array, gpointer, 1)) + return FAILED ("5 The value in the array is incorrect"); + if (ptr1 != g_array_index (array, gpointer, 2)) + return FAILED ("6 The value in the array is incorrect"); + if (ptr2 != g_array_index (array, gpointer, 3)) + return FAILED ("7 The value in the array is incorrect"); + + g_array_free (array, TRUE); + return NULL; +} + +RESULT +test_array_remove () +{ + GArray *array = g_array_new (FALSE, FALSE, sizeof (int)); + int v[] = {30, 29, 28, 27, 26, 25}; + + g_array_append_vals (array, v, 6); + + if (6 != array->len) + return FAILED ("append_vals fail"); + + g_array_remove_index (array, 3); + + if (5 != array->len) + return FAILED ("remove_index failed to update length"); + + if (26 != g_array_index (array, int, 3)) + return FAILED ("remove_index failed to update the array"); + + g_array_free (array, TRUE); + + return NULL; +} + +static Test array_tests [] = { + {"big", test_array_big}, + {"append", test_array_append}, + {"insert_val", test_array_insert_val}, + {"index", test_array_index}, + {"remove", test_array_remove}, + {"append_zero_term", test_array_append_zero_terminated}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(array_tests_init, array_tests) diff --git a/deps/eglib/test/dir.c b/deps/eglib/test/dir.c new file mode 100644 index 00000000..f8711217 --- /dev/null +++ b/deps/eglib/test/dir.c @@ -0,0 +1,66 @@ +#include <config.h> +#include <glib.h> +#include <string.h> +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef G_OS_UNIX +#include <pthread.h> +#endif +#include "test.h" + +/* This test is just to be used with valgrind */ +RESULT +test_dir () +{ + GDir *dir; + GError *error; + const gchar *name; + + /* + dir = g_dir_open (NULL, 0, NULL); + */ + dir = g_dir_open ("", 0, NULL); + if (dir != NULL) + return FAILED ("1 Should be an error"); + + dir = g_dir_open ("", 9, NULL); + if (dir != NULL) + return FAILED ("2 Should be an error"); + + error = NULL; + dir = g_dir_open (".ljasdslakjd", 9, &error); + if (dir != NULL) + return FAILED ("3 opendir should fail"); + if (error == NULL) + return FAILED ("4 got no error"); + g_error_free (error); + error = NULL; + dir = g_dir_open (g_get_tmp_dir (), 9, &error); + if (dir == NULL) + return FAILED ("5 opendir should succeed"); + if (error != NULL) + return FAILED ("6 got an error"); + name = NULL; + name = g_dir_read_name (dir); + if (name == NULL) + return FAILED ("7 didn't read a file name"); + while ((name = g_dir_read_name (dir)) != NULL) { + if (strcmp (name, ".") == 0) + return FAILED (". directory found"); + if (strcmp (name, "..") == 0) + return FAILED (".. directory found"); + } + g_dir_close (dir); + return OK; +} + +static Test dir_tests [] = { + {"g_dir_*", test_dir}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(dir_tests_init, dir_tests) + + diff --git a/deps/eglib/test/driver.c b/deps/eglib/test/driver.c new file mode 100644 index 00000000..23e7638b --- /dev/null +++ b/deps/eglib/test/driver.c @@ -0,0 +1,248 @@ +/* + * EGLib Unit Test Driver + * + * Author: + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include <config.h> +#include "test.h" +#include "tests.h" + +#include <stdio.h> +#ifdef HAVE_GETOPT_H +#include <getopt.h> +#endif + +#if defined(HAVE_UNISTD_H) +#include <unistd.h> +#endif + +#ifndef DRIVER_NAME +#define DRIVER_NAME "EGlib" +#endif + +typedef struct _StringArray { + gchar **strings; + gint length; +} StringArray; + +static StringArray * +string_array_append(StringArray *array, gchar *string) +{ + if(array == NULL) { + array = g_new0(StringArray, 1); + array->length = 1; + array->strings = g_malloc(sizeof(gchar *) * 2); + } else { + array->length++; + array->strings = g_realloc(array->strings, sizeof(gchar *) + * (array->length + 1)); + } + + array->strings[array->length - 1] = string; + array->strings[array->length] = NULL; + + return array; +} + +gint global_passed = 0, global_tests = 0; + +static void +string_array_free(StringArray *array) +{ + g_free(array->strings); + g_free(array); +} + +static void print_help(char *s) +{ + gint i; + + printf("Usage: %s [OPTION]... [TESTGROUP]...\n\n", s); + printf("OPTIONS are:\n"); + printf(" -h, --help show this help\n"); + printf(" -t, --time time the tests\n"); + printf(" -i, --iterations number of times to run tests\n"); + printf(" -q, --quiet do not print test results; " + "final time always prints\n"); + printf(" -n, --no-labels print final time without labels, " + "nice for scripts\n"); + printf(" -d, --debug do not run tests, " + "debug the driver itself for valgrind\n\n"); + printf("TESTGROUPS available:\n"); + + for(i = 0; test_groups[i].name != NULL; i++) { + if(test_groups[i].handler != fake_tests_init) { + printf(" %s\n", test_groups[i].name); + } + } + + printf("\n"); +} + +gint main(gint argc, gchar **argv) +{ + gint i, j, c, iterations = 1; + StringArray *tests_to_run = NULL; + gdouble time_start; + gboolean report_time = FALSE; + gboolean quiet = FALSE; + gboolean global_failure = FALSE; + gboolean no_final_time_labels = FALSE; + gboolean debug = FALSE; + +#if HAVE_GETOPT_H + static struct option long_options [] = { + {"help", no_argument, 0, 'h'}, + {"time", no_argument, 0, 't'}, + {"quiet", no_argument, 0, 'q'}, + {"iterations", required_argument, 0, 'i'}, + {"debug", no_argument, 0, 'd'}, + {"no-labels", no_argument, 0, 'n'}, + {0, 0, 0, 0} + }; + + while((c = getopt_long(argc, argv, "dhtqni:", long_options, NULL)) != -1) { switch(c) { + case 'h': + print_help(argv[0]); + return 1; + case 't': + report_time = TRUE; + break; + case 'i': + iterations = atoi(optarg); + break; + case 'q': + quiet = TRUE; + break; + case 'n': + no_final_time_labels = TRUE; + break; + case 'd': + debug = TRUE; + break; + } + } + + for(i = optind; i < argc; i++) { + if(argv[i][0] == '-') { + continue; + } + + tests_to_run = string_array_append(tests_to_run, argv[i]); + } +#endif + + time_start = get_timestamp(); + + for(j = 0; test_groups[j].name != NULL; j++) { + gboolean run = TRUE; + gchar *tests = NULL; + gchar *group = NULL; + + if(tests_to_run != NULL) { + gint k; + run = FALSE; + + for(k = 0; k < tests_to_run->length; k++) { + gchar *user = tests_to_run->strings[k]; + const gchar *table = test_groups[j].name; + size_t user_len = strlen(user); + size_t table_len = strlen(table); + + if(strncmp(user, table, table_len) == 0) { + if(user_len > table_len && user[table_len] != ':') { + break; + } + + run = TRUE; + group = tests_to_run->strings[k]; + break; + } + } + } + + if(run) { + gboolean passed; + gchar **split = NULL; + + if(debug && test_groups[j].handler != fake_tests_init) { + printf("Skipping %s, in driver debug mode\n", + test_groups[j].name); + continue; + } else if(!debug && test_groups[j].handler == fake_tests_init) { + continue; + } + + if(group != NULL) { + split = eg_strsplit(group, ":", -1); + if(split != NULL) { + gint m; + for(m = 0; split[m] != NULL; m++) { + if(m == 1) { + tests = strdup(split[m]); + break; + } + } + eg_strfreev(split); + } + } + + passed = run_group(&(test_groups[j]), + iterations, quiet, report_time, tests); + + if(tests != NULL) { + g_free(tests); + } + + if(!passed && !global_failure) { + global_failure = TRUE; + } + } + } + + if(!quiet) { + gdouble pass_percentage = ((gdouble)global_passed / (gdouble)global_tests) * 100.0; + printf("=============================\n"); + printf("Overall result: %s : %d / %d (%g%%)\n", global_failure ? "FAILED" : "OK", global_passed, global_tests, pass_percentage); + } + + if(report_time) { + gdouble duration = get_timestamp() - time_start; + if(no_final_time_labels) { + printf("%g\n", duration); + } else { + printf("%s Total Time: %g\n", DRIVER_NAME, duration); + } + } + + if(tests_to_run != NULL) { + string_array_free(tests_to_run); + } + + return global_tests - global_passed; +} + + diff --git a/deps/eglib/test/endian.c b/deps/eglib/test/endian.c new file mode 100644 index 00000000..3347d765 --- /dev/null +++ b/deps/eglib/test/endian.c @@ -0,0 +1,38 @@ +#include "test.h" + +RESULT +test_swap () +{ + guint32 a = 0xabcdef01, res32; + guint64 b = (((guint64)a) << 32) | a, res64; + guint64 b_expect = (((guint64)0x1efcdab) << 32) | 0x01efcdab; + guint16 c = 0xabcd, res16; + + res32 = GUINT32_SWAP_LE_BE (a); + if (res32 != 0x01efcdab) + return FAILED ("GUINT32_SWAP_LE_BE returned 0x%x", res32); + res32 = GUINT32_SWAP_LE_BE (1); + if (res32 != 0x1000000) + return FAILED ("GUINT32_SWAP_LE_BE returned 0x%x", res32); + + res64 = GUINT64_SWAP_LE_BE(b); + if (res64 != b_expect) + return FAILED ("GUINT64_SWAP_LE_BE returned 0x%llx (had=0x%llx)", res64, b); + res16 = GUINT16_SWAP_LE_BE(c); + if (res16 != 0xcdab) + return FAILED ("GUINT16_SWAP_LE_BE returned 0x%x", (guint32) res16); + + return OK; +} + +/* + * test initialization + */ + +static Test endian_tests [] = { + {"swap", test_swap}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(endian_tests_init, endian_tests) + diff --git a/deps/eglib/test/fake.c b/deps/eglib/test/fake.c new file mode 100644 index 00000000..c8d9af61 --- /dev/null +++ b/deps/eglib/test/fake.c @@ -0,0 +1,19 @@ +/* + * Fake test allows debugging of the driver itself + */ + +#include "test.h" + +RESULT +test_fake() +{ + return OK; +} + +static Test fake_tests [] = { + {"fake", test_fake}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(fake_tests_init, fake_tests) + diff --git a/deps/eglib/test/file.c b/deps/eglib/test/file.c new file mode 100644 index 00000000..411c9452 --- /dev/null +++ b/deps/eglib/test/file.c @@ -0,0 +1,228 @@ +#include <config.h> +#include <glib.h> +#include <string.h> +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdio.h> +#include "test.h" + +#ifdef G_OS_WIN32 +#include <io.h> +#define close _close +#endif + +RESULT +test_file_get_contents () +{ + GError *error; + gchar *content; + gboolean ret; + gsize length; +#ifdef G_OS_WIN32 + const gchar *filename = "c:\\Windows\\system.ini"; +#else + const gchar *filename = "/etc/hosts"; +#endif + + /* + filename != NULL + ret = g_file_get_contents (NULL, NULL, NULL, NULL); + contents != NULL + ret = g_file_get_contents ("", NULL, NULL, NULL); + error no such file and fails for 'error' not being null too + ret = g_file_get_contents ("", &content, NULL, &error); + */ + + error = NULL; + ret = g_file_get_contents ("", &content, NULL, &error); + if (ret) + return FAILED ("HAH!"); + if (error == NULL) + return FAILED ("Got nothing as error."); + if (content != NULL) + return FAILED ("Content is uninitialized"); + + g_error_free (error); + error = NULL; + ret = g_file_get_contents (filename, &content, &length, &error); + if (!ret) + return FAILED ("The error is %d %s\n", error->code, error->message); + if (error != NULL) + return FAILED ("Got an error returning TRUE"); + if (content == NULL) + return FAILED ("Content is NULL"); + if (strlen (content) != length) + return FAILED ("length is %d but the string is %d", length, strlen (content)); + g_free (content); + + return OK; +} + +RESULT +test_open_tmp () +{ + GError *error; + gint fd; + gchar *name = GINT_TO_POINTER (-1); + + /* + * Okay, this works, but creates a .xxx file in /tmp on every run. Disabled. + * fd = g_file_open_tmp (NULL, NULL, NULL); + * if (fd < 0) + * return FAILED ("Default failed."); + * close (fd); + */ + error = NULL; + fd = g_file_open_tmp ("invalidtemplate", NULL, &error); + if (fd != -1) + return FAILED ("The template was invalid and accepted"); + if (error == NULL) + return FAILED ("No error returned."); + g_error_free (error); + + error = NULL; + fd = g_file_open_tmp ("i/nvalidtemplate", &name, &error); + if (fd != -1) + return FAILED ("The template was invalid and accepted"); + if (error == NULL) + return FAILED ("No error returned."); + if (name == NULL) + return FAILED ("'name' is not reset"); + g_error_free (error); + + error = NULL; + fd = g_file_open_tmp ("valid-XXXXXX", &name, &error); + if (fd == -1) + return FAILED ("This should be valid"); + if (error != NULL) + return FAILED ("No error returned."); + if (name == NULL) + return FAILED ("No name returned."); + close (fd); + unlink (name); + g_free (name); + return OK; +} + +RESULT +test_file () +{ + gboolean res; + const gchar *tmp; + gchar *path; + +#ifndef G_OS_WIN32 /* FIXME */ + gchar *sympath; + gint ignored; +#endif + + res = g_file_test (NULL, 0); + if (res) + return FAILED ("Should return FALSE HERE"); + + res = g_file_test ("file.c", 0); + if (res) + return FAILED ("Should return FALSE HERE"); + + tmp = g_get_tmp_dir (); + res = g_file_test (tmp, G_FILE_TEST_EXISTS); + if (!res) + return FAILED ("tmp does not exist."); + res = g_file_test (tmp, G_FILE_TEST_IS_REGULAR); + if (res) + return FAILED ("tmp is regular"); + + res = g_file_test (tmp, G_FILE_TEST_IS_DIR); + if (!res) + return FAILED ("tmp is not a directory"); + res = g_file_test (tmp, G_FILE_TEST_IS_EXECUTABLE); + if (!res) + return FAILED ("tmp is not a executable"); + + res = g_file_test (tmp, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK); + if (!res) + return FAILED ("2 tmp does not exist."); + res = g_file_test (tmp, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK); + if (res) + return FAILED ("2 tmp is regular"); + + res = g_file_test (tmp, G_FILE_TEST_IS_DIR | G_FILE_TEST_IS_SYMLINK); + if (!res) + return FAILED ("2 tmp is not a directory"); + res = g_file_test (tmp, G_FILE_TEST_IS_EXECUTABLE | G_FILE_TEST_IS_SYMLINK); + if (!res) + return FAILED ("2 tmp is not a executable"); + + close (g_file_open_tmp (NULL, &path, NULL)); /* create an empty file */ + res = g_file_test (path, G_FILE_TEST_EXISTS); + if (!res) + return FAILED ("3 %s should exist", path); + res = g_file_test (path, G_FILE_TEST_IS_REGULAR); + /* This is strange. Empty file is reported as not existing! */ + if (!res) + return FAILED ("3 %s IS_REGULAR", path); + res = g_file_test (path, G_FILE_TEST_IS_DIR); + if (res) + return FAILED ("3 %s should not be a directory", path); + res = g_file_test (path, G_FILE_TEST_IS_EXECUTABLE); + if (res) + return FAILED ("3 %s should not be executable", path); + res = g_file_test (path, G_FILE_TEST_IS_SYMLINK); + if (res) + return FAILED ("3 %s should not be a symlink", path); + +#ifndef G_OS_WIN32 /* FIXME */ + sympath = g_strconcat (path, "-link", NULL); + ignored = symlink (path, sympath); + res = g_file_test (sympath, G_FILE_TEST_EXISTS); + if (!res) + return FAILED ("4 %s should not exist", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_REGULAR); + if (!res) + return FAILED ("4 %s should not be a regular file", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_DIR); + if (res) + return FAILED ("4 %s should not be a directory", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_EXECUTABLE); + if (res) + return FAILED ("4 %s should not be executable", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_SYMLINK); + if (!res) + return FAILED ("4 %s should be a symlink", sympath); + + unlink (path); + + res = g_file_test (sympath, G_FILE_TEST_EXISTS); + if (res) + return FAILED ("5 %s should exist", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_REGULAR); + if (res) + return FAILED ("5 %s should be a regular file", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_DIR); + if (res) + return FAILED ("5 %s should not be a directory", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_EXECUTABLE); + if (res) + return FAILED ("5 %s should not be executable", sympath); + res = g_file_test (sympath, G_FILE_TEST_IS_SYMLINK); + if (!res) + return FAILED ("5 %s should be a symlink", sympath); + unlink (sympath); + g_free (sympath); +#endif + g_free (path); + return OK; +} + +static Test file_tests [] = { + {"g_file_get_contents", test_file_get_contents}, + {"g_file_open_tmp", test_open_tmp}, + {"g_file_test", test_file}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(file_tests_init, file_tests) + + diff --git a/deps/eglib/test/hashtable.c b/deps/eglib/test/hashtable.c new file mode 100644 index 00000000..8eb98852 --- /dev/null +++ b/deps/eglib/test/hashtable.c @@ -0,0 +1,177 @@ +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include "test.h" + +int foreach_count = 0; +int foreach_fail = 0; + +void foreach (gpointer key, gpointer value, gpointer user_data) +{ + foreach_count++; + if (GPOINTER_TO_INT (user_data) != 'a') + foreach_fail = 1; +} + +RESULT hash_t1 (void) +{ + GHashTable *t = g_hash_table_new (g_str_hash, g_str_equal); + + foreach_count = 0; + foreach_fail = 0; + g_hash_table_insert (t, "hello", "world"); + g_hash_table_insert (t, "my", "god"); + + g_hash_table_foreach (t, foreach, GINT_TO_POINTER('a')); + if (foreach_count != 2) + return FAILED ("did not find all keys, got %d expected 2", foreach_count); + if (foreach_fail) + return FAILED("failed to pass the user-data to foreach"); + + if (!g_hash_table_remove (t, "my")) + return FAILED ("did not find known key"); + if (g_hash_table_size (t) != 1) + return FAILED ("unexpected size"); + g_hash_table_insert(t, "hello", "moon"); + if (strcmp (g_hash_table_lookup (t, "hello"), "moon") != 0) + return FAILED ("did not replace world with moon"); + + if (!g_hash_table_remove (t, "hello")) + return FAILED ("did not find known key"); + if (g_hash_table_size (t) != 0) + return FAILED ("unexpected size"); + g_hash_table_destroy (t); + + return OK; +} + +RESULT hash_t2 (void) +{ + return OK; +} + +RESULT hash_default (void) +{ + GHashTable *hash = g_hash_table_new (NULL, NULL); + + if (hash == NULL) + return FAILED ("g_hash_table_new should return a valid hash"); + + g_hash_table_destroy (hash); + return NULL; +} + +RESULT +hash_null_lookup (void) +{ + GHashTable *hash = g_hash_table_new (NULL, NULL); + gpointer ok, ov; + + g_hash_table_insert (hash, NULL, GINT_TO_POINTER (1)); + g_hash_table_insert (hash, GINT_TO_POINTER(1), GINT_TO_POINTER(2)); + + if (!g_hash_table_lookup_extended (hash, NULL, &ok, &ov)) + return FAILED ("Did not find the NULL"); + if (ok != NULL) + return FAILED ("Incorrect key found"); + if (ov != GINT_TO_POINTER (1)) + return FAILED ("Got wrong value %p\n", ov); + + if (!g_hash_table_lookup_extended (hash, GINT_TO_POINTER(1), &ok, &ov)) + return FAILED ("Did not find the 1"); + if (ok != GINT_TO_POINTER(1)) + return FAILED ("Incorrect key found"); + if (ov != GINT_TO_POINTER (2)) + return FAILED ("Got wrong value %p\n", ov); + + g_hash_table_destroy (hash); + + return NULL; +} + +static void +counter (gpointer key, gpointer value, gpointer user_data) +{ + int *counter = (int *) user_data; + + (*counter)++; +} + +RESULT hash_grow (void) +{ + GHashTable *hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + int i, count = 0; + + for (i = 0; i < 1000; i++) + g_hash_table_insert (hash, g_strdup_printf ("%d", i), g_strdup_printf ("x-%d", i)); + + for (i = 0; i < 1000; i++){ + char buffer [30]; + gpointer value; + + sprintf (buffer, "%d", i); + + value = g_hash_table_lookup (hash, buffer); + sprintf (buffer, "x-%d", i); + if (strcmp (value, buffer) != 0){ + return FAILED ("Failed to lookup the key %d, the value was %s\n", i, value); + } + } + + if (g_hash_table_size (hash) != 1000) + return FAILED ("Did not find 1000 elements on the hash, found %d\n", g_hash_table_size (hash)); + + /* Now do the manual count, lets not trust the internals */ + g_hash_table_foreach (hash, counter, &count); + if (count != 1000){ + return FAILED ("Foreach count is not 1000"); + } + + g_hash_table_destroy (hash); + return NULL; +} + +RESULT hash_iter (void) +{ +#if !defined(GLIB_MAJOR_VERSION) || GLIB_CHECK_VERSION(2, 16, 0) + GHashTable *hash = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); + GHashTableIter iter; + int i, sum, keys_sum, values_sum; + gpointer key, value; + + sum = 0; + for (i = 0; i < 1000; i++) { + sum += i; + g_hash_table_insert (hash, GUINT_TO_POINTER (i), GUINT_TO_POINTER (i)); + } + + keys_sum = values_sum = 0; + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) { + if (key != value) + return FAILED ("key != value"); + keys_sum += GPOINTER_TO_UINT (key); + values_sum += GPOINTER_TO_UINT (value); + } + if (keys_sum != sum || values_sum != sum) + return FAILED ("Did not find all key-value pairs"); + g_hash_table_destroy (hash); + return NULL; +#else + /* GHashTableIter was added in glib 2.16 */ + return NULL; +#endif +} + +static Test hashtable_tests [] = { + {"t1", hash_t1}, + {"t2", hash_t2}, + {"grow", hash_grow}, + {"default", hash_default}, + {"null_lookup", hash_null_lookup}, + {"iter", hash_iter}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(hashtable_tests_init, hashtable_tests) + diff --git a/deps/eglib/test/list.c b/deps/eglib/test/list.c new file mode 100644 index 00000000..68dadee6 --- /dev/null +++ b/deps/eglib/test/list.c @@ -0,0 +1,438 @@ +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include "test.h" + +RESULT +test_list_length () +{ + GList *list = g_list_prepend (NULL, "foo"); + + if (g_list_length (list) != 1) + return FAILED ("length failed. #1"); + + list = g_list_prepend (list, "bar"); + if (g_list_length (list) != 2) + return FAILED ("length failed. #2"); + + list = g_list_append (list, "bar"); + if (g_list_length (list) != 3) + return FAILED ("length failed. #3"); + + g_list_free (list); + return NULL; +} + +RESULT +test_list_nth () +{ + char *foo = "foo"; + char *bar = "bar"; + char *baz = "baz"; + GList *nth, *list; + list = g_list_prepend (NULL, baz); + list = g_list_prepend (list, bar); + list = g_list_prepend (list, foo); + + nth = g_list_nth (list, 0); + if (nth->data != foo) + return FAILED ("nth failed. #0"); + + nth = g_list_nth (list, 1); + if (nth->data != bar) + return FAILED ("nth failed. #1"); + + nth = g_list_nth (list, 2); + if (nth->data != baz) + return FAILED ("nth failed. #2"); + + nth = g_list_nth (list, 3); + if (nth) + return FAILED ("nth failed. #3: %s", nth->data); + + g_list_free (list); + return OK; +} + +RESULT +test_list_index () +{ + int i; + char *foo = "foo"; + char *bar = "bar"; + char *baz = "baz"; + GList *list; + list = g_list_prepend (NULL, baz); + list = g_list_prepend (list, bar); + list = g_list_prepend (list, foo); + + i = g_list_index (list, foo); + if (i != 0) + return FAILED ("index failed. #0: %d", i); + + i = g_list_index (list, bar); + if (i != 1) + return FAILED ("index failed. #1: %d", i); + + i = g_list_index (list, baz); + if (i != 2) + return FAILED ("index failed. #2: %d", i); + + g_list_free (list); + return OK; +} + +RESULT +test_list_append () +{ + GList *list = g_list_prepend (NULL, "first"); + if (g_list_length (list) != 1) + return FAILED ("Prepend failed"); + + list = g_list_append (list, "second"); + + if (g_list_length (list) != 2) + return FAILED ("Append failed"); + + g_list_free (list); + return OK; +} + +RESULT +test_list_last () +{ + GList *foo = g_list_prepend (NULL, "foo"); + GList *bar = g_list_prepend (NULL, "bar"); + GList *last; + + foo = g_list_concat (foo, bar); + last = g_list_last (foo); + + if (last != bar) + return FAILED ("last failed. #1"); + + foo = g_list_concat (foo, g_list_prepend (NULL, "baz")); + foo = g_list_concat (foo, g_list_prepend (NULL, "quux")); + + last = g_list_last (foo); + if (strcmp ("quux", last->data)) + return FAILED ("last failed. #2"); + + g_list_free (foo); + + return OK; +} + +RESULT +test_list_concat () +{ + GList *foo = g_list_prepend (NULL, "foo"); + GList *bar = g_list_prepend (NULL, "bar"); + GList *list = g_list_concat (foo, bar); + + if (g_list_length (list) != 2) + return FAILED ("Concat failed. #1"); + + if (strcmp (list->data, "foo")) + return FAILED ("Concat failed. #2"); + + if (strcmp (list->next->data, "bar")) + return FAILED ("Concat failed. #3"); + + if (g_list_first (list) != foo) + return FAILED ("Concat failed. #4"); + + if (g_list_last (list) != bar) + return FAILED ("Concat failed. #5"); + + g_list_free (list); + + return OK; +} + + +static gint +compare (gconstpointer a, gconstpointer b) +{ + char *foo = (char *) a; + char *bar = (char *) b; + + if (strlen (foo) < strlen (bar)) + return -1; + + return 1; +} + +RESULT +test_list_insert_sorted () +{ + GList *list = g_list_prepend (NULL, "a"); + list = g_list_append (list, "aaa"); + + /* insert at the middle */ + list = g_list_insert_sorted (list, "aa", compare); + if (strcmp ("aa", list->next->data)) + return FAILED ("insert_sorted failed. #1"); + + /* insert at the beginning */ + list = g_list_insert_sorted (list, "", compare); + if (strcmp ("", list->data)) + return FAILED ("insert_sorted failed. #2"); + + /* insert at the end */ + list = g_list_insert_sorted (list, "aaaa", compare); + if (strcmp ("aaaa", g_list_last (list)->data)) + return FAILED ("insert_sorted failed. #3"); + + g_list_free (list); + return OK; +} + +RESULT +test_list_copy () +{ + int i, length; + GList *list, *copy; + list = g_list_prepend (NULL, "a"); + list = g_list_append (list, "aa"); + list = g_list_append (list, "aaa"); + list = g_list_append (list, "aaaa"); + + length = g_list_length (list); + copy = g_list_copy (list); + + for (i = 0; i < length; i++) + if (strcmp (g_list_nth (list, i)->data, + g_list_nth (copy, i)->data)) + return FAILED ("copy failed."); + + g_list_free (list); + g_list_free (copy); + return OK; +} + +RESULT +test_list_reverse () +{ + guint i, length; + GList *list, *reverse; + list = g_list_prepend (NULL, "a"); + list = g_list_append (list, "aa"); + list = g_list_append (list, "aaa"); + list = g_list_append (list, "aaaa"); + + length = g_list_length (list); + reverse = g_list_reverse (g_list_copy (list)); + + if (g_list_length (reverse) != length) + return FAILED ("reverse failed #1"); + + for (i = 0; i < length; i++){ + guint j = length - i - 1; + if (strcmp (g_list_nth (list, i)->data, + g_list_nth (reverse, j)->data)) + return FAILED ("reverse failed. #2"); + } + + g_list_free (list); + g_list_free (reverse); + return OK; +} + +RESULT +test_list_remove () +{ + GList *list = g_list_prepend (NULL, "three"); + char *one = "one"; + list = g_list_prepend (list, "two"); + list = g_list_prepend (list, one); + + list = g_list_remove (list, one); + + if (g_list_length (list) != 2) + return FAILED ("Remove failed"); + + if (strcmp ("two", list->data) != 0) + return FAILED ("Remove failed"); + + g_list_free (list); + return OK; +} + +RESULT +test_list_remove_link () +{ + GList *foo = g_list_prepend (NULL, "a"); + GList *bar = g_list_prepend (NULL, "b"); + GList *baz = g_list_prepend (NULL, "c"); + GList *list = foo; + + foo = g_list_concat (foo, bar); + foo = g_list_concat (foo, baz); + + list = g_list_remove_link (list, bar); + + if (g_list_length (list) != 2) + return FAILED ("remove_link failed #1"); + + if (bar->next != NULL) + return FAILED ("remove_link failed #2"); + + g_list_free (list); + g_list_free (bar); + return OK; +} + +RESULT +test_list_insert_before () +{ + GList *foo, *bar, *baz; + + foo = g_list_prepend (NULL, "foo"); + foo = g_list_insert_before (foo, NULL, "bar"); + bar = g_list_last (foo); + + if (strcmp (bar->data, "bar")) + return FAILED ("1"); + + baz = g_list_insert_before (foo, bar, "baz"); + if (foo != baz) + return FAILED ("2"); + + if (strcmp (g_list_nth_data (foo, 1), "baz")) + return FAILED ("3: %s", g_list_nth_data (foo, 1)); + + g_list_free (foo); + return OK; +} + +#define N_ELEMS 101 + +static int intcompare (gconstpointer p1, gconstpointer p2) +{ + return GPOINTER_TO_INT (p1) - GPOINTER_TO_INT (p2); +} + +static gboolean verify_sort (GList *list, int len) +{ + int prev; + + if (list->prev) + return FALSE; + + prev = GPOINTER_TO_INT (list->data); + len--; + for (list = list->next; list; list = list->next) { + int curr = GPOINTER_TO_INT (list->data); + if (prev > curr) + return FALSE; + prev = curr; + + if (!list->prev || list->prev->next != list) + return FALSE; + + if (len == 0) + return FALSE; + len--; + } + return len == 0; +} + +RESULT +test_list_sort () +{ + int i, j, mul; + GList *list = NULL; + + for (i = 0; i < N_ELEMS; ++i) + list = g_list_prepend (list, GINT_TO_POINTER (i)); + list = g_list_sort (list, intcompare); + if (!verify_sort (list, N_ELEMS)) + return FAILED ("decreasing list"); + + g_list_free (list); + + list = NULL; + for (i = 0; i < N_ELEMS; ++i) + list = g_list_prepend (list, GINT_TO_POINTER (-i)); + list = g_list_sort (list, intcompare); + if (!verify_sort (list, N_ELEMS)) + return FAILED ("increasing list"); + + g_list_free (list); + + list = g_list_prepend (NULL, GINT_TO_POINTER (0)); + for (i = 1; i < N_ELEMS; ++i) { + list = g_list_prepend (list, GINT_TO_POINTER (i)); + list = g_list_prepend (list, GINT_TO_POINTER (-i)); + } + list = g_list_sort (list, intcompare); + if (!verify_sort (list, 2*N_ELEMS-1)) + return FAILED ("alternating list"); + + g_list_free (list); + + list = NULL; + mul = 1; + for (i = 1; i < N_ELEMS; ++i) { + mul = -mul; + for (j = 0; j < i; ++j) + list = g_list_prepend (list, GINT_TO_POINTER (mul * j)); + } + list = g_list_sort (list, intcompare); + if (!verify_sort (list, (N_ELEMS*N_ELEMS - N_ELEMS)/2)) + return FAILED ("wavering list"); + + g_list_free (list); + + return OK; +} + +static gint +find_custom (gconstpointer a, gconstpointer b) +{ + return(strcmp (a, b)); +} + +RESULT +test_list_find_custom () +{ + GList *list = NULL, *found; + char *foo = "foo"; + char *bar = "bar"; + char *baz = "baz"; + + list = g_list_prepend (list, baz); + list = g_list_prepend (list, bar); + list = g_list_prepend (list, foo); + + found = g_list_find_custom (list, baz, find_custom); + + if (found == NULL) + return FAILED ("Find failed"); + + g_list_free (list); + + return OK; +} + +static Test list_tests [] = { + { "length", test_list_length}, + { "nth", test_list_nth}, + { "index", test_list_index}, + { "last", test_list_last}, + { "append", test_list_append}, + { "concat", test_list_concat}, + {"insert_sorted", test_list_insert_sorted}, + {"insert_before", test_list_insert_before}, + { "copy", test_list_copy}, + { "reverse", test_list_reverse}, + { "remove", test_list_remove}, + { "remove_link", test_list_remove_link}, + { "remove_link", test_list_remove_link}, + { "sort", test_list_sort}, + { "find_custom", test_list_find_custom}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(list_tests_init, list_tests) diff --git a/deps/eglib/test/markup.c b/deps/eglib/test/markup.c new file mode 100644 index 00000000..cf8d3f2d --- /dev/null +++ b/deps/eglib/test/markup.c @@ -0,0 +1,234 @@ +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include "test.h" + +#define do_bad_test(s) do { char *r = markup_test (s); if (r == NULL) return FAILED ("Failed on test " # s); else g_free (r); } while (0) +#define do_ok_test(s) do { char *r = markup_test (s); if (r != NULL) return FAILED ("Could not parse valid " # s); } while (0) + +static char * +markup_test (const char *s) +{ + GMarkupParser *parser = g_new0 (GMarkupParser, 1); + GMarkupParseContext *context; + GError *error = NULL; + + context = g_markup_parse_context_new (parser, 0, 0, 0); + + g_markup_parse_context_parse (context, s, strlen (s), &error); + g_markup_parse_context_free (context); + + if (error != NULL){ + char *msg = g_strdup (error->message); + g_error_free (error); + + g_free (parser); + return msg; + } + g_free (parser); + return NULL; +} + +RESULT +invalid_documents (void) +{ + /* These should fail */ + do_bad_test ("<1>"); + do_bad_test ("<a<"); + do_bad_test ("</a>"); + do_bad_test ("<a b>"); + do_bad_test ("<a b=>"); + do_bad_test ("<a b=c>"); + + return OK; +} + +RESULT +valid_documents (void) +{ + /* These should fail */ + do_ok_test ("<a>"); + do_ok_test ("<a a=\"b\">"); + + return OK; +} + +/* + * This is a test for the kind of files that the code in mono/domain.c + * parses; This code comes from Mono + */ +typedef struct { + GSList *supported_runtimes; + char *required_runtime; + int configuration_count; + int startup_count; +} AppConfigInfo; + +static char * +get_attribute_value (const gchar **attribute_names, + const gchar **attribute_values, + const char *att_name) +{ + int n; + for (n=0; attribute_names[n] != NULL; n++) { + if (strcmp (attribute_names[n], att_name) == 0) + return g_strdup (attribute_values[n]); + } + return NULL; +} + +static void +start_element (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + AppConfigInfo* app_config = (AppConfigInfo*) user_data; + + if (strcmp (element_name, "configuration") == 0) { + app_config->configuration_count++; + return; + } + if (strcmp (element_name, "startup") == 0) { + app_config->startup_count++; + return; + } + + if (app_config->configuration_count != 1 || app_config->startup_count != 1) + return; + + if (strcmp (element_name, "requiredRuntime") == 0) { + app_config->required_runtime = get_attribute_value (attribute_names, attribute_values, "version"); + } else if (strcmp (element_name, "supportedRuntime") == 0) { + char *version = get_attribute_value (attribute_names, attribute_values, "version"); + app_config->supported_runtimes = g_slist_append (app_config->supported_runtimes, version); + } +} + +static void +end_element (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + AppConfigInfo* app_config = (AppConfigInfo*) user_data; + + if (strcmp (element_name, "configuration") == 0) { + app_config->configuration_count--; + } else if (strcmp (element_name, "startup") == 0) { + app_config->startup_count--; + } +} + +static const GMarkupParser +mono_parser = { + start_element, + end_element, + NULL, + NULL, + NULL +}; + +AppConfigInfo * +domain_test (char *text) +{ + AppConfigInfo *app_config = g_new0 (AppConfigInfo, 1); + GMarkupParseContext *context; + + context = g_markup_parse_context_new (&mono_parser, 0, app_config, NULL); + if (g_markup_parse_context_parse (context, text, strlen (text), NULL)) { + g_markup_parse_context_end_parse (context, NULL); + } + g_markup_parse_context_free (context); + + return app_config; +} + +void +domain_free (AppConfigInfo *info) +{ + GSList *l; + if (info->required_runtime) + g_free (info->required_runtime); + for (l = info->supported_runtimes; l != NULL; l = l->next){ + g_free (l->data); + } + g_slist_free (info->supported_runtimes); + g_free (info); +} + +RESULT +mono_domain (void) +{ + AppConfigInfo *info; + + info = domain_test ("<configuration><!--hello--><startup><!--world--><requiredRuntime version=\"v1\"><!--r--></requiredRuntime></startup></configuration>"); + if (info->required_runtime == NULL) + return FAILED ("No required runtime section"); + if (strcmp (info->required_runtime, "v1") != 0) + return FAILED ("Got a runtime version %s, expected v1", info->required_runtime); + domain_free (info); + + info = domain_test ("<configuration><startup><requiredRuntime version=\"v1\"/><!--comment--></configuration><!--end-->"); + if (info->required_runtime == NULL) + return FAILED ("No required runtime section on auto-close section"); + if (strcmp (info->required_runtime, "v1") != 0) + return FAILED ("Got a runtime version %s, expected v1", info->required_runtime); + domain_free (info); + + info = domain_test ("<!--start--><configuration><startup><supportedRuntime version=\"v1\"/><!--middle--><supportedRuntime version=\"v2\"/></startup></configuration>"); + if ((strcmp ((char*)info->supported_runtimes->data, "v1") == 0)){ + if (info->supported_runtimes->next == NULL) + return FAILED ("Expected 2 supported runtimes"); + + if ((strcmp ((char*)info->supported_runtimes->next->data, "v2") != 0)) + return FAILED ("Expected v1, v2, got %s", info->supported_runtimes->next->data); + if (info->supported_runtimes->next->next != NULL) + return FAILED ("Expected v1, v2, got more"); + } else + return FAILED ("Expected `v1', got %s", info->supported_runtimes->data); + domain_free (info); + + return NULL; +} + +RESULT +mcs_config (void) +{ + return markup_test ("<configuration>\r\n <system.diagnostics>\r\n <trace autoflush=\"true\" indentsize=\"4\">\r\n <listeners>\r\n <add name=\"compilerLogListener\" type=\"System.Diagnostics.TextWriterTraceListener,System\"/> </listeners> </trace> </system.diagnostics> </configuration>"); + +} + +RESULT +xml_parse (void) +{ + return markup_test ("<?xml version=\"1.0\" encoding=\"utf-8\"?><a></a>"); +} + +RESULT +machine_config (void) +{ + char *data; + gsize size; + + if (g_file_get_contents ("../../data/net_1_1/machine.config", &data, &size, NULL)){ + return markup_test (data); + } + printf ("Ignoring this test\n"); + return NULL; +} + +static Test markup_tests [] = { + {"invalid_documents", invalid_documents}, + {"good_documents", valid_documents}, + {"mono_domain", mono_domain}, + {"mcs_config", mcs_config}, + {"xml_parse", xml_parse}, + {"machine_config", machine_config}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(markup_tests_init, markup_tests) + diff --git a/deps/eglib/test/memory.c b/deps/eglib/test/memory.c new file mode 100644 index 00000000..db7db080 --- /dev/null +++ b/deps/eglib/test/memory.c @@ -0,0 +1,40 @@ + +#include <glib.h> +#include "test.h" + +RESULT +test_memory_zero_size_allocations () +{ + gpointer p; + + p = g_malloc (0); + if (p) + return FAILED ("Calling g_malloc with size zero should return NULL."); + + p = g_malloc0 (0); + if (p) + return FAILED ("Calling g_malloc0 with size zero should return NULL."); + + p = g_realloc (NULL, 0); + if (p) + return FAILED ("Calling g_realloc with size zero should return NULL."); + + p = g_new (int, 0); + if (p) + return FAILED ("Calling g_new with size zero should return NULL."); + + p = g_new0 (int, 0); + if (p) + return FAILED ("Calling g_new0 with size zero should return NULL."); + + return OK; +} + + +static Test memory_tests [] = { + { "zero_size_allocations", test_memory_zero_size_allocations}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(memory_tests_init, memory_tests) + diff --git a/deps/eglib/test/module.c b/deps/eglib/test/module.c new file mode 100644 index 00000000..a2836378 --- /dev/null +++ b/deps/eglib/test/module.c @@ -0,0 +1,64 @@ +#include <config.h> +#include <glib.h> +#include <gmodule.h> +#include <string.h> +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include "test.h" + +#if defined (G_OS_WIN32) +#define EXTERNAL_SYMBOL "GetProcAddress" +#else +#define EXTERNAL_SYMBOL "system" +#endif + +void G_MODULE_EXPORT +dummy_test_export () +{ +} + +/* test for g_module_open (NULL, ...) */ +RESULT +test_module_symbol_null () +{ + gpointer proc = GINT_TO_POINTER (42); + + GModule *m = g_module_open (NULL, G_MODULE_BIND_LAZY); + + if (m == NULL) + return FAILED ("bind to main module failed. #0"); + + if (g_module_symbol (m, "__unlikely_\nexistent__", &proc)) + return FAILED ("non-existent symbol lookup failed. #1"); + + if (proc) + return FAILED ("non-existent symbol lookup failed. #2"); + + if (!g_module_symbol (m, EXTERNAL_SYMBOL, &proc)) + return FAILED ("external lookup failed. #3"); + + if (!proc) + return FAILED ("external lookup failed. #4"); + + if (!g_module_symbol (m, "dummy_test_export", &proc)) + return FAILED ("in-proc lookup failed. #5"); + + if (!proc) + return FAILED ("in-proc lookup failed. #6"); + + if (!g_module_close (m)) + return FAILED ("close failed. #7"); + + return OK; +} + +static Test module_tests [] = { + {"g_module_symbol_null", test_module_symbol_null}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(module_tests_init, module_tests) + + diff --git a/deps/eglib/test/path.c b/deps/eglib/test/path.c new file mode 100644 index 00000000..e3832a04 --- /dev/null +++ b/deps/eglib/test/path.c @@ -0,0 +1,357 @@ +#include <config.h> +#include <glib.h> +#include <string.h> +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef G_OS_UNIX +#include <pthread.h> +#endif +#include "test.h" + +#ifdef G_OS_WIN32 +#include <direct.h> +#define chdir _chdir +#endif + +/* This test is just to be used with valgrind */ +RESULT +test_buildpath () +{ + char *s; + char *buffer = "var/private"; + char *dir = "/"; + + s = g_build_path ("/", "hola///", "//mundo", NULL); + if (strcmp (s, "hola/mundo") != 0) + return FAILED ("1 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("/", "hola/", "/mundo", NULL); + if (strcmp (s, "hola/mundo") != 0) + return FAILED ("2 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("/", "hola/", "mundo", NULL); + if (strcmp (s, "hola/mundo") != 0) + return FAILED ("3 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("/", "hola", "/mundo", NULL); + if (strcmp (s, "hola/mundo") != 0) + return FAILED ("4 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("/", "/hello", "world/", NULL); + if (strcmp (s, "/hello/world/") != 0) + return FAILED ("5 Got wrong result, got: %s", s); + g_free (s); + + /* Now test multi-char-separators */ + s = g_build_path ("**", "hello", "world", NULL); + if (strcmp (s, "hello**world") != 0) + return FAILED ("6 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("**", "hello**", "world", NULL); + if (strcmp (s, "hello**world") != 0) + return FAILED ("7 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("**", "hello**", "**world", NULL); + if (strcmp (s, "hello**world") != 0) + return FAILED ("8 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("**", "hello**", "**world", NULL); + if (strcmp (s, "hello**world") != 0) + return FAILED ("9 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("1234567890", "hello", "world", NULL); + if (strcmp (s, "hello1234567890world") != 0) + return FAILED ("10 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("1234567890", "hello1234567890", "1234567890world", NULL); + if (strcmp (s, "hello1234567890world") != 0) + return FAILED ("11 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("1234567890", "hello12345678901234567890", "1234567890world", NULL); + if (strcmp (s, "hello1234567890world") != 0) + return FAILED ("12 Got wrong result, got: %s", s); + g_free (s); + + /* Multiple */ + s = g_build_path ("/", "a", "b", "c", "d", NULL); + if (strcmp (s, "a/b/c/d") != 0) + return FAILED ("13 Got wrong result, got: %s", s); + g_free (s); + + s = g_build_path ("/", "/a", "", "/c/", NULL); + if (strcmp (s, "/a/c/") != 0) + return FAILED ("14 Got wrong result, got: %s", s); + g_free (s); + + /* Null */ + s = g_build_path ("/", NULL, NULL); + if (s == NULL) + return FAILED ("must get a non-NULL return"); + if (s [0] != 0) + return FAILED ("must get an empty string"); + + // This is to test the regression introduced by Levi for the Windows support + // that code errouneously read below the allowed area (in this case dir [-1]). + // and caused all kinds of random errors. + dir = "//"; + dir++; + s = g_build_filename (dir, buffer, NULL); + if (s [0] != '/') + return FAILED ("Must have a '/' at the start"); + + g_free (s); + return OK; +} + +RESULT +test_buildfname () +{ + char *s; + + s = g_build_filename ("a", "b", "c", "d", NULL); +#ifdef G_OS_WIN32 + if (strcmp (s, "a\\b\\c\\d") != 0) +#else + if (strcmp (s, "a/b/c/d") != 0) +#endif + return FAILED ("1 Got wrong result, got: %s", s); + g_free (s); + +#ifdef G_OS_WIN32 + s = g_build_filename ("C:\\", "a", NULL); + if (strcmp (s, "C:\\a") != 0) +#else + s = g_build_filename ("/", "a", NULL); + if (strcmp (s, "/a") != 0) +#endif + return FAILED ("1 Got wrong result, got: %s", s); + +#ifndef G_OS_WIN32 + s = g_build_filename ("/", "foo", "/bar", "tolo/", "/meo/", NULL); + if (strcmp (s, "/foo/bar/tolo/meo/") != 0) + return FAILED ("1 Got wrong result, got: %s", s); +#endif + + return OK; +} + +char * +test_dirname () +{ + char *s; + +#ifdef G_OS_WIN32 + s = g_path_get_dirname ("c:\\home\\miguel"); + if (strcmp (s, "c:\\home") != 0) + return FAILED ("Expected c:\\home, got %s", s); + g_free (s); + + s = g_path_get_dirname ("c:/home/miguel"); + if (strcmp (s, "c:/home") != 0) + return FAILED ("Expected c:/home, got %s", s); + g_free (s); + + s = g_path_get_dirname ("c:\\home\\dingus\\"); + if (strcmp (s, "c:\\home\\dingus") != 0) + return FAILED ("Expected c:\\home\\dingus, got %s", s); + g_free (s); + + s = g_path_get_dirname ("dir.c"); + if (strcmp (s, ".") != 0) + return FAILED ("Expected `.', got %s", s); + g_free (s); + + s = g_path_get_dirname ("c:\\index.html"); + if (strcmp (s, "c:") != 0) + return FAILED ("Expected [c:], got [%s]", s); +#else + s = g_path_get_dirname ("/home/miguel"); + if (strcmp (s, "/home") != 0) + return FAILED ("Expected /home, got %s", s); + g_free (s); + + s = g_path_get_dirname ("/home/dingus/"); + if (strcmp (s, "/home/dingus") != 0) + return FAILED ("Expected /home/dingus, got %s", s); + g_free (s); + + s = g_path_get_dirname ("dir.c"); + if (strcmp (s, ".") != 0) + return FAILED ("Expected `.', got %s", s); + g_free (s); + + s = g_path_get_dirname ("/index.html"); + if (strcmp (s, "/") != 0) + return FAILED ("Expected [/], got [%s]", s); +#endif + return OK; +} + +char * +test_basename () +{ + char *s; + +#ifdef G_OS_WIN32 + s = g_path_get_basename (""); + if (strcmp (s, ".") != 0) + return FAILED ("Expected `.', got %s", s); + g_free (s); + + s = g_path_get_basename ("c:\\home\\dingus\\"); + if (strcmp (s, "dingus") != 0) + return FAILED ("1 Expected dingus, got %s", s); + g_free (s); + + s = g_path_get_basename ("c:/home/dingus/"); + if (strcmp (s, "dingus") != 0) + return FAILED ("1 Expected dingus, got %s", s); + g_free (s); + + s = g_path_get_basename ("c:\\home\\dingus"); + if (strcmp (s, "dingus") != 0) + return FAILED ("2 Expected dingus, got %s", s); + g_free (s); + + s = g_path_get_basename ("c:/home/dingus"); + if (strcmp (s, "dingus") != 0) + return FAILED ("2 Expected dingus, got %s", s); + g_free (s); +#else + s = g_path_get_basename (""); + if (strcmp (s, ".") != 0) + return FAILED ("Expected `.', got %s", s); + g_free (s); + + s = g_path_get_basename ("/home/dingus/"); + if (strcmp (s, "dingus") != 0) + return FAILED ("1 Expected dingus, got %s", s); + g_free (s); + + s = g_path_get_basename ("/home/dingus"); + if (strcmp (s, "dingus") != 0) + return FAILED ("2 Expected dingus, got %s", s); + g_free (s); +#endif + return OK; +} + +gchar * +test_ppath () +{ + char *s; +#ifdef G_OS_WIN32 + const gchar *searchfor = "explorer.exe"; +#else + const gchar *searchfor = "ls"; +#endif + s = g_find_program_in_path (searchfor); + if (s == NULL) + return FAILED ("No %s on this system?", searchfor); + g_free (s); + return OK; +} + +gchar * +test_ppath2 () +{ + char *s; + const char *path = g_getenv ("PATH"); +#ifdef G_OS_WIN32 + const gchar *searchfor = "test_eglib.exe"; +#else + const gchar *searchfor = "test-glib"; +#endif + + g_setenv ("PATH", "", TRUE); + s = g_find_program_in_path ("ls"); + if (s != NULL) { + g_setenv ("PATH", path, TRUE); + return FAILED ("Found something interesting here: %s", s); + } + g_free (s); + s = g_find_program_in_path (searchfor); + if (s == NULL) { + g_setenv ("PATH", path, TRUE); + return FAILED ("It should find '%s' in the current directory.", searchfor); + } + g_free (s); + g_setenv ("PATH", path, TRUE); + return OK; +} + +#ifndef DISABLE_FILESYSTEM_TESTS +gchar * +test_cwd () +{ + char *dir = g_get_current_dir (); +#ifdef G_OS_WIN32 + const gchar *newdir = "C:\\Windows"; +#else + const gchar *newdir = "/bin"; +#endif + + if (dir == NULL) + return FAILED ("No current directory?"); + g_free (dir); + + if (chdir (newdir) == -1) + return FAILED ("No %s?", newdir); + + dir = g_get_current_dir (); + if (strcmp (dir, newdir) != 0) + return FAILED("Did not go to %s?", newdir); + g_free (dir); + + return OK; +} +#else +gchar * +test_cwd () +{ + return OK; +} +#endif + +gchar * +test_misc () +{ + const char *home = g_get_home_dir (); + const char *tmp = g_get_tmp_dir (); + + if (home == NULL) + return FAILED ("Where did my home go?"); + + if (tmp == NULL) + return FAILED ("Where did my /tmp go?"); + + return OK; +} + +static Test path_tests [] = { + {"g_build_filename", test_buildfname}, + {"g_buildpath", test_buildpath}, + {"g_path_get_dirname", test_dirname}, + {"g_path_get_basename", test_basename}, + {"g_find_program_in_path", test_ppath}, + {"g_find_program_in_path2", test_ppath2}, + {"test_cwd", test_cwd }, + {"test_misc", test_misc }, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(path_tests_init, path_tests) + + diff --git a/deps/eglib/test/pattern.c b/deps/eglib/test/pattern.c new file mode 100644 index 00000000..7db5a7be --- /dev/null +++ b/deps/eglib/test/pattern.c @@ -0,0 +1,61 @@ +#include <config.h> +#include <glib.h> +#include <string.h> +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdio.h> +#include "test.h" + +#define MATCH(pat,string,error_if,msg) \ + spec = g_pattern_spec_new (pat); \ + res = g_pattern_match_string (spec, string); \ + if (res == error_if) \ + return FAILED (msg " returned %s", res ? "TRUE" : "FALSE"); \ + g_pattern_spec_free (spec); + +#define TEST_MATCH(pat,string,n) MATCH (pat, string, FALSE, "MATCH " #n) +#define TEST_NO_MATCH(pat,string,n) MATCH (pat, string,TRUE, "NO_MATCH " #n) + +RESULT +test_pattern_spec () +{ + GPatternSpec *spec; + gboolean res; + + /* spec = g_pattern_spec_new (NULL); */ + TEST_MATCH ("*", "hola", 1); + TEST_MATCH ("hola", "hola", 2); + TEST_MATCH ("????", "hola", 3); + TEST_MATCH ("???a", "hola", 4); + TEST_MATCH ("h??a", "hola", 5); + TEST_MATCH ("h??*", "hola", 6); + TEST_MATCH ("h*", "hola", 7); + TEST_MATCH ("*hola", "hola", 8); + TEST_MATCH ("*l*", "hola", 9); + TEST_MATCH ("h*??", "hola", 10); + TEST_MATCH ("h*???", "hola", 11); + TEST_MATCH ("?o??", "hola", 12); + TEST_MATCH ("*h*o*l*a*", "hola", 13); + TEST_MATCH ("h*o*l*a", "hola", 14); + TEST_MATCH ("h?*?", "hola", 15); + + TEST_NO_MATCH ("", "hola", 1); + TEST_NO_MATCH ("?????", "hola", 2); + TEST_NO_MATCH ("???", "hola", 3); + TEST_NO_MATCH ("*o", "hola", 4); + TEST_NO_MATCH ("h", "hola", 5); + TEST_NO_MATCH ("h*????", "hola", 6); + + return OK; +} + +static Test pattern_tests [] = { + {"g_pattern_spec*", test_pattern_spec}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(pattern_tests_init, pattern_tests) + + diff --git a/deps/eglib/test/ptrarray.c b/deps/eglib/test/ptrarray.c new file mode 100644 index 00000000..34d78b02 --- /dev/null +++ b/deps/eglib/test/ptrarray.c @@ -0,0 +1,349 @@ +#include <stdio.h> +#include <glib.h> +#include "test.h" + +/* Redefine the private structure only to verify proper allocations */ +typedef struct _GPtrArrayPriv { + gpointer *pdata; + guint len; + guint size; +} GPtrArrayPriv; + +/* Don't add more than 32 items to this please */ +static const char *items [] = { + "Apples", "Oranges", "Plumbs", "Goats", "Snorps", "Grapes", + "Tickle", "Place", "Coffee", "Cookies", "Cake", "Cheese", + "Tseng", "Holiday", "Avenue", "Smashing", "Water", "Toilet", + NULL +}; + +static GPtrArray *ptrarray_alloc_and_fill(guint *item_count) +{ + GPtrArray *array = g_ptr_array_new(); + gint i; + + for(i = 0; items[i] != NULL; i++) { + g_ptr_array_add(array, (gpointer)items[i]); + } + + if(item_count != NULL) { + *item_count = i; + } + + return array; +} + +static guint guess_size(guint length) +{ + guint size = 1; + + while(size < length) { + size <<= 1; + } + + return size; +} + +RESULT ptrarray_alloc() +{ + GPtrArrayPriv *array; + guint i; + + array = (GPtrArrayPriv *)ptrarray_alloc_and_fill(&i); + + if(array->size != guess_size(array->len)) { + return FAILED("Size should be %d, but it is %d", + guess_size(array->len), array->size); + } + + if(array->len != i) { + return FAILED("Expected %d node(s) in the array", i); + } + + g_ptr_array_free((GPtrArray *)array, TRUE); + + return OK; +} + +RESULT ptrarray_for_iterate() +{ + GPtrArray *array = ptrarray_alloc_and_fill(NULL); + guint i; + + for(i = 0; i < array->len; i++) { + char *item = (char *)g_ptr_array_index(array, i); + if(item != items[i]) { + return FAILED( + "Expected item at %d to be %s, but it was %s", + i, items[i], item); + } + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +static gint foreach_iterate_index = 0; +static char *foreach_iterate_error = NULL; + +void foreach_callback(gpointer data, gpointer user_data) +{ + char *item = (char *)data; + const char *item_cmp = items[foreach_iterate_index++]; + + if(foreach_iterate_error != NULL) { + return; + } + + if(item != item_cmp) { + foreach_iterate_error = FAILED( + "Expected item at %d to be %s, but it was %s", + foreach_iterate_index - 1, item_cmp, item); + } +} + +RESULT ptrarray_foreach_iterate() +{ + GPtrArray *array = ptrarray_alloc_and_fill(NULL); + + foreach_iterate_index = 0; + foreach_iterate_error = NULL; + + g_ptr_array_foreach(array, foreach_callback, array); + + g_ptr_array_free(array, TRUE); + + return foreach_iterate_error; +} + +RESULT ptrarray_set_size() +{ + GPtrArray *array = g_ptr_array_new(); + guint i, grow_length = 50; + + g_ptr_array_add(array, (gpointer)items[0]); + g_ptr_array_add(array, (gpointer)items[1]); + g_ptr_array_set_size(array, grow_length); + + if(array->len != grow_length) { + return FAILED("Array length should be 50, it is %d", array->len); + } else if(array->pdata[0] != items[0]) { + return FAILED("Item 0 was overwritten, should be %s", items[0]); + } else if(array->pdata[1] != items[1]) { + return FAILED("Item 1 was overwritten, should be %s", items[1]); + } + + for(i = 2; i < array->len; i++) { + if(array->pdata[i] != NULL) { + return FAILED("Item %d is not NULL, it is %p", i, array->pdata[i]); + } + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +RESULT ptrarray_remove_index() +{ + GPtrArray *array; + guint i; + + array = ptrarray_alloc_and_fill(&i); + + g_ptr_array_remove_index(array, 0); + if(array->pdata[0] != items[1]) { + return FAILED("First item is not %s, it is %s", items[1], + array->pdata[0]); + } + + g_ptr_array_remove_index(array, array->len - 1); + + if(array->pdata[array->len - 1] != items[array->len]) { + return FAILED("Last item is not %s, it is %s", + items[array->len - 2], array->pdata[array->len - 1]); + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +RESULT ptrarray_remove_index_fast() +{ + GPtrArray *array; + guint i; + + array = ptrarray_alloc_and_fill(&i); + + g_ptr_array_remove_index_fast(array, 0); + if(array->pdata[0] != items[array->len]) { + return FAILED("First item is not %s, it is %s", items[array->len], + array->pdata[0]); + } + + g_ptr_array_remove_index_fast(array, array->len - 1); + if(array->pdata[array->len - 1] != items[array->len - 1]) { + return FAILED("Last item is not %s, it is %s", + items[array->len - 1], array->pdata[array->len - 1]); + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +RESULT ptrarray_remove() +{ + GPtrArray *array; + guint i; + + array = ptrarray_alloc_and_fill(&i); + + g_ptr_array_remove(array, (gpointer)items[7]); + + if(!g_ptr_array_remove(array, (gpointer)items[4])) { + return FAILED("Item %s not removed", items[4]); + } + + if(g_ptr_array_remove(array, (gpointer)items[4])) { + return FAILED("Item %s still in array after removal", items[4]); + } + + if(array->pdata[array->len - 1] != items[array->len + 1]) { + return FAILED("Last item in GPtrArray not correct"); + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +static gint ptrarray_sort_compare(gconstpointer a, gconstpointer b) +{ + gchar *stra = *(gchar **) a; + gchar *strb = *(gchar **) b; + return strcmp(stra, strb); +} + +RESULT ptrarray_sort() +{ + GPtrArray *array = g_ptr_array_new(); + guint i; + gchar *letters [] = { "A", "B", "C", "D", "E" }; + + g_ptr_array_add(array, letters[0]); + g_ptr_array_add(array, letters[1]); + g_ptr_array_add(array, letters[2]); + g_ptr_array_add(array, letters[3]); + g_ptr_array_add(array, letters[4]); + + g_ptr_array_sort(array, ptrarray_sort_compare); + + for(i = 0; i < array->len; i++) { + if(array->pdata[i] != letters[i]) { + return FAILED("Array out of order, expected %s got %s at position %d", + letters [i], (gchar *) array->pdata [i], i); + } + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +static gint ptrarray_sort_compare_with_data (gconstpointer a, gconstpointer b, gpointer user_data) +{ + gchar *stra = *(gchar **) a; + gchar *strb = *(gchar **) b; + + if (strcmp (user_data, "this is the data for qsort") != 0) + fprintf (stderr, "oops at compare with_data\n"); + + return strcmp(stra, strb); +} + +RESULT ptrarray_sort_with_data () +{ + GPtrArray *array = g_ptr_array_new(); + guint i; + gchar *letters [] = { "A", "B", "C", "D", "E" }; + + g_ptr_array_add(array, letters[4]); + g_ptr_array_add(array, letters[1]); + g_ptr_array_add(array, letters[2]); + g_ptr_array_add(array, letters[0]); + g_ptr_array_add(array, letters[3]); + + g_ptr_array_sort_with_data(array, ptrarray_sort_compare_with_data, "this is the data for qsort"); + + for(i = 0; i < array->len; i++) { + if(array->pdata[i] != letters[i]) { + return FAILED("Array out of order, expected %s got %s at position %d", + letters [i], (gchar *) array->pdata [i], i); + } + } + + g_ptr_array_free(array, TRUE); + + return OK; +} + +RESULT ptrarray_remove_fast() +{ + GPtrArray *array = g_ptr_array_new(); + gchar *letters [] = { "A", "B", "C", "D", "E" }; + + if (g_ptr_array_remove_fast (array, NULL)) + return FAILED ("Removing NULL succeeded"); + + g_ptr_array_add(array, letters[0]); + if (!g_ptr_array_remove_fast (array, letters[0]) || array->len != 0) + return FAILED ("Removing last element failed"); + + g_ptr_array_add(array, letters[0]); + g_ptr_array_add(array, letters[1]); + g_ptr_array_add(array, letters[2]); + g_ptr_array_add(array, letters[3]); + g_ptr_array_add(array, letters[4]); + + if (!g_ptr_array_remove_fast (array, letters[0]) || array->len != 4) + return FAILED ("Removing first element failed"); + + if (array->pdata [0] != letters [4]) + return FAILED ("First element wasn't replaced with last upon removal"); + + if (g_ptr_array_remove_fast (array, letters[0])) + return FAILED ("Succedeed removing a non-existing element"); + + if (!g_ptr_array_remove_fast (array, letters[3]) || array->len != 3) + return FAILED ("Failed removing \"D\""); + + if (!g_ptr_array_remove_fast (array, letters[1]) || array->len != 2) + return FAILED ("Failed removing \"B\""); + + if (array->pdata [0] != letters [4] || array->pdata [1] != letters [2]) + return FAILED ("Last two elements are wrong"); + g_ptr_array_free(array, TRUE); + + return OK; +} + +static Test ptrarray_tests [] = { + {"alloc", ptrarray_alloc}, + {"for_iterate", ptrarray_for_iterate}, + {"foreach_iterate", ptrarray_foreach_iterate}, + {"set_size", ptrarray_set_size}, + {"remove_index", ptrarray_remove_index}, + {"remove_index_fast", ptrarray_remove_index_fast}, + {"remove", ptrarray_remove}, + {"sort", ptrarray_sort}, + {"remove_fast", ptrarray_remove_fast}, + {"sort_with_data", ptrarray_sort_with_data}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(ptrarray_tests_init, ptrarray_tests) + + diff --git a/deps/eglib/test/queue.c b/deps/eglib/test/queue.c new file mode 100644 index 00000000..b12ddec1 --- /dev/null +++ b/deps/eglib/test/queue.c @@ -0,0 +1,184 @@ +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include "test.h" + +RESULT +test_queue_push () +{ + GQueue *queue = g_queue_new (); + + g_queue_push_head (queue, "foo"); + g_queue_push_head (queue, "bar"); + g_queue_push_head (queue, "baz"); + + if (queue->length != 3) + return FAILED ("push failed"); + + if (NULL != queue->head->prev) + return FAILED ("HEAD: prev is wrong"); + if (strcmp ("baz", queue->head->data)) + return FAILED ("HEAD: First element is wrong"); + if (strcmp ("bar", queue->head->next->data)) + return FAILED ("HEAD: Second element is wrong"); + if (strcmp ("foo", queue->head->next->next->data)) + return FAILED ("HEAD: Third element is wrong"); + if (NULL != queue->head->next->next->next) + return FAILED ("HEAD: End is wrong"); + + if (NULL != queue->tail->next) + return FAILED ("TAIL: next is wrong"); + if (strcmp ("foo", queue->tail->data)) + return FAILED ("TAIL: Third element is wrong"); + if (strcmp ("bar", queue->tail->prev->data)) + return FAILED ("TAIL: Second element is wrong"); + if (strcmp ("baz", queue->tail->prev->prev->data)) + return FAILED ("TAIL: First element is wrong"); + if (NULL != queue->tail->prev->prev->prev) + return FAILED ("TAIL: End is wrong"); + + g_queue_free (queue); + return OK; +} + +RESULT +test_queue_push_tail () +{ + GQueue *queue = g_queue_new (); + + g_queue_push_tail (queue, "baz"); + g_queue_push_tail (queue, "bar"); + g_queue_push_tail (queue, "foo"); + + if (queue->length != 3) + return FAILED ("push failed"); + + if (NULL != queue->head->prev) + return FAILED ("HEAD: prev is wrong"); + if (strcmp ("baz", queue->head->data)) + return FAILED ("HEAD: First element is wrong"); + if (strcmp ("bar", queue->head->next->data)) + return FAILED ("HEAD: Second element is wrong"); + if (strcmp ("foo", queue->head->next->next->data)) + return FAILED ("HEAD: Third element is wrong"); + if (NULL != queue->head->next->next->next) + return FAILED ("HEAD: End is wrong"); + + if (NULL != queue->tail->next) + return FAILED ("TAIL: next is wrong"); + if (strcmp ("foo", queue->tail->data)) + return FAILED ("TAIL: Third element is wrong"); + if (strcmp ("bar", queue->tail->prev->data)) + return FAILED ("TAIL: Second element is wrong"); + if (strcmp ("baz", queue->tail->prev->prev->data)) + return FAILED ("TAIL: First element is wrong"); + if (NULL != queue->tail->prev->prev->prev) + return FAILED ("TAIL: End is wrong"); + + g_queue_free (queue); + return OK; +} + +RESULT +test_queue_pop () +{ + GQueue *queue = g_queue_new (); + gpointer data; + + g_queue_push_head (queue, "foo"); + g_queue_push_head (queue, "bar"); + g_queue_push_head (queue, "baz"); + + data = g_queue_pop_head (queue); + if (strcmp ("baz", data)) + return FAILED ("expect baz."); + + data = g_queue_pop_head (queue); + if (strcmp ("bar", data)) + return FAILED ("expect bar."); + + data = g_queue_pop_head (queue); + if (strcmp ("foo", data)) + return FAILED ("expect foo."); + + if (g_queue_is_empty (queue) == FALSE) + return FAILED ("expect is_empty."); + + if (queue->length != 0) + return FAILED ("expect 0 length ."); + + g_queue_push_head (queue, "foo"); + g_queue_push_head (queue, "bar"); + g_queue_push_head (queue, "baz"); + + g_queue_pop_head (queue); + + if (NULL != queue->head->prev) + return FAILED ("HEAD: prev is wrong"); + if (strcmp ("bar", queue->head->data)) + return FAILED ("HEAD: Second element is wrong"); + if (strcmp ("foo", queue->head->next->data)) + return FAILED ("HEAD: Third element is wrong"); + if (NULL != queue->head->next->next) + return FAILED ("HEAD: End is wrong"); + + if (NULL != queue->tail->next) + return FAILED ("TAIL: next is wrong"); + if (strcmp ("foo", queue->tail->data)) + return FAILED ("TAIL: Second element is wrong"); + if (strcmp ("bar", queue->tail->prev->data)) + return FAILED ("TAIL: First element is wrong"); + if (NULL != queue->tail->prev->prev) + return FAILED ("TAIL: End is wrong"); + + g_queue_free (queue); + return OK; +} + +RESULT +test_queue_new () +{ + GQueue *queue = g_queue_new (); + + if (queue->length != 0) + return FAILED ("expect length == 0"); + + if (queue->head != NULL) + return FAILED ("expect head == NULL"); + + if (queue->tail != NULL) + return FAILED ("expect tail == NULL"); + + g_queue_free (queue); + return OK; +} + +RESULT +test_queue_is_empty () +{ + GQueue *queue = g_queue_new (); + + if (g_queue_is_empty (queue) == FALSE) + return FAILED ("new queue should be empty"); + + g_queue_push_head (queue, "foo"); + + if (g_queue_is_empty (queue) == TRUE) + return FAILED ("expected TRUE"); + + g_queue_free (queue); + + return OK; +} + +static Test queue_tests [] = { + { "push", test_queue_push}, + {"push_tail", test_queue_push_tail}, + { "pop", test_queue_pop}, + { "new", test_queue_new}, + {"is_empty", test_queue_is_empty}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(queue_tests_init, queue_tests) + diff --git a/deps/eglib/test/shell.c b/deps/eglib/test/shell.c new file mode 100644 index 00000000..4715f1ca --- /dev/null +++ b/deps/eglib/test/shell.c @@ -0,0 +1,331 @@ +#include <glib.h> +#include <string.h> +#include <stdio.h> +#include "test.h" + +RESULT +test_shell_argv1 () +{ + GError *error; + gint argc; + gchar **argv; + gboolean ret; + + /* The next line prints a critical error and returns FALSE + ret = g_shell_parse_argv (NULL, NULL, NULL, NULL); + */ + ret = g_shell_parse_argv ("", NULL, NULL, NULL); + if (ret) + return FAILED ("1. It should return FALSE"); + + ret = g_shell_parse_argv ("hola", NULL, NULL, NULL); + if (!ret) + return FAILED ("2. It should return TRUE"); + + argc = 0; + ret = g_shell_parse_argv ("hola", &argc, NULL, NULL); + if (!ret) + return FAILED ("3. It should return TRUE"); + if (argc != 1) + return FAILED ("4. argc was %d", argc); + + argc = 0; + ret = g_shell_parse_argv ("hola bola", &argc, NULL, NULL); + if (!ret) + return FAILED ("5. It should return TRUE"); + if (argc != 2) + return FAILED ("6. argc was %d", argc); + + argc = 0; + ret = g_shell_parse_argv ("hola bola", &argc, &argv, NULL); + if (!ret) + return FAILED ("7. It should return TRUE"); + if (argc != 2) + return FAILED ("8. argc was %d", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("9. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "bola")) + return FAILED ("10. argv[1] was %s", argv [1]); + + g_strfreev (argv); + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola 'bola'", &argc, &argv, &error); + if (!ret) + return FAILED ("11. It should return TRUE"); + if (argc != 2) + return FAILED ("12. argc was %d expected 2", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("13. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "bola")) + return FAILED ("14. argv[1] was %s", argv [1]); + if (error != NULL) + return FAILED ("15. error is not null"); + + + g_strfreev (argv); + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola '' 'bola'", &argc, &argv, &error); + if (!ret) + return FAILED ("16. It should return TRUE"); + if (argc != 3) + return FAILED ("17. argc was %d expected 3", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("18. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "")) + return FAILED ("19. argv[2] was %s", argv [1]); + if (strcmp (argv [2], "bola")) + return FAILED ("19. argv[2] was %s", argv [2]); + if (error != NULL) + return FAILED ("20. error is not null"); + + g_strfreev (argv); + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola'' bola", &argc, &argv, &error); + if (!ret) + return FAILED ("21. It should return TRUE"); + if (argc != 2) + return FAILED ("22. argc was %d expected 2", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("23. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "bola")) + return FAILED ("24. argv[2] was %s", argv [1]); + if (error != NULL) + return FAILED ("25. error is not null"); + + return OK; +} + +RESULT +test_shell_argv2 () +{ + GError *error; + gint argc; + gchar **argv; + gboolean ret; + + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola \"bola\"", &argc, &argv, &error); + if (!ret) + return FAILED ("1. It should return TRUE"); + if (argc != 2) + return FAILED ("2. argc was %d expected 2", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("3. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "bola")) + return FAILED ("4. argv[1] was %s", argv [1]); + if (error != NULL) + return FAILED ("5. error is not null"); + + g_strfreev (argv); + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola \"\" \"bola \"", &argc, &argv, &error); + if (!ret) + return FAILED ("6. It should return TRUE"); + if (argc != 3) + return FAILED ("7. argc was %d expected 3", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("8. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "")) + return FAILED ("9. argv[2] was %s", argv [1]); + if (strcmp (argv [2], "bola ")) + return FAILED ("10. argv[2] was %s", argv [2]); + if (error != NULL) + return FAILED ("11. error is not null"); + + g_strfreev (argv); + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola\n\t \"\t\" \"bola \"", &argc, &argv, &error); + if (!ret) + return FAILED ("10. It should return TRUE"); + if (argc != 3) + return FAILED ("11. argc was %d expected 3", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("12. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "\t")) + return FAILED ("13. argv[2] was %s", argv [1]); + if (strcmp (argv [2], "bola ")) + return FAILED ("14. argv[2] was %s", argv [2]); + if (error != NULL) + return FAILED ("15. error is not null"); + + g_strfreev (argv); + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola\n\t \\\n \"\t\" \"bola \"", &argc, &argv, &error); + if (!ret) + return FAILED ("16. It should return TRUE"); + if (argc != 3) + return FAILED ("17. argc was %d expected 3", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("18. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "\t")) + return FAILED ("19. argv[2] was %s", argv [1]); + if (strcmp (argv [2], "bola ")) + return FAILED ("20. argv[2] was %s", argv [2]); + if (error != NULL) + return FAILED ("21. error is not null"); + + g_strfreev (argv); + return OK; +} + +RESULT +test_shell_argv3 () +{ + GError *error; + gint argc; + gchar **argv; + gboolean ret; + + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv ("hola \"bola", &argc, &argv, &error); + if (ret) + return FAILED ("1. It should return FALSE"); + if (argc != 0) + return FAILED ("2. argc was %d expected 0", argc); + if (argv != NULL) + return FAILED ("3. argv[0] was %s", argv [0]); + if (error == NULL) + return FAILED ("4. error is null"); + + /* Text ended before matching quote was found for ". (The text was 'hola "bola') */ + g_error_free (error); + error = NULL; + ret = g_shell_parse_argv ("hola \\\"bola", &argc, &argv, &error); + if (!ret) + return FAILED ("5. It should return TRUE"); + if (argc != 2) + return FAILED ("6. argc was %d expected 2", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("18. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "\"bola")) + return FAILED ("18. argv[1] was %s", argv [1]); + if (error != NULL) + return FAILED ("8. error is not null"); + + g_strfreev (argv); + argv = NULL; + argc = 0; + ret = g_shell_parse_argv ("hola \"\n\\'bola\"", &argc, &argv, &error); + if (!ret) + return FAILED ("9. It should return TRUE. %s", error->message); + if (argc != 2) + return FAILED ("10. argc was %d expected 2", argc); + if (strcmp (argv [0], "hola")) + return FAILED ("11. argv[0] was %s", argv [0]); + if (strcmp (argv [1], "\n\\'bola")) + return FAILED ("12. argv[1] was %s", argv [1]); + if (error != NULL) + return FAILED ("13. error is not null"); + + g_strfreev (argv); + argv = NULL; + argc = 0; + return OK; +} + +// This was the 2.8 showstopper error +RESULT +test_shell_argv4 () +{ + GError *error; + gint argc; + gchar **argv; + gboolean ret; + char *str = "'/usr/bin/gnome-terminal' -e \"bash -c 'read -p \\\"Press any key to continue...\\\" -n1;'\""; + + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv (str, &argc, &argv, &error); + if (!ret) + return FAILED ("1. It should return TRUE"); + if (argc != 3) + return FAILED ("2. argc was %d expected 3", argc); + if (argv == NULL) + return FAILED ("3. argv[0] was NULL"); + if (error != NULL) + return FAILED ("4. error was set"); + + if (strcmp (argv [0], "/usr/bin/gnome-terminal")) + return FAILED ("5. Expected /usr/bin/gnome-terminal got %s", argv [0]); + if (strcmp (argv [1], "-e")) + return FAILED ("6. Expected -e, got: %s", argv [1]); + if (strcmp (argv [2], "bash -c 'read -p \"Press any key to continue...\" -n1;'")) + return FAILED ("7. Got unexpected result: %s\n", argv [2]); + + return OK; +} + +// This is https://bugzilla.novell.com/show_bug.cgi?id=655896 +RESULT +test_shell_argv5 () +{ + GError *error; + gint argc; + gchar **argv; + gboolean ret; + char *str = "echo \"foo\",\"bar\""; + + argv = NULL; + argc = 0; + error = NULL; + ret = g_shell_parse_argv (str, &argc, &argv, &error); + if (!ret) + return FAILED ("1. It should return TRUE"); + if (argc != 2) + return FAILED ("2. argc was %d expected 2", argc); + if (argv == NULL) + return FAILED ("3. argv[0] was NULL"); + if (error != NULL) + return FAILED ("4. error was set"); + + if (strcmp (argv [0], "echo")) + return FAILED ("5. Expected echo got %s", argv [0]); + if (strcmp (argv [1], "foo,bar")) + return FAILED ("6. Expected foo,bar, got: %s", argv [1]); + + return OK; +} + +RESULT +test_quote () +{ + if (strcmp (g_shell_quote ("foo"), "'foo'")) + return FAILED ("Should return 'foo'"); + + if (strcmp (g_shell_quote ("foo'bar"), "'foo'\\''bar'")) + return FAILED ("Should return 'foo'\\''bar'"); + + if (strcmp (g_shell_quote ("foo bar"), "'foo bar'")) + return FAILED ("Should return 'foo bar'"); + return OK; +} + +static Test shell_tests [] = { + {"test_shell_argv1", test_shell_argv1}, + {"test_shell_argv2", test_shell_argv2}, + {"test_shell_argv3", test_shell_argv3}, + {"test_shell_argv4", test_shell_argv4}, + {"test_shell_argv5", test_shell_argv5}, + {"g_shell_quote", test_quote}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(shell_tests_init, shell_tests) + diff --git a/deps/eglib/test/sizes.c b/deps/eglib/test/sizes.c new file mode 100644 index 00000000..06ed8a5a --- /dev/null +++ b/deps/eglib/test/sizes.c @@ -0,0 +1,108 @@ +/* + * Tests to ensure that our type definitions are correct + * + * These depend on -Werror, -Wall being set to catch the build error. + */ +#include <stdio.h> +#ifndef _MSC_VER +#include <stdint.h> +#endif +#include <string.h> +#include <glib.h> +#include "test.h" + +RESULT +test_formats () +{ + char buffer [1024]; + gsize a = 1; + + sprintf (buffer, "%" G_GSIZE_FORMAT, a); + + return NULL; +} + +RESULT +test_ptrconv () +{ + int iv, iv2; + unsigned int uv, uv2; + gpointer ptr; + + iv = G_MAXINT32; + ptr = GINT_TO_POINTER (iv); + iv2 = GPOINTER_TO_INT (ptr); + if (iv != iv2) + return FAILED ("int to pointer and back conversions fail %d != %d", iv, iv2); + + iv = G_MININT32; + ptr = GINT_TO_POINTER (iv); + iv2 = GPOINTER_TO_INT (ptr); + if (iv != iv2) + return FAILED ("int to pointer and back conversions fail %d != %d", iv, iv2); + + iv = 1; + ptr = GINT_TO_POINTER (iv); + iv2 = GPOINTER_TO_INT (ptr); + if (iv != iv2) + return FAILED ("int to pointer and back conversions fail %d != %d", iv, iv2); + + iv = -1; + ptr = GINT_TO_POINTER (iv); + iv2 = GPOINTER_TO_INT (ptr); + if (iv != iv2) + return FAILED ("int to pointer and back conversions fail %d != %d", iv, iv2); + + iv = 0; + ptr = GINT_TO_POINTER (iv); + iv2 = GPOINTER_TO_INT (ptr); + if (iv != iv2) + return FAILED ("int to pointer and back conversions fail %d != %d", iv, iv2); + + uv = 0; + ptr = GUINT_TO_POINTER (uv); + uv2 = GPOINTER_TO_UINT (ptr); + if (uv != uv2) + return FAILED ("uint to pointer and back conversions fail %u != %d", uv, uv2); + + uv = 1; + ptr = GUINT_TO_POINTER (uv); + uv2 = GPOINTER_TO_UINT (ptr); + if (uv != uv2) + return FAILED ("uint to pointer and back conversions fail %u != %d", uv, uv2); + + uv = UINT32_MAX; + ptr = GUINT_TO_POINTER (uv); + uv2 = GPOINTER_TO_UINT (ptr); + if (uv != uv2) + return FAILED ("uint to pointer and back conversions fail %u != %d", uv, uv2); + + return NULL; + +} + +typedef struct { + int a; + int b; +} my_struct; + +RESULT +test_offset () +{ + if (G_STRUCT_OFFSET (my_struct, a) != 0) + return FAILED ("offset of a is not zero"); + + if (G_STRUCT_OFFSET (my_struct, b) != 4 && G_STRUCT_OFFSET (my_struct, b) != 8) + return FAILED ("offset of b is 4 or 8, macro might be busted"); + + return OK; +} + +static Test size_tests [] = { + {"formats", test_formats}, + {"ptrconv", test_ptrconv}, + {"g_struct_offset", test_offset}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(size_tests_init, size_tests) diff --git a/deps/eglib/test/slist.c b/deps/eglib/test/slist.c new file mode 100644 index 00000000..3f8360ec --- /dev/null +++ b/deps/eglib/test/slist.c @@ -0,0 +1,345 @@ +#include <stdio.h> +#include <string.h> +#include <glib.h> +#include "test.h" + + +RESULT +test_slist_nth () +{ + char *foo = "foo"; + char *bar = "bar"; + char *baz = "baz"; + GSList *nth, *list; + list = g_slist_prepend (NULL, baz); + list = g_slist_prepend (list, bar); + list = g_slist_prepend (list, foo); + + nth = g_slist_nth (list, 0); + if (nth->data != foo) + return FAILED ("nth failed. #0"); + + nth = g_slist_nth (list, 1); + if (nth->data != bar) + return FAILED ("nth failed. #1"); + + nth = g_slist_nth (list, 2); + if (nth->data != baz) + return FAILED ("nth failed. #2"); + + nth = g_slist_nth (list, 3); + if (nth) + return FAILED ("nth failed. #3: %s", nth->data); + + g_slist_free (list); + return OK; +} + +RESULT +test_slist_index () +{ + int i; + char *foo = "foo"; + char *bar = "bar"; + char *baz = "baz"; + GSList *list; + list = g_slist_prepend (NULL, baz); + list = g_slist_prepend (list, bar); + list = g_slist_prepend (list, foo); + + i = g_slist_index (list, foo); + if (i != 0) + return FAILED ("index failed. #0: %d", i); + + i = g_slist_index (list, bar); + if (i != 1) + return FAILED ("index failed. #1: %d", i); + + i = g_slist_index (list, baz); + if (i != 2) + return FAILED ("index failed. #2: %d", i); + + g_slist_free (list); + return OK; +} + +RESULT +test_slist_append () +{ + GSList *foo; + GSList *list = g_slist_append (NULL, "first"); + if (g_slist_length (list) != 1) + return FAILED ("append(null,...) failed"); + + foo = g_slist_append (list, "second"); + if (foo != list) + return FAILED ("changed list head on non-empty"); + + if (g_slist_length (list) != 2) + return FAILED ("Append failed"); + + g_slist_free (list); + return OK; +} + +RESULT +test_slist_concat () +{ + GSList *foo = g_slist_prepend (NULL, "foo"); + GSList *bar = g_slist_prepend (NULL, "bar"); + + GSList *list = g_slist_concat (foo, bar); + + if (g_slist_length (list) != 2) + return FAILED ("Concat failed."); + + g_slist_free (list); + return OK; +} + +RESULT +test_slist_find () +{ + GSList *list = g_slist_prepend (NULL, "three"); + GSList *found; + char *data; + + list = g_slist_prepend (list, "two"); + list = g_slist_prepend (list, "one"); + + data = "four"; + list = g_slist_append (list, data); + + found = g_slist_find (list, data); + + if (found->data != data) + return FAILED ("Find failed"); + + g_slist_free (list); + return OK; +} + +static gint +find_custom (gconstpointer a, gconstpointer b) +{ + return(strcmp (a, b)); +} + +RESULT +test_slist_find_custom () +{ + GSList *list = NULL, *found; + char *foo = "foo"; + char *bar = "bar"; + char *baz = "baz"; + + list = g_slist_prepend (list, baz); + list = g_slist_prepend (list, bar); + list = g_slist_prepend (list, foo); + + found = g_slist_find_custom (list, baz, find_custom); + + if (found == NULL) + return FAILED ("Find failed"); + + g_slist_free (list); + + return OK; +} + +RESULT +test_slist_remove () +{ + GSList *list = g_slist_prepend (NULL, "three"); + char *one = "one"; + list = g_slist_prepend (list, "two"); + list = g_slist_prepend (list, one); + + list = g_slist_remove (list, one); + + if (g_slist_length (list) != 2) + return FAILED ("Remove failed"); + + if (strcmp ("two", list->data) != 0) + return FAILED ("Remove failed"); + + g_slist_free (list); + return OK; +} + +RESULT +test_slist_remove_link () +{ + GSList *foo = g_slist_prepend (NULL, "a"); + GSList *bar = g_slist_prepend (NULL, "b"); + GSList *baz = g_slist_prepend (NULL, "c"); + GSList *list = foo; + + foo = g_slist_concat (foo, bar); + foo = g_slist_concat (foo, baz); + + list = g_slist_remove_link (list, bar); + + if (g_slist_length (list) != 2) + return FAILED ("remove_link failed #1"); + + if (bar->next != NULL) + return FAILED ("remove_link failed #2"); + + g_slist_free (list); + g_slist_free (bar); + + return OK; +} + +static gint +compare (gconstpointer a, gconstpointer b) +{ + char *foo = (char *) a; + char *bar = (char *) b; + + if (strlen (foo) < strlen (bar)) + return -1; + + return 1; +} + +RESULT +test_slist_insert_sorted () +{ + GSList *list = g_slist_prepend (NULL, "a"); + list = g_slist_append (list, "aaa"); + + /* insert at the middle */ + list = g_slist_insert_sorted (list, "aa", compare); + if (strcmp ("aa", list->next->data)) + return FAILED("insert_sorted failed #1"); + + /* insert at the beginning */ + list = g_slist_insert_sorted (list, "", compare); + if (strcmp ("", list->data)) + return FAILED ("insert_sorted failed #2"); + + /* insert at the end */ + list = g_slist_insert_sorted (list, "aaaa", compare); + if (strcmp ("aaaa", g_slist_last (list)->data)) + return FAILED ("insert_sorted failed #3"); + + g_slist_free (list); + return OK; +} + +RESULT +test_slist_insert_before () +{ + GSList *foo, *bar, *baz; + + foo = g_slist_prepend (NULL, "foo"); + foo = g_slist_insert_before (foo, NULL, "bar"); + bar = g_slist_last (foo); + + if (strcmp (bar->data, "bar")) + return FAILED ("1"); + + baz = g_slist_insert_before (foo, bar, "baz"); + if (foo != baz) + return FAILED ("2"); + + if (strcmp (foo->next->data, "baz")) + return FAILED ("3: %s", foo->next->data); + + g_slist_free (foo); + return OK; +} + +#define N_ELEMS 100 + +static int intcompare (gconstpointer p1, gconstpointer p2) +{ + return GPOINTER_TO_INT (p1) - GPOINTER_TO_INT (p2); +} + +static gboolean verify_sort (GSList *list, int len) +{ + int prev = GPOINTER_TO_INT (list->data); + len--; + for (list = list->next; list; list = list->next) { + int curr = GPOINTER_TO_INT (list->data); + if (prev > curr) + return FALSE; + prev = curr; + + if (len == 0) + return FALSE; + len--; + } + return len == 0; +} + +RESULT +test_slist_sort () +{ + int i, j, mul; + GSList *list = NULL; + + for (i = 0; i < N_ELEMS; ++i) + list = g_slist_prepend (list, GINT_TO_POINTER (i)); + list = g_slist_sort (list, intcompare); + if (!verify_sort (list, N_ELEMS)) + return FAILED ("decreasing list"); + + g_slist_free (list); + + list = NULL; + for (i = 0; i < N_ELEMS; ++i) + list = g_slist_prepend (list, GINT_TO_POINTER (-i)); + list = g_slist_sort (list, intcompare); + if (!verify_sort (list, N_ELEMS)) + return FAILED ("increasing list"); + + g_slist_free (list); + + list = g_slist_prepend (NULL, GINT_TO_POINTER (0)); + for (i = 1; i < N_ELEMS; ++i) { + list = g_slist_prepend (list, GINT_TO_POINTER (-i)); + list = g_slist_prepend (list, GINT_TO_POINTER (i)); + } + list = g_slist_sort (list, intcompare); + if (!verify_sort (list, 2*N_ELEMS-1)) + return FAILED ("alternating list"); + + g_slist_free (list); + + list = NULL; + mul = 1; + for (i = 1; i < N_ELEMS; ++i) { + mul = -mul; + for (j = 0; j < i; ++j) + list = g_slist_prepend (list, GINT_TO_POINTER (mul * j)); + } + list = g_slist_sort (list, intcompare); + if (!verify_sort (list, (N_ELEMS*N_ELEMS - N_ELEMS)/2)) + return FAILED ("wavering list"); + + g_slist_free (list); + + return OK; +} + +static Test slist_tests [] = { + {"nth", test_slist_nth}, + {"index", test_slist_index}, + {"append", test_slist_append}, + {"concat", test_slist_concat}, + {"find", test_slist_find}, + {"find_custom", test_slist_find_custom}, + {"remove", test_slist_remove}, + {"remove_link", test_slist_remove_link}, + {"insert_sorted", test_slist_insert_sorted}, + {"insert_before", test_slist_insert_before}, + {"sort", test_slist_sort}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(slist_tests_init, slist_tests) + diff --git a/deps/eglib/test/spawn.c b/deps/eglib/test/spawn.c new file mode 100644 index 00000000..ec30fc86 --- /dev/null +++ b/deps/eglib/test/spawn.c @@ -0,0 +1,82 @@ +#include <config.h> +#include <glib.h> +#include <string.h> +#include <stdio.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include "test.h" + +#ifdef G_OS_WIN32 +#include <io.h> +#define read _read +#define close _close +#endif + +RESULT +test_spawn_sync () +{ + gchar *out; + gchar *err; + gint status = -1; + GError *error = NULL; + + if (!g_spawn_command_line_sync ("ls", &out, &err, &status, &error)) + return FAILED ("Error executing 'ls'"); + + if (status != 0) + return FAILED ("Status is %d", status); + + if (out == NULL || strlen (out) == 0) + return FAILED ("Didn't get any output from ls!?"); + + g_free (out); + g_free (err); + return OK; +} + +RESULT +test_spawn_async () +{ + /* +gboolean +g_spawn_async_with_pipes (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) */ + char *argv [15]; + int stdout_fd = -1; + char buffer [512]; + pid_t child_pid = 0; + + memset (argv, 0, 15 * sizeof (char *)); + argv [0] = "ls"; + if (!g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &child_pid, NULL, &stdout_fd, NULL, NULL)) + return FAILED ("1 Failed to run ls"); + if (child_pid == 0) + return FAILED ("2 child pid not returned"); + if (stdout_fd == -1) + return FAILED ("3 out fd is -1"); + + while (read (stdout_fd, buffer, 512) > 0); + close (stdout_fd); + + return OK; +} + +static Test spawn_tests [] = { + {"g_shell_spawn_sync", test_spawn_sync}, + {"g_shell_spawn_async_with_pipes", test_spawn_async}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(spawn_tests_init, spawn_tests) + + diff --git a/deps/eglib/test/string-util.c b/deps/eglib/test/string-util.c new file mode 100644 index 00000000..73efd13f --- /dev/null +++ b/deps/eglib/test/string-util.c @@ -0,0 +1,698 @@ +#include <glib.h> +#include <string.h> +#include <stdio.h> +#include "test.h" + +/* This test is just to be used with valgrind */ +RESULT +test_strfreev () +{ + gchar **array = g_new (gchar *, 4); + array [0] = g_strdup ("one"); + array [1] = g_strdup ("two"); + array [2] = g_strdup ("three"); + array [3] = NULL; + + g_strfreev (array); + g_strfreev (NULL); + + return OK; +} + +RESULT +test_concat () +{ + gchar *x = g_strconcat ("Hello", ", ", "world", NULL); + if (strcmp (x, "Hello, world") != 0) + return FAILED("concat failed, got: %s", x); + g_free (x); + return OK; +} + +RESULT +test_split () +{ + const gchar *to_split = "Hello world, how are we doing today?"; + gint i; + gchar **v; + + v= g_strsplit(to_split, " ", 0); + + if(v == NULL) { + return FAILED("split failed, got NULL vector (1)"); + } + + for(i = 0; v[i] != NULL; i++); + if(i != 7) { + return FAILED("split failed, expected 7 tokens, got %d", i); + } + + g_strfreev(v); + + v = g_strsplit(to_split, ":", -1); + if(v == NULL) { + return FAILED("split failed, got NULL vector (2)"); + } + + for(i = 0; v[i] != NULL; i++); + if(i != 1) { + return FAILED("split failed, expected 1 token, got %d", i); + } + + if(strcmp(v[0], to_split) != 0) { + return FAILED("expected vector[0] to be '%s' but it was '%s'", + to_split, v[0]); + } + g_strfreev(v); + + v = g_strsplit ("", ":", 0); + if (v == NULL) + return FAILED ("g_strsplit returned NULL"); + g_strfreev (v); + + v = g_strsplit ("/home/miguel/dingus", "/", 0); + if (v [0][0] != 0) + return FAILED ("Got a non-empty first element"); + g_strfreev (v); + + v = g_strsplit ("appdomain1, Version=0.0.0.0, Culture=neutral", ",", 4); + if (strcmp (v [0], "appdomain1") != 0) + return FAILED ("Invalid value"); + + if (strcmp (v [1], " Version=0.0.0.0") != 0) + return FAILED ("Invalid value"); + + if (strcmp (v [2], " Culture=neutral") != 0) + return FAILED ("Invalid value"); + + if (v [3] != NULL) + return FAILED ("Expected only 3 elements"); + + g_strfreev (v); + + v = g_strsplit ("abcXYdefXghiXYjklYmno", "XY", 4); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 0"); + + if (strcmp (v [1], "defXghi") != 0) + return FAILED ("Invalid value 1"); + + if (strcmp (v [2], "jklYmno") != 0) + return FAILED ("Invalid value 2"); + + if (v [3] != NULL) + return FAILED ("Expected only 3 elements (1)"); + + g_strfreev (v); + + v = g_strsplit ("abcXYdefXghiXYjklYmno", "XY", 2); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 3"); + + if (strcmp (v [1], "defXghiXYjklYmno") != 0) + return FAILED ("Invalid value 4"); + + if (v [2] != NULL) + return FAILED ("Expected only 2 elements (2)"); + + g_strfreev (v); + + v = g_strsplit ("abcXYdefXghiXYjklYmnoXY", "XY", 3); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 5"); + + if (strcmp (v [1], "defXghi") != 0) + return FAILED ("Invalid value 6"); + + if (strcmp (v [2], "jklYmnoXY") != 0) + return FAILED ("Invalid value 7"); + + if (v [3] != NULL) + return FAILED ("Expected only 3 elements (3)"); + + g_strfreev (v); + + v = g_strsplit ("abcXYXYXYdefXY", "XY", -1); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 8"); + + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 9"); + + if (strcmp (v [2], "") != 0) + return FAILED ("Invalid value 10"); + + if (strcmp (v [3], "def") != 0) + return FAILED ("Invalid value 11"); + + if (strcmp (v [4], "") != 0) + return FAILED ("Invalid value 12"); + + if (v [5] != NULL) + return FAILED ("Expected only 5 elements (4)"); + + g_strfreev (v); + + v = g_strsplit ("XYXYXYabcXYdef", "XY", -1); + if (strcmp (v [0], "") != 0) + return FAILED ("Invalid value 13"); + + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 14"); + + if (strcmp (v [2], "") != 0) + return FAILED ("Invalid value 15"); + + if (strcmp (v [3], "abc") != 0) + return FAILED ("Invalid value 16"); + + if (strcmp (v [4], "def") != 0) + return FAILED ("Invalid value 17"); + + if (v [5] != NULL) + return FAILED ("Expected only 5 elements (5)"); + + g_strfreev (v); + + v = g_strsplit ("value=", "=", 2); + if (strcmp (v [0], "value") != 0) + return FAILED ("Invalid value 18; expected 'value', got '%s'", v [0]); + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 19; expected '', got '%s'", v [1]); + if (v [2] != NULL) + return FAILED ("Expected only 2 elements (6)"); + + g_strfreev (v); + + return OK; +} + +RESULT +test_split_set () +{ + gchar **v; + + v = g_strsplit_set ("abcXYdefXghiXYjklYmno", "XY", 6); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 0"); + + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 1"); + + if (strcmp (v [2], "def") != 0) + return FAILED ("Invalid value 2"); + + if (strcmp (v [3], "ghi") != 0) + return FAILED ("Invalid value 3"); + + if (strcmp (v [4], "") != 0) + return FAILED ("Invalid value 4"); + + if (strcmp (v [5], "jklYmno") != 0) + return FAILED ("Invalid value 5"); + + if (v [6] != NULL) + return FAILED ("Expected only 6 elements (1)"); + + g_strfreev (v); + + v = g_strsplit_set ("abcXYdefXghiXYjklYmno", "XY", 3); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 6"); + + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 7"); + + if (strcmp (v [2], "defXghiXYjklYmno") != 0) + return FAILED ("Invalid value 8"); + + if (v [3] != NULL) + return FAILED ("Expected only 3 elements (2)"); + + g_strfreev (v); + + v = g_strsplit_set ("abcXdefYghiXjklYmnoX", "XY", 5); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 9"); + + if (strcmp (v [1], "def") != 0) + return FAILED ("Invalid value 10"); + + if (strcmp (v [2], "ghi") != 0) + return FAILED ("Invalid value 11"); + + if (strcmp (v [3], "jkl") != 0) + return FAILED ("Invalid value 12"); + + if (strcmp (v [4], "mnoX") != 0) + return FAILED ("Invalid value 13"); + + if (v [5] != NULL) + return FAILED ("Expected only 5 elements (5)"); + + g_strfreev (v); + + v = g_strsplit_set ("abcXYXdefXY", "XY", -1); + if (strcmp (v [0], "abc") != 0) + return FAILED ("Invalid value 14"); + + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 15"); + + if (strcmp (v [2], "") != 0) + return FAILED ("Invalid value 16"); + + if (strcmp (v [3], "def") != 0) + return FAILED ("Invalid value 17"); + + if (strcmp (v [4], "") != 0) + return FAILED ("Invalid value 18"); + + if (strcmp (v [5], "") != 0) + return FAILED ("Invalid value 19"); + + if (v [6] != NULL) + return FAILED ("Expected only 6 elements (4)"); + + g_strfreev (v); + + v = g_strsplit_set ("XYXabcXYdef", "XY", -1); + if (strcmp (v [0], "") != 0) + return FAILED ("Invalid value 20"); + + if (strcmp (v [1], "") != 0) + return FAILED ("Invalid value 21"); + + if (strcmp (v [2], "") != 0) + return FAILED ("Invalid value 22"); + + if (strcmp (v [3], "abc") != 0) + return FAILED ("Invalid value 23"); + + if (strcmp (v [4], "") != 0) + return FAILED ("Invalid value 24"); + + if (strcmp (v [5], "def") != 0) + return FAILED ("Invalid value 25"); + + if (v [6] != NULL) + return FAILED ("Expected only 6 elements (5)"); + + g_strfreev (v); + + return OK; +} + +RESULT +test_strreverse () +{ + RESULT res = OK; + gchar *a = g_strdup ("onetwothree"); + gchar *a_target = "eerhtowteno"; + gchar *b = g_strdup ("onetwothre"); + gchar *b_target = "erhtowteno"; + gchar *c = g_strdup (""); + gchar *c_target = ""; + + g_strreverse (a); + if (strcmp (a, a_target)) { + res = FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", a, a_target); + goto cleanup; + } + + g_strreverse (b); + if (strcmp (b, b_target)) { + res = FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", b, b_target); + goto cleanup; + } + + g_strreverse (c); + if (strcmp (c, c_target)) { + res = FAILED("strreverse failed. Expecting: '%s' and got '%s'\n", b, b_target); + goto cleanup; + } + +cleanup: + g_free (c); + g_free (b); + g_free (a); + return res; +} + +RESULT +test_strjoin () +{ + char *s; + + s = g_strjoin (NULL, "a", "b", NULL); + if (strcmp (s, "ab") != 0) + return FAILED ("Join of two strings with no separator fails"); + g_free (s); + + s = g_strjoin ("", "a", "b", NULL); + if (strcmp (s, "ab") != 0) + return FAILED ("Join of two strings with empty separator fails"); + g_free (s); + + s = g_strjoin ("-", "a", "b", NULL); + if (strcmp (s, "a-b") != 0) + return FAILED ("Join of two strings with separator fails"); + g_free (s); + + s = g_strjoin ("-", "aaaa", "bbbb", "cccc", "dddd", NULL); + if (strcmp (s, "aaaa-bbbb-cccc-dddd") != 0) + return FAILED ("Join of multiple strings fails"); + g_free (s); + + s = g_strjoin ("-", NULL); + if (s == NULL || (strcmp (s, "") != 0)) + return FAILED ("Failed to join empty arguments"); + g_free (s); + + return OK; +} + +RESULT +test_strchug () +{ + char *str = g_strdup (" \t\n hola"); + + g_strchug (str); + if (strcmp ("hola", str)) { + fprintf (stderr, "%s\n", str); + g_free (str); + return FAILED ("Failed."); + } + g_free (str); + return OK; +} + +RESULT +test_strchomp () +{ + char *str = g_strdup ("hola \t"); + + g_strchomp (str); + if (strcmp ("hola", str)) { + fprintf (stderr, "%s\n", str); + g_free (str); + return FAILED ("Failed."); + } + g_free (str); + return OK; +} + +RESULT +test_strstrip () +{ + char *str = g_strdup (" \t hola "); + + g_strstrip (str); + if (strcmp ("hola", str)) { + fprintf (stderr, "%s\n", str); + g_free (str); + return FAILED ("Failed."); + } + g_free (str); + return OK; +} + +#define urit(so,j) do { s = g_filename_to_uri (so, NULL, NULL); if (strcmp (s, j) != 0) return FAILED("Got %s expected %s", s, j); g_free (s); } while (0); + +#define errit(so) do { s = g_filename_to_uri (so, NULL, NULL); if (s != NULL) return FAILED ("got %s, expected NULL", s); } while (0); + +RESULT +test_filename_to_uri () +{ +#ifdef G_OS_WIN32 +#else + char *s; + + urit ("/a", "file:///a"); + urit ("/home/miguel", "file:///home/miguel"); + urit ("/home/mig uel", "file:///home/mig%20uel"); + urit ("/\303\241", "file:///%C3%A1"); + urit ("/\303\241/octal", "file:///%C3%A1/octal"); + urit ("/%", "file:///%25"); + urit ("/\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040", "file:///%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20"); + urit ("/!$&'()*+,-./", "file:///!$&'()*+,-./"); + urit ("/\042\043\045", "file:///%22%23%25"); + urit ("/0123456789:=", "file:///0123456789:="); + urit ("/\073\074\076\077", "file:///%3B%3C%3E%3F"); + urit ("/\133\134\135\136_\140\173\174\175", "file:///%5B%5C%5D%5E_%60%7B%7C%7D"); + urit ("/\173\174\175\176\177\200", "file:///%7B%7C%7D~%7F%80"); + urit ("/@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", "file:///@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + errit ("a"); + errit ("./hola"); +#endif + + return OK; +} + +#define fileit(so,j) do { s = g_filename_from_uri (so, NULL, NULL); if (strcmp (s, j) != 0) return FAILED("Got %s expected %s", s, j); g_free (s); } while (0); + +#define ferrit(so) do { s = g_filename_from_uri (so, NULL, NULL); if (s != NULL) return FAILED ("got %s, expected NULL", s); } while (0); + +RESULT +test_filename_from_uri () +{ +#ifdef G_OS_WIN32 +#else + char *s; + + fileit ("file:///a", "/a"); + fileit ("file:///%41", "/A"); + fileit ("file:///home/miguel", "/home/miguel"); + fileit ("file:///home/mig%20uel", "/home/mig uel"); + ferrit ("/a"); + ferrit ("a"); + ferrit ("file://a"); + ferrit ("file:a"); + ferrit ("file:///%"); + ferrit ("file:///%0"); + ferrit ("file:///%jj"); +#endif + + return OK; +} + +RESULT +test_ascii_xdigit_value () +{ + int i; + gchar j; + + i = g_ascii_xdigit_value ('9' + 1); + if (i != -1) + return FAILED ("'9' + 1"); + i = g_ascii_xdigit_value ('0' - 1); + if (i != -1) + return FAILED ("'0' - 1"); + i = g_ascii_xdigit_value ('a' - 1); + if (i != -1) + return FAILED ("'a' - 1"); + i = g_ascii_xdigit_value ('f' + 1); + if (i != -1) + return FAILED ("'f' + 1"); + i = g_ascii_xdigit_value ('A' - 1); + if (i != -1) + return FAILED ("'A' - 1"); + i = g_ascii_xdigit_value ('F' + 1); + if (i != -1) + return FAILED ("'F' + 1"); + + for (j = '0'; j < '9'; j++) { + int c = g_ascii_xdigit_value (j); + if (c != (j - '0')) + return FAILED ("Digits %c -> %d", j, c); + } + for (j = 'a'; j < 'f'; j++) { + int c = g_ascii_xdigit_value (j); + if (c != (j - 'a' + 10)) + return FAILED ("Lower %c -> %d", j, c); + } + for (j = 'A'; j < 'F'; j++) { + int c = g_ascii_xdigit_value (j); + if (c != (j - 'A' + 10)) + return FAILED ("Upper %c -> %d", j, c); + } + return OK; +} + +RESULT +test_strdelimit () +{ + gchar *str; + + str = g_strdup (G_STR_DELIMITERS); + str = g_strdelimit (str, NULL, 'a'); + if (0 != strcmp ("aaaaaaa", str)) + return FAILED ("All delimiters: '%s'", str); + g_free (str); + str = g_strdup ("hola"); + str = g_strdelimit (str, "ha", '+'); + if (0 != strcmp ("+ol+", str)) + return FAILED ("2 delimiters: '%s'", str); + g_free (str); + return OK; +} + +#define NUMBERS "0123456789" + +RESULT +test_strlcpy () +{ + const gchar *src = "onetwothree"; + gchar *dest; + gsize i; + + dest = g_malloc (strlen (src) + 1); + memset (dest, 0, strlen (src) + 1); + i = g_strlcpy (dest, src, (gsize)-1); + if (i != strlen (src)) + return FAILED ("Test1 got %d", i); + + if (0 != strcmp (dest, src)) + return FAILED ("Src and dest not equal"); + + i = g_strlcpy (dest, src, 3); + if (i != strlen (src)) + return FAILED ("Test1 got %d", i); + if (0 != strcmp (dest, "on")) + return FAILED ("Test2"); + + i = g_strlcpy (dest, src, 1); + if (i != strlen (src)) + return FAILED ("Test3 got %d", i); + if (*dest != '\0') + return FAILED ("Test4"); + + i = g_strlcpy (dest, src, 12345); + if (i != strlen (src)) + return FAILED ("Test4 got %d", i); + if (0 != strcmp (dest, src)) + return FAILED ("Src and dest not equal 2"); + g_free (dest); + + /* This is a test for g_filename_from_utf8, even if it does not look like it */ + dest = g_filename_from_utf8 (NUMBERS, strlen (NUMBERS), NULL, NULL, NULL); + if (0 != strcmp (dest, NUMBERS)) + return FAILED ("problem [%s] and [%s]", dest, NUMBERS); + g_free (dest); + + return OK; +} + +RESULT +test_strescape () +{ + gchar *str; + + str = g_strescape ("abc", NULL); + if (strcmp ("abc", str)) + return FAILED ("#1"); + str = g_strescape ("\t\b\f\n\r\\\"abc", NULL); + if (strcmp ("\\t\\b\\f\\n\\r\\\\\\\"abc", str)) + return FAILED ("#2 %s", str); + str = g_strescape ("\001abc", NULL); + if (strcmp ("\\001abc", str)) + return FAILED ("#3 %s", str); + str = g_strescape ("\001abc", "\001"); + if (strcmp ("\001abc", str)) + return FAILED ("#3 %s", str); + return OK; +} + +RESULT +test_ascii_strncasecmp () +{ + int n; + + n = g_ascii_strncasecmp ("123", "123", 1); + if (n != 0) + return FAILED ("Should have been 0"); + + n = g_ascii_strncasecmp ("423", "123", 1); + if (n != 3) + return FAILED ("Should have been 3, got %d", n); + + n = g_ascii_strncasecmp ("123", "423", 1); + if (n != -3) + return FAILED ("Should have been -3, got %d", n); + + n = g_ascii_strncasecmp ("1", "1", 10); + if (n != 0) + return FAILED ("Should have been 0, got %d", n); + return OK; +} + +RESULT +test_ascii_strdown () +{ + const gchar *a = "~09+AaBcDeFzZ$0909EmPAbCdEEEEEZZZZAAA"; + const gchar *b = "~09+aabcdefzz$0909empabcdeeeeezzzzaaa"; + gchar *c; + gint n, l; + + l = (gint)strlen (b); + c = g_ascii_strdown (a, l); + n = g_ascii_strncasecmp (b, c, l); + + if (n != 0) { + g_free (c); + return FAILED ("Should have been 0, got %d", n); + } + + g_free (c); + return OK; +} + +RESULT +test_strdupv () +{ + gchar **one; + gchar **two; + gint len; + + one = g_strdupv (NULL); + if (one) + return FAILED ("Should have been NULL"); + + one = g_malloc (sizeof (gchar *)); + *one = NULL; + two = g_strdupv (one); + if (!two) + FAILED ("Should have been not NULL"); + len = g_strv_length (two); + if (len) + FAILED ("Should have been 0"); + g_strfreev (two); + g_strfreev (one); + return NULL; +} + +static Test strutil_tests [] = { + {"g_strfreev", test_strfreev}, + {"g_strconcat", test_concat}, + {"g_strsplit", test_split}, + {"g_strsplit_set", test_split_set}, + {"g_strreverse", test_strreverse}, + {"g_strjoin", test_strjoin}, + {"g_strchug", test_strchug}, + {"g_strchomp", test_strchomp}, + {"g_strstrip", test_strstrip}, + {"g_filename_to_uri", test_filename_to_uri}, + {"g_filename_from_uri", test_filename_from_uri}, + {"g_ascii_xdigit_value", test_ascii_xdigit_value}, + {"g_strdelimit", test_strdelimit}, + {"g_strlcpy", test_strlcpy}, + {"g_strescape", test_strescape}, + {"g_ascii_strncasecmp", test_ascii_strncasecmp }, + {"g_ascii_strdown", test_ascii_strdown }, + {"g_strdupv", test_strdupv }, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(strutil_tests_init, strutil_tests) + + diff --git a/deps/eglib/test/string.c b/deps/eglib/test/string.c new file mode 100644 index 00000000..02ad0ad3 --- /dev/null +++ b/deps/eglib/test/string.c @@ -0,0 +1,237 @@ +#include <glib.h> +#include <string.h> +#include <stdio.h> +#include "test.h" + +#define sfail(k,p) if (s->str [p] != k) { g_string_free (s,TRUE); return FAILED("Got %s, Failed at %d, expected '%c'", s->str, p, k);} + +RESULT +test_append_speed() +{ + GString *s = g_string_new(""); + gint i; + + for(i = 0; i < 1024; i++) { + g_string_append(s, "x"); + } + + if(strlen (s->str) != 1024) { + return FAILED("Incorrect string size, got: %s %d", + s->str, strlen(s->str)); + } + + g_string_free (s, TRUE); + + return OK; +} + +RESULT +test_append_c_speed() +{ + GString *s = g_string_new(""); + gint i; + + for(i = 0; i < 1024; i++) { + g_string_append_c(s, 'x'); + } + + if(strlen(s->str) != 1024) { + return FAILED("Incorrect string size, got: %s %d", s->str, + strlen(s->str)); + } + + g_string_free(s, TRUE); + + return OK; +} + +RESULT +test_gstring () +{ + GString *s = g_string_new_len ("My stuff", 2); + char *ret; + int i; + + if (strcmp (s->str, "My") != 0) + return "Expected only 'My' on the string"; + g_string_free (s, TRUE); + + s = g_string_new_len ("My\0\0Rest", 6); + if (s->str [2] != 0) + return "Null was not copied"; + if (strcmp (s->str+4, "Re") != 0){ + return "Did not find the 'Re' part"; + } + + g_string_append (s, "lalalalalalalalalalalalalalalalalalalalalalal"); + if (s->str [2] != 0) + return "Null as not copied"; + if (strncmp (s->str+4, "Relala", 6) != 0){ + return FAILED("Did not copy correctly, got: %s", s->str+4); + } + + g_string_free (s, TRUE); + + s = g_string_new (""); + for (i = 0; i < 1024; i++){ + g_string_append_c (s, 'x'); + } + if (strlen (s->str) != 1024){ + return FAILED("Incorrect string size, got: %s %d\n", s->str, strlen (s->str)); + } + g_string_free (s, TRUE); + + s = g_string_new ("hola"); + g_string_sprintfa (s, "%s%d", ", bola", 5); + if (strcmp (s->str, "hola, bola5") != 0){ + return FAILED("Incorrect data, got: %s\n", s->str); + } + g_string_free (s, TRUE); + + s = g_string_new ("Hola"); + g_string_printf (s, "Dingus"); + + /* Test that it does not release it */ + ret = g_string_free (s, FALSE); + g_free (ret); + + s = g_string_new_len ("H" "\000" "H", 3); + g_string_append_len (s, "1" "\000" "2", 3); + sfail ('H', 0); + sfail ( 0, 1); + sfail ('H', 2); + sfail ('1', 3); + sfail ( 0, 4); + sfail ('2', 5); + g_string_free (s, TRUE); + + return OK; +} + +RESULT +test_sized () +{ + GString *s = g_string_sized_new (20); + + if (s->str [0] != 0) + return FAILED ("Expected an empty string"); + if (s->len != 0) + return FAILED ("Expected an empty len"); + + g_string_free (s, TRUE); + + return NULL; +} + +RESULT +test_truncate () +{ + GString *s = g_string_new ("0123456789"); + g_string_truncate (s, 3); + + if (strlen (s->str) != 3) + return FAILED ("size of string should have been 3, instead it is [%s]\n", s->str); + g_string_free (s, TRUE); + + s = g_string_new ("a"); + s = g_string_truncate (s, 10); + if (strlen (s->str) != 1) + return FAILED ("The size is not 1"); + g_string_truncate (s, (gsize)-1); + if (strlen (s->str) != 1) + return FAILED ("The size is not 1"); + g_string_truncate (s, 0); + if (strlen (s->str) != 0) + return FAILED ("The size is not 0"); + + g_string_free (s, TRUE); + + return NULL; +} + +RESULT +test_prepend () +{ + GString *s = g_string_new ("dingus"); + g_string_prepend (s, "one"); + + if (strcmp (s->str, "onedingus") != 0) + return FAILED ("Failed, expected onedingus, got [%s]", s->str); + + g_string_free (s, TRUE); + + /* This is to force the code that where stuff does not fit in the allocated block */ + s = g_string_sized_new (1); + g_string_prepend (s, "one"); + if (strcmp (s->str, "one") != 0) + return FAILED ("Got erroneous result, expected [one] got [%s]", s->str); + g_string_free (s, TRUE); + + /* This is to force the path where things fit */ + s = g_string_new ("123123123123123123123123"); + g_string_truncate (s, 1); + if (strcmp (s->str, "1") != 0) + return FAILED ("Expected [1] string, got [%s]", s->str); + + g_string_prepend (s, "pre"); + if (strcmp (s->str, "pre1") != 0) + return FAILED ("Expected [pre1], got [%s]", s->str); + g_string_free (s, TRUE); + + return NULL; +} + +RESULT +test_appendlen () +{ + GString *s = g_string_new (""); + + g_string_append_len (s, "boo\000x", 0); + if (s->len != 0) + return FAILED ("The length is not zero %d", s->len); + g_string_append_len (s, "boo\000x", 5); + if (s->len != 5) + return FAILED ("The length is not five %d", s->len); + g_string_append_len (s, "ha", -1); + if (s->len != 7) + return FAILED ("The length is not seven %d", s->len); + + g_string_free (s, TRUE); + + return NULL; +} + +RESULT +test_macros () +{ + char *s = g_strdup (G_STRLOC); + char *p = strchr (s + 2, ':'); + int n; + + if (p == NULL) + return FAILED ("Did not find a separator"); + n = atoi (p+1); + if (n <= 0) + return FAILED ("did not find a valid line number"); + + *p = 0; + if (strcmp (s + strlen(s) - 8 , "string.c") != 0) + return FAILED ("This did not store the filename on G_STRLOC"); + + g_free (s); + return NULL; +} + +static Test string_tests [] = { + {"append-speed", test_append_speed}, + {"append_c-speed", test_append_c_speed}, + {"ctor+append", test_gstring }, + {"ctor+sized", test_sized }, + {"truncate", test_truncate }, + {"prepend", test_prepend }, + {"append_len", test_appendlen }, + {"macros", test_macros }, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(string_tests_init, string_tests) diff --git a/deps/eglib/test/test-both b/deps/eglib/test/test-both new file mode 100755 index 00000000..038c927e --- /dev/null +++ b/deps/eglib/test/test-both @@ -0,0 +1,74 @@ +#!/bin/sh + +for arg in $@; do + if [ "x$arg" = "x--help" ]; then + echo "Usage: $0 [OPTION]... [ITERATIONS] [TESTGROUP]..." + echo "" + echo "Works the same as test-eglib or test-glib with the following" + echo "exception. Run test-eglib --help for details on normal testing" + echo "" + echo "If the first OPTION is --speed-compare, the following is" + echo "applicable to this program:" + echo "" + echo " --speed-compare run drivers in -qtni mode and report" + echo " speed comparison information" + echo "" + echo "After --speed-compare, the number of iterations " + echo "(optional, default is 100000) can be specified, followed " + echo "by specific tests to run (or none to run all)" + echo "" + echo "If --speed-compare is not the first argument, all arguments are" + echo "passed on directly to each driver" + echo "" + exit 1 + fi +done + +if [ ! -x "./test-glib" -o ! -x "./test-eglib" ]; then + make +fi + +if [ "x$1" = "x--speed-compare" ]; then + ITERATIONS=100000 + if [ ! -z "$2" ]; then + case $2 in + *[0-9]*) ITERATIONS=$2; break; + esac + fi + + OPTIONS="-qnti $ITERATIONS" + + for arg in $@; do + if [ "x$arg" = "x--speed-compare" ]; then + continue; + elif [ "$arg" = "$ITERATIONS" ]; then + continue; + fi + + OPTIONS="$OPTIONS $arg" + done + + echo "Running tests with $OPTIONS..." + + GLIB=`./test-glib $OPTIONS` + EGLIB=`./test-eglib $OPTIONS` + + # this blows + FASTER_NAME=`echo "$GLIB GLib $EGLIB EGlib" | awk '{ if($1 < $3) print $2; else print $4 }'` + FASTER_SPEED=`echo "$GLIB $EGLIB" | awk '{ if($1 < $2) print $1; else print $2 }'` + SLOWER_NAME=`echo "$GLIB GLib $EGLIB EGlib" | awk '{ if($1 > $3) print $2; else print $4 }'` + SLOWER_SPEED=`echo "$GLIB $EGLIB" | awk '{ if($1 > $2) print $1; else print $2 }'` + + FASTER_PERCENTAGE=`echo "$SLOWER_SPEED $FASTER_SPEED" | awk '{ print ($1 / $2) * 100 }'` + + echo "$FASTER_NAME $FASTER_SPEED" + echo "$SLOWER_NAME $SLOWER_SPEED" + echo "------------------------------------------------" + echo "$FASTER_NAME is $FASTER_PERCENTAGE% faster than $SLOWER_NAME" + + exit 0; +fi + +./test-eglib $@ +./test-glib $@ + diff --git a/deps/eglib/test/test.c b/deps/eglib/test/test.c new file mode 100644 index 00000000..6dd7bf47 --- /dev/null +++ b/deps/eglib/test/test.c @@ -0,0 +1,282 @@ +/* + * EGLib Unit Group/Test Runners + * + * Author: + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <glib.h> +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef G_OS_WIN32 +#include <winsock2.h> +#endif + +#include "test.h" + +extern gint global_passed, global_tests; + +#ifndef HAVE_VASPRINTF + /* systen does not provide a vasprintf function, use the one + provided within eglib itself */ +extern int vasprintf(char **ret, const char *format, va_list ap); +#endif + +static gchar *last_result = NULL; + +gboolean +run_test(Test *test, gchar **result_out) +{ + gchar *result; + + if((result = test->handler()) == NULL) { + *result_out = NULL; + return TRUE; + } else { + *result_out = result; + return FALSE; + } +} + +gboolean +run_group(Group *group, gint iterations, gboolean quiet, + gboolean time, gchar *tests_to_run_s) +{ + Test *tests = group->handler(); + gint i, j, passed = 0, total = 0; + gdouble start_time_group, start_time_test; + gchar **tests_to_run = NULL; + + if(!quiet) { + if(iterations > 1) { + printf("[%s] (%dx)\n", group->name, iterations); + } else { + printf("[%s]\n", group->name); + } + } + + if(tests_to_run_s != NULL) { + tests_to_run = eg_strsplit(tests_to_run_s, ",", -1); + } + + start_time_group = get_timestamp(); + + for(i = 0; tests[i].name != NULL; i++) { + gchar *result = ""; + gboolean iter_pass, run; + + iter_pass = FALSE; + if(tests_to_run != NULL) { + gint j; + run = FALSE; + for(j = 0; tests_to_run[j] != NULL; j++) { + if(strcmp(tests_to_run[j], tests[i].name) == 0) { + run = TRUE; + break; + } + } + } else { + run = TRUE; + } + + if(!run) { + continue; + } + + total++; + + if(!quiet) { + printf(" %s: ", tests[i].name); + } + + start_time_test = get_timestamp(); + + for(j = 0; j < iterations; j++) { + iter_pass = run_test(&(tests[i]), &result); + if(!iter_pass) { + break; + } + } + + if(iter_pass) { + passed++; + if(!quiet) { + if(time) { + printf("OK (%g)\n", get_timestamp() - start_time_test); + } else { + printf("OK\n"); + } + } + } else { + if(!quiet) { + printf("FAILED (%s)\n", result); + } + + if(last_result == result) { + last_result = NULL; + g_free(result); + } + } + } + + global_passed += passed; + global_tests += total; + + if(!quiet) { + gdouble pass_percentage = ((gdouble)passed / (gdouble)total) * 100.0; + if(time) { + printf(" %d / %d (%g%%, %g)\n", passed, total, + pass_percentage, get_timestamp() - start_time_group); + } else { + printf(" %d / %d (%g%%)\n", passed, total, pass_percentage); + } + } + + if(tests_to_run != NULL) { + eg_strfreev(tests_to_run); + } + + return passed == total; +} + +RESULT +FAILED(const gchar *format, ...) +{ + gchar *ret; + va_list args; + gint n; + +#if !defined(HAVE_VASPRINTF) && !defined(_EGLIB_MAJOR) + /* We are linked against the real glib, no vasprintf */ + g_assert_not_reached (); + return NULL; +#else + va_start(args, format); + n = vasprintf(&ret, format, args); + va_end(args); + + if(n == -1) { + last_result = NULL; + return NULL; + } + + last_result = ret; + return ret; +#endif +} + +gdouble +get_timestamp() +{ + /* FIXME: We should use g_get_current_time here */ + GTimeVal res; + g_get_current_time (&res); + return res.tv_sec + (1.e-6) * res.tv_usec; +} + +/* + * Duplicating code here from EGlib to avoid g_strsplit skew between + * EGLib and GLib + */ + +gchar ** +eg_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens) +{ + gchar *string_c; + gchar *strtok_save, **vector; + gchar *token, *token_c; + gint size = 1; + size_t token_length; + + g_return_val_if_fail(string != NULL, NULL); + g_return_val_if_fail(delimiter != NULL, NULL); + g_return_val_if_fail(delimiter[0] != 0, NULL); + + token_length = strlen(string); + string_c = (gchar *)g_malloc(token_length + 1); + memcpy(string_c, string, token_length); + string_c[token_length] = 0; + + vector = NULL; + token = (gchar *)strtok_r(string_c, delimiter, &strtok_save); + + while(token != NULL) { + token_length = strlen(token); + token_c = (gchar *)g_malloc(token_length + 1); + memcpy(token_c, token, token_length); + token_c[token_length] = 0; + + vector = vector == NULL ? + (gchar **)g_malloc(2 * sizeof(vector)) : + (gchar **)g_realloc(vector, (size + 1) * sizeof(vector)); + + vector[size - 1] = token_c; + size++; + + if(max_tokens > 0 && size >= max_tokens) { + if(size > max_tokens) { + break; + } + + token = strtok_save; + } else { + token = (gchar *)strtok_r(NULL, delimiter, &strtok_save); + } + } + + if(vector != NULL && size > 0) { + vector[size - 1] = NULL; + } + + g_free(string_c); + string_c = NULL; + + return vector; +} + +void +eg_strfreev (gchar **str_array) +{ + gchar **orig = str_array; + if (str_array == NULL) + return; + while (*str_array != NULL){ + g_free (*str_array); + str_array++; + } + g_free (orig); +} + + + diff --git a/deps/eglib/test/test.h b/deps/eglib/test/test.h new file mode 100644 index 00000000..5c7275e0 --- /dev/null +++ b/deps/eglib/test/test.h @@ -0,0 +1,82 @@ +/* + * EGLib Unit Group/Test Runners + * + * Author: + * Aaron Bockover (abockover@novell.com) + * + * (C) 2006 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _TEST_H +#define _TEST_H + +#include <config.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <glib.h> + +#ifdef _MSC_VER +/* disable the following warnings + * C4100: The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored. + * C4127: conditional expression is constant (test macros produce a lot of these) +*/ +#pragma warning(disable:4100 4127) +#endif + +typedef gchar * RESULT; + +typedef struct _Test Test; +typedef struct _Group Group; + +typedef gchar * (* RunTestHandler)(); +typedef Test * (* LoadGroupHandler)(); + +struct _Test { + const gchar *name; + RunTestHandler handler; +}; + +struct _Group { + const gchar *name; + LoadGroupHandler handler; +}; + +gboolean run_group(Group *group, gint iterations, gboolean quiet, + gboolean time, gchar *tests); +#undef FAILED +RESULT FAILED(const gchar *format, ...); +gdouble get_timestamp(); +gchar ** eg_strsplit (const gchar *string, const gchar *delimiter, gint max_tokens); +void eg_strfreev (gchar **str_array); + +#define OK NULL + +#define DEFINE_TEST_GROUP_INIT(name, table) \ + Test * (name)() { return table; } + +#define DEFINE_TEST_GROUP_INIT_H(name) \ + Test * (name)(); + +#endif /* _TEST_H */ + + diff --git a/deps/eglib/test/tests.h b/deps/eglib/test/tests.h new file mode 100644 index 00000000..fdca3957 --- /dev/null +++ b/deps/eglib/test/tests.h @@ -0,0 +1,57 @@ +#include "test.h" + +DEFINE_TEST_GROUP_INIT_H(string_tests_init); +DEFINE_TEST_GROUP_INIT_H(strutil_tests_init); +DEFINE_TEST_GROUP_INIT_H(slist_tests_init); +DEFINE_TEST_GROUP_INIT_H(list_tests_init); +DEFINE_TEST_GROUP_INIT_H(hashtable_tests_init); +DEFINE_TEST_GROUP_INIT_H(ptrarray_tests_init); +DEFINE_TEST_GROUP_INIT_H(size_tests_init); +DEFINE_TEST_GROUP_INIT_H(fake_tests_init); +DEFINE_TEST_GROUP_INIT_H(array_tests_init); +DEFINE_TEST_GROUP_INIT_H(queue_tests_init); +DEFINE_TEST_GROUP_INIT_H(path_tests_init); +DEFINE_TEST_GROUP_INIT_H(shell_tests_init); +DEFINE_TEST_GROUP_INIT_H(spawn_tests_init); +DEFINE_TEST_GROUP_INIT_H(timer_tests_init); +DEFINE_TEST_GROUP_INIT_H(file_tests_init); +DEFINE_TEST_GROUP_INIT_H(pattern_tests_init); +DEFINE_TEST_GROUP_INIT_H(dir_tests_init); +DEFINE_TEST_GROUP_INIT_H(markup_tests_init); +DEFINE_TEST_GROUP_INIT_H(unicode_tests_init); +DEFINE_TEST_GROUP_INIT_H(utf8_tests_init); +DEFINE_TEST_GROUP_INIT_H(endian_tests_init); +DEFINE_TEST_GROUP_INIT_H(module_tests_init); +DEFINE_TEST_GROUP_INIT_H(memory_tests_init); + +static Group test_groups [] = { + {"string", string_tests_init}, + {"strutil", strutil_tests_init}, + {"ptrarray", ptrarray_tests_init}, + {"slist", slist_tests_init}, + {"list", list_tests_init}, + {"hashtable", hashtable_tests_init}, + {"sizes", size_tests_init}, + {"fake", fake_tests_init}, + {"array", array_tests_init}, + {"queue", queue_tests_init}, + {"path", path_tests_init}, + {"shell", shell_tests_init}, + {"markup", markup_tests_init}, +#if !DISABLE_PROCESS_TESTS + {"spawn", spawn_tests_init}, + {"module", module_tests_init}, +#endif +#if !DISABLE_FILESYSTEM_TESTS + {"file", file_tests_init}, +#endif + {"timer", timer_tests_init}, + {"pattern", pattern_tests_init}, + {"dir", dir_tests_init}, + {"unicode", unicode_tests_init}, + {"utf8", utf8_tests_init}, + {"endian", endian_tests_init}, + {"memory", memory_tests_init}, + {NULL, NULL} +}; + diff --git a/deps/eglib/test/timer.c b/deps/eglib/test/timer.c new file mode 100644 index 00000000..7b41f800 --- /dev/null +++ b/deps/eglib/test/timer.c @@ -0,0 +1,55 @@ +#include <config.h> +#include <glib.h> +#include <string.h> +#include <math.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <stdlib.h> +#include <stdio.h> + +#ifdef G_OS_WIN32 +#include <windows.h> +#define sleep(t) Sleep((t) * 1000) +#endif + +#include "test.h" + +RESULT +test_timer () +{ + GTimer *timer; + gdouble elapsed1, elapsed2; + gulong usec = 0; + + timer = g_timer_new (); + sleep (1); + elapsed1 = g_timer_elapsed (timer, NULL); + if ((elapsed1 + 0.1) < 1.0) + return FAILED ("Elapsed time should be around 1s and was %f", elapsed1); + + g_timer_stop (timer); + elapsed1 = g_timer_elapsed (timer, NULL); + elapsed2 = g_timer_elapsed (timer, &usec); + if (fabs (elapsed1 - elapsed2) > 0.000001) + return FAILED ("The elapsed times are not equal %f - %f.", elapsed1, elapsed2); + + elapsed2 *= 1000000; + while (elapsed2 > 1000000) + elapsed2 -= 1000000; + + if (fabs (usec - elapsed2) > 100.0) + return FAILED ("usecs are wrong."); + + g_timer_destroy (timer); + return OK; +} + +static Test timer_tests [] = { + {"g_timer", test_timer}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(timer_tests_init, timer_tests) + + diff --git a/deps/eglib/test/unicode.c b/deps/eglib/test/unicode.c new file mode 100644 index 00000000..c1c3402b --- /dev/null +++ b/deps/eglib/test/unicode.c @@ -0,0 +1,99 @@ +#include "test.h" + +/* + * g_unichar_type + */ +RESULT +test_g_unichar_type () +{ + if (g_unichar_type ('A') != G_UNICODE_UPPERCASE_LETTER) + return FAILED ("#1"); + if (g_unichar_type ('a') != G_UNICODE_LOWERCASE_LETTER) + return FAILED ("#2"); + if (g_unichar_type ('1') != G_UNICODE_DECIMAL_NUMBER) + return FAILED ("#3"); + if (g_unichar_type (0xA3) != G_UNICODE_CURRENCY_SYMBOL) + return FAILED ("#4"); + return NULL; +} + +/* + * g_unichar_toupper + */ +RESULT +test_g_unichar_toupper () +{ + if (g_unichar_toupper (0) != 0) + return FAILED ("#0"); + if (g_unichar_toupper ('a') != 'A') + return FAILED ("#1"); + if (g_unichar_toupper ('1') != '1') + return FAILED ("#2"); + if (g_unichar_toupper (0x1C4) != 0x1C4) + return FAILED ("#3"); + if (g_unichar_toupper (0x1F2) != 0x1F1) + return FAILED ("#4"); + if (g_unichar_toupper (0x1F3) != 0x1F1) + return FAILED ("#5"); + if (g_unichar_toupper (0xFFFF) != 0xFFFF) + return FAILED ("#6"); + if (g_unichar_toupper (0x10428) != 0x10400) + return FAILED ("#7"); + return NULL; +} + +/* + * g_unichar_tolower + */ +RESULT +test_g_unichar_tolower () +{ + if (g_unichar_tolower (0) != 0) + return FAILED ("#0"); + if (g_unichar_tolower ('A') != 'a') + return FAILED ("#1"); + if (g_unichar_tolower ('1') != '1') + return FAILED ("#2"); + if (g_unichar_tolower (0x1C5) != 0x1C6) + return FAILED ("#3"); + if (g_unichar_tolower (0x1F1) != 0x1F3) + return FAILED ("#4"); + if (g_unichar_tolower (0x1F2) != 0x1F3) + return FAILED ("#5"); + if (g_unichar_tolower (0xFFFF) != 0xFFFF) + return FAILED ("#6"); + return NULL; +} + +/* + * g_unichar_totitle + */ +RESULT +test_g_unichar_totitle () +{ + if (g_unichar_toupper (0) != 0) + return FAILED ("#0"); + if (g_unichar_totitle ('a') != 'A') + return FAILED ("#1"); + if (g_unichar_totitle ('1') != '1') + return FAILED ("#2"); + if (g_unichar_totitle (0x1C4) != 0x1C5) + return FAILED ("#3"); + if (g_unichar_totitle (0x1F2) != 0x1F2) + return FAILED ("#4"); + if (g_unichar_totitle (0x1F3) != 0x1F2) + return FAILED ("#5"); + if (g_unichar_toupper (0xFFFF) != 0xFFFF) + return FAILED ("#6"); + return NULL; +} + +static Test unicode_tests [] = { + {"g_unichar_type", test_g_unichar_type}, + {"g_unichar_toupper", test_g_unichar_toupper}, + {"g_unichar_tolower", test_g_unichar_tolower}, + {"g_unichar_totitle", test_g_unichar_totitle}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(unicode_tests_init, unicode_tests) diff --git a/deps/eglib/test/utf8.c b/deps/eglib/test/utf8.c new file mode 100644 index 00000000..a924902c --- /dev/null +++ b/deps/eglib/test/utf8.c @@ -0,0 +1,935 @@ +#include <stdlib.h> + +#include "test.h" + +/* + * g_utf16_to_utf8 + */ + +glong +compare_strings_utf8_pos (const gchar *expected, const gchar *actual, glong size) +{ + int i; + for (i = 0; i < size; i++) + if (expected [i] != actual [i]) + return i; + return -1; +} + +RESULT +compare_strings_utf8_RESULT (const gchar *expected, const gchar *actual, glong size) +{ + glong ret; + + ret = compare_strings_utf8_pos (expected, actual, size); + if (ret < 0) + return OK; + return FAILED ("Incorrect output: expected '%s' but was '%s', differ at %d\n", expected, actual, ret); +} + +void +gchar_to_gunichar2 (gunichar2 ret[], const gchar *src) +{ + int i; + + for (i = 0; src [i]; i++) + ret [i] = src [i]; + ret [i] = 0; +} + +RESULT +compare_utf16_to_utf8_explicit (const gchar *expected, const gunichar2 *utf16, glong len_in, glong len_out, glong size_spec) +{ + GError *error; + gchar* ret; + RESULT result; + glong in_read, out_read; + + result = NULL; + + error = NULL; + ret = g_utf16_to_utf8 (utf16, size_spec, &in_read, &out_read, &error); + if (error) { + result = FAILED ("The error is %d %s\n", (error)->code, (error)->message); + g_error_free (error); + if (ret) + g_free (ret); + return result; + } + if (in_read != len_in) + result = FAILED ("Read size is incorrect: expected %d but was %d\n", len_in, in_read); + else if (out_read != len_out) + result = FAILED ("Converted size is incorrect: expected %d but was %d\n", len_out, out_read); + else + result = compare_strings_utf8_RESULT (expected, ret, len_out); + + g_free (ret); + if (result) + return result; + + return OK; +} + +RESULT +compare_utf16_to_utf8 (const gchar *expected, const gunichar2 *utf16, glong len_in, glong len_out) +{ + RESULT result; + + result = compare_utf16_to_utf8_explicit (expected, utf16, len_in, len_out, -1); + if (result != OK) + return result; + return compare_utf16_to_utf8_explicit (expected, utf16, len_in, len_out, len_in); +} + +RESULT +test_utf16_to_utf8 () +{ + const gchar *src0 = "", *src1 = "ABCDE", *src2 = "\xE5\xB9\xB4\x27", *src3 = "\xEF\xBC\xA1", *src4 = "\xEF\xBD\x81", *src5 = "\xF0\x90\x90\x80"; + gunichar2 str0 [] = {0}, str1 [6], str2 [] = {0x5E74, 39, 0}, str3 [] = {0xFF21, 0}, str4 [] = {0xFF41, 0}, str5 [] = {0xD801, 0xDC00, 0}; + RESULT result; + + gchar_to_gunichar2 (str1, src1); + + /* empty string */ + result = compare_utf16_to_utf8 (src0, str0, 0, 0); + if (result != OK) + return result; + + result = compare_utf16_to_utf8 (src1, str1, 5, 5); + if (result != OK) + return result; + result = compare_utf16_to_utf8 (src2, str2, 2, 4); + if (result != OK) + return result; + result = compare_utf16_to_utf8 (src3, str3, 1, 3); + if (result != OK) + return result; + result = compare_utf16_to_utf8 (src4, str4, 1, 3); + if (result != OK) + return result; + result = compare_utf16_to_utf8 (src5, str5, 2, 4); + if (result != OK) + return result; + + return OK; +} + +/* + * g_utf8_to_utf16 + */ + +glong +compare_strings_utf16_pos (const gunichar2 *expected, const gunichar2 *actual, glong size) +{ + int i; + for (i = 0; i < size; i++) + if (expected [i] != actual [i]) + return i; + return -1; +} + +RESULT +compare_strings_utf16_RESULT (const gunichar2 *expected, const gunichar2 *actual, glong size) +{ + glong ret; + + ret = compare_strings_utf16_pos (expected, actual, size); + if (ret < 0) + return OK; + return FAILED ("Incorrect output: expected '%s' but was '%s', differ at %d ('%c' x '%c')\n", expected, actual, ret, expected [ret], actual [ret]); +} + +#if !defined(EGLIB_TESTS) +#define eg_utf8_to_utf16_with_nuls g_utf8_to_utf16 +#endif + +RESULT +compare_utf8_to_utf16_explicit (const gunichar2 *expected, const gchar *utf8, glong len_in, glong len_out, glong size_spec, gboolean include_nuls) +{ + GError *error; + gunichar2* ret; + RESULT result; + glong in_read, out_read; + + result = NULL; + + error = NULL; + if (include_nuls) + ret = eg_utf8_to_utf16_with_nuls (utf8, size_spec, &in_read, &out_read, &error); + else + ret = g_utf8_to_utf16 (utf8, size_spec, &in_read, &out_read, &error); + + if (error) { + result = FAILED ("The error is %d %s\n", (error)->code, (error)->message); + g_error_free (error); + if (ret) + g_free (ret); + return result; + } + if (in_read != len_in) + result = FAILED ("Read size is incorrect: expected %d but was %d\n", len_in, in_read); + else if (out_read != len_out) + result = FAILED ("Converted size is incorrect: expected %d but was %d\n", len_out, out_read); + else + result = compare_strings_utf16_RESULT (expected, ret, len_out); + + g_free (ret); + if (result) + return result; + + return OK; +} + +RESULT +compare_utf8_to_utf16_general (const gunichar2 *expected, const gchar *utf8, glong len_in, glong len_out, gboolean include_nuls) +{ + RESULT result; + + result = compare_utf8_to_utf16_explicit (expected, utf8, len_in, len_out, -1, include_nuls); + if (result != OK) + return result; + return compare_utf8_to_utf16_explicit (expected, utf8, len_in, len_out, len_in, include_nuls); +} + +RESULT +compare_utf8_to_utf16 (const gunichar2 *expected, const gchar *utf8, glong len_in, glong len_out) +{ + return compare_utf8_to_utf16_general (expected, utf8, len_in, len_out, FALSE); +} + +RESULT +compare_utf8_to_utf16_with_nuls (const gunichar2 *expected, const gchar *utf8, glong len_in, glong len_out) +{ + return compare_utf8_to_utf16_explicit (expected, utf8, len_in, len_out, len_in, TRUE); +} + + +RESULT +test_utf8_seq () +{ + const gchar *src = "\xE5\xB9\xB4\x27"; + glong in_read, out_read; + //gunichar2 expected [6]; + GError *error = NULL; + gunichar2 *dst; + + //printf ("got: %s\n", src); + dst = g_utf8_to_utf16 (src, (glong)strlen (src), &in_read, &out_read, &error); + if (error != NULL){ + return error->message; + } + + if (in_read != 4) { + return FAILED ("in_read is expected to be 4 but was %d\n", in_read); + } + if (out_read != 2) { + return FAILED ("out_read is expected to be 2 but was %d\n", out_read); + } + g_free (dst); + + return OK; +} + +RESULT +test_utf8_to_utf16 () +{ + const gchar *src0 = "", *src1 = "ABCDE", *src2 = "\xE5\xB9\xB4\x27", *src3 = "\xEF\xBC\xA1", *src4 = "\xEF\xBD\x81"; + gunichar2 str0 [] = {0}, str1 [6], str2 [] = {0x5E74, 39, 0}, str3 [] = {0xFF21, 0}, str4 [] = {0xFF41, 0}; + RESULT result; + + gchar_to_gunichar2 (str1, src1); + + /* empty string */ + result = compare_utf8_to_utf16 (str0, src0, 0, 0); + if (result != OK) + return result; + + result = compare_utf8_to_utf16 (str1, src1, 5, 5); + if (result != OK) + return result; + result = compare_utf8_to_utf16 (str2, src2, 4, 2); + if (result != OK) + return result; + result = compare_utf8_to_utf16 (str3, src3, 3, 1); + if (result != OK) + return result; + result = compare_utf8_to_utf16 (str4, src4, 3, 1); + if (result != OK) + return result; + + return OK; +} + +RESULT +test_utf8_to_utf16_with_nuls () +{ + const gchar *src0 = "", *src1 = "AB\0DE", *src2 = "\xE5\xB9\xB4\x27", *src3 = "\xEF\xBC\xA1", *src4 = "\xEF\xBD\x81"; + gunichar2 str0 [] = {0}, str1 [] = {'A', 'B', 0, 'D', 'E', 0}, str2 [] = {0x5E74, 39, 0}, str3 [] = {0xFF21, 0}, str4 [] = {0xFF41, 0}; + RESULT result; + +#if !defined(EGLIB_TESTS) + return OK; +#endif + + /* implicit length is forbidden */ + if (eg_utf8_to_utf16_with_nuls (src1, -1, NULL, NULL, NULL) != NULL) + return FAILED ("explicit nulls must fail with -1 length\n"); + + /* empty string */ + result = compare_utf8_to_utf16_with_nuls (str0, src0, 0, 0); + if (result != OK) + return result; + + result = compare_utf8_to_utf16_with_nuls (str1, src1, 5, 5); + if (result != OK) + return result; + result = compare_utf8_to_utf16_with_nuls (str2, src2, 4, 2); + if (result != OK) + return result; + result = compare_utf8_to_utf16_with_nuls (str3, src3, 3, 1); + if (result != OK) + return result; + result = compare_utf8_to_utf16_with_nuls (str4, src4, 3, 1); + if (result != OK) + return result; + + return OK; +} + +typedef struct { + char *content; + size_t length; +} convert_result_t; + +RESULT +test_convert () +{ + static const char *charsets[] = { "UTF-8", "UTF-16LE", "UTF-16BE", "UTF-32LE", "UTF-32BE" }; + gsize length, converted_length, n; + char *content, *converted, *path; + convert_result_t **expected; + GError *err = NULL; + const char *srcdir; + gboolean loaded; + guint i, j, k; + char c; + + if (!(srcdir = getenv ("srcdir")) && !(srcdir = getenv ("PWD"))) + return FAILED ("srcdir not defined!"); + + expected = g_malloc (sizeof (convert_result_t *) * G_N_ELEMENTS (charsets)); + + /* first load all our test samples... */ + for (i = 0; i < G_N_ELEMENTS (charsets); i++) { + path = g_strdup_printf ("%s%c%s.txt", srcdir, G_DIR_SEPARATOR, charsets[i]); + loaded = g_file_get_contents (path, &content, &length, &err); + g_free (path); + + if (!loaded) { + for (j = 0; j < i; j++) { + g_free (expected[j]->content); + g_free (expected[j]); + } + + g_free (expected); + + return FAILED ("Failed to load content for %s: %s", charsets[i], err->message); + } + + expected[i] = g_malloc (sizeof (convert_result_t)); + expected[i]->content = content; + expected[i]->length = length; + } + + /* test conversion from every charset to every other charset */ + for (i = 0; i < G_N_ELEMENTS (charsets); i++) { + for (j = 0; j < G_N_ELEMENTS (charsets); j++) { + converted = g_convert (expected[i]->content, expected[i]->length, charsets[j], + charsets[i], NULL, &converted_length, NULL); + + if (converted == NULL) { + for (k = 0; k < G_N_ELEMENTS (charsets); k++) { + g_free (expected[k]->content); + g_free (expected[k]); + } + + g_free (expected); + + return FAILED ("Failed to convert from %s to %s: NULL", charsets[i], charsets[j]); + } + + if (converted_length != expected[j]->length) { + length = expected[j]->length; + + for (k = 0; k < G_N_ELEMENTS (charsets); k++) { + g_free (expected[k]->content); + g_free (expected[k]); + } + + g_free (converted); + g_free (expected); + + return FAILED ("Failed to convert from %s to %s: expected %u bytes, got %u", + charsets[i], charsets[j], length, converted_length); + } + + for (n = 0; n < converted_length; n++) { + if (converted[n] != expected[j]->content[n]) { + c = expected[j]->content[n]; + + for (k = 0; k < G_N_ELEMENTS (charsets); k++) { + g_free (expected[k]->content); + g_free (expected[k]); + } + + g_free (converted); + g_free (expected); + + return FAILED ("Failed to convert from %s to %s: expected 0x%x at offset %u, got 0x%x", + charsets[i], charsets[j], c, n, converted[n]); + } + } + + g_free (converted); + } + } + + for (k = 0; k < G_N_ELEMENTS (charsets); k++) { + g_free (expected[k]->content); + g_free (expected[k]); + } + + g_free (expected); + + return OK; +} + + +RESULT +test_xdigit () +{ + static char test_chars[] = { + '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'A', 'B', 'C', 'D', 'E', 'F', 'G'}; + static gint32 test_values[] = { + 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, -1, + 10, 11, 12, 13, 14, 15, -1}; + + int i =0; + + for (i = 0; i < sizeof(test_chars); i++) + if (g_unichar_xdigit_value ((gunichar)test_chars[i]) != test_values[i]) + return FAILED("Incorrect value %d at index %d", test_values[i], i); + + return OK; +} + +static RESULT +ucs4_to_utf16_check_result (const gunichar2 *result_str, const gunichar2 *expected_str, + glong result_items_read, glong expected_items_read, + glong result_items_written, glong expected_items_written, + GError* result_error, gboolean expect_error) +{ + glong i; + if (result_items_read != expected_items_read) + return FAILED("Incorrect number of items read; expected %d, got %d", expected_items_read, result_items_read); + if (result_items_written != expected_items_written) + return FAILED("Incorrect number of items written; expected %d, got %d", expected_items_written, result_items_written); + if (result_error && !expect_error) + return FAILED("There should not be an error code."); + if (!result_error && expect_error) + return FAILED("Unexpected error object."); + if (expect_error && result_str) + return FAILED("NULL should be returned when an error occurs."); + if (!expect_error && !result_str) + return FAILED("When no error occurs NULL should not be returned."); + for (i=0; i<expected_items_written;i++) { + if (result_str [i] != expected_str [i]) + return FAILED("Incorrect value %d at index %d", result_str [i], i); + } + if (result_str && result_str[expected_items_written] != '\0') + return FAILED("Null termination not found at the end of the string."); + + return OK; +} + +RESULT +test_ucs4_to_utf16 () +{ + static gunichar str1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'}; + static gunichar2 exp1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'}; + static gunichar str2[3] = {'h',0x80000000,'\0'}; + static gunichar2 exp2[2] = {'h','\0'}; + static gunichar str3[3] = {'h',0xDA00,'\0'}; + static gunichar str4[3] = {'h',0x10FFFF,'\0'}; + static gunichar2 exp4[4] = {'h',0xdbff,0xdfff,'\0'}; + static gunichar str5[7] = {0xD7FF,0xD800,0xDFFF,0xE000,0x110000,0x10FFFF,'\0'}; + static gunichar2 exp5[5] = {0xD7FF,0xE000,0xdbff,0xdfff,'\0'}; + static gunichar str6[2] = {0x10400, '\0'}; + static gunichar2 exp6[3] = {0xD801, 0xDC00, '\0'}; + static glong read_write[12] = {1,1,0,0,0,0,1,1,0,0,1,2}; + gunichar2* res; + glong items_read, items_written, current_write_index; + GError* err=0; + RESULT check_result; + glong i; + + res = g_ucs4_to_utf16 (str1, 12, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, exp1, items_read, 11, items_written, 11, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_ucs4_to_utf16 (str2, 0, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, exp2, items_read, 0, items_written, 0, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_ucs4_to_utf16 (str2, 1, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, exp2, items_read, 1, items_written, 1, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_ucs4_to_utf16 (str2, 2, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, 0, items_read, 1, items_written, 0, err, TRUE); + g_free (res); + if (check_result) return check_result; + + items_read = items_written = 0; + err = 0; + res = g_ucs4_to_utf16 (str3, 2, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, 0, items_read, 1, items_written, 0, err, TRUE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + err = 0; + res = g_ucs4_to_utf16 (str4, 5, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, exp4, items_read, 2, items_written, 3, err, FALSE); + if (check_result) return check_result; + g_free (res); + + // This loop tests the bounds of the conversion algorithm + current_write_index = 0; + for (i=0;i<6;i++) { + items_read = items_written = 0; + err = 0; + res = g_ucs4_to_utf16 (&str5[i], 1, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, &exp5[current_write_index], + items_read, read_write[i*2], items_written, read_write[(i*2)+1], err, !read_write[(i*2)+1]); + if (check_result) return check_result; + g_free (res); + current_write_index += items_written; + } + + items_read = items_written = 0; + err = 0; + res = g_ucs4_to_utf16 (str6, 1, &items_read, &items_written, &err); + check_result = ucs4_to_utf16_check_result (res, exp6, items_read, 1, items_written, 2, err, FALSE); + if (check_result) return check_result; + g_free (res); + + return OK; +} + +static RESULT +utf16_to_ucs4_check_result (const gunichar *result_str, const gunichar *expected_str, + glong result_items_read, glong expected_items_read, + glong result_items_written, glong expected_items_written, + GError* result_error, gboolean expect_error) +{ + glong i; + if (result_items_read != expected_items_read) + return FAILED("Incorrect number of items read; expected %d, got %d", expected_items_read, result_items_read); + if (result_items_written != expected_items_written) + return FAILED("Incorrect number of items written; expected %d, got %d", expected_items_written, result_items_written); + if (result_error && !expect_error) + return FAILED("There should not be an error code."); + if (!result_error && expect_error) + return FAILED("Unexpected error object."); + if (expect_error && result_str) + return FAILED("NULL should be returned when an error occurs."); + if (!expect_error && !result_str) + return FAILED("When no error occurs NULL should not be returned."); + for (i=0; i<expected_items_written;i++) { + if (result_str [i] != expected_str [i]) + return FAILED("Incorrect value %d at index %d", result_str [i], i); + } + if (result_str && result_str[expected_items_written] != '\0') + return FAILED("Null termination not found at the end of the string."); + + return OK; +} + +RESULT +test_utf16_to_ucs4 () +{ + static gunichar2 str1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'}; + static gunichar exp1[12] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'}; + static gunichar2 str2[7] = {'H', 0xD800, 0xDC01,0xD800,0xDBFF,'l','\0'}; + static gunichar exp2[3] = {'H',0x00010001,'\0'}; + static gunichar2 str3[4] = {'H', 0xDC00 ,'l','\0'}; + static gunichar exp3[2] = {'H','\0'}; + static gunichar2 str4[20] = {0xDC00,0xDFFF,0xDFF,0xD800,0xDBFF,0xD800,0xDC00,0xD800,0xDFFF, + 0xD800,0xE000,0xDBFF,0xDBFF,0xDBFF,0xDC00,0xDBFF,0xDFFF,0xDBFF,0xE000,'\0'}; + static gunichar exp4[6] = {0xDFF,0x10000,0x103ff,0x10fc00,0x10FFFF,'\0'}; + static gunichar2 str5[3] = {0xD801, 0xDC00, 0}; + static gunichar exp5[2] = {0x10400, 0}; + static glong read_write[33] = {1,0,0,1,0,0,1,1,1,2,1,0,2,2,1,2,2,1,2,1,0,2,1,0,2,2,1,2,2,1,2,1,0}; + gunichar* res; + glong items_read, items_written, current_read_index,current_write_index; + GError* err=0; + RESULT check_result; + glong i; + + res = g_utf16_to_ucs4 (str1, 12, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp1, items_read, 11, items_written, 11, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_utf16_to_ucs4 (str2, 0, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 0, items_written, 0, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_utf16_to_ucs4 (str2, 1, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 1, items_written, 1, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_utf16_to_ucs4 (str2, 2, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 1, items_written, 1, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_utf16_to_ucs4 (str2, 3, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 3, items_written, 2, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_utf16_to_ucs4 (str2, 4, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 3, items_written, 2, err, FALSE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + res = g_utf16_to_ucs4 (str2, 5, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp2, items_read, 4, items_written, 0, err, TRUE); + if (check_result) return check_result; + g_free (res); + + items_read = items_written = 0; + err = 0; + res = g_utf16_to_ucs4 (str3, 5, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp3, items_read, 1, items_written, 0, err, TRUE); + if (check_result) return check_result; + g_free (res); + + // This loop tests the bounds of the conversion algorithm + current_read_index = current_write_index = 0; + for (i=0;i<11;i++) { + items_read = items_written = 0; + err = 0; + res = g_utf16_to_ucs4 (&str4[current_read_index], read_write[i*3], &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, &exp4[current_write_index], items_read, + read_write[(i*3)+1], items_written, read_write[(i*3)+2], err, + !read_write[(i*3)+2]); + if (check_result) return check_result; + g_free (res); + current_read_index += read_write[i*3]; + current_write_index += items_written; + } + + items_read = items_written = 0; + err = 0; + res = g_utf16_to_ucs4 (str5, 2, &items_read, &items_written, &err); + check_result = utf16_to_ucs4_check_result (res, exp5, items_read, 2, items_written, 1, err, FALSE); + if (check_result) return check_result; + g_free (res); + + return OK; +} +RESULT +test_utf8_strlen () +{ + gchar word1 [] = {0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,0xF1, 0x82, 0x82, 0x82,'\0'};//Valid, len = 5 + gchar word2 [] = {0xF1, 0x82, 0x82, 0x82,0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,'\0'};//Valid, len = 5 + gchar word3 [] = {'h','e',0xC2, 0x82,0x45,'\0'}; //Valid, len = 4 + gchar word4 [] = {0x62,0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,'\0'}; //Valid, len = 5 + + glong len = 0; + + //Test word1 + len = g_utf8_strlen (word1,-1); + if (len != 5) + return FAILED ("Word1 expected length of 5, but was %i", len); + //Do tests with different values for max parameter. + len = g_utf8_strlen (word1,1); + if (len != 0) + return FAILED ("Word1, max = 1, expected length of 0, but was %i", len); + len = g_utf8_strlen (word1,2); + if (len != 1) + return FAILED ("Word1, max = 1, expected length of 1, but was %i", len); + len = g_utf8_strlen (word1,3); + if (len != 2) + return FAILED ("Word1, max = 2, expected length of 2, but was %i", len); + + //Test word2 + len = g_utf8_strlen (word2,-1); + if (len != 5) + return FAILED ("Word2 expected length of 5, but was %i", len); + + //Test word3 + len = g_utf8_strlen (word3,-1); + if (len != 4) + return FAILED ("Word3 expected length of 4, but was %i", len); + + //Test word4 + len = g_utf8_strlen (word4,-1); + if (len != 5) + return FAILED ("Word4 expected length of 5, but was %i", len); + + //Test null case + len = g_utf8_strlen(NULL,0); + if (len != 0) + return FAILED ("Expected passing null to result in a length of 0"); + return OK; +} + +RESULT +test_utf8_get_char() +{ + gchar word1 [] = {0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,0xF1, 0x82, 0x82, 0x82,'\0'}; //Valid, len = 5 + + gunichar value = g_utf8_get_char (&word1 [0]); + if (value != 0x82UL) + return FAILED ("Expected value of 0x82, but was %x", value); + value = g_utf8_get_char (&word1 [2]); + if (value != 0x45UL) + return FAILED ("Expected value of 0x45, but was %x", value); + value = g_utf8_get_char (&word1 [3]); + if (value != 0x1043UL) + return FAILED ("Expected value of 0x1043, but was %x", value); + value = g_utf8_get_char (&word1 [6]); + if (value != 0x58UL) + return FAILED ("Expected value of 0x58, but was %x", value); + value = g_utf8_get_char (&word1 [7]); + if (value != 0x42082UL) + return FAILED ("Expected value of 0x42082, but was %x", value); + + return OK; +} + +RESULT +test_utf8_next_char() +{ + gchar word1 [] = {0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,0xF1, 0x82, 0x82, 0x82,'\0'}; //Valid, len = 5 + gchar word2 [] = {0xF1, 0x82, 0x82, 0x82,0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,'\0'}; //Valid, len = 5 + gchar word1ExpectedValues [] = {0xC2, 0x45,0xE1, 0x58, 0xF1}; + gchar word2ExpectedValues [] = {0xF1, 0xC2, 0x45, 0xE1, 0x58}; + + gchar* ptr = word1; + gint count = 0; + //Test word1 + while (*ptr != 0) { + if (count > 4) + return FAILED ("Word1 has gone past its expected length"); + if (*ptr != word1ExpectedValues[count]) + return FAILED ("Word1 has an incorrect next_char at index %i", count); + ptr = g_utf8_next_char (ptr); + count++; + } + + //Test word2 + count = 0; + ptr = word2; + while (*ptr != 0) { + if (count > 4) + return FAILED ("Word2 has gone past its expected length"); + if (*ptr != word2ExpectedValues[count]) + return FAILED ("Word2 has an incorrect next_char at index %i", count); + ptr = g_utf8_next_char (ptr); + count++; + } + + return OK; +} + +RESULT +test_utf8_validate() +{ + gchar invalidWord1 [] = {0xC3, 0x82, 0xC1,0x90,'\0'}; //Invalid, 1nd oct Can't be 0xC0 or 0xC1 + gchar invalidWord2 [] = {0xC1, 0x89, 0x60, '\0'}; //Invalid, 1st oct can not be 0xC1 + gchar invalidWord3 [] = {0xC2, 0x45,0xE1, 0x81, 0x83,0x58,'\0'}; //Invalid, oct after 0xC2 must be > 0x80 + + gchar validWord1 [] = {0xC2, 0x82, 0xC3,0xA0,'\0'}; //Valid + gchar validWord2 [] = {0xC2, 0x82,0x45,0xE1, 0x81, 0x83,0x58,0xF1, 0x82, 0x82, 0x82,'\0'}; //Valid + + const gchar* end; + gboolean retVal = g_utf8_validate (invalidWord1, -1, &end); + if (retVal != FALSE) + return FAILED ("Expected invalidWord1 to be invalid"); + if (end != &invalidWord1 [2]) + return FAILED ("Expected end parameter to be pointing to invalidWord1[2]"); + + end = NULL; + retVal = g_utf8_validate (invalidWord2, -1, &end); + if (retVal != FALSE) + return FAILED ("Expected invalidWord2 to be invalid"); + if (end != &invalidWord2 [0]) + return FAILED ("Expected end parameter to be pointing to invalidWord2[0]"); + + end = NULL; + retVal = g_utf8_validate (invalidWord3, -1, &end); + if (retVal != FALSE) + return FAILED ("Expected invalidWord3 to be invalid"); + if (end != &invalidWord3 [0]) + return FAILED ("Expected end parameter to be pointing to invalidWord3[1]"); + + end = NULL; + retVal = g_utf8_validate (validWord1, -1, &end); + if (retVal != TRUE) + return FAILED ("Expected validWord1 to be valid"); + if (end != &validWord1 [4]) + return FAILED ("Expected end parameter to be pointing to validWord1[4]"); + + end = NULL; + retVal = g_utf8_validate (validWord2, -1, &end); + if (retVal != TRUE) + return FAILED ("Expected validWord2 to be valid"); + if (end != &validWord2 [11]) + return FAILED ("Expected end parameter to be pointing to validWord2[11]"); + return OK; +} + +glong +utf8_byteslen (const gchar *src) +{ + int i = 0; + do { + if (src [i] == '\0') + return i; + i++; + } while (TRUE); +} + +RESULT +test_utf8_strcase_each (const gchar *src, const gchar *expected, gboolean strup) +{ + gchar *tmp; + glong len, len2; + RESULT r; + + len = utf8_byteslen (src); + tmp = strup ? g_utf8_strup (src, len) : g_utf8_strdown (src, len); + len2 = utf8_byteslen (tmp); + r = compare_strings_utf8_RESULT (expected, tmp, len < len2 ? len2 : len); + g_free (tmp); + return r; +} + +RESULT +test_utf8_strup_each (const gchar *src, const gchar *expected) +{ + return test_utf8_strcase_each (src, expected, TRUE); +} + +RESULT +test_utf8_strdown_each (const gchar *src, const gchar *expected) +{ + return test_utf8_strcase_each (src, expected, FALSE); +} + +/* + * g_utf8_strup + */ +RESULT +test_utf8_strup () +{ + RESULT r; + + if ((r = test_utf8_strup_each ("aBc", "ABC")) != OK) + return r; + if ((r = test_utf8_strup_each ("x86-64", "X86-64")) != OK) + return r; + // U+3B1 U+392 -> U+391 U+392 + if ((r = test_utf8_strup_each ("\xCE\xB1\xCE\x92", "\xCE\x91\xCE\x92")) != OK) + return r; + // U+FF21 -> U+FF21 + if ((r = test_utf8_strup_each ("\xEF\xBC\xA1", "\xEF\xBC\xA1")) != OK) + return r; + // U+FF41 -> U+FF21 + if ((r = test_utf8_strup_each ("\xEF\xBD\x81", "\xEF\xBC\xA1")) != OK) + return r; + // U+10428 -> U+10400 + if ((r = test_utf8_strup_each ("\xF0\x90\x90\xA8", "\xF0\x90\x90\x80")) != OK) + return r; + + return OK; +} + +/* + * g_utf8_strdown + */ +RESULT +test_utf8_strdown () +{ + RESULT r; + + if ((r = test_utf8_strdown_each ("aBc", "abc")) != OK) + return r; + if ((r = test_utf8_strdown_each ("X86-64", "x86-64")) != OK) + return r; + // U+391 U+3B2 -> U+3B1 U+3B2 + if ((r = test_utf8_strdown_each ("\xCE\x91\xCE\xB2", "\xCE\xB1\xCE\xB2")) != OK) + return r; +/* + // U+FF41 -> U+FF41 + if ((r = test_utf8_strdown_each ("\xEF\xBC\x81", "\xEF\xBC\x81")) != OK) + return r; + // U+FF21 -> U+FF41 + if ((r = test_utf8_strdown_each ("\xEF\xBC\xA1", "\xEF\xBD\x81")) != OK) + return r; + // U+10400 -> U+10428 + if ((r = test_utf8_strdown_each ("\xF0\x90\x90\x80", "\xF0\x90\x90\xA8")) != OK) + return r; +*/ + return OK; +} + +/* + * test initialization + */ + +static Test utf8_tests [] = { + {"g_utf16_to_utf8", test_utf16_to_utf8}, + {"g_utf8_to_utf16", test_utf8_to_utf16}, + {"g_utf8_to_utf16_with_nuls", test_utf8_to_utf16_with_nuls}, + {"g_utf8_seq", test_utf8_seq}, + {"g_convert", test_convert }, + {"g_unichar_xdigit_value", test_xdigit }, + {"g_ucs4_to_utf16", test_ucs4_to_utf16 }, + {"g_utf16_to_ucs4", test_utf16_to_ucs4 }, + {"g_utf8_strlen", test_utf8_strlen }, + {"g_utf8_get_char", test_utf8_get_char }, + {"g_utf8_next_char", test_utf8_next_char }, + {"g_utf8_validate", test_utf8_validate }, + {"g_utf8_strup", test_utf8_strup}, + {"g_utf8_strdown", test_utf8_strdown}, + {NULL, NULL} +}; + +DEFINE_TEST_GROUP_INIT(utf8_tests_init, utf8_tests) + + diff --git a/deps/eglib/test/whats-implemented b/deps/eglib/test/whats-implemented new file mode 100755 index 00000000..8a113578 --- /dev/null +++ b/deps/eglib/test/whats-implemented @@ -0,0 +1,83 @@ +#!/bin/bash + +# Author: Aaron Bockover +# Licensed under MIT/X11 +# (C) 2006 Novell + +if [ "x$1" = "x--help" ]; then + echo "Usage: $0 [--show-only-mono]" + echo "" + echo "This script prints a sorted list of GLib functions used in Mono" + echo "that have not yet been implemented in EGlib." + echo "" + echo "If --show-only-mono is passed, then the script will print all" + echo "GLib functions used in Mono, whether or not they have been" + echo "implemented in EGlib yet." + echo "" + echo "This script relies on the MONO_CHECKOUT environment variable." + echo "MONO_CHECKOUT should be set to the location of a mono checkout." + echo "" + exit 1 +fi + +IGNORE_FUNCTIONS="g_hash_table_lookup_node g_hash_table_foreach_remove_or_steal g_hash_table_resize" + +if [ -z $MONO_CHECKOUT ]; then + if [ -e ../../mono.pc.in ]; then + MONO_CHECKOUT=../.. + else + MONO_CHECKOUT=~/cvs/mono/mono + fi +fi + +if [ ! -d $MONO_CHECKOUT ]; then + echo "Cannot find mono checkout; set MONO_CHECKOUT" + exit 1 +fi + +MONO_CHECKOUT="$MONO_CHECKOUT/mono" +RESULTS_FILE=.results + +(for i in `find $MONO_CHECKOUT -iregex \.*.c$`; do + grep -oP "[ \t\(\)]+g_[a-z_]+[ ]{0,1}\([A-Za-z_\&\*\,\(\) ]+\)" $i | + awk 'BEGIN { FS="(" } { print $1 }' | + sed -e 's/[^A-Za-z_]//g' + done +) > $RESULTS_FILE + +if [ ! "x$1" = "x--show-only-mono" ]; then + IMPLEMENTED_FUNCTIONS=`grep -oP "g_[a-z_]+[ ]{0,1}" ../src/glib.h | awk 'BEGIN { FS="(" } { print $1 }'` + + rm -f $RESULTS_FILE.tmp + + for mono_function in `cat $RESULTS_FILE`; do + matched="no" + for implemented_function in $IMPLEMENTED_FUNCTIONS; do + if [ "x$mono_function" = "x$implemented_function" ]; then + matched="yes" + break + fi + done + + for ignore_function in $IGNORE_FUNCTIONS; do + if [ "x$ignore_function" = "x$mono_function" ]; then + matched="yes" + break + fi + done + + if [ "x$matched" = "xno" ]; then + echo $mono_function >> $RESULTS_FILE.tmp + fi + done + + mv $RESULTS_FILE.tmp $RESULTS_FILE +fi + +(for i in `cat $RESULTS_FILE | sort -u`; do + echo "`grep -c $i $RESULTS_FILE` $i"; + done; +) | sort -nr + +rm $RESULTS_FILE + diff --git a/deps/eglib/winconfig.h b/deps/eglib/winconfig.h new file mode 100755 index 00000000..fdab3dda --- /dev/null +++ b/deps/eglib/winconfig.h @@ -0,0 +1,76 @@ +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the <pwd.h> header file. */ +/* #undef HAVE_PWD_H 1 */ + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +/* #undef HAVE_SYS_TIME_H */ + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <sys/wait.h> header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define to 1 if you have the <unistd.h> header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Name of package */ +#define PACKAGE "eglib" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* The size of a `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of a `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 4 + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.1" + +#define HAVE_STRTOK_R 1 diff --git a/deps/glib/COPYING b/deps/glib/COPYING deleted file mode 100644 index bf50f20d..00000000 --- a/deps/glib/COPYING +++ /dev/null @@ -1,482 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - 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. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/deps/glib/Makefile.am b/deps/glib/Makefile.am deleted file mode 100644 index 9a4544ff..00000000 --- a/deps/glib/Makefile.am +++ /dev/null @@ -1,75 +0,0 @@ - -noinst_LTLIBRARIES = libglib.la - -libglib_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/deps \ - -Wall \ - $(NULL) - -libglib_la_SOURCES = \ - galloca.h \ - garray.c \ - garray.h \ - gatomic.c \ - gatomic.h \ - gbacktrace.h \ - gbitlock.c \ - gbitlock.h \ - gconvert.c \ - gconvert.h \ - gdatasetprivate.h \ - gdataset.c \ - gdataset.h \ - gdebug.h \ - gerror.c \ - gerror.h \ - gfileutils.c \ - gfileutils.h \ - ghash.c \ - ghash.h \ - ghook.c \ - ghook.h \ - gi18n-lib.h \ - glibintl.h \ - glib.h \ - glib-object.h \ - glib_trace.h \ - glist.c \ - glist.h \ - gmacros.h \ - gmain.c \ - gmain.h \ - gmem.c \ - gmem.h \ - gmessages.c \ - gmessages.h \ - gprintf.c \ - gprintf.h \ - gprintfint.h \ - gqsort.c \ - gqsort.h \ - gquark.h \ - gqueue.c \ - gqueue.h \ - gslice.c \ - gslice.h \ - gslist.c \ - gslist.h \ - gstdio.c \ - gstdio.h \ - gstrfuncs.c \ - gstrfuncs.h \ - gstring.c \ - gstring.h \ - gtestutils.c \ - gtestutils.h \ - gthread.c \ - gthread.h \ - gtypes.h \ - gunicode.h \ - gutils.c \ - gutils.h \ - $(NULL) - -EXTRA_DIST = README diff --git a/deps/glib/README b/deps/glib/README deleted file mode 100644 index 312dbafb..00000000 --- a/deps/glib/README +++ /dev/null @@ -1,14 +0,0 @@ -These are files striped from glib 2.30.2 to build a standalone cogl. A few -changes were done on those imported files: - -- the needed functions in gconvert.[ch] have been stubbed (don't want any of the - charset conversions in error messages in standalone mode, -- gmain.c has been stipped to only have the one used function - (g_get_current_time()), -- gtestutils.c has also being stripped down to what cogl uses to reduce what it - pulls in, -- gmessage.c has seen the charset conversions and invalid unicode caracters - escaping stripped. -- charset conversion in error messages has been removed in gstrfuncs.c -- g_string_append_uri_escaped() has been removed from gstrinc.c -- remove g_get_codeset() from gutils.c diff --git a/deps/glib/galloca.h b/deps/glib/galloca.h deleted file mode 100644 index 49435658..00000000 --- a/deps/glib/galloca.h +++ /dev/null @@ -1,108 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_ALLOCA_H__ -#define __G_ALLOCA_H__ - -#include <glib/gtypes.h> - -#ifdef __GNUC__ -/* GCC does the right thing */ -# undef alloca -# define alloca(size) __builtin_alloca (size) -#elif defined (GLIB_HAVE_ALLOCA_H) -/* a native and working alloca.h is there */ -# include <alloca.h> -#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */ -# if defined(_MSC_VER) || defined(__DMC__) -# include <malloc.h> -# define alloca _alloca -# else /* !_MSC_VER && !__DMC__ */ -# ifdef _AIX -# pragma alloca -# else /* !_AIX */ -# ifndef alloca /* predefined by HP cc +Olibcalls */ -G_BEGIN_DECLS -char *alloca (); -G_END_DECLS -# endif /* !alloca */ -# endif /* !_AIX */ -# endif /* !_MSC_VER && !__DMC__ */ -#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */ - -/** - * g_alloca: - * @size: number of bytes to allocate. - * - * Allocates @size bytes on the stack; these bytes will be freed when the current - * stack frame is cleaned up. This macro essentially just wraps the alloca() - * function present on most UNIX variants. - * Thus it provides the same advantages and pitfalls as alloca(): - * <variablelist> - * <varlistentry><term></term><listitem><para> - * + alloca() is very fast, as on most systems it's implemented by just adjusting - * the stack pointer register. - * </para></listitem></varlistentry> - * <varlistentry><term></term><listitem><para> - * + It doesn't cause any memory fragmentation, within its scope, separate alloca() - * blocks just build up and are released together at function end. - * </para></listitem></varlistentry> - * <varlistentry><term></term><listitem><para> - * - Allocation sizes have to fit into the current stack frame. For instance in a - * threaded environment on Linux, the per-thread stack size is limited to 2 Megabytes, - * so be sparse with alloca() uses. - * </para></listitem></varlistentry> - * <varlistentry><term></term><listitem><para> - * - Allocation failure due to insufficient stack space is not indicated with a %NULL - * return like e.g. with malloc(). Instead, most systems probably handle it the same - * way as out of stack space situations from infinite function recursion, i.e. - * with a segmentation fault. - * </para></listitem></varlistentry> - * <varlistentry><term></term><listitem><para> - * - Special care has to be taken when mixing alloca() with GNU C variable sized arrays. - * Stack space allocated with alloca() in the same scope as a variable sized array - * will be freed together with the variable sized array upon exit of that scope, and - * not upon exit of the enclosing function scope. - * </para></listitem></varlistentry> - * </variablelist> - * - * Returns: space for @size bytes, allocated on the stack - */ -#define g_alloca(size) alloca (size) -/** - * g_newa: - * @struct_type: Type of memory chunks to be allocated - * @n_structs: Number of chunks to be allocated - * - * Wraps g_alloca() in a more typesafe manner. - * - * Returns: Pointer to stack space for @n_structs chunks of type @struct_type - */ -#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs))) - -#endif /* __G_ALLOCA_H__ */ diff --git a/deps/glib/garray.c b/deps/glib/garray.c deleted file mode 100644 index 782b4dbd..00000000 --- a/deps/glib/garray.c +++ /dev/null @@ -1,1622 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include <string.h> -#include <stdlib.h> - -#include "garray.h" - -#include "gmem.h" -#include "gatomic.h" -#include "gmessages.h" -#include "gqsort.h" - - -/** - * SECTION:arrays - * @title: Arrays - * @short_description: arrays of arbitrary elements which grow - * automatically as elements are added - * - * Arrays are similar to standard C arrays, except that they grow - * automatically as elements are added. - * - * Array elements can be of any size (though all elements of one array - * are the same size), and the array can be automatically cleared to - * '0's and zero-terminated. - * - * To create a new array use g_array_new(). - * - * To add elements to an array, use g_array_append_val(), - * g_array_append_vals(), g_array_prepend_val(), and - * g_array_prepend_vals(). - * - * To access an element of an array, use g_array_index(). - * - * To set the size of an array, use g_array_set_size(). - * - * To free an array, use g_array_free(). - * - * <example> - * <title>Using a #GArray to store #gint values</title> - * <programlisting> - * GArray *garray; - * gint i; - * /<!-- -->* We create a new array to store gint values. - * We don't want it zero-terminated or cleared to 0's. *<!-- -->/ - * garray = g_array_new (FALSE, FALSE, sizeof (gint)); - * for (i = 0; i < 10000; i++) - * g_array_append_val (garray, i); - * for (i = 0; i < 10000; i++) - * if (g_array_index (garray, gint, i) != i) - * g_print ("ERROR: got %d instead of %d\n", - * g_array_index (garray, gint, i), i); - * g_array_free (garray, TRUE); - * </programlisting> - * </example> - **/ - -#define MIN_ARRAY_SIZE 16 - -typedef struct _GRealArray GRealArray; - -/** - * GArray: - * @data: a pointer to the element data. The data may be moved as - * elements are added to the #GArray. - * @len: the number of elements in the #GArray not including the - * possible terminating zero element. - * - * Contains the public fields of an <link linkend="glib-Arrays">Array</link>. - **/ -struct _GRealArray -{ - guint8 *data; - guint len; - guint alloc; - guint elt_size; - guint zero_terminated : 1; - guint clear : 1; - gint ref_count; -}; - -/** - * g_array_index: - * @a: a #GArray. - * @t: the type of the elements. - * @i: the index of the element to return. - * @Returns: the element of the #GArray at the index given by @i. - * - * Returns the element of a #GArray at the given index. The return - * value is cast to the given type. - * - * <example> - * <title>Getting a pointer to an element in a #GArray</title> - * <programlisting> - * EDayViewEvent *event; - * /<!-- -->* This gets a pointer to the 4th element - * in the array of EDayViewEvent structs. *<!-- -->/ - * event = &g_array_index (events, EDayViewEvent, 3); - * </programlisting> - * </example> - **/ - -#define g_array_elt_len(array,i) ((array)->elt_size * (i)) -#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i))) -#define g_array_elt_zero(array, pos, len) \ - (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len))) -#define g_array_zero_terminate(array) G_STMT_START{ \ - if ((array)->zero_terminated) \ - g_array_elt_zero ((array), (array)->len, 1); \ -}G_STMT_END - -static guint g_nearest_pow (gint num) G_GNUC_CONST; -static void g_array_maybe_expand (GRealArray *array, - gint len); - -/** - * g_array_new: - * @zero_terminated: %TRUE if the array should have an extra element at - * the end which is set to 0. - * @clear_: %TRUE if #GArray elements should be automatically cleared - * to 0 when they are allocated. - * @element_size: the size of each element in bytes. - * @Returns: the new #GArray. - * - * Creates a new #GArray with a reference count of 1. - **/ -GArray* -g_array_new (gboolean zero_terminated, - gboolean clear, - guint elt_size) -{ - return (GArray*) g_array_sized_new (zero_terminated, clear, elt_size, 0); -} - -/** - * g_array_sized_new: - * @zero_terminated: %TRUE if the array should have an extra element at - * the end with all bits cleared. - * @clear_: %TRUE if all bits in the array should be cleared to 0 on - * allocation. - * @element_size: size of each element in the array. - * @reserved_size: number of elements preallocated. - * @Returns: the new #GArray. - * - * Creates a new #GArray with @reserved_size elements preallocated and - * a reference count of 1. This avoids frequent reallocation, if you - * are going to add many elements to the array. Note however that the - * size of the array is still 0. - **/ -GArray* g_array_sized_new (gboolean zero_terminated, - gboolean clear, - guint elt_size, - guint reserved_size) -{ - GRealArray *array = g_slice_new (GRealArray); - - array->data = NULL; - array->len = 0; - array->alloc = 0; - array->zero_terminated = (zero_terminated ? 1 : 0); - array->clear = (clear ? 1 : 0); - array->elt_size = elt_size; - array->ref_count = 1; - - if (array->zero_terminated || reserved_size != 0) - { - g_array_maybe_expand (array, reserved_size); - g_array_zero_terminate(array); - } - - return (GArray*) array; -} - -/** - * g_array_ref: - * @array: A #GArray. - * - * Atomically increments the reference count of @array by one. This - * function is MT-safe and may be called from any thread. - * - * Returns: The passed in #GArray. - * - * Since: 2.22 - **/ -GArray * -g_array_ref (GArray *array) -{ - GRealArray *rarray = (GRealArray*) array; - g_return_val_if_fail (array, NULL); - - g_atomic_int_inc (&rarray->ref_count); - - return array; -} - -/** - * g_array_unref: - * @array: A #GArray. - * - * Atomically decrements the reference count of @array by one. If the - * reference count drops to 0, all memory allocated by the array is - * released. This function is MT-safe and may be called from any - * thread. - * - * Since: 2.22 - **/ -void -g_array_unref (GArray *array) -{ - GRealArray *rarray = (GRealArray*) array; - g_return_if_fail (array); - - if (g_atomic_int_dec_and_test (&rarray->ref_count)) - g_array_free (array, TRUE); -} - -/** - * g_array_get_element_size: - * @array: A #GArray. - * - * Gets the size of the elements in @array. - * - * Returns: Size of each element, in bytes. - * - * Since: 2.22 - **/ -guint -g_array_get_element_size (GArray *array) -{ - GRealArray *rarray = (GRealArray*) array; - - g_return_val_if_fail (array, 0); - - return rarray->elt_size; -} - -/** - * g_array_free: - * @array: a #GArray. - * @free_segment: if %TRUE the actual element data is freed as well. - * @Returns: the element data if @free_segment is %FALSE, otherwise - * %NULL. The element data should be freed using g_free(). - * - * Frees the memory allocated for the #GArray. If @free_segment is - * %TRUE it frees the memory block holding the elements as well and - * also each element if @array has a @element_free_func set. Pass - * %FALSE if you want to free the #GArray wrapper but preserve the - * underlying array for use elsewhere. If the reference count of @array - * is greater than one, the #GArray wrapper is preserved but the size - * of @array will be set to zero. - * - * <note><para>If array elements contain dynamically-allocated memory, - * they should be freed separately.</para></note> - **/ -gchar* -g_array_free (GArray *farray, - gboolean free_segment) -{ - GRealArray *array = (GRealArray*) farray; - gchar* segment; - gboolean preserve_wrapper; - - g_return_val_if_fail (array, NULL); - - /* if others are holding a reference, preserve the wrapper but do free/return the data */ - preserve_wrapper = FALSE; - if (g_atomic_int_get (&array->ref_count) > 1) - preserve_wrapper = TRUE; - - if (free_segment) - { - g_free (array->data); - segment = NULL; - } - else - segment = (gchar*) array->data; - - if (preserve_wrapper) - { - array->data = NULL; - array->len = 0; - array->alloc = 0; - } - else - { - g_slice_free1 (sizeof (GRealArray), array); - } - - return segment; -} - -/** - * g_array_append_vals: - * @array: a #GArray. - * @data: a pointer to the elements to append to the end of the array. - * @len: the number of elements to append. - * @Returns: the #GArray. - * - * Adds @len elements onto the end of the array. - **/ -/** - * g_array_append_val: - * @a: a #GArray. - * @v: the value to append to the #GArray. - * @Returns: the #GArray. - * - * Adds the value on to the end of the array. The array will grow in - * size automatically if necessary. - * - * <note><para>g_array_append_val() is a macro which uses a reference - * to the value parameter @v. This means that you cannot use it with - * literal values such as "27". You must use variables.</para></note> - **/ -GArray* -g_array_append_vals (GArray *farray, - gconstpointer data, - guint len) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - - g_array_maybe_expand (array, len); - - memcpy (g_array_elt_pos (array, array->len), data, - g_array_elt_len (array, len)); - - array->len += len; - - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_prepend_vals: - * @array: a #GArray. - * @data: a pointer to the elements to prepend to the start of the - * array. - * @len: the number of elements to prepend. - * @Returns: the #GArray. - * - * Adds @len elements onto the start of the array. - * - * This operation is slower than g_array_append_vals() since the - * existing elements in the array have to be moved to make space for - * the new elements. - **/ -/** - * g_array_prepend_val: - * @a: a #GArray. - * @v: the value to prepend to the #GArray. - * @Returns: the #GArray. - * - * Adds the value on to the start of the array. The array will grow in - * size automatically if necessary. - * - * This operation is slower than g_array_append_val() since the - * existing elements in the array have to be moved to make space for - * the new element. - * - * <note><para>g_array_prepend_val() is a macro which uses a reference - * to the value parameter @v. This means that you cannot use it with - * literal values such as "27". You must use variables.</para></note> - **/ -GArray* -g_array_prepend_vals (GArray *farray, - gconstpointer data, - guint len) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - - g_array_maybe_expand (array, len); - - g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), - g_array_elt_len (array, array->len)); - - memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len)); - - array->len += len; - - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_insert_vals: - * @array: a #GArray. - * @index_: the index to place the elements at. - * @data: a pointer to the elements to insert. - * @len: the number of elements to insert. - * @Returns: the #GArray. - * - * Inserts @len elements into a #GArray at the given index. - **/ -/** - * g_array_insert_val: - * @a: a #GArray. - * @i: the index to place the element at. - * @v: the value to insert into the array. - * @Returns: the #GArray. - * - * Inserts an element into an array at the given index. - * - * <note><para>g_array_insert_val() is a macro which uses a reference - * to the value parameter @v. This means that you cannot use it with - * literal values such as "27". You must use variables.</para></note> - **/ -GArray* -g_array_insert_vals (GArray *farray, - guint index_, - gconstpointer data, - guint len) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - - g_array_maybe_expand (array, len); - - g_memmove (g_array_elt_pos (array, len + index_), - g_array_elt_pos (array, index_), - g_array_elt_len (array, array->len - index_)); - - memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len)); - - array->len += len; - - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_set_size: - * @array: a #GArray. - * @length: the new size of the #GArray. - * @Returns: the #GArray. - * - * Sets the size of the array, expanding it if necessary. If the array - * was created with @clear_ set to %TRUE, the new elements are set to 0. - **/ -GArray* -g_array_set_size (GArray *farray, - guint length) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - - if (length > array->len) - { - g_array_maybe_expand (array, length - array->len); - - if (array->clear) - g_array_elt_zero (array, array->len, length - array->len); - } - else if (G_UNLIKELY (g_mem_gc_friendly) && length < array->len) - g_array_elt_zero (array, length, array->len - length); - - array->len = length; - - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_remove_index: - * @array: a #GArray. - * @index_: the index of the element to remove. - * @Returns: the #GArray. - * - * Removes the element at the given index from a #GArray. The following - * elements are moved down one place. - **/ -GArray* -g_array_remove_index (GArray *farray, - guint index_) -{ - GRealArray* array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - - g_return_val_if_fail (index_ < array->len, NULL); - - if (index_ != array->len - 1) - g_memmove (g_array_elt_pos (array, index_), - g_array_elt_pos (array, index_ + 1), - g_array_elt_len (array, array->len - index_ - 1)); - - array->len -= 1; - - if (G_UNLIKELY (g_mem_gc_friendly)) - g_array_elt_zero (array, array->len, 1); - else - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_remove_index_fast: - * @array: a @GArray. - * @index_: the index of the element to remove. - * @Returns: the #GArray. - * - * Removes the element at the given index from a #GArray. The last - * element in the array is used to fill in the space, so this function - * does not preserve the order of the #GArray. But it is faster than - * g_array_remove_index(). - **/ -GArray* -g_array_remove_index_fast (GArray *farray, - guint index_) -{ - GRealArray* array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - - g_return_val_if_fail (index_ < array->len, NULL); - - if (index_ != array->len - 1) - memcpy (g_array_elt_pos (array, index_), - g_array_elt_pos (array, array->len - 1), - g_array_elt_len (array, 1)); - - array->len -= 1; - - if (G_UNLIKELY (g_mem_gc_friendly)) - g_array_elt_zero (array, array->len, 1); - else - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_remove_range: - * @array: a @GArray. - * @index_: the index of the first element to remove. - * @length: the number of elements to remove. - * @Returns: the #GArray. - * - * Removes the given number of elements starting at the given index - * from a #GArray. The following elements are moved to close the gap. - * - * Since: 2.4 - **/ -GArray* -g_array_remove_range (GArray *farray, - guint index_, - guint length) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_val_if_fail (array, NULL); - g_return_val_if_fail (index_ < array->len, NULL); - g_return_val_if_fail (index_ + length <= array->len, NULL); - - if (index_ + length != array->len) - g_memmove (g_array_elt_pos (array, index_), - g_array_elt_pos (array, index_ + length), - (array->len - (index_ + length)) * array->elt_size); - - array->len -= length; - if (G_UNLIKELY (g_mem_gc_friendly)) - g_array_elt_zero (array, array->len, length); - else - g_array_zero_terminate (array); - - return farray; -} - -/** - * g_array_sort: - * @array: a #GArray. - * @compare_func: comparison function. - * - * Sorts a #GArray using @compare_func which should be a qsort()-style - * comparison function (returns less than zero for first arg is less - * than second arg, zero for equal, greater zero if first arg is - * greater than second arg). - * - * If two array elements compare equal, their order in the sorted array - * is undefined. If you want equal elements to keep their order – i.e. - * you want a stable sort – you can write a comparison function that, - * if two elements would otherwise compare equal, compares them by - * their addresses. - **/ -void -g_array_sort (GArray *farray, - GCompareFunc compare_func) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_if_fail (array != NULL); - - qsort (array->data, - array->len, - array->elt_size, - compare_func); -} - -/** - * g_array_sort_with_data: - * @array: a #GArray. - * @compare_func: comparison function. - * @user_data: data to pass to @compare_func. - * - * Like g_array_sort(), but the comparison function receives an extra - * user data argument. - **/ -void -g_array_sort_with_data (GArray *farray, - GCompareDataFunc compare_func, - gpointer user_data) -{ - GRealArray *array = (GRealArray*) farray; - - g_return_if_fail (array != NULL); - - g_qsort_with_data (array->data, - array->len, - array->elt_size, - compare_func, - user_data); -} - -/* Returns the smallest power of 2 greater than n, or n if - * such power does not fit in a guint - */ -static guint -g_nearest_pow (gint num) -{ - guint n = 1; - - while (n < num && n > 0) - n <<= 1; - - return n ? n : num; -} - -static void -g_array_maybe_expand (GRealArray *array, - gint len) -{ - guint want_alloc = g_array_elt_len (array, array->len + len + - array->zero_terminated); - - if (want_alloc > array->alloc) - { - want_alloc = g_nearest_pow (want_alloc); - want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); - - array->data = g_realloc (array->data, want_alloc); - - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (array->data + array->alloc, 0, want_alloc - array->alloc); - - array->alloc = want_alloc; - } -} - -/** - * SECTION:arrays_pointer - * @title: Pointer Arrays - * @short_description: arrays of pointers to any type of data, which - * grow automatically as new elements are added - * - * Pointer Arrays are similar to Arrays but are used only for storing - * pointers. - * - * <note><para>If you remove elements from the array, elements at the - * end of the array are moved into the space previously occupied by the - * removed element. This means that you should not rely on the index of - * particular elements remaining the same. You should also be careful - * when deleting elements while iterating over the array.</para></note> - * - * To create a pointer array, use g_ptr_array_new(). - * - * To add elements to a pointer array, use g_ptr_array_add(). - * - * To remove elements from a pointer array, use g_ptr_array_remove(), - * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast(). - * - * To access an element of a pointer array, use g_ptr_array_index(). - * - * To set the size of a pointer array, use g_ptr_array_set_size(). - * - * To free a pointer array, use g_ptr_array_free(). - * - * <example> - * <title>Using a #GPtrArray</title> - * <programlisting> - * GPtrArray *gparray; - * gchar *string1 = "one", *string2 = "two", *string3 = "three"; - * - * gparray = g_ptr_array_new (<!-- -->); - * g_ptr_array_add (gparray, (gpointer) string1); - * g_ptr_array_add (gparray, (gpointer) string2); - * g_ptr_array_add (gparray, (gpointer) string3); - * - * if (g_ptr_array_index (gparray, 0) != (gpointer) string1) - * g_print ("ERROR: got %p instead of %p\n", - * g_ptr_array_index (gparray, 0), string1); - * - * g_ptr_array_free (gparray, TRUE); - * </programlisting> - * </example> - **/ - -typedef struct _GRealPtrArray GRealPtrArray; - -/** - * GPtrArray: - * @pdata: points to the array of pointers, which may be moved when the - * array grows. - * @len: number of pointers in the array. - * - * Contains the public fields of a pointer array. - **/ -struct _GRealPtrArray -{ - gpointer *pdata; - guint len; - guint alloc; - gint ref_count; - GDestroyNotify element_free_func; -}; - -/** - * g_ptr_array_index: - * @array: a #GPtrArray. - * @index_: the index of the pointer to return. - * @Returns: the pointer at the given index. - * - * Returns the pointer at the given index of the pointer array. - **/ - -static void g_ptr_array_maybe_expand (GRealPtrArray *array, - gint len); - -/** - * g_ptr_array_new: - * @Returns: the new #GPtrArray. - * - * Creates a new #GPtrArray with a reference count of 1. - **/ -GPtrArray* -g_ptr_array_new (void) -{ - return g_ptr_array_sized_new (0); -} - -/** - * g_ptr_array_sized_new: - * @reserved_size: number of pointers preallocated. - * @Returns: the new #GPtrArray. - * - * Creates a new #GPtrArray with @reserved_size pointers preallocated - * and a reference count of 1. This avoids frequent reallocation, if - * you are going to add many pointers to the array. Note however that - * the size of the array is still 0. - **/ -GPtrArray* -g_ptr_array_sized_new (guint reserved_size) -{ - GRealPtrArray *array = g_slice_new (GRealPtrArray); - - array->pdata = NULL; - array->len = 0; - array->alloc = 0; - array->ref_count = 1; - array->element_free_func = NULL; - - if (reserved_size != 0) - g_ptr_array_maybe_expand (array, reserved_size); - - return (GPtrArray*) array; -} - -/** - * g_ptr_array_new_with_free_func: - * @element_free_func: A function to free elements with destroy @array or %NULL. - * - * Creates a new #GPtrArray with a reference count of 1 and use @element_free_func - * for freeing each element when the array is destroyed either via - * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment - * set to %TRUE or when removing elements. - * - * Returns: A new #GPtrArray. - * - * Since: 2.22 - **/ -GPtrArray * -g_ptr_array_new_with_free_func (GDestroyNotify element_free_func) -{ - GPtrArray *array; - - array = g_ptr_array_new (); - g_ptr_array_set_free_func (array, element_free_func); - return array; -} - -/** - * g_ptr_array_new_full: - * @reserved_size: number of pointers preallocated. - * @element_free_func: A function to free elements with destroy @array or %NULL. - * - * Creates a new #GPtrArray with @reserved_size pointers preallocated - * and a reference count of 1. This avoids frequent reallocation, if - * you are going to add many pointers to the array. Note however that - * the size of the array is still 0. It also set @element_free_func - * for freeing each element when the array is destroyed either via - * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment - * set to %TRUE or when removing elements. - * - * Returns: A new #GPtrArray. - * - * Since: 2.30 - **/ -GPtrArray * -g_ptr_array_new_full (guint reserved_size, - GDestroyNotify element_free_func) -{ - GPtrArray *array; - - array = g_ptr_array_sized_new (reserved_size); - g_ptr_array_set_free_func (array, element_free_func); - return array; -} - -/** - * g_ptr_array_set_free_func: - * @array: A #GPtrArray. - * @element_free_func: A function to free elements with destroy @array or %NULL. - * - * Sets a function for freeing each element when @array is destroyed - * either via g_ptr_array_unref(), when g_ptr_array_free() is called - * with @free_segment set to %TRUE or when removing elements. - * - * Since: 2.22 - **/ -void -g_ptr_array_set_free_func (GPtrArray *array, - GDestroyNotify element_free_func) -{ - GRealPtrArray* rarray = (GRealPtrArray*) array; - - g_return_if_fail (array); - - rarray->element_free_func = element_free_func; -} - -/** - * g_ptr_array_ref: - * @array: A #GArray. - * - * Atomically increments the reference count of @array by one. This - * function is MT-safe and may be called from any thread. - * - * Returns: The passed in #GPtrArray. - * - * Since: 2.22 - **/ -GPtrArray * -g_ptr_array_ref (GPtrArray *array) -{ - GRealPtrArray *rarray = (GRealPtrArray*) array; - - g_return_val_if_fail (array, NULL); - - g_atomic_int_inc (&rarray->ref_count); - - return array; -} - -/** - * g_ptr_array_unref: - * @array: A #GPtrArray. - * - * Atomically decrements the reference count of @array by one. If the - * reference count drops to 0, the effect is the same as calling - * g_ptr_array_free() with @free_segment set to %TRUE. This function - * is MT-safe and may be called from any thread. - * - * Since: 2.22 - **/ -void -g_ptr_array_unref (GPtrArray *array) -{ - GRealPtrArray *rarray = (GRealPtrArray*) array; - g_return_if_fail (array); - - if (g_atomic_int_dec_and_test (&rarray->ref_count)) - g_ptr_array_free (array, TRUE); -} - -/** - * g_ptr_array_free: - * @array: a #GPtrArray. - * @free_seg: if %TRUE the actual pointer array is freed as well. - * @Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL. - * The pointer array should be freed using g_free(). - * - * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE - * it frees the memory block holding the elements as well. Pass %FALSE - * if you want to free the #GPtrArray wrapper but preserve the - * underlying array for use elsewhere. If the reference count of @array - * is greater than one, the #GPtrArray wrapper is preserved but the - * size of @array will be set to zero. - * - * <note><para>If array contents point to dynamically-allocated - * memory, they should be freed separately if @free_seg is %TRUE and no - * #GDestroyNotify function has been set for @array.</para></note> - **/ -gpointer* -g_ptr_array_free (GPtrArray *farray, - gboolean free_segment) -{ - GRealPtrArray *array = (GRealPtrArray*) farray; - gpointer* segment; - gboolean preserve_wrapper; - - g_return_val_if_fail (array, NULL); - - /* if others are holding a reference, preserve the wrapper but do free/return the data */ - preserve_wrapper = FALSE; - if (g_atomic_int_get (&array->ref_count) > 1) - preserve_wrapper = TRUE; - - if (free_segment) - { - if (array->element_free_func != NULL) - g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL); - g_free (array->pdata); - segment = NULL; - } - else - segment = array->pdata; - - if (preserve_wrapper) - { - array->pdata = NULL; - array->len = 0; - array->alloc = 0; - } - else - { - g_slice_free1 (sizeof (GRealPtrArray), array); - } - - return segment; -} - -static void -g_ptr_array_maybe_expand (GRealPtrArray *array, - gint len) -{ - if ((array->len + len) > array->alloc) - { - guint old_alloc = array->alloc; - array->alloc = g_nearest_pow (array->len + len); - array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE); - array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc); - if (G_UNLIKELY (g_mem_gc_friendly)) - for ( ; old_alloc < array->alloc; old_alloc++) - array->pdata [old_alloc] = NULL; - } -} - -/** - * g_ptr_array_set_size: - * @array: a #GPtrArray. - * @length: the new length of the pointer array. - * - * Sets the size of the array. When making the array larger, - * newly-added elements will be set to %NULL. When making it smaller, - * if @array has a non-%NULL #GDestroyNotify function then it will be - * called for the removed elements. - **/ -void -g_ptr_array_set_size (GPtrArray *farray, - gint length) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - - g_return_if_fail (array); - - if (length > array->len) - { - int i; - g_ptr_array_maybe_expand (array, (length - array->len)); - /* This is not - * memset (array->pdata + array->len, 0, - * sizeof (gpointer) * (length - array->len)); - * to make it really portable. Remember (void*)NULL needn't be - * bitwise zero. It of course is silly not to use memset (..,0,..). - */ - for (i = array->len; i < length; i++) - array->pdata[i] = NULL; - } - else if (length < array->len) - g_ptr_array_remove_range (farray, length, array->len - length); - - array->len = length; -} - -/** - * g_ptr_array_remove_index: - * @array: a #GPtrArray. - * @index_: the index of the pointer to remove. - * @Returns: the pointer which was removed. - * - * Removes the pointer at the given index from the pointer array. The - * following elements are moved down one place. If @array has a - * non-%NULL #GDestroyNotify function it is called for the removed - * element. - **/ -gpointer -g_ptr_array_remove_index (GPtrArray *farray, - guint index_) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - gpointer result; - - g_return_val_if_fail (array, NULL); - - g_return_val_if_fail (index_ < array->len, NULL); - - result = array->pdata[index_]; - - if (array->element_free_func != NULL) - array->element_free_func (array->pdata[index_]); - - if (index_ != array->len - 1) - g_memmove (array->pdata + index_, array->pdata + index_ + 1, - sizeof (gpointer) * (array->len - index_ - 1)); - - array->len -= 1; - - if (G_UNLIKELY (g_mem_gc_friendly)) - array->pdata[array->len] = NULL; - - return result; -} - -/** - * g_ptr_array_remove_index_fast: - * @array: a #GPtrArray. - * @index_: the index of the pointer to remove. - * @Returns: the pointer which was removed. - * - * Removes the pointer at the given index from the pointer array. The - * last element in the array is used to fill in the space, so this - * function does not preserve the order of the array. But it is faster - * than g_ptr_array_remove_index(). If @array has a non-%NULL - * #GDestroyNotify function it is called for the removed element. - **/ -gpointer -g_ptr_array_remove_index_fast (GPtrArray *farray, - guint index_) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - gpointer result; - - g_return_val_if_fail (array, NULL); - - g_return_val_if_fail (index_ < array->len, NULL); - - result = array->pdata[index_]; - - if (array->element_free_func != NULL) - array->element_free_func (array->pdata[index_]); - - if (index_ != array->len - 1) - array->pdata[index_] = array->pdata[array->len - 1]; - - array->len -= 1; - - if (G_UNLIKELY (g_mem_gc_friendly)) - array->pdata[array->len] = NULL; - - return result; -} - -/** - * g_ptr_array_remove_range: - * @array: a @GPtrArray. - * @index_: the index of the first pointer to remove. - * @length: the number of pointers to remove. - * - * Removes the given number of pointers starting at the given index - * from a #GPtrArray. The following elements are moved to close the - * gap. If @array has a non-%NULL #GDestroyNotify function it is called - * for the removed elements. - * - * Since: 2.4 - **/ -void -g_ptr_array_remove_range (GPtrArray *farray, - guint index_, - guint length) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - guint n; - - g_return_if_fail (array); - g_return_if_fail (index_ < array->len); - g_return_if_fail (index_ + length <= array->len); - - if (array->element_free_func != NULL) - { - for (n = index_; n < index_ + length; n++) - array->element_free_func (array->pdata[n]); - } - - if (index_ + length != array->len) - { - g_memmove (&array->pdata[index_], - &array->pdata[index_ + length], - (array->len - (index_ + length)) * sizeof (gpointer)); - } - - array->len -= length; - if (G_UNLIKELY (g_mem_gc_friendly)) - { - guint i; - for (i = 0; i < length; i++) - array->pdata[array->len + i] = NULL; - } -} - -/** - * g_ptr_array_remove: - * @array: a #GPtrArray. - * @data: the pointer to remove. - * @Returns: %TRUE if the pointer is removed. %FALSE if the pointer is - * not found in the array. - * - * Removes the first occurrence of the given pointer from the pointer - * array. The following elements are moved down one place. If @array - * has a non-%NULL #GDestroyNotify function it is called for the - * removed element. - * - * It returns %TRUE if the pointer was removed, or %FALSE if the - * pointer was not found. - **/ -gboolean -g_ptr_array_remove (GPtrArray *farray, - gpointer data) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - guint i; - - g_return_val_if_fail (array, FALSE); - - for (i = 0; i < array->len; i += 1) - { - if (array->pdata[i] == data) - { - g_ptr_array_remove_index (farray, i); - return TRUE; - } - } - - return FALSE; -} - -/** - * g_ptr_array_remove_fast: - * @array: a #GPtrArray. - * @data: the pointer to remove. - * @Returns: %TRUE if the pointer was found in the array. - * - * Removes the first occurrence of the given pointer from the pointer - * array. The last element in the array is used to fill in the space, - * so this function does not preserve the order of the array. But it is - * faster than g_ptr_array_remove(). If @array has a non-%NULL - * #GDestroyNotify function it is called for the removed element. - * - * It returns %TRUE if the pointer was removed, or %FALSE if the - * pointer was not found. - **/ -gboolean -g_ptr_array_remove_fast (GPtrArray *farray, - gpointer data) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - guint i; - - g_return_val_if_fail (array, FALSE); - - for (i = 0; i < array->len; i += 1) - { - if (array->pdata[i] == data) - { - g_ptr_array_remove_index_fast (farray, i); - return TRUE; - } - } - - return FALSE; -} - -/** - * g_ptr_array_add: - * @array: a #GPtrArray. - * @data: the pointer to add. - * - * Adds a pointer to the end of the pointer array. The array will grow - * in size automatically if necessary. - **/ -void -g_ptr_array_add (GPtrArray *farray, - gpointer data) -{ - GRealPtrArray* array = (GRealPtrArray*) farray; - - g_return_if_fail (array); - - g_ptr_array_maybe_expand (array, 1); - - array->pdata[array->len++] = data; -} - -/** - * g_ptr_array_sort: - * @array: a #GPtrArray. - * @compare_func: comparison function. - * - * Sorts the array, using @compare_func which should be a qsort()-style - * comparison function (returns less than zero for first arg is less - * than second arg, zero for equal, greater than zero if irst arg is - * greater than second arg). - * - * If two array elements compare equal, their order in the sorted array - * is undefined. If you want equal elements to keep their order – i.e. - * you want a stable sort – you can write a comparison function that, - * if two elements would otherwise compare equal, compares them by - * their addresses. - * - * <note><para>The comparison function for g_ptr_array_sort() doesn't - * take the pointers from the array as arguments, it takes pointers to - * the pointers in the array.</para></note> - **/ -void -g_ptr_array_sort (GPtrArray *array, - GCompareFunc compare_func) -{ - g_return_if_fail (array != NULL); - - qsort (array->pdata, - array->len, - sizeof (gpointer), - compare_func); -} - -/** - * g_ptr_array_sort_with_data: - * @array: a #GPtrArray. - * @compare_func: comparison function. - * @user_data: data to pass to @compare_func. - * - * Like g_ptr_array_sort(), but the comparison function has an extra - * user data argument. - * - * <note><para>The comparison function for g_ptr_array_sort_with_data() - * doesn't take the pointers from the array as arguments, it takes - * pointers to the pointers in the array.</para></note> - **/ -void -g_ptr_array_sort_with_data (GPtrArray *array, - GCompareDataFunc compare_func, - gpointer user_data) -{ - g_return_if_fail (array != NULL); - - g_qsort_with_data (array->pdata, - array->len, - sizeof (gpointer), - compare_func, - user_data); -} - -/** - * g_ptr_array_foreach: - * @array: a #GPtrArray - * @func: the function to call for each array element - * @user_data: user data to pass to the function - * - * Calls a function for each element of a #GPtrArray. - * - * Since: 2.4 - **/ -void -g_ptr_array_foreach (GPtrArray *array, - GFunc func, - gpointer user_data) -{ - guint i; - - g_return_if_fail (array); - - for (i = 0; i < array->len; i++) - (*func) (array->pdata[i], user_data); -} - -/** - * SECTION:arrays_byte - * @title: Byte Arrays - * @short_description: arrays of bytes, which grow automatically as - * elements are added - * - * #GByteArray is based on #GArray, to provide arrays of bytes which - * grow automatically as elements are added. - * - * To create a new #GByteArray use g_byte_array_new(). - * - * To add elements to a #GByteArray, use g_byte_array_append(), and - * g_byte_array_prepend(). - * - * To set the size of a #GByteArray, use g_byte_array_set_size(). - * - * To free a #GByteArray, use g_byte_array_free(). - * - * <example> - * <title>Using a #GByteArray</title> - * <programlisting> - * GByteArray *gbarray; - * gint i; - * - * gbarray = g_byte_array_new (<!-- -->); - * for (i = 0; i < 10000; i++) - * g_byte_array_append (gbarray, (guint8*) "abcd", 4); - * - * for (i = 0; i < 10000; i++) - * { - * g_assert (gbarray->data[4*i] == 'a'); - * g_assert (gbarray->data[4*i+1] == 'b'); - * g_assert (gbarray->data[4*i+2] == 'c'); - * g_assert (gbarray->data[4*i+3] == 'd'); - * } - * - * g_byte_array_free (gbarray, TRUE); - * </programlisting> - * </example> - **/ - -/** - * GByteArray: - * @data: a pointer to the element data. The data may be moved as - * elements are added to the #GByteArray. - * @len: the number of elements in the #GByteArray. - * - * The <structname>GByteArray</structname> struct allows access to the - * public fields of a <structname>GByteArray</structname>. - **/ - -/** - * g_byte_array_new: - * @Returns: the new #GByteArray. - * - * Creates a new #GByteArray with a reference count of 1. - **/ -GByteArray* g_byte_array_new (void) -{ - return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0); -} - -/** - * g_byte_array_sized_new: - * @reserved_size: number of bytes preallocated. - * @Returns: the new #GByteArray. - * - * Creates a new #GByteArray with @reserved_size bytes preallocated. - * This avoids frequent reallocation, if you are going to add many - * bytes to the array. Note however that the size of the array is still - * 0. - **/ -GByteArray* g_byte_array_sized_new (guint reserved_size) -{ - return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size); -} - -/** - * g_byte_array_free: - * @array: a #GByteArray. - * @free_segment: if %TRUE the actual byte data is freed as well. - * @Returns: the element data if @free_segment is %FALSE, otherwise - * %NULL. The element data should be freed using g_free(). - * - * Frees the memory allocated by the #GByteArray. If @free_segment is - * %TRUE it frees the actual byte data. If the reference count of - * @array is greater than one, the #GByteArray wrapper is preserved but - * the size of @array will be set to zero. - **/ -guint8* g_byte_array_free (GByteArray *array, - gboolean free_segment) -{ - return (guint8*) g_array_free ((GArray*) array, free_segment); -} - -/** - * g_byte_array_ref: - * @array: A #GByteArray. - * - * Atomically increments the reference count of @array by one. This - * function is MT-safe and may be called from any thread. - * - * Returns: The passed in #GByteArray. - * - * Since: 2.22 - **/ -GByteArray * -g_byte_array_ref (GByteArray *array) -{ - return (GByteArray *) g_array_ref ((GArray *) array); -} - -/** - * g_byte_array_unref: - * @array: A #GByteArray. - * - * Atomically decrements the reference count of @array by one. If the - * reference count drops to 0, all memory allocated by the array is - * released. This function is MT-safe and may be called from any - * thread. - * - * Since: 2.22 - **/ -void -g_byte_array_unref (GByteArray *array) -{ - g_array_unref ((GArray *) array); -} - -/** - * g_byte_array_append: - * @array: a #GByteArray. - * @data: the byte data to be added. - * @len: the number of bytes to add. - * @Returns: the #GByteArray. - * - * Adds the given bytes to the end of the #GByteArray. The array will - * grow in size automatically if necessary. - **/ -GByteArray* g_byte_array_append (GByteArray *array, - const guint8 *data, - guint len) -{ - g_array_append_vals ((GArray*) array, (guint8*)data, len); - - return array; -} - -/** - * g_byte_array_prepend: - * @array: a #GByteArray. - * @data: the byte data to be added. - * @len: the number of bytes to add. - * @Returns: the #GByteArray. - * - * Adds the given data to the start of the #GByteArray. The array will - * grow in size automatically if necessary. - **/ -GByteArray* g_byte_array_prepend (GByteArray *array, - const guint8 *data, - guint len) -{ - g_array_prepend_vals ((GArray*) array, (guint8*)data, len); - - return array; -} - -/** - * g_byte_array_set_size: - * @array: a #GByteArray. - * @length: the new size of the #GByteArray. - * @Returns: the #GByteArray. - * - * Sets the size of the #GByteArray, expanding it if necessary. - **/ -GByteArray* g_byte_array_set_size (GByteArray *array, - guint length) -{ - g_array_set_size ((GArray*) array, length); - - return array; -} - -/** - * g_byte_array_remove_index: - * @array: a #GByteArray. - * @index_: the index of the byte to remove. - * @Returns: the #GByteArray. - * - * Removes the byte at the given index from a #GByteArray. The - * following bytes are moved down one place. - **/ -GByteArray* g_byte_array_remove_index (GByteArray *array, - guint index_) -{ - g_array_remove_index ((GArray*) array, index_); - - return array; -} - -/** - * g_byte_array_remove_index_fast: - * @array: a #GByteArray. - * @index_: the index of the byte to remove. - * @Returns: the #GByteArray. - * - * Removes the byte at the given index from a #GByteArray. The last - * element in the array is used to fill in the space, so this function - * does not preserve the order of the #GByteArray. But it is faster - * than g_byte_array_remove_index(). - **/ -GByteArray* g_byte_array_remove_index_fast (GByteArray *array, - guint index_) -{ - g_array_remove_index_fast ((GArray*) array, index_); - - return array; -} - -/** - * g_byte_array_remove_range: - * @array: a @GByteArray. - * @index_: the index of the first byte to remove. - * @length: the number of bytes to remove. - * @Returns: the #GByteArray. - * - * Removes the given number of bytes starting at the given index from a - * #GByteArray. The following elements are moved to close the gap. - * - * Since: 2.4 - **/ -GByteArray* -g_byte_array_remove_range (GByteArray *array, - guint index_, - guint length) -{ - g_return_val_if_fail (array, NULL); - g_return_val_if_fail (index_ < array->len, NULL); - g_return_val_if_fail (index_ + length <= array->len, NULL); - - return (GByteArray *)g_array_remove_range ((GArray*) array, index_, length); -} - -/** - * g_byte_array_sort: - * @array: a #GByteArray. - * @compare_func: comparison function. - * - * Sorts a byte array, using @compare_func which should be a - * qsort()-style comparison function (returns less than zero for first - * arg is less than second arg, zero for equal, greater than zero if - * first arg is greater than second arg). - * - * If two array elements compare equal, their order in the sorted array - * is undefined. If you want equal elements to keep their order – i.e. - * you want a stable sort – you can write a comparison function that, - * if two elements would otherwise compare equal, compares them by - * their addresses. - **/ -void -g_byte_array_sort (GByteArray *array, - GCompareFunc compare_func) -{ - g_array_sort ((GArray *) array, compare_func); -} - -/** - * g_byte_array_sort_with_data: - * @array: a #GByteArray. - * @compare_func: comparison function. - * @user_data: data to pass to @compare_func. - * - * Like g_byte_array_sort(), but the comparison function takes an extra - * user data argument. - **/ -void -g_byte_array_sort_with_data (GByteArray *array, - GCompareDataFunc compare_func, - gpointer user_data) -{ - g_array_sort_with_data ((GArray *) array, compare_func, user_data); -} diff --git a/deps/glib/garray.h b/deps/glib/garray.h deleted file mode 100644 index 582766fb..00000000 --- a/deps/glib/garray.h +++ /dev/null @@ -1,179 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_ARRAY_H__ -#define __G_ARRAY_H__ - -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -typedef struct _GArray GArray; -typedef struct _GByteArray GByteArray; -typedef struct _GPtrArray GPtrArray; - -struct _GArray -{ - gchar *data; - guint len; -}; - -struct _GByteArray -{ - guint8 *data; - guint len; -}; - -struct _GPtrArray -{ - gpointer *pdata; - guint len; -}; - -/* Resizable arrays. remove fills any cleared spot and shortens the - * array, while preserving the order. remove_fast will distort the - * order by moving the last element to the position of the removed. - */ - -#define g_array_append_val(a,v) g_array_append_vals (a, &(v), 1) -#define g_array_prepend_val(a,v) g_array_prepend_vals (a, &(v), 1) -#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &(v), 1) -#define g_array_index(a,t,i) (((t*) (void *) (a)->data) [(i)]) - -GArray* g_array_new (gboolean zero_terminated, - gboolean clear_, - guint element_size); -GArray* g_array_sized_new (gboolean zero_terminated, - gboolean clear_, - guint element_size, - guint reserved_size); -gchar* g_array_free (GArray *array, - gboolean free_segment); -GArray *g_array_ref (GArray *array); -void g_array_unref (GArray *array); -guint g_array_get_element_size (GArray *array); -GArray* g_array_append_vals (GArray *array, - gconstpointer data, - guint len); -GArray* g_array_prepend_vals (GArray *array, - gconstpointer data, - guint len); -GArray* g_array_insert_vals (GArray *array, - guint index_, - gconstpointer data, - guint len); -GArray* g_array_set_size (GArray *array, - guint length); -GArray* g_array_remove_index (GArray *array, - guint index_); -GArray* g_array_remove_index_fast (GArray *array, - guint index_); -GArray* g_array_remove_range (GArray *array, - guint index_, - guint length); -void g_array_sort (GArray *array, - GCompareFunc compare_func); -void g_array_sort_with_data (GArray *array, - GCompareDataFunc compare_func, - gpointer user_data); - -/* Resizable pointer array. This interface is much less complicated - * than the above. Add appends a pointer. Remove fills any cleared - * spot and shortens the array. remove_fast will again distort order. - */ -#define g_ptr_array_index(array,index_) ((array)->pdata)[index_] -GPtrArray* g_ptr_array_new (void); -GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func); -GPtrArray* g_ptr_array_sized_new (guint reserved_size); -GPtrArray* g_ptr_array_new_full (guint reserved_size, - GDestroyNotify element_free_func); -gpointer* g_ptr_array_free (GPtrArray *array, - gboolean free_seg); -GPtrArray* g_ptr_array_ref (GPtrArray *array); -void g_ptr_array_unref (GPtrArray *array); -void g_ptr_array_set_free_func (GPtrArray *array, - GDestroyNotify element_free_func); -void g_ptr_array_set_size (GPtrArray *array, - gint length); -gpointer g_ptr_array_remove_index (GPtrArray *array, - guint index_); -gpointer g_ptr_array_remove_index_fast (GPtrArray *array, - guint index_); -gboolean g_ptr_array_remove (GPtrArray *array, - gpointer data); -gboolean g_ptr_array_remove_fast (GPtrArray *array, - gpointer data); -void g_ptr_array_remove_range (GPtrArray *array, - guint index_, - guint length); -void g_ptr_array_add (GPtrArray *array, - gpointer data); -void g_ptr_array_sort (GPtrArray *array, - GCompareFunc compare_func); -void g_ptr_array_sort_with_data (GPtrArray *array, - GCompareDataFunc compare_func, - gpointer user_data); -void g_ptr_array_foreach (GPtrArray *array, - GFunc func, - gpointer user_data); - - -/* Byte arrays, an array of guint8. Implemented as a GArray, - * but type-safe. - */ - -GByteArray* g_byte_array_new (void); -GByteArray* g_byte_array_sized_new (guint reserved_size); -guint8* g_byte_array_free (GByteArray *array, - gboolean free_segment); -GByteArray *g_byte_array_ref (GByteArray *array); -void g_byte_array_unref (GByteArray *array); -GByteArray* g_byte_array_append (GByteArray *array, - const guint8 *data, - guint len); -GByteArray* g_byte_array_prepend (GByteArray *array, - const guint8 *data, - guint len); -GByteArray* g_byte_array_set_size (GByteArray *array, - guint length); -GByteArray* g_byte_array_remove_index (GByteArray *array, - guint index_); -GByteArray* g_byte_array_remove_index_fast (GByteArray *array, - guint index_); -GByteArray* g_byte_array_remove_range (GByteArray *array, - guint index_, - guint length); -void g_byte_array_sort (GByteArray *array, - GCompareFunc compare_func); -void g_byte_array_sort_with_data (GByteArray *array, - GCompareDataFunc compare_func, - gpointer user_data); - -G_END_DECLS - -#endif /* __G_ARRAY_H__ */ diff --git a/deps/glib/gatomic.c b/deps/glib/gatomic.c deleted file mode 100644 index 7674eebb..00000000 --- a/deps/glib/gatomic.c +++ /dev/null @@ -1,846 +0,0 @@ -/* - * Copyright © 2011 Ryan Lortie - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Ryan Lortie <desrt@desrt.ca> - */ - -#include "config.h" - -#include "gatomic.h" - -/** - * SECTION:atomic_operations - * @title: Atomic Operations - * @short_description: basic atomic integer and pointer operations - * @see_also: #GMutex - * - * The following is a collection of compiler macros to provide atomic - * access to integer and pointer-sized values. - * - * The macros that have 'int' in the name will operate on pointers to - * #gint and #guint. The macros with 'pointer' in the name will operate - * on pointers to any pointer-sized value, including #gsize. There is - * no support for 64bit operations on platforms with 32bit pointers - * because it is not generally possible to perform these operations - * atomically. - * - * The get, set and exchange operations for integers and pointers - * nominally operate on #gint and #gpointer, respectively. Of the - * arithmetic operations, the 'add' operation operates on (and returns) - * signed integer values (#gint and #gssize) and the 'and', 'or', and - * 'xor' operations operate on (and return) unsigned integer values - * (#guint and #gsize). - * - * All of the operations act as a full compiler and (where appropriate) - * hardware memory barrier. Acquire and release or producer and - * consumer barrier semantics are not available through this API. - * - * On GCC, these macros are implemented using GCC intrinsic operations. - * On non-GCC compilers they will evaluate to function calls to - * functions implemented by GLib. - * - * If GLib itself was compiled with GCC then these functions will again - * be implemented by the GCC intrinsics. On Windows without GCC, the - * interlocked API is used to implement the functions. - * - * With non-GCC compilers on non-Windows systems, the functions are - * currently incapable of implementing true atomic operations -- - * instead, they fallback to holding a global lock while performing the - * operation. This provides atomicity between the threads of one - * process, but not between separate processes. For this reason, one - * should exercise caution when attempting to use these options on - * shared memory regions. - * - * It is very important that all accesses to a particular integer or - * pointer be performed using only this API and that different sizes of - * operation are not mixed or used on overlapping memory regions. Never - * read or assign directly from or to a value -- always use this API. - * - * For simple reference counting purposes you should use - * g_atomic_int_inc() and g_atomic_int_dec_and_test(). Other uses that - * fall outside of simple reference counting patterns are prone to - * subtle bugs and occasionally undefined behaviour. It is also worth - * noting that since all of these operations require global - * synchronisation of the entire machine, they can be quite slow. In - * the case of performing multiple atomic operations it can often be - * faster to simply acquire a mutex lock around the critical area, - * perform the operations normally and then release the lock. - **/ - -#ifdef G_ATOMIC_OP_USE_GCC_BUILTINS - -#ifndef __GNUC__ -#error Using GCC builtin atomic ops, but not compiling with GCC? -#endif - -/** - * g_atomic_int_get: - * @atomic: a pointer to a #gint or #guint - * - * Gets the current value of @atomic. - * - * This call acts as a full compiler and hardware - * memory barrier (before the get). - * - * Returns: the value of the integer - * - * Since: 2.4 - **/ -gint -(g_atomic_int_get) (volatile gint *atomic) -{ - return g_atomic_int_get (atomic); -} - -/** - * g_atomic_int_set: - * @atomic: a pointer to a #gint or #guint - * @newval: a new value to store - * - * Sets the value of @atomic to @newval. - * - * This call acts as a full compiler and hardware - * memory barrier (after the set). - * - * Since: 2.4 - */ -void -(g_atomic_int_set) (volatile gint *atomic, - gint newval) -{ - g_atomic_int_set (atomic, newval); -} - -/** - * g_atomic_int_inc: - * @atomic: a pointer to a #gint or #guint - * - * Increments the value of @atomic by 1. - * - * Think of this operation as an atomic version of - * <literal>{ *@atomic += 1; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Since: 2.4 - **/ -void -(g_atomic_int_inc) (volatile gint *atomic) -{ - g_atomic_int_inc (atomic); -} - -/** - * g_atomic_int_dec_and_test: - * @atomic: a pointer to a #gint or #guint - * - * Decrements the value of @atomic by 1. - * - * Think of this operation as an atomic version of - * <literal>{ *@atomic -= 1; return (*@atomic == 0); }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: %TRUE if the resultant value is zero - * - * Since: 2.4 - **/ -gboolean -(g_atomic_int_dec_and_test) (volatile gint *atomic) -{ - return g_atomic_int_dec_and_test (atomic); -} - -/** - * g_atomic_int_compare_and_exchange: - * @atomic: a pointer to a #gint or #guint - * @oldval: the value to compare with - * @newval: the value to conditionally replace with - * - * Compares @atomic to @oldval and, if equal, sets it to @newval. - * If @atomic was not equal to @oldval then no change occurs. - * - * This compare and exchange is done atomically. - * - * Think of this operation as an atomic version of - * <literal>{ if (*@atomic == @oldval) { *@atomic = @newval; return TRUE; } else return FALSE; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: %TRUE if the exchange took place - * - * Since: 2.4 - **/ -gboolean -(g_atomic_int_compare_and_exchange) (volatile gint *atomic, - gint oldval, - gint newval) -{ - return g_atomic_int_compare_and_exchange (atomic, oldval, newval); -} - -/** - * g_atomic_int_add: - * @atomic: a pointer to a #gint or #guint - * @val: the value to add - * - * Atomically adds @val to the value of @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic += @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Before version 2.30, this function did not return a value - * (but g_atomic_int_exchange_and_add() did, and had the same meaning). - * - * Returns: the value of @atomic before the add, signed - * - * Since: 2.4 - **/ -gint -(g_atomic_int_add) (volatile gint *atomic, - gint val) -{ - return g_atomic_int_add (atomic, val); -} - -/** - * g_atomic_int_and: - * @atomic: a pointer to a #gint or #guint - * @val: the value to 'and' - * - * Performs an atomic bitwise 'and' of the value of @atomic and @val, - * storing the result back in @atomic. - * - * This call acts as a full compiler and hardware memory barrier. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic &= @val; return tmp; }</literal> - * - * Returns: the value of @atomic before the operation, unsigned - * - * Since: 2.30 - **/ -guint -(g_atomic_int_and) (volatile guint *atomic, - guint val) -{ - return g_atomic_int_and (atomic, val); -} - -/** - * g_atomic_int_or: - * @atomic: a pointer to a #gint or #guint - * @val: the value to 'or' - * - * Performs an atomic bitwise 'or' of the value of @atomic and @val, - * storing the result back in @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic |= @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: the value of @atomic before the operation, unsigned - * - * Since: 2.30 - **/ -guint -(g_atomic_int_or) (volatile guint *atomic, - guint val) -{ - return g_atomic_int_or (atomic, val); -} - -/** - * g_atomic_int_xor: - * @atomic: a pointer to a #gint or #guint - * @val: the value to 'xor' - * - * Performs an atomic bitwise 'xor' of the value of @atomic and @val, - * storing the result back in @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic ^= @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: the value of @atomic before the operation, unsigned - * - * Since: 2.30 - **/ -guint -(g_atomic_int_xor) (volatile guint *atomic, - guint val) -{ - return g_atomic_int_xor (atomic, val); -} - - -/** - * g_atomic_pointer_get: - * @atomic: a pointer to a #gpointer-sized value - * - * Gets the current value of @atomic. - * - * This call acts as a full compiler and hardware - * memory barrier (before the get). - * - * Returns: the value of the pointer - * - * Since: 2.4 - **/ -gpointer -(g_atomic_pointer_get) (volatile void *atomic) -{ - return g_atomic_pointer_get ((volatile gpointer *) atomic); -} - -/** - * g_atomic_pointer_set: - * @atomic: a pointer to a #gpointer-sized value - * @newval: a new value to store - * - * Sets the value of @atomic to @newval. - * - * This call acts as a full compiler and hardware - * memory barrier (after the set). - * - * Since: 2.4 - **/ -void -(g_atomic_pointer_set) (volatile void *atomic, - gpointer newval) -{ - g_atomic_pointer_set ((volatile gpointer *) atomic, newval); -} - -/** - * g_atomic_pointer_compare_and_exchange: - * @atomic: a pointer to a #gpointer-sized value - * @oldval: the value to compare with - * @newval: the value to conditionally replace with - * - * Compares @atomic to @oldval and, if equal, sets it to @newval. - * If @atomic was not equal to @oldval then no change occurs. - * - * This compare and exchange is done atomically. - * - * Think of this operation as an atomic version of - * <literal>{ if (*@atomic == @oldval) { *@atomic = @newval; return TRUE; } else return FALSE; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: %TRUE if the exchange took place - * - * Since: 2.4 - **/ -gboolean -(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, - gpointer oldval, - gpointer newval) -{ - return g_atomic_pointer_compare_and_exchange ((volatile gpointer *) atomic, - oldval, newval); -} - -/** - * g_atomic_pointer_add: - * @atomic: a pointer to a #gpointer-sized value - * @val: the value to add - * - * Atomically adds @val to the value of @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic += @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: the value of @atomic before the add, signed - * - * Since: 2.30 - **/ -gssize -(g_atomic_pointer_add) (volatile void *atomic, - gssize val) -{ - return g_atomic_pointer_add ((volatile gpointer *) atomic, val); -} - -/** - * g_atomic_pointer_and: - * @atomic: a pointer to a #gpointer-sized value - * @val: the value to 'and' - * - * Performs an atomic bitwise 'and' of the value of @atomic and @val, - * storing the result back in @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic &= @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: the value of @atomic before the operation, unsigned - * - * Since: 2.30 - **/ -gsize -(g_atomic_pointer_and) (volatile void *atomic, - gsize val) -{ - return g_atomic_pointer_and ((volatile gpointer *) atomic, val); -} - -/** - * g_atomic_pointer_or: - * @atomic: a pointer to a #gpointer-sized value - * @val: the value to 'or' - * - * Performs an atomic bitwise 'or' of the value of @atomic and @val, - * storing the result back in @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic |= @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: the value of @atomic before the operation, unsigned - * - * Since: 2.30 - **/ -gsize -(g_atomic_pointer_or) (volatile void *atomic, - gsize val) -{ - return g_atomic_pointer_or ((volatile gpointer *) atomic, val); -} - -/** - * g_atomic_pointer_xor: - * @atomic: a pointer to a #gpointer-sized value - * @val: the value to 'xor' - * - * Performs an atomic bitwise 'xor' of the value of @atomic and @val, - * storing the result back in @atomic. - * - * Think of this operation as an atomic version of - * <literal>{ tmp = *atomic; *@atomic ^= @val; return tmp; }</literal> - * - * This call acts as a full compiler and hardware memory barrier. - * - * Returns: the value of @atomic before the operation, unsigned - * - * Since: 2.30 - **/ -gsize -(g_atomic_pointer_xor) (volatile void *atomic, - gsize val) -{ - return g_atomic_pointer_xor ((volatile gpointer *) atomic, val); -} - -#elif defined (G_PLATFORM_WIN32) && defined(HAVE_WIN32_BUILTINS_FOR_ATOMIC_OPERATIONS) - -#include <windows.h> -#if !defined(_M_AMD64) && !defined (_M_IA64) && !defined(_M_X64) -#define InterlockedAnd _InterlockedAnd -#define InterlockedOr _InterlockedOr -#define InterlockedXor _InterlockedXor -#endif - -/* - * http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx - */ -gint -(g_atomic_int_get) (volatile gint *atomic) -{ - MemoryBarrier (); - return *atomic; -} - -void -(g_atomic_int_set) (volatile gint *atomic, - gint newval) -{ - *atomic = newval; - MemoryBarrier (); -} - -void -(g_atomic_int_inc) (volatile gint *atomic) -{ - InterlockedIncrement (atomic); -} - -gboolean -(g_atomic_int_dec_and_test) (volatile gint *atomic) -{ - return InterlockedDecrement (atomic) == 0; -} - -gboolean -(g_atomic_int_compare_and_exchange) (volatile gint *atomic, - gint oldval, - gint newval) -{ - return InterlockedCompareExchange (atomic, newval, oldval) == oldval; -} - -gint -(g_atomic_int_add) (volatile gint *atomic, - gint val) -{ - return InterlockedExchangeAdd (atomic, val); -} - -guint -(g_atomic_int_and) (volatile guint *atomic, - guint val) -{ - return InterlockedAnd (atomic, val); -} - -guint -(g_atomic_int_or) (volatile guint *atomic, - guint val) -{ - return InterlockedOr (atomic, val); -} - -guint -(g_atomic_int_xor) (volatile guint *atomic, - guint val) -{ - return InterlockedXor (atomic, val); -} - - -gpointer -(g_atomic_pointer_get) (volatile void *atomic) -{ - volatile gpointer *ptr = atomic; - - MemoryBarrier (); - return *ptr; -} - -void -(g_atomic_pointer_set) (volatile void *atomic, - gpointer newval) -{ - volatile gpointer *ptr = atomic; - - *ptr = newval; - MemoryBarrier (); -} - -gboolean -(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, - gpointer oldval, - gpointer newval) -{ - return InterlockedCompareExchangePointer (atomic, newval, oldval) == oldval; -} - -gssize -(g_atomic_pointer_add) (volatile void *atomic, - gssize val) -{ -#if GLIB_SIZEOF_VOID_P == 8 - return InterlockedExchangeAdd64 (atomic, val); -#else - return InterlockedExchangeAdd (atomic, val); -#endif -} - -gsize -(g_atomic_pointer_and) (volatile void *atomic, - gsize val) -{ -#if GLIB_SIZEOF_VOID_P == 8 - return InterlockedAnd64 (atomic, val); -#else - return InterlockedAnd (atomic, val); -#endif -} - -gsize -(g_atomic_pointer_or) (volatile void *atomic, - gsize val) -{ -#if GLIB_SIZEOF_VOID_P == 8 - return InterlockedOr64 (atomic, val); -#else - return InterlockedOr (atomic, val); -#endif -} - -gsize -(g_atomic_pointer_xor) (volatile void *atomic, - gsize val) -{ -#if GLIB_SIZEOF_VOID_P == 8 - return InterlockedXor64 (atomic, val); -#else - return InterlockedXor (atomic, val); -#endif -} - -#else - -#include "gthread.h" - -static GStaticMutex g_atomic_lock; - -gint -(g_atomic_int_get) (volatile gint *atomic) -{ - gint value; - - g_static_mutex_lock (&g_atomic_lock); - value = *atomic; - g_static_mutex_unlock (&g_atomic_lock); - - return value; -} - -void -(g_atomic_int_set) (volatile gint *atomic, - gint value) -{ - g_static_mutex_lock (&g_atomic_lock); - *atomic = value; - g_static_mutex_unlock (&g_atomic_lock); -} - -void -(g_atomic_int_inc) (volatile gint *atomic) -{ - g_static_mutex_lock (&g_atomic_lock); - (*atomic)++; - g_static_mutex_unlock (&g_atomic_lock); -} - -gboolean -(g_atomic_int_dec_and_test) (volatile gint *atomic) -{ - gboolean is_zero; - - g_static_mutex_lock (&g_atomic_lock); - is_zero = --(*atomic) == 0; - g_static_mutex_unlock (&g_atomic_lock); - - return is_zero; -} - -gboolean -(g_atomic_int_compare_and_exchange) (volatile gint *atomic, - gint oldval, - gint newval) -{ - gboolean success; - - g_static_mutex_lock (&g_atomic_lock); - - if ((success = (*atomic == oldval))) - *atomic = newval; - - g_static_mutex_unlock (&g_atomic_lock); - - return success; -} - -gint -(g_atomic_int_add) (volatile gint *atomic, - gint val) -{ - gint oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *atomic; - *atomic = oldval + val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -guint -(g_atomic_int_and) (volatile guint *atomic, - guint val) -{ - guint oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *atomic; - *atomic = oldval & val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -guint -(g_atomic_int_or) (volatile guint *atomic, - guint val) -{ - guint oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *atomic; - *atomic = oldval | val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -guint -(g_atomic_int_xor) (volatile guint *atomic, - guint val) -{ - guint oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *atomic; - *atomic = oldval ^ val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - - -gpointer -(g_atomic_pointer_get) (volatile void *atomic) -{ - volatile gpointer *ptr = atomic; - gpointer value; - - g_static_mutex_lock (&g_atomic_lock); - value = *ptr; - g_static_mutex_unlock (&g_atomic_lock); - - return value; -} - -void -(g_atomic_pointer_set) (volatile void *atomic, - gpointer newval) -{ - volatile gpointer *ptr = atomic; - - g_static_mutex_lock (&g_atomic_lock); - *ptr = newval; - g_static_mutex_unlock (&g_atomic_lock); -} - -gboolean -(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, - gpointer oldval, - gpointer newval) -{ - volatile gpointer *ptr = atomic; - gboolean success; - - g_static_mutex_lock (&g_atomic_lock); - - if ((success = (*ptr == oldval))) - *ptr = newval; - - g_static_mutex_unlock (&g_atomic_lock); - - return success; -} - -gssize -(g_atomic_pointer_add) (volatile void *atomic, - gssize val) -{ - volatile gssize *ptr = atomic; - gssize oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *ptr; - *ptr = oldval + val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -gsize -(g_atomic_pointer_and) (volatile void *atomic, - gsize val) -{ - volatile gsize *ptr = atomic; - gsize oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *ptr; - *ptr = oldval & val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -gsize -(g_atomic_pointer_or) (volatile void *atomic, - gsize val) -{ - volatile gsize *ptr = atomic; - gsize oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *ptr; - *ptr = oldval | val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -gsize -(g_atomic_pointer_xor) (volatile void *atomic, - gsize val) -{ - volatile gsize *ptr = atomic; - gsize oldval; - - g_static_mutex_lock (&g_atomic_lock); - oldval = *ptr; - *ptr = oldval ^ val; - g_static_mutex_unlock (&g_atomic_lock); - - return oldval; -} - -#endif - -/** - * g_atomic_int_exchange_and_add: - * @atomic: a pointer to a #gint - * @val: the value to add - * - * This function existed before g_atomic_int_add() returned the prior - * value of the integer (which it now does). It is retained only for - * compatibility reasons. Don't use this function in new code. - * - * Returns: the value of @atomic before the add, signed - * Since: 2.4 - * Deprecated: 2.30: Use g_atomic_int_add() instead. - **/ -gint -g_atomic_int_exchange_and_add (volatile gint *atomic, - gint val) -{ - return (g_atomic_int_add) (atomic, val); -} diff --git a/deps/glib/gatomic.h b/deps/glib/gatomic.h deleted file mode 100644 index 3ebc8a07..00000000 --- a/deps/glib/gatomic.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright © 2011 Ryan Lortie - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Ryan Lortie <desrt@desrt.ca> - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_ATOMIC_H__ -#define __G_ATOMIC_H__ - -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -gint g_atomic_int_get (volatile gint *atomic); -void g_atomic_int_set (volatile gint *atomic, - gint newval); -void g_atomic_int_inc (volatile gint *atomic); -gboolean g_atomic_int_dec_and_test (volatile gint *atomic); -gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic, - gint oldval, - gint newval); -gint g_atomic_int_add (volatile gint *atomic, - gint val); -guint g_atomic_int_and (volatile guint *atomic, - guint val); -guint g_atomic_int_or (volatile guint *atomic, - guint val); -guint g_atomic_int_xor (volatile guint *atomic, - guint val); - -gpointer g_atomic_pointer_get (volatile void *atomic); -void g_atomic_pointer_set (volatile void *atomic, - gpointer newval); -gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic, - gpointer oldval, - gpointer newval); -gssize g_atomic_pointer_add (volatile void *atomic, - gssize val); -gsize g_atomic_pointer_and (volatile void *atomic, - gsize val); -gsize g_atomic_pointer_or (volatile void *atomic, - gsize val); -gsize g_atomic_pointer_xor (volatile void *atomic, - gsize val); - -#ifndef G_DISABLE_DEPRECATED -gint g_atomic_int_exchange_and_add (volatile gint *atomic, - gint val); -#endif - -G_END_DECLS - -#if defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) - -#define g_atomic_int_get(atomic) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ *(atomic) : 0); \ - __sync_synchronize (); \ - (gint) *(atomic); \ - })) -#define g_atomic_int_set(atomic, newval) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ (newval) : 0); \ - *(atomic) = (newval); \ - __sync_synchronize (); \ - })) -#define g_atomic_int_inc(atomic) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ *(atomic) : 0); \ - (void) __sync_fetch_and_add ((atomic), 1); \ - })) -#define g_atomic_int_dec_and_test(atomic) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ *(atomic) : 0); \ - __sync_fetch_and_sub ((atomic), 1) == 1; \ - })) -#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 0); \ - (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \ - })) -#define g_atomic_int_add(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ (val) : 0); \ - (gint) __sync_fetch_and_add ((atomic), (val)); \ - })) -#define g_atomic_int_and(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ (val) : 0); \ - (guint) __sync_fetch_and_and ((atomic), (val)); \ - })) -#define g_atomic_int_or(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ (val) : 0); \ - (guint) __sync_fetch_and_or ((atomic), (val)); \ - })) -#define g_atomic_int_xor(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ - (void) (0 ? *(atomic) ^ (val) : 0); \ - (guint) __sync_fetch_and_xor ((atomic), (val)); \ - })) - -#define g_atomic_pointer_get(atomic) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - __sync_synchronize (); \ - (gpointer) *(atomic); \ - })) -#define g_atomic_pointer_set(atomic, newval) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - *(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \ - __sync_synchronize (); \ - })) -#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \ - })) -#define g_atomic_pointer_add(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - (void) (0 ? (val) ^ (val) : 0); \ - (gssize) __sync_fetch_and_add ((atomic), (val)); \ - })) -#define g_atomic_pointer_and(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - (void) (0 ? (val) ^ (val) : 0); \ - (gsize) __sync_fetch_and_and ((atomic), (val)); \ - })) -#define g_atomic_pointer_or(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - (void) (0 ? (val) ^ (val) : 0); \ - (gsize) __sync_fetch_and_or ((atomic), (val)); \ - })) -#define g_atomic_pointer_xor(atomic, val) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - (void) (0 ? (val) ^ (val) : 0); \ - (gsize) __sync_fetch_and_xor ((atomic), (val)); \ - })) - -#else /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */ - -#define g_atomic_int_get(atomic) \ - (g_atomic_int_get ((gint *) (atomic))) -#define g_atomic_int_set(atomic, newval) \ - (g_atomic_int_set ((gint *) (atomic), (gint) (newval))) -#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ - (g_atomic_int_compare_and_exchange ((gint *) (atomic), (oldval), (newval))) -#define g_atomic_int_add(atomic, val) \ - (g_atomic_int_add ((gint *) (atomic), (val))) -#define g_atomic_int_and(atomic, val) \ - (g_atomic_int_and ((gint *) (atomic), (val))) -#define g_atomic_int_or(atomic, val) \ - (g_atomic_int_or ((gint *) (atomic), (val))) -#define g_atomic_int_xor(atomic, val) \ - (g_atomic_int_xor ((gint *) (atomic), (val))) -#define g_atomic_int_inc(atomic) \ - (g_atomic_int_inc ((gint *) (atomic))) -#define g_atomic_int_dec_and_test(atomic) \ - (g_atomic_int_dec_and_test ((gint *) (atomic))) - -#define g_atomic_pointer_get(atomic) \ - (g_atomic_pointer_get (atomic)) -#define g_atomic_pointer_set(atomic, newval) \ - (g_atomic_pointer_set ((atomic), (gpointer) (newval))) -#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ - (g_atomic_pointer_compare_and_exchange ((atomic), (gpointer) (oldval), (gpointer) (newval))) -#define g_atomic_pointer_add(atomic, val) \ - (g_atomic_pointer_add ((atomic), (gssize) (val))) -#define g_atomic_pointer_and(atomic, val) \ - (g_atomic_pointer_and ((atomic), (gsize) (val))) -#define g_atomic_pointer_or(atomic, val) \ - (g_atomic_pointer_or ((atomic), (gsize) (val))) -#define g_atomic_pointer_xor(atomic, val) \ - (g_atomic_pointer_xor ((atomic), (gsize) (val))) - -#endif /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */ - -#endif /* __G_ATOMIC_H__ */ diff --git a/deps/glib/gbacktrace.h b/deps/glib/gbacktrace.h deleted file mode 100644 index e32b86d3..00000000 --- a/deps/glib/gbacktrace.h +++ /dev/null @@ -1,59 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_BACKTRACE_H__ -#define __G_BACKTRACE_H__ - -#include <glib/gtypes.h> -#include <signal.h> - -G_BEGIN_DECLS - -/** - * G_BREAKPOINT: - * - * Inserts a breakpoint instruction into the code. - * - * On x86 and alpha systems this is implemented as a soft interrupt - * and on other architectures it raises a %SIGTRAP signal. - */ -#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__) && __GNUC__ >= 2 -# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END -#elif (defined (_MSC_VER) || defined (__DMC__)) && defined (_M_IX86) -# define G_BREAKPOINT() G_STMT_START{ __asm int 3h }G_STMT_END -#elif defined (_MSC_VER) -# define G_BREAKPOINT() G_STMT_START{ __debugbreak(); }G_STMT_END -#elif defined (__alpha__) && !defined(__osf__) && defined (__GNUC__) && __GNUC__ >= 2 -# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END -#else /* !__i386__ && !__alpha__ */ -# define G_BREAKPOINT() G_STMT_START{ raise (SIGTRAP); }G_STMT_END -#endif /* __i386__ */ - -G_END_DECLS - -#endif /* __G_BACKTRACE_H__ */ diff --git a/deps/glib/gbitlock.c b/deps/glib/gbitlock.c deleted file mode 100644 index b6488733..00000000 --- a/deps/glib/gbitlock.c +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright © 2008 Ryan Lortie - * Copyright © 2010 Codethink Limited - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Ryan Lortie <desrt@desrt.ca> - */ - -#include "gbitlock.h" - -#include <glib/gmessages.h> -#include <glib/gatomic.h> -#include <glib/gslist.h> -#include <glib/gthread.h> - -#include "gthreadprivate.h" -#include "config.h" - - -#ifdef G_BIT_LOCK_FORCE_FUTEX_EMULATION -#undef HAVE_FUTEX -#endif - -#ifndef HAVE_FUTEX -static GSList *g_futex_address_list = NULL; -static GMutex *g_futex_mutex = NULL; -#endif - -void -_g_futex_thread_init (void) { -#ifndef HAVE_FUTEX - g_futex_mutex = g_mutex_new (); -#endif -} - -#ifdef HAVE_FUTEX -/* - * We have headers for futex(2) on the build machine. This does not - * imply that every system that ever runs the resulting glib will have - * kernel support for futex, but you'd have to have a pretty old - * kernel in order for that not to be the case. - * - * If anyone actually gets bit by this, please file a bug. :) - */ -#include <linux/futex.h> -#include <sys/syscall.h> -#include <unistd.h> - -/* < private > - * g_futex_wait: - * @address: a pointer to an integer - * @value: the value that should be at @address - * - * Atomically checks that the value stored at @address is equal to - * @value and then blocks. If the value stored at @address is not - * equal to @value then this function returns immediately. - * - * To unblock, call g_futex_wake() on @address. - * - * This call may spuriously unblock (for example, in response to the - * process receiving a signal) but this is not guaranteed. Unlike the - * Linux system call of a similar name, there is no guarantee that a - * waiting process will unblock due to a g_futex_wake() call in a - * separate process. - */ -static void -g_futex_wait (const volatile gint *address, - gint value) -{ - syscall (__NR_futex, address, (gsize) FUTEX_WAIT, (gsize) value, NULL); -} - -/* < private > - * g_futex_wake: - * @address: a pointer to an integer - * - * Nominally, wakes one thread that is blocked in g_futex_wait() on - * @address (if any thread is currently waiting). - * - * As mentioned in the documention for g_futex_wait(), spurious - * wakeups may occur. As such, this call may result in more than one - * thread being woken up. - */ -static void -g_futex_wake (const volatile gint *address) -{ - syscall (__NR_futex, address, (gsize) FUTEX_WAKE, (gsize) 1, NULL); -} - -#else - -/* emulate futex(2) */ -typedef struct -{ - const volatile gint *address; - gint ref_count; - GCond *wait_queue; -} WaitAddress; - -static WaitAddress * -g_futex_find_address (const volatile gint *address) -{ - GSList *node; - - for (node = g_futex_address_list; node; node = node->next) - { - WaitAddress *waiter = node->data; - - if (waiter->address == address) - return waiter; - } - - return NULL; -} - -static void -g_futex_wait (const volatile gint *address, - gint value) -{ - g_mutex_lock (g_futex_mutex); - if G_LIKELY (g_atomic_int_get (address) == value) - { - WaitAddress *waiter; - - if ((waiter = g_futex_find_address (address)) == NULL) - { - waiter = g_slice_new (WaitAddress); - waiter->address = address; - waiter->wait_queue = g_cond_new (); - waiter->ref_count = 0; - g_futex_address_list = - g_slist_prepend (g_futex_address_list, waiter); - } - - waiter->ref_count++; - g_cond_wait (waiter->wait_queue, g_futex_mutex); - - if (!--waiter->ref_count) - { - g_futex_address_list = - g_slist_remove (g_futex_address_list, waiter); - g_cond_free (waiter->wait_queue); - g_slice_free (WaitAddress, waiter); - } - } - g_mutex_unlock (g_futex_mutex); -} - -static void -g_futex_wake (const volatile gint *address) -{ - WaitAddress *waiter; - - /* need to lock here for two reasons: - * 1) need to acquire/release lock to ensure waiter is not in - * the process of registering a wait - * 2) need to -stay- locked until the end to ensure a wake() - * in another thread doesn't cause 'waiter' to stop existing - */ - g_mutex_lock (g_futex_mutex); - if ((waiter = g_futex_find_address (address))) - g_cond_signal (waiter->wait_queue); - g_mutex_unlock (g_futex_mutex); -} -#endif - -#define CONTENTION_CLASSES 11 -static volatile gint g_bit_lock_contended[CONTENTION_CLASSES]; - -#if (defined (i386) || defined (__amd64__)) - #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) - #define USE_ASM_GOTO 1 - #endif -#endif - -/** - * g_bit_lock: - * @address: a pointer to an integer - * @lock_bit: a bit value between 0 and 31 - * - * Sets the indicated @lock_bit in @address. If the bit is already - * set, this call will block until g_bit_unlock() unsets the - * corresponding bit. - * - * Attempting to lock on two different bits within the same integer is - * not supported and will very probably cause deadlocks. - * - * The value of the bit that is set is (1u << @bit). If @bit is not - * between 0 and 31 then the result is undefined. - * - * This function accesses @address atomically. All other accesses to - * @address must be atomic in order for this function to work - * reliably. - * - * Since: 2.24 - **/ -void -g_bit_lock (volatile gint *address, - gint lock_bit) -{ -#ifdef USE_ASM_GOTO - retry: - asm volatile goto ("lock bts %1, (%0)\n" - "jc %l[contended]" - : /* no output */ - : "r" (address), "r" (lock_bit) - : "cc", "memory" - : contended); - return; - - contended: - { - guint mask = 1u << lock_bit; - guint v; - - v = g_atomic_int_get (address); - if (v & mask) - { - guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); - - g_atomic_int_add (&g_bit_lock_contended[class], +1); - g_futex_wait (address, v); - g_atomic_int_add (&g_bit_lock_contended[class], -1); - } - } - goto retry; -#else - guint mask = 1u << lock_bit; - guint v; - - retry: - v = g_atomic_int_or (address, mask); - if (v & mask) - /* already locked */ - { - guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); - - g_atomic_int_add (&g_bit_lock_contended[class], +1); - g_futex_wait (address, v); - g_atomic_int_add (&g_bit_lock_contended[class], -1); - - goto retry; - } -#endif -} - -/** - * g_bit_trylock: - * @address: a pointer to an integer - * @lock_bit: a bit value between 0 and 31 - * @returns: %TRUE if the lock was acquired - * - * Sets the indicated @lock_bit in @address, returning %TRUE if - * successful. If the bit is already set, returns %FALSE immediately. - * - * Attempting to lock on two different bits within the same integer is - * not supported. - * - * The value of the bit that is set is (1u << @bit). If @bit is not - * between 0 and 31 then the result is undefined. - * - * This function accesses @address atomically. All other accesses to - * @address must be atomic in order for this function to work - * reliably. - * - * Since: 2.24 - **/ -gboolean -g_bit_trylock (volatile gint *address, - gint lock_bit) -{ -#ifdef USE_ASM_GOTO - gboolean result; - - asm volatile ("lock bts %2, (%1)\n" - "setnc %%al\n" - "movzx %%al, %0" - : "=r" (result) - : "r" (address), "r" (lock_bit) - : "cc", "memory"); - - return result; -#else - guint mask = 1u << lock_bit; - guint v; - - v = g_atomic_int_or (address, mask); - - return ~v & mask; -#endif -} - -/** - * g_bit_unlock: - * @address: a pointer to an integer - * @lock_bit: a bit value between 0 and 31 - * - * Clears the indicated @lock_bit in @address. If another thread is - * currently blocked in g_bit_lock() on this same bit then it will be - * woken up. - * - * This function accesses @address atomically. All other accesses to - * @address must be atomic in order for this function to work - * reliably. - * - * Since: 2.24 - **/ -void -g_bit_unlock (volatile gint *address, - gint lock_bit) -{ -#ifdef USE_ASM_GOTO - asm volatile ("lock btr %1, (%0)" - : /* no output */ - : "r" (address), "r" (lock_bit) - : "cc", "memory"); -#else - guint mask = 1u << lock_bit; - - g_atomic_int_and (address, ~mask); -#endif - - { - guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); - - if (g_atomic_int_get (&g_bit_lock_contended[class])) - g_futex_wake (address); - } -} - - -/* We emulate pointer-sized futex(2) because the kernel API only - * supports integers. - * - * We assume that the 'interesting' part is always the lower order bits. - * This assumption holds because pointer bitlocks are restricted to - * using the low order bits of the pointer as the lock. - * - * On 32 bits, there is nothing to do since the pointer size is equal to - * the integer size. On little endian the lower-order bits don't move, - * so do nothing. Only on 64bit big endian do we need to do a bit of - * pointer arithmetic: the low order bits are shifted by 4 bytes. We - * have a helper function that always does the right thing here. - * - * Since we always consider the low-order bits of the integer value, a - * simple cast from (gsize) to (guint) always takes care of that. - * - * After that, pointer-sized futex becomes as simple as: - * - * g_futex_wait (g_futex_int_address (address), (guint) value); - * - * and - * - * g_futex_wake (g_futex_int_address (int_address)); - */ -static const volatile gint * -g_futex_int_address (const volatile void *address) -{ - const volatile gint *int_address = address; - -#if G_BYTE_ORDER == G_BIG_ENDIAN && GLIB_SIZEOF_VOID_P == 8 - int_address++; -#endif - - return int_address; -} - -/** - * g_pointer_bit_lock: - * @address: a pointer to a #gpointer-sized value - * @lock_bit: a bit value between 0 and 31 - * - * This is equivalent to g_bit_lock, but working on pointers (or other - * pointer-sized values). - * - * For portability reasons, you may only lock on the bottom 32 bits of - * the pointer. - * - * Since: 2.30 - **/ -void -(g_pointer_bit_lock) (volatile void *address, - gint lock_bit) -{ - g_return_if_fail (lock_bit < 32); - - { -#ifdef USE_ASM_GOTO - retry: - asm volatile goto ("lock bts %1, (%0)\n" - "jc %l[contended]" - : /* no output */ - : "r" (address), "r" ((gsize) lock_bit) - : "cc", "memory" - : contended); - return; - - contended: - { - volatile gsize *pointer_address = address; - gsize mask = 1u << lock_bit; - gsize v; - - v = (gsize) g_atomic_pointer_get (pointer_address); - if (v & mask) - { - guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); - - g_atomic_int_add (&g_bit_lock_contended[class], +1); - g_futex_wait (g_futex_int_address (address), v); - g_atomic_int_add (&g_bit_lock_contended[class], -1); - } - } - goto retry; -#else - volatile gsize *pointer_address = address; - gsize mask = 1u << lock_bit; - gsize v; - - retry: - v = g_atomic_pointer_or (pointer_address, mask); - if (v & mask) - /* already locked */ - { - guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); - - g_atomic_int_add (&g_bit_lock_contended[class], +1); - g_futex_wait (g_futex_int_address (address), (guint) v); - g_atomic_int_add (&g_bit_lock_contended[class], -1); - - goto retry; - } -#endif - } -} - -/** - * g_pointer_bit_trylock: - * @address: a pointer to a #gpointer-sized value - * @lock_bit: a bit value between 0 and 31 - * @returns: %TRUE if the lock was acquired - * - * This is equivalent to g_bit_trylock, but working on pointers (or - * other pointer-sized values). - * - * For portability reasons, you may only lock on the bottom 32 bits of - * the pointer. - * - * Since: 2.30 - **/ -gboolean -(g_pointer_bit_trylock) (volatile void *address, - gint lock_bit) -{ - g_return_val_if_fail (lock_bit < 32, FALSE); - - { -#ifdef USE_ASM_GOTO - gboolean result; - - asm volatile ("lock bts %2, (%1)\n" - "setnc %%al\n" - "movzx %%al, %0" - : "=r" (result) - : "r" (address), "r" ((gsize) lock_bit) - : "cc", "memory"); - - return result; -#else - volatile gsize *pointer_address = address; - gsize mask = 1u << lock_bit; - gsize v; - - g_return_val_if_fail (lock_bit < 32, FALSE); - - v = g_atomic_pointer_or (pointer_address, mask); - - return ~v & mask; -#endif - } -} - -/** - * g_pointer_bit_unlock: - * @address: a pointer to a #gpointer-sized value - * @lock_bit: a bit value between 0 and 31 - * - * This is equivalent to g_bit_unlock, but working on pointers (or other - * pointer-sized values). - * - * For portability reasons, you may only lock on the bottom 32 bits of - * the pointer. - * - * Since: 2.30 - **/ -void -(g_pointer_bit_unlock) (volatile void *address, - gint lock_bit) -{ - g_return_if_fail (lock_bit < 32); - - { -#ifdef USE_ASM_GOTO - asm volatile ("lock btr %1, (%0)" - : /* no output */ - : "r" (address), "r" ((gsize) lock_bit) - : "cc", "memory"); -#else - volatile gsize *pointer_address = address; - gsize mask = 1u << lock_bit; - - g_atomic_pointer_and (pointer_address, ~mask); -#endif - - { - guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); - if (g_atomic_int_get (&g_bit_lock_contended[class])) - g_futex_wake (g_futex_int_address (address)); - } - } -} diff --git a/deps/glib/gbitlock.h b/deps/glib/gbitlock.h deleted file mode 100644 index 58a7ce82..00000000 --- a/deps/glib/gbitlock.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright © 2008 Ryan Lortie - * Copyright © 2010 Codethink Limited - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Ryan Lortie <desrt@desrt.ca> - */ - -#ifndef __G_BITLOCK_H__ -#define __G_BITLOCK_H__ - -#include <glib/gtypes.h> - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -G_BEGIN_DECLS - -void g_bit_lock (volatile gint *address, - gint lock_bit); -gboolean g_bit_trylock (volatile gint *address, - gint lock_bit); -void g_bit_unlock (volatile gint *address, - gint lock_bit); - -void g_pointer_bit_lock (volatile void *address, - gint lock_bit); -gboolean g_pointer_bit_trylock (volatile void *address, - gint lock_bit); -void g_pointer_bit_unlock (volatile void *address, - gint lock_bit); - -#ifdef __GNUC__ - -#define g_pointer_bit_lock(address, lock_bit) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ - g_pointer_bit_lock ((address), (lock_bit)); \ - })) - -#define g_pointer_bit_trylock(address, lock_bit) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ - g_pointer_bit_trylock ((address), (lock_bit)); \ - })) - -#define g_pointer_bit_unlock(address, lock_bit) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ - g_pointer_bit_unlock ((address), (lock_bit)); \ - })) - -#endif - -G_END_DECLS - -#endif /* __G_BITLOCK_H_ */ diff --git a/deps/glib/gconvert.c b/deps/glib/gconvert.c deleted file mode 100644 index c269f74e..00000000 --- a/deps/glib/gconvert.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "gstrfuncs.h" -#include "gconvert.h" - -gchar* -g_convert_with_fallback (const gchar *str, - gssize len, - const gchar *to_codeset, - const gchar *from_codeset, - const gchar *fallback, - gsize *bytes_read, - gsize *bytes_written, - GError **error) -{ - return g_strdup(str); -} - -gchar* -g_locale_to_utf8 (const gchar *opsysstring, - gssize len, - gsize *bytes_read, - gsize *bytes_written, - GError **error) -{ - return g_strdup(opsysstring); -} - -gchar * -g_filename_display_name (const gchar *filename) -{ - return g_strdup(filename); -} diff --git a/deps/glib/gconvert.h b/deps/glib/gconvert.h deleted file mode 100644 index d1a5e518..00000000 --- a/deps/glib/gconvert.h +++ /dev/null @@ -1,92 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * This file has been hacked up to contain a few stubs to get a - * standalone glib that does not care about string charset conversions - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_CONVERT_H__ -#define __G_CONVERT_H__ - -#include <glib/gerror.h> - -G_BEGIN_DECLS - -/** - * GConvertError: - * @G_CONVERT_ERROR_NO_CONVERSION: Conversion between the requested character - * sets is not supported. - * @G_CONVERT_ERROR_ILLEGAL_SEQUENCE: Invalid byte sequence in conversion input. - * @G_CONVERT_ERROR_FAILED: Conversion failed for some reason. - * @G_CONVERT_ERROR_PARTIAL_INPUT: Partial character sequence at end of input. - * @G_CONVERT_ERROR_BAD_URI: URI is invalid. - * @G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: Pathname is not an absolute path. - * - * Error codes returned by character set conversion routines. - */ -typedef enum -{ - G_CONVERT_ERROR_NO_CONVERSION, - G_CONVERT_ERROR_ILLEGAL_SEQUENCE, - G_CONVERT_ERROR_FAILED, - G_CONVERT_ERROR_PARTIAL_INPUT, - G_CONVERT_ERROR_BAD_URI, - G_CONVERT_ERROR_NOT_ABSOLUTE_PATH -} GConvertError; - -/** - * G_CONVERT_ERROR: - * - * Error domain for character set conversions. Errors in this domain will - * be from the #GConvertError enumeration. See #GError for information on - * error domains. - */ -#define G_CONVERT_ERROR g_convert_error_quark() -GQuark g_convert_error_quark (void); - -gchar* g_convert_with_fallback (const gchar *str, - gssize len, - const gchar *to_codeset, - const gchar *from_codeset, - const gchar *fallback, - gsize *bytes_read, - gsize *bytes_written, - GError **error) G_GNUC_MALLOC; - -gchar* g_locale_to_utf8 (const gchar *opsysstring, - gssize len, - gsize *bytes_read, - gsize *bytes_written, - GError **error) G_GNUC_MALLOC; - -gchar *g_filename_display_name (const gchar *filename) G_GNUC_MALLOC; - -G_END_DECLS - -#endif /* __G_CONVERT_H__ */ diff --git a/deps/glib/gdataset.c b/deps/glib/gdataset.c deleted file mode 100644 index fc4cf1ac..00000000 --- a/deps/glib/gdataset.c +++ /dev/null @@ -1,1360 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * gdataset.c: Generic dataset mechanism, similar to GtkObject data. - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe ; except for g_data*_foreach() - */ - -#include "config.h" - -#include <string.h> - -#include "gdataset.h" -#include "gbitlock.h" - -#include "gdatasetprivate.h" -#include "ghash.h" -#include "gquark.h" -#include "gstrfuncs.h" -#include "gtestutils.h" -#include "gthread.h" -#include "glib_trace.h" - -/** - * SECTION:datasets - * @title: Datasets - * @short_description: associate groups of data elements with - * particular memory locations - * - * Datasets associate groups of data elements with particular memory - * locations. These are useful if you need to associate data with a - * structure returned from an external library. Since you cannot modify - * the structure, you use its location in memory as the key into a - * dataset, where you can associate any number of data elements with it. - * - * There are two forms of most of the dataset functions. The first form - * uses strings to identify the data elements associated with a - * location. The second form uses #GQuark identifiers, which are - * created with a call to g_quark_from_string() or - * g_quark_from_static_string(). The second form is quicker, since it - * does not require looking up the string in the hash table of #GQuark - * identifiers. - * - * There is no function to create a dataset. It is automatically - * created as soon as you add elements to it. - * - * To add data elements to a dataset use g_dataset_id_set_data(), - * g_dataset_id_set_data_full(), g_dataset_set_data() and - * g_dataset_set_data_full(). - * - * To get data elements from a dataset use g_dataset_id_get_data() and - * g_dataset_get_data(). - * - * To iterate over all data elements in a dataset use - * g_dataset_foreach() (not thread-safe). - * - * To remove data elements from a dataset use - * g_dataset_id_remove_data() and g_dataset_remove_data(). - * - * To destroy a dataset, use g_dataset_destroy(). - **/ - -/** - * SECTION:datalist - * @title: Keyed Data Lists - * @short_description: lists of data elements which are accessible by a - * string or GQuark identifier - * - * Keyed data lists provide lists of arbitrary data elements which can - * be accessed either with a string or with a #GQuark corresponding to - * the string. - * - * The #GQuark methods are quicker, since the strings have to be - * converted to #GQuarks anyway. - * - * Data lists are used for associating arbitrary data with #GObjects, - * using g_object_set_data() and related functions. - * - * To create a datalist, use g_datalist_init(). - * - * To add data elements to a datalist use g_datalist_id_set_data(), - * g_datalist_id_set_data_full(), g_datalist_set_data() and - * g_datalist_set_data_full(). - * - * To get data elements from a datalist use g_datalist_id_get_data() - * and g_datalist_get_data(). - * - * To iterate over all data elements in a datalist use - * g_datalist_foreach() (not thread-safe). - * - * To remove data elements from a datalist use - * g_datalist_id_remove_data() and g_datalist_remove_data(). - * - * To remove all data elements from a datalist, use g_datalist_clear(). - **/ - -/** - * GData: - * - * The #GData struct is an opaque data structure to represent a <link - * linkend="glib-Keyed-Data-Lists">Keyed Data List</link>. It should - * only be accessed via the following functions. - **/ - -/** - * GDestroyNotify: - * @data: the data element. - * - * Specifies the type of function which is called when a data element - * is destroyed. It is passed the pointer to the data element and - * should free any memory and resources allocated for it. - **/ - -/* --- defines --- */ -#define G_QUARK_BLOCK_SIZE (2048) - -#define G_DATALIST_FLAGS_MASK_INTERNAL 0x7 - -/* datalist pointer accesses have to be carried out atomically */ -#define G_DATALIST_GET_POINTER(datalist) \ - ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL)) - -#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \ - gpointer _oldv, _newv; \ - do { \ - _oldv = g_atomic_pointer_get (datalist); \ - _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (gsize) pointer); \ - } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \ -} G_STMT_END - -/* --- structures --- */ -typedef struct { - GQuark key; - gpointer data; - GDestroyNotify destroy; -} GDataElt; - -typedef struct _GDataset GDataset; -struct _GData -{ - guint32 len; /* Number of elements */ - guint32 alloc; /* Number of allocated elements */ - GDataElt data[1]; /* Flexible array */ -}; - -struct _GDataset -{ - gconstpointer location; - GData *datalist; -}; - - -/* --- prototypes --- */ -static inline GDataset* g_dataset_lookup (gconstpointer dataset_location); -static inline void g_datalist_clear_i (GData **datalist); -static void g_dataset_destroy_internal (GDataset *dataset); -static inline gpointer g_data_set_internal (GData **datalist, - GQuark key_id, - gpointer data, - GDestroyNotify destroy_func, - GDataset *dataset); -static void g_data_initialize (void); -static inline GQuark g_quark_new (gchar *string); - - -/* Locking model: - * Each standalone GDataList is protected by a bitlock in the datalist pointer, - * which protects that modification of the non-flags part of the datalist pointer - * and the contents of the datalist. - * - * For GDataSet we have a global lock g_dataset_global that protects - * the global dataset hash and cache, and additionally it protects the - * datalist such that we can avoid to use the bit lock in a few places - * where it is easy. - */ - -/* --- variables --- */ -G_LOCK_DEFINE_STATIC (g_dataset_global); -static GHashTable *g_dataset_location_ht = NULL; -static GDataset *g_dataset_cached = NULL; /* should this be - threadspecific? */ -G_LOCK_DEFINE_STATIC (g_quark_global); -static GHashTable *g_quark_ht = NULL; -static gchar **g_quarks = NULL; -static int g_quark_seq_id = 0; - -/* --- functions --- */ - -#define DATALIST_LOCK_BIT 2 - -static void -g_datalist_lock (GData **datalist) -{ - g_pointer_bit_lock ((void **)datalist, DATALIST_LOCK_BIT); -} - -static void -g_datalist_unlock (GData **datalist) -{ - g_pointer_bit_unlock ((void **)datalist, DATALIST_LOCK_BIT); -} - -/* Called with the datalist lock held, or the dataset global - * lock for dataset lists - */ -static void -g_datalist_clear_i (GData **datalist) -{ - GData *data; - gint i; - - data = G_DATALIST_GET_POINTER (datalist); - G_DATALIST_SET_POINTER (datalist, NULL); - - if (data) - { - G_UNLOCK (g_dataset_global); - for (i = 0; i < data->len; i++) - { - if (data->data[i].data && data->data[i].destroy) - data->data[i].destroy (data->data[i].data); - } - G_LOCK (g_dataset_global); - - g_free (data); - } - -} - -/** - * g_datalist_clear: - * @datalist: a datalist. - * - * Frees all the data elements of the datalist. - * The data elements' destroy functions are called - * if they have been set. - **/ -void -g_datalist_clear (GData **datalist) -{ - GData *data; - gint i; - - g_return_if_fail (datalist != NULL); - - g_datalist_lock (datalist); - - data = G_DATALIST_GET_POINTER (datalist); - G_DATALIST_SET_POINTER (datalist, NULL); - - g_datalist_unlock (datalist); - - if (data) - { - for (i = 0; i < data->len; i++) - { - if (data->data[i].data && data->data[i].destroy) - data->data[i].destroy (data->data[i].data); - } - - g_free (data); - } -} - -/* HOLDS: g_dataset_global_lock */ -static inline GDataset* -g_dataset_lookup (gconstpointer dataset_location) -{ - register GDataset *dataset; - - if (g_dataset_cached && g_dataset_cached->location == dataset_location) - return g_dataset_cached; - - dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location); - if (dataset) - g_dataset_cached = dataset; - - return dataset; -} - -/* HOLDS: g_dataset_global_lock */ -static void -g_dataset_destroy_internal (GDataset *dataset) -{ - register gconstpointer dataset_location; - - dataset_location = dataset->location; - while (dataset) - { - if (G_DATALIST_GET_POINTER(&dataset->datalist) == NULL) - { - if (dataset == g_dataset_cached) - g_dataset_cached = NULL; - g_hash_table_remove (g_dataset_location_ht, dataset_location); - g_slice_free (GDataset, dataset); - break; - } - - g_datalist_clear_i (&dataset->datalist); - dataset = g_dataset_lookup (dataset_location); - } -} - -/** - * g_dataset_destroy: - * @dataset_location: the location identifying the dataset. - * - * Destroys the dataset, freeing all memory allocated, and calling any - * destroy functions set for data elements. - */ -void -g_dataset_destroy (gconstpointer dataset_location) -{ - g_return_if_fail (dataset_location != NULL); - - G_LOCK (g_dataset_global); - if (g_dataset_location_ht) - { - register GDataset *dataset; - - dataset = g_dataset_lookup (dataset_location); - if (dataset) - g_dataset_destroy_internal (dataset); - } - G_UNLOCK (g_dataset_global); -} - -/* HOLDS: g_dataset_global_lock if dataset != null */ -static inline gpointer -g_data_set_internal (GData **datalist, - GQuark key_id, - gpointer new_data, - GDestroyNotify new_destroy_func, - GDataset *dataset) -{ - GData *d, *old_d; - GDataElt old, *data, *data_last, *data_end; - - g_datalist_lock (datalist); - - d = G_DATALIST_GET_POINTER (datalist); - - if (new_data == NULL) /* remove */ - { - if (d) - { - data = d->data; - data_last = data + d->len - 1; - while (data <= data_last) - { - if (data->key == key_id) - { - old = *data; - if (data != data_last) - *data = *data_last; - d->len--; - - /* We don't bother to shrink, but if all data are now gone - * we at least free the memory - */ - if (d->len == 0) - { - G_DATALIST_SET_POINTER (datalist, NULL); - g_free (d); - /* datalist may be situated in dataset, so must not be - * unlocked after we free it - */ - g_datalist_unlock (datalist); - - /* the dataset destruction *must* be done - * prior to invocation of the data destroy function - */ - if (dataset) - g_dataset_destroy_internal (dataset); - } - else - { - g_datalist_unlock (datalist); - } - - /* We found and removed an old value - * the GData struct *must* already be unlinked - * when invoking the destroy function. - * we use (new_data==NULL && new_destroy_func!=NULL) as - * a special hint combination to "steal" - * data without destroy notification - */ - if (old.destroy && !new_destroy_func) - { - if (dataset) - G_UNLOCK (g_dataset_global); - old.destroy (old.data); - if (dataset) - G_LOCK (g_dataset_global); - old.data = NULL; - } - - return old.data; - } - data++; - } - } - } - else - { - old.data = NULL; - if (d) - { - data = d->data; - data_end = data + d->len; - while (data < data_end) - { - if (data->key == key_id) - { - if (!data->destroy) - { - data->data = new_data; - data->destroy = new_destroy_func; - g_datalist_unlock (datalist); - } - else - { - old = *data; - data->data = new_data; - data->destroy = new_destroy_func; - - g_datalist_unlock (datalist); - - /* We found and replaced an old value - * the GData struct *must* already be unlinked - * when invoking the destroy function. - */ - if (dataset) - G_UNLOCK (g_dataset_global); - old.destroy (old.data); - if (dataset) - G_LOCK (g_dataset_global); - } - return NULL; - } - data++; - } - } - - /* The key was not found, insert it */ - old_d = d; - if (d == NULL) - { - d = g_malloc (sizeof (GData)); - d->len = 0; - d->alloc = 1; - } - else if (d->len == d->alloc) - { - d->alloc = d->alloc * 2; - d = g_realloc (d, sizeof (GData) + (d->alloc - 1) * sizeof (GDataElt)); - } - if (old_d != d) - G_DATALIST_SET_POINTER (datalist, d); - - d->data[d->len].key = key_id; - d->data[d->len].data = new_data; - d->data[d->len].destroy = new_destroy_func; - d->len++; - } - - g_datalist_unlock (datalist); - - return NULL; - -} - -/** - * g_dataset_id_set_data_full: - * @dataset_location: the location identifying the dataset. - * @key_id: the #GQuark id to identify the data element. - * @data: the data element. - * @destroy_func: the function to call when the data element is - * removed. This function will be called with the data - * element and can be used to free any memory allocated - * for it. - * - * Sets the data element associated with the given #GQuark id, and also - * the function to call when the data element is destroyed. Any - * previous data with the same key is removed, and its destroy function - * is called. - **/ -/** - * g_dataset_set_data_full: - * @l: the location identifying the dataset. - * @k: the string to identify the data element. - * @d: the data element. - * @f: the function to call when the data element is removed. This - * function will be called with the data element and can be used to - * free any memory allocated for it. - * - * Sets the data corresponding to the given string identifier, and the - * function to call when the data element is destroyed. - **/ -/** - * g_dataset_id_set_data: - * @l: the location identifying the dataset. - * @k: the #GQuark id to identify the data element. - * @d: the data element. - * - * Sets the data element associated with the given #GQuark id. Any - * previous data with the same key is removed, and its destroy function - * is called. - **/ -/** - * g_dataset_set_data: - * @l: the location identifying the dataset. - * @k: the string to identify the data element. - * @d: the data element. - * - * Sets the data corresponding to the given string identifier. - **/ -/** - * g_dataset_id_remove_data: - * @l: the location identifying the dataset. - * @k: the #GQuark id identifying the data element. - * - * Removes a data element from a dataset. The data element's destroy - * function is called if it has been set. - **/ -/** - * g_dataset_remove_data: - * @l: the location identifying the dataset. - * @k: the string identifying the data element. - * - * Removes a data element corresponding to a string. Its destroy - * function is called if it has been set. - **/ -void -g_dataset_id_set_data_full (gconstpointer dataset_location, - GQuark key_id, - gpointer data, - GDestroyNotify destroy_func) -{ - register GDataset *dataset; - - g_return_if_fail (dataset_location != NULL); - if (!data) - g_return_if_fail (destroy_func == NULL); - if (!key_id) - { - if (data) - g_return_if_fail (key_id > 0); - else - return; - } - - G_LOCK (g_dataset_global); - if (!g_dataset_location_ht) - g_data_initialize (); - - dataset = g_dataset_lookup (dataset_location); - if (!dataset) - { - dataset = g_slice_new (GDataset); - dataset->location = dataset_location; - g_datalist_init (&dataset->datalist); - g_hash_table_insert (g_dataset_location_ht, - (gpointer) dataset->location, - dataset); - } - - g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset); - G_UNLOCK (g_dataset_global); -} - -/** - * g_datalist_id_set_data_full: - * @datalist: a datalist. - * @key_id: the #GQuark to identify the data element. - * @data: the data element or %NULL to remove any previous element - * corresponding to @key_id. - * @destroy_func: the function to call when the data element is - * removed. This function will be called with the data - * element and can be used to free any memory allocated - * for it. If @data is %NULL, then @destroy_func must - * also be %NULL. - * - * Sets the data corresponding to the given #GQuark id, and the - * function to be called when the element is removed from the datalist. - * Any previous data with the same key is removed, and its destroy - * function is called. - **/ -/** - * g_datalist_set_data_full: - * @dl: a datalist. - * @k: the string to identify the data element. - * @d: the data element, or %NULL to remove any previous element - * corresponding to @k. - * @f: the function to call when the data element is removed. This - * function will be called with the data element and can be used to - * free any memory allocated for it. If @d is %NULL, then @f must - * also be %NULL. - * - * Sets the data element corresponding to the given string identifier, - * and the function to be called when the data element is removed. - **/ -/** - * g_datalist_id_set_data: - * @dl: a datalist. - * @q: the #GQuark to identify the data element. - * @d: the data element, or %NULL to remove any previous element - * corresponding to @q. - * - * Sets the data corresponding to the given #GQuark id. Any previous - * data with the same key is removed, and its destroy function is - * called. - **/ -/** - * g_datalist_set_data: - * @dl: a datalist. - * @k: the string to identify the data element. - * @d: the data element, or %NULL to remove any previous element - * corresponding to @k. - * - * Sets the data element corresponding to the given string identifier. - **/ -/** - * g_datalist_id_remove_data: - * @dl: a datalist. - * @q: the #GQuark identifying the data element. - * - * Removes an element, using its #GQuark identifier. - **/ -/** - * g_datalist_remove_data: - * @dl: a datalist. - * @k: the string identifying the data element. - * - * Removes an element using its string identifier. The data element's - * destroy function is called if it has been set. - **/ -void -g_datalist_id_set_data_full (GData **datalist, - GQuark key_id, - gpointer data, - GDestroyNotify destroy_func) -{ - g_return_if_fail (datalist != NULL); - if (!data) - g_return_if_fail (destroy_func == NULL); - if (!key_id) - { - if (data) - g_return_if_fail (key_id > 0); - else - return; - } - - g_data_set_internal (datalist, key_id, data, destroy_func, NULL); -} - -/** - * g_dataset_id_remove_no_notify: - * @dataset_location: the location identifying the dataset. - * @key_id: the #GQuark ID identifying the data element. - * @Returns: the data previously stored at @key_id, or %NULL if none. - * - * Removes an element, without calling its destroy notification - * function. - **/ -/** - * g_dataset_remove_no_notify: - * @l: the location identifying the dataset. - * @k: the string identifying the data element. - * - * Removes an element, without calling its destroy notifier. - **/ -gpointer -g_dataset_id_remove_no_notify (gconstpointer dataset_location, - GQuark key_id) -{ - gpointer ret_data = NULL; - - g_return_val_if_fail (dataset_location != NULL, NULL); - - G_LOCK (g_dataset_global); - if (key_id && g_dataset_location_ht) - { - GDataset *dataset; - - dataset = g_dataset_lookup (dataset_location); - if (dataset) - ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset); - } - G_UNLOCK (g_dataset_global); - - return ret_data; -} - -/** - * g_datalist_id_remove_no_notify: - * @datalist: a datalist. - * @key_id: the #GQuark identifying a data element. - * @Returns: the data previously stored at @key_id, or %NULL if none. - * - * Removes an element, without calling its destroy notification - * function. - **/ -/** - * g_datalist_remove_no_notify: - * @dl: a datalist. - * @k: the string identifying the data element. - * - * Removes an element, without calling its destroy notifier. - **/ -gpointer -g_datalist_id_remove_no_notify (GData **datalist, - GQuark key_id) -{ - gpointer ret_data = NULL; - - g_return_val_if_fail (datalist != NULL, NULL); - - if (key_id) - ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); - - return ret_data; -} - -/** - * g_dataset_id_get_data: - * @dataset_location: the location identifying the dataset. - * @key_id: the #GQuark id to identify the data element. - * @Returns: the data element corresponding to the #GQuark, or %NULL if - * it is not found. - * - * Gets the data element corresponding to a #GQuark. - **/ -/** - * g_dataset_get_data: - * @l: the location identifying the dataset. - * @k: the string identifying the data element. - * @Returns: the data element corresponding to the string, or %NULL if - * it is not found. - * - * Gets the data element corresponding to a string. - **/ -gpointer -g_dataset_id_get_data (gconstpointer dataset_location, - GQuark key_id) -{ - gpointer retval = NULL; - - g_return_val_if_fail (dataset_location != NULL, NULL); - - G_LOCK (g_dataset_global); - if (key_id && g_dataset_location_ht) - { - GDataset *dataset; - - dataset = g_dataset_lookup (dataset_location); - if (dataset) - retval = g_datalist_id_get_data (&dataset->datalist, key_id); - } - G_UNLOCK (g_dataset_global); - - return retval; -} - -/** - * g_datalist_id_get_data: - * @datalist: a datalist. - * @key_id: the #GQuark identifying a data element. - * @Returns: the data element, or %NULL if it is not found. - * - * Retrieves the data element corresponding to @key_id. - **/ -gpointer -g_datalist_id_get_data (GData **datalist, - GQuark key_id) -{ - gpointer res = NULL; - - g_return_val_if_fail (datalist != NULL, NULL); - if (key_id) - { - GData *d; - GDataElt *data, *data_end; - - g_datalist_lock (datalist); - - d = G_DATALIST_GET_POINTER (datalist); - if (d) - { - data = d->data; - data_end = data + d->len; - while (data < data_end) - { - if (data->key == key_id) - { - res = data->data; - break; - } - data++; - } - } - - g_datalist_unlock (datalist); - } - - return res; -} - -/** - * g_datalist_get_data: - * @datalist: a datalist. - * @key: the string identifying a data element. - * @Returns: the data element, or %NULL if it is not found. - * - * Gets a data element, using its string identifer. This is slower than - * g_datalist_id_get_data() because it compares strings. - **/ -gpointer -g_datalist_get_data (GData **datalist, - const gchar *key) -{ - gpointer res = NULL; - GData *d; - GDataElt *data, *data_end; - - g_return_val_if_fail (datalist != NULL, NULL); - - g_datalist_lock (datalist); - - d = G_DATALIST_GET_POINTER (datalist); - if (d) - { - data = d->data; - data_end = data + d->len; - while (data < data_end) - { - if (strcmp (g_quark_to_string (data->key), key) == 0) - { - res = data->data; - break; - } - data++; - } - } - - g_datalist_unlock (datalist); - - return res; -} - -/** - * GDataForeachFunc: - * @key_id: the #GQuark id to identifying the data element. - * @data: the data element. - * @user_data: user data passed to g_dataset_foreach(). - * - * Specifies the type of function passed to g_dataset_foreach(). It is - * called with each #GQuark id and associated data element, together - * with the @user_data parameter supplied to g_dataset_foreach(). - **/ - -/** - * g_dataset_foreach: - * @dataset_location: the location identifying the dataset. - * @func: the function to call for each data element. - * @user_data: user data to pass to the function. - * - * Calls the given function for each data element which is associated - * with the given location. Note that this function is NOT thread-safe. - * So unless @datalist can be protected from any modifications during - * invocation of this function, it should not be called. - **/ -void -g_dataset_foreach (gconstpointer dataset_location, - GDataForeachFunc func, - gpointer user_data) -{ - register GDataset *dataset; - - g_return_if_fail (dataset_location != NULL); - g_return_if_fail (func != NULL); - - G_LOCK (g_dataset_global); - if (g_dataset_location_ht) - { - dataset = g_dataset_lookup (dataset_location); - G_UNLOCK (g_dataset_global); - if (dataset) - g_datalist_foreach (&dataset->datalist, func, user_data); - } - else - { - G_UNLOCK (g_dataset_global); - } -} - -/** - * g_datalist_foreach: - * @datalist: a datalist. - * @func: the function to call for each data element. - * @user_data: user data to pass to the function. - * - * Calls the given function for each data element of the datalist. The - * function is called with each data element's #GQuark id and data, - * together with the given @user_data parameter. Note that this - * function is NOT thread-safe. So unless @datalist can be protected - * from any modifications during invocation of this function, it should - * not be called. - **/ -void -g_datalist_foreach (GData **datalist, - GDataForeachFunc func, - gpointer user_data) -{ - GData *d; - int i, j, len; - GQuark *keys; - - g_return_if_fail (datalist != NULL); - g_return_if_fail (func != NULL); - - d = G_DATALIST_GET_POINTER (datalist); - if (d == NULL) - return; - - /* We make a copy of the keys so that we can handle it changing - in the callback */ - len = d->len; - keys = g_new (GQuark, len); - for (i = 0; i < len; i++) - keys[i] = d->data[i].key; - - for (i = 0; i < len; i++) - { - /* A previous callback might have removed a later item, so always check that - it still exists before calling */ - d = G_DATALIST_GET_POINTER (datalist); - - if (d == NULL) - break; - for (j = 0; j < d->len; j++) - { - if (d->data[j].key == keys[i]) { - func (d->data[i].key, d->data[i].data, user_data); - break; - } - } - } - g_free (keys); -} - -/** - * g_datalist_init: - * @datalist: a pointer to a pointer to a datalist. - * - * Resets the datalist to %NULL. It does not free any memory or call - * any destroy functions. - **/ -void -g_datalist_init (GData **datalist) -{ - g_return_if_fail (datalist != NULL); - - g_atomic_pointer_set (datalist, NULL); -} - -/** - * g_datalist_set_flags: - * @datalist: pointer to the location that holds a list - * @flags: the flags to turn on. The values of the flags are - * restricted by %G_DATALIST_FLAGS_MASK (currently - * 3; giving two possible boolean flags). - * A value for @flags that doesn't fit within the mask is - * an error. - * - * Turns on flag values for a data list. This function is used - * to keep a small number of boolean flags in an object with - * a data list without using any additional space. It is - * not generally useful except in circumstances where space - * is very tight. (It is used in the base #GObject type, for - * example.) - * - * Since: 2.8 - **/ -void -g_datalist_set_flags (GData **datalist, - guint flags) -{ - g_return_if_fail (datalist != NULL); - g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); - - g_atomic_pointer_or (datalist, (gsize)flags); -} - -/** - * g_datalist_unset_flags: - * @datalist: pointer to the location that holds a list - * @flags: the flags to turn off. The values of the flags are - * restricted by %G_DATALIST_FLAGS_MASK (currently - * 3: giving two possible boolean flags). - * A value for @flags that doesn't fit within the mask is - * an error. - * - * Turns off flag values for a data list. See g_datalist_unset_flags() - * - * Since: 2.8 - **/ -void -g_datalist_unset_flags (GData **datalist, - guint flags) -{ - g_return_if_fail (datalist != NULL); - g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); - - g_atomic_pointer_and (datalist, ~(gsize)flags); -} - -/** - * g_datalist_get_flags: - * @datalist: pointer to the location that holds a list - * - * Gets flags values packed in together with the datalist. - * See g_datalist_set_flags(). - * - * Return value: the flags of the datalist - * - * Since: 2.8 - **/ -guint -g_datalist_get_flags (GData **datalist) -{ - g_return_val_if_fail (datalist != NULL, 0); - - return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */ -} - -/* HOLDS: g_dataset_global_lock */ -static void -g_data_initialize (void) -{ - g_return_if_fail (g_dataset_location_ht == NULL); - - g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL); - g_dataset_cached = NULL; -} - -/** - * SECTION:quarks - * @title: Quarks - * @short_description: a 2-way association between a string and a - * unique integer identifier - * - * Quarks are associations between strings and integer identifiers. - * Given either the string or the #GQuark identifier it is possible to - * retrieve the other. - * - * Quarks are used for both <link - * linkend="glib-Datasets">Datasets</link> and <link - * linkend="glib-Keyed-Data-Lists">Keyed Data Lists</link>. - * - * To create a new quark from a string, use g_quark_from_string() or - * g_quark_from_static_string(). - * - * To find the string corresponding to a given #GQuark, use - * g_quark_to_string(). - * - * To find the #GQuark corresponding to a given string, use - * g_quark_try_string(). - * - * Another use for the string pool maintained for the quark functions - * is string interning, using g_intern_string() or - * g_intern_static_string(). An interned string is a canonical - * representation for a string. One important advantage of interned - * strings is that they can be compared for equality by a simple - * pointer comparison, rather than using strcmp(). - **/ - -/** - * GQuark: - * - * A GQuark is a non-zero integer which uniquely identifies a - * particular string. A GQuark value of zero is associated to %NULL. - **/ - -/** - * g_quark_try_string: - * @string: (allow-none): a string. - * @Returns: the #GQuark associated with the string, or 0 if @string is - * %NULL or there is no #GQuark associated with it. - * - * Gets the #GQuark associated with the given string, or 0 if string is - * %NULL or it has no associated #GQuark. - * - * If you want the GQuark to be created if it doesn't already exist, - * use g_quark_from_string() or g_quark_from_static_string(). - **/ -GQuark -g_quark_try_string (const gchar *string) -{ - GQuark quark = 0; - - if (string == NULL) - return 0; - - G_LOCK (g_quark_global); - if (g_quark_ht) - quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); - G_UNLOCK (g_quark_global); - - return quark; -} - -#define QUARK_STRING_BLOCK_SIZE (4096 - sizeof (gsize)) -static char *quark_block = NULL; -static int quark_block_offset = 0; - -/* HOLDS: g_quark_global_lock */ -static char * -quark_strdup(const gchar *string) -{ - gchar *copy; - gsize len; - - len = strlen (string) + 1; - - /* For strings longer than half the block size, fall back - to strdup so that we fill our blocks at least 50%. */ - if (len > QUARK_STRING_BLOCK_SIZE / 2) - return g_strdup (string); - - if (quark_block == NULL || - QUARK_STRING_BLOCK_SIZE - quark_block_offset < len) - { - quark_block = g_malloc (QUARK_STRING_BLOCK_SIZE); - quark_block_offset = 0; - } - - copy = quark_block + quark_block_offset; - memcpy (copy, string, len); - quark_block_offset += len; - - return copy; -} - -/* HOLDS: g_quark_global_lock */ -static inline GQuark -g_quark_from_string_internal (const gchar *string, - gboolean duplicate) -{ - GQuark quark = 0; - - if (g_quark_ht) - quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); - - if (!quark) - { - quark = g_quark_new (duplicate ? quark_strdup (string) : (gchar *)string); - TRACE(GLIB_QUARK_NEW(string, quark)); - } - - return quark; -} - -/** - * g_quark_from_string: - * @string: (allow-none): a string. - * @Returns: the #GQuark identifying the string, or 0 if @string is - * %NULL. - * - * Gets the #GQuark identifying the given string. If the string does - * not currently have an associated #GQuark, a new #GQuark is created, - * using a copy of the string. - **/ -GQuark -g_quark_from_string (const gchar *string) -{ - GQuark quark; - - if (!string) - return 0; - - G_LOCK (g_quark_global); - quark = g_quark_from_string_internal (string, TRUE); - G_UNLOCK (g_quark_global); - - return quark; -} - -/** - * g_quark_from_static_string: - * @string: (allow-none): a string. - * @Returns: the #GQuark identifying the string, or 0 if @string is - * %NULL. - * - * Gets the #GQuark identifying the given (static) string. If the - * string does not currently have an associated #GQuark, a new #GQuark - * is created, linked to the given string. - * - * Note that this function is identical to g_quark_from_string() except - * that if a new #GQuark is created the string itself is used rather - * than a copy. This saves memory, but can only be used if the string - * will <emphasis>always</emphasis> exist. It can be used with - * statically allocated strings in the main program, but not with - * statically allocated memory in dynamically loaded modules, if you - * expect to ever unload the module again (e.g. do not use this - * function in GTK+ theme engines). - **/ -GQuark -g_quark_from_static_string (const gchar *string) -{ - GQuark quark; - - if (!string) - return 0; - - G_LOCK (g_quark_global); - quark = g_quark_from_string_internal (string, FALSE); - G_UNLOCK (g_quark_global); - - return quark; -} - -/** - * g_quark_to_string: - * @quark: a #GQuark. - * @Returns: the string associated with the #GQuark. - * - * Gets the string associated with the given #GQuark. - **/ -const gchar * -g_quark_to_string (GQuark quark) -{ - gchar* result = NULL; - gchar **quarks; - gint quark_seq_id; - - quark_seq_id = g_atomic_int_get (&g_quark_seq_id); - quarks = g_atomic_pointer_get (&g_quarks); - - if (quark < quark_seq_id) - result = quarks[quark]; - - return result; -} - -/* HOLDS: g_quark_global_lock */ -static inline GQuark -g_quark_new (gchar *string) -{ - GQuark quark; - gchar **g_quarks_new; - - if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0) - { - g_quarks_new = g_new (gchar*, g_quark_seq_id + G_QUARK_BLOCK_SIZE); - if (g_quark_seq_id != 0) - memcpy (g_quarks_new, g_quarks, sizeof (char *) * g_quark_seq_id); - memset (g_quarks_new + g_quark_seq_id, 0, sizeof (char *) * G_QUARK_BLOCK_SIZE); - /* This leaks the old quarks array. Its unfortunate, but it allows - us to do lockless lookup of the arrays, and there shouldn't be that - many quarks in an app */ - g_atomic_pointer_set (&g_quarks, g_quarks_new); - } - if (!g_quark_ht) - { - g_assert (g_quark_seq_id == 0); - g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); - g_quarks[g_quark_seq_id] = NULL; - g_atomic_int_inc (&g_quark_seq_id); - } - - quark = g_quark_seq_id; - g_atomic_pointer_set (&g_quarks[quark], string); - g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark)); - g_atomic_int_inc (&g_quark_seq_id); - - return quark; -} - -/** - * g_intern_string: - * @string: (allow-none): a string - * - * Returns a canonical representation for @string. Interned strings can - * be compared for equality by comparing the pointers, instead of using strcmp(). - * - * Returns: a canonical representation for the string - * - * Since: 2.10 - */ -const gchar * -g_intern_string (const gchar *string) -{ - const gchar *result; - GQuark quark; - - if (!string) - return NULL; - - G_LOCK (g_quark_global); - quark = g_quark_from_string_internal (string, TRUE); - result = g_quarks[quark]; - G_UNLOCK (g_quark_global); - - return result; -} - -/** - * g_intern_static_string: - * @string: (allow-none): a static string - * - * Returns a canonical representation for @string. Interned strings can - * be compared for equality by comparing the pointers, instead of using strcmp(). - * g_intern_static_string() does not copy the string, therefore @string must - * not be freed or modified. - * - * Returns: a canonical representation for the string - * - * Since: 2.10 - */ -const gchar * -g_intern_static_string (const gchar *string) -{ - GQuark quark; - const gchar *result; - - if (!string) - return NULL; - - G_LOCK (g_quark_global); - quark = g_quark_from_string_internal (string, FALSE); - result = g_quarks[quark]; - G_UNLOCK (g_quark_global); - - return result; -} diff --git a/deps/glib/gdataset.h b/deps/glib/gdataset.h deleted file mode 100644 index 7c97c963..00000000 --- a/deps/glib/gdataset.h +++ /dev/null @@ -1,120 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_DATASET_H__ -#define __G_DATASET_H__ - -#include <glib/gquark.h> - -G_BEGIN_DECLS - -typedef struct _GData GData; - -typedef void (*GDataForeachFunc) (GQuark key_id, - gpointer data, - gpointer user_data); - -/* Keyed Data List - */ -void g_datalist_init (GData **datalist); -void g_datalist_clear (GData **datalist); -gpointer g_datalist_id_get_data (GData **datalist, - GQuark key_id); -void g_datalist_id_set_data_full (GData **datalist, - GQuark key_id, - gpointer data, - GDestroyNotify destroy_func); -gpointer g_datalist_id_remove_no_notify (GData **datalist, - GQuark key_id); -void g_datalist_foreach (GData **datalist, - GDataForeachFunc func, - gpointer user_data); - -/** - * G_DATALIST_FLAGS_MASK: - * - * A bitmask that restricts the possible flags passed to - * g_datalist_set_flags(). Passing a flags value where - * flags & ~G_DATALIST_FLAGS_MASK != 0 is an error. - */ -#define G_DATALIST_FLAGS_MASK 0x3 - -void g_datalist_set_flags (GData **datalist, - guint flags); -void g_datalist_unset_flags (GData **datalist, - guint flags); -guint g_datalist_get_flags (GData **datalist); - -#define g_datalist_id_set_data(dl, q, d) \ - g_datalist_id_set_data_full ((dl), (q), (d), NULL) -#define g_datalist_id_remove_data(dl, q) \ - g_datalist_id_set_data ((dl), (q), NULL) -#define g_datalist_set_data_full(dl, k, d, f) \ - g_datalist_id_set_data_full ((dl), g_quark_from_string (k), (d), (f)) -#define g_datalist_remove_no_notify(dl, k) \ - g_datalist_id_remove_no_notify ((dl), g_quark_try_string (k)) -#define g_datalist_set_data(dl, k, d) \ - g_datalist_set_data_full ((dl), (k), (d), NULL) -#define g_datalist_remove_data(dl, k) \ - g_datalist_id_set_data ((dl), g_quark_try_string (k), NULL) - - -/* Location Associated Keyed Data - */ -void g_dataset_destroy (gconstpointer dataset_location); -gpointer g_dataset_id_get_data (gconstpointer dataset_location, - GQuark key_id); -gpointer g_datalist_get_data (GData **datalist, - const gchar *key); -void g_dataset_id_set_data_full (gconstpointer dataset_location, - GQuark key_id, - gpointer data, - GDestroyNotify destroy_func); -gpointer g_dataset_id_remove_no_notify (gconstpointer dataset_location, - GQuark key_id); -void g_dataset_foreach (gconstpointer dataset_location, - GDataForeachFunc func, - gpointer user_data); -#define g_dataset_id_set_data(l, k, d) \ - g_dataset_id_set_data_full ((l), (k), (d), NULL) -#define g_dataset_id_remove_data(l, k) \ - g_dataset_id_set_data ((l), (k), NULL) -#define g_dataset_get_data(l, k) \ - (g_dataset_id_get_data ((l), g_quark_try_string (k))) -#define g_dataset_set_data_full(l, k, d, f) \ - g_dataset_id_set_data_full ((l), g_quark_from_string (k), (d), (f)) -#define g_dataset_remove_no_notify(l, k) \ - g_dataset_id_remove_no_notify ((l), g_quark_try_string (k)) -#define g_dataset_set_data(l, k, d) \ - g_dataset_set_data_full ((l), (k), (d), NULL) -#define g_dataset_remove_data(l, k) \ - g_dataset_id_set_data ((l), g_quark_try_string (k), NULL) - -G_END_DECLS - -#endif /* __G_DATASET_H__ */ diff --git a/deps/glib/gdatasetprivate.h b/deps/glib/gdatasetprivate.h deleted file mode 100644 index 4f98040c..00000000 --- a/deps/glib/gdatasetprivate.h +++ /dev/null @@ -1,42 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * gdataset-private.h: Internal macros for accessing dataset values - * Copyright (C) 2005 Red Hat - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __G_DATASETPRIVATE_H__ -#define __G_DATASETPRIVATE_H__ - -#include <gatomic.h> - -G_BEGIN_DECLS - -/* GET_FLAGS is implemented via atomic pointer access, to allow memory - * barriers to take effect without acquiring the global dataset mutex. - */ -#define G_DATALIST_GET_FLAGS(datalist) \ - ((gsize) g_atomic_pointer_get (datalist) & G_DATALIST_FLAGS_MASK) - - -G_END_DECLS - -#endif /* __G_DATASETPRIVATE_H__ */ diff --git a/deps/glib/gdebug.h b/deps/glib/gdebug.h deleted file mode 100644 index e27a14ea..00000000 --- a/deps/glib/gdebug.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __G_DEBUG_H__ -#define __G_DEBUG_H__ - -G_BEGIN_DECLS - -typedef enum { - G_DEBUG_FATAL_WARNINGS = 1 << 0, - G_DEBUG_FATAL_CRITICALS = 1 << 1 -} GDebugFlag; - - -#ifdef G_ENABLE_DEBUG - -#define G_NOTE(type, action) G_STMT_START { \ - if (!_g_debug_initialized) \ - { _g_debug_init (); } \ - if (_g_debug_flags & G_DEBUG_##type) \ - { action; }; } G_STMT_END - -#else /* !G_ENABLE_DEBUG */ - -#define G_NOTE(type, action) - -#endif /* G_ENABLE_DEBUG */ - -GLIB_VAR gboolean _g_debug_initialized; -GLIB_VAR guint _g_debug_flags; - -G_GNUC_INTERNAL void _g_debug_init (void); - -G_END_DECLS - -#endif /* __G_DEBUG_H__ */ diff --git a/deps/glib/gerror.c b/deps/glib/gerror.c deleted file mode 100644 index dc7a6447..00000000 --- a/deps/glib/gerror.c +++ /dev/null @@ -1,709 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/** - * SECTION:error_reporting - * @Title: Error Reporting - * @Short_description: a system for reporting errors - * - * GLib provides a standard method of reporting errors from a called - * function to the calling code. (This is the same problem solved by - * exceptions in other languages.) It's important to understand that - * this method is both a <emphasis>data type</emphasis> (the #GError - * object) and a <emphasis>set of rules.</emphasis> If you use #GError - * incorrectly, then your code will not properly interoperate with other - * code that uses #GError, and users of your API will probably get confused. - * - * First and foremost: <emphasis>#GError should only be used to report - * recoverable runtime errors, never to report programming - * errors.</emphasis> If the programmer has screwed up, then you should - * use g_warning(), g_return_if_fail(), g_assert(), g_error(), or some - * similar facility. (Incidentally, remember that the g_error() function - * should <emphasis>only</emphasis> be used for programming errors, it - * should not be used to print any error reportable via #GError.) - * - * Examples of recoverable runtime errors are "file not found" or - * "failed to parse input." Examples of programming errors are "NULL - * passed to strcmp()" or "attempted to free the same pointer twice." - * These two kinds of errors are fundamentally different: runtime errors - * should be handled or reported to the user, programming errors should - * be eliminated by fixing the bug in the program. This is why most - * functions in GLib and GTK+ do not use the #GError facility. - * - * Functions that can fail take a return location for a #GError as their - * last argument. For example: - * |[ - * gboolean g_file_get_contents (const gchar *filename, - * gchar **contents, - * gsize *length, - * GError **error); - * ]| - * If you pass a non-%NULL value for the <literal>error</literal> - * argument, it should point to a location where an error can be placed. - * For example: - * |[ - * gchar *contents; - * GError *err = NULL; - * g_file_get_contents ("foo.txt", &contents, NULL, &err); - * g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL)); - * if (err != NULL) - * { - * /* Report error to user, and free error */ - * g_assert (contents == NULL); - * fprintf (stderr, "Unable to read file: %s\n", err->message); - * g_error_free (err); - * } - * else - * { - * /* Use file contents */ - * g_assert (contents != NULL); - * } - * ]| - * Note that <literal>err != NULL</literal> in this example is a - * <emphasis>reliable</emphasis> indicator of whether - * g_file_get_contents() failed. Additionally, g_file_get_contents() - * returns a boolean which indicates whether it was successful. - * - * Because g_file_get_contents() returns %FALSE on failure, if you - * are only interested in whether it failed and don't need to display - * an error message, you can pass %NULL for the <literal>error</literal> - * argument: - * |[ - * if (g_file_get_contents ("foo.txt", &contents, NULL, NULL)) /* ignore errors */ - * /* no error occurred */ ; - * else - * /* error */ ; - * ]| - * - * The #GError object contains three fields: <literal>domain</literal> - * indicates the module the error-reporting function is located in, - * <literal>code</literal> indicates the specific error that occurred, - * and <literal>message</literal> is a user-readable error message with - * as many details as possible. Several functions are provided to deal - * with an error received from a called function: g_error_matches() - * returns %TRUE if the error matches a given domain and code, - * g_propagate_error() copies an error into an error location (so the - * calling function will receive it), and g_clear_error() clears an - * error location by freeing the error and resetting the location to - * %NULL. To display an error to the user, simply display - * <literal>error->message</literal>, perhaps along with additional - * context known only to the calling function (the file being opened, - * or whatever -- though in the g_file_get_contents() case, - * <literal>error->message</literal> already contains a filename). - * - * When implementing a function that can report errors, the basic - * tool is g_set_error(). Typically, if a fatal error occurs you - * want to g_set_error(), then return immediately. g_set_error() - * does nothing if the error location passed to it is %NULL. - * Here's an example: - * |[ - * gint - * foo_open_file (GError **error) - * { - * gint fd; - * - * fd = open ("file.txt", O_RDONLY); - * - * if (fd < 0) - * { - * g_set_error (error, - * FOO_ERROR, /* error domain */ - * FOO_ERROR_BLAH, /* error code */ - * "Failed to open file: %s", /* error message format string */ - * g_strerror (errno)); - * return -1; - * } - * else - * return fd; - * } - * ]| - * - * Things are somewhat more complicated if you yourself call another - * function that can report a #GError. If the sub-function indicates - * fatal errors in some way other than reporting a #GError, such as - * by returning %TRUE on success, you can simply do the following: - * |[ - * gboolean - * my_function_that_can_fail (GError **err) - * { - * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); - * - * if (!sub_function_that_can_fail (err)) - * { - * /* assert that error was set by the sub-function */ - * g_assert (err == NULL || *err != NULL); - * return FALSE; - * } - * - * /* otherwise continue, no error occurred */ - * g_assert (err == NULL || *err == NULL); - * } - * ]| - * - * If the sub-function does not indicate errors other than by - * reporting a #GError, you need to create a temporary #GError - * since the passed-in one may be %NULL. g_propagate_error() is - * intended for use in this case. - * |[ - * gboolean - * my_function_that_can_fail (GError **err) - * { - * GError *tmp_error; - * - * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); - * - * tmp_error = NULL; - * sub_function_that_can_fail (&tmp_error); - * - * if (tmp_error != NULL) - * { - * /* store tmp_error in err, if err != NULL, - * * otherwise call g_error_free() on tmp_error - * */ - * g_propagate_error (err, tmp_error); - * return FALSE; - * } - * - * /* otherwise continue, no error occurred */ - * } - * ]| - * - * Error pileups are always a bug. For example, this code is incorrect: - * |[ - * gboolean - * my_function_that_can_fail (GError **err) - * { - * GError *tmp_error; - * - * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); - * - * tmp_error = NULL; - * sub_function_that_can_fail (&tmp_error); - * other_function_that_can_fail (&tmp_error); - * - * if (tmp_error != NULL) - * { - * g_propagate_error (err, tmp_error); - * return FALSE; - * } - * } - * ]| - * <literal>tmp_error</literal> should be checked immediately after - * sub_function_that_can_fail(), and either cleared or propagated - * upward. The rule is: <emphasis>after each error, you must either - * handle the error, or return it to the calling function</emphasis>. - * Note that passing %NULL for the error location is the equivalent - * of handling an error by always doing nothing about it. So the - * following code is fine, assuming errors in sub_function_that_can_fail() - * are not fatal to my_function_that_can_fail(): - * |[ - * gboolean - * my_function_that_can_fail (GError **err) - * { - * GError *tmp_error; - * - * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); - * - * sub_function_that_can_fail (NULL); /* ignore errors */ - * - * tmp_error = NULL; - * other_function_that_can_fail (&tmp_error); - * - * if (tmp_error != NULL) - * { - * g_propagate_error (err, tmp_error); - * return FALSE; - * } - * } - * ]| - * - * Note that passing %NULL for the error location - * <emphasis>ignores</emphasis> errors; it's equivalent to - * <literal>try { sub_function_that_can_fail (); } catch (...) {}</literal> - * in C++. It does <emphasis>not</emphasis> mean to leave errors - * unhandled; it means to handle them by doing nothing. - * - * Error domains and codes are conventionally named as follows: - * <itemizedlist> - * <listitem><para> - * The error domain is called - * <literal><NAMESPACE>_<MODULE>_ERROR</literal>, - * for example %G_SPAWN_ERROR or %G_THREAD_ERROR: - * |[ - * #define G_SPAWN_ERROR g_spawn_error_quark () - * - * GQuark - * g_spawn_error_quark (void) - * { - * return g_quark_from_static_string ("g-spawn-error-quark"); - * } - * ]| - * </para></listitem> - * <listitem><para> - * The quark function for the error domain is called - * <literal><namespace>_<module>_error_quark</literal>, - * for example g_spawn_error_quark() or %g_thread_error_quark(). - * </para></listitem> - * <listitem><para> - * The error codes are in an enumeration called - * <literal><Namespace><Module>Error</literal>; - * for example,#GThreadError or #GSpawnError. - * </para></listitem> - * <listitem><para> - * Members of the error code enumeration are called - * <literal><NAMESPACE>_<MODULE>_ERROR_<CODE></literal>, - * for example %G_SPAWN_ERROR_FORK or %G_THREAD_ERROR_AGAIN. - * </para></listitem> - * <listitem><para> - * If there's a "generic" or "unknown" error code for unrecoverable - * errors it doesn't make sense to distinguish with specific codes, - * it should be called <literal><NAMESPACE>_<MODULE>_ERROR_FAILED</literal>, - * for example %G_SPAWN_ERROR_FAILED or %G_THREAD_ERROR_FAILED. - * </para></listitem> - * </itemizedlist> - * - * Summary of rules for use of #GError: - * <itemizedlist> - * <listitem><para> - * Do not report programming errors via #GError. - * </para></listitem> - * <listitem><para> - * The last argument of a function that returns an error should - * be a location where a #GError can be placed (i.e. "#GError** error"). - * If #GError is used with varargs, the #GError** should be the last - * argument before the "...". - * </para></listitem> - * <listitem><para> - * The caller may pass %NULL for the #GError** if they are not interested - * in details of the exact error that occurred. - * </para></listitem> - * <listitem><para> - * If %NULL is passed for the #GError** argument, then errors should - * not be returned to the caller, but your function should still - * abort and return if an error occurs. That is, control flow should - * not be affected by whether the caller wants to get a #GError. - * </para></listitem> - * <listitem><para> - * If a #GError is reported, then your function by definition - * <emphasis>had a fatal failure and did not complete whatever - * it was supposed to do</emphasis>. If the failure was not fatal, - * then you handled it and you should not report it. If it was fatal, - * then you must report it and discontinue whatever you were doing - * immediately. - * </para></listitem> - * <listitem><para> - * A #GError* must be initialized to %NULL before passing its address - * to a function that can report errors. - * </para></listitem> - * <listitem><para> - * "Piling up" errors is always a bug. That is, if you assign a - * new #GError to a #GError* that is non-%NULL, thus overwriting - * the previous error, it indicates that you should have aborted - * the operation instead of continuing. If you were able to continue, - * you should have cleared the previous error with g_clear_error(). - * g_set_error() will complain if you pile up errors. - * </para></listitem> - * <listitem><para> - * By convention, if you return a boolean value indicating success - * then %TRUE means success and %FALSE means failure. If %FALSE is - * returned, the error <emphasis>must</emphasis> be set to a non-%NULL - * value. - * </para></listitem> - * <listitem><para> - * A %NULL return value is also frequently used to mean that an error - * occurred. You should make clear in your documentation whether %NULL - * is a valid return value in non-error cases; if %NULL is a valid value, - * then users must check whether an error was returned to see if the - * function succeeded. - * </para></listitem> - * <listitem><para> - * When implementing a function that can report errors, you may want - * to add a check at the top of your function that the error return - * location is either %NULL or contains a %NULL error (e.g. - * <literal>g_return_if_fail (error == NULL || *error == NULL);</literal>). - * </para></listitem> - * </itemizedlist> - */ - -#include "config.h" - -#include "gerror.h" - -#include "gstrfuncs.h" -#include "gtestutils.h" - -/** - * g_error_new_valist: - * @domain: error domain - * @code: error code - * @format: printf()-style format for error message - * @args: #va_list of parameters for the message format - * - * Creates a new #GError with the given @domain and @code, - * and a message formatted with @format. - * - * Returns: a new #GError - * - * Since: 2.22 - */ -GError* -g_error_new_valist (GQuark domain, - gint code, - const gchar *format, - va_list args) -{ - GError *error; - - error = g_slice_new (GError); - - error->domain = domain; - error->code = code; - error->message = g_strdup_vprintf (format, args); - - return error; -} - -/** - * g_error_new: - * @domain: error domain - * @code: error code - * @format: printf()-style format for error message - * @...: parameters for message format - * - * Creates a new #GError with the given @domain and @code, - * and a message formatted with @format. - * - * Return value: a new #GError - */ -GError* -g_error_new (GQuark domain, - gint code, - const gchar *format, - ...) -{ - GError* error; - va_list args; - - g_return_val_if_fail (format != NULL, NULL); - g_return_val_if_fail (domain != 0, NULL); - - va_start (args, format); - error = g_error_new_valist (domain, code, format, args); - va_end (args); - - return error; -} - -/** - * g_error_new_literal: - * @domain: error domain - * @code: error code - * @message: error message - * - * Creates a new #GError; unlike g_error_new(), @message is - * not a printf()-style format string. Use this function if - * @message contains text you don't have control over, - * that could include printf() escape sequences. - * - * Return value: a new #GError - **/ -GError* -g_error_new_literal (GQuark domain, - gint code, - const gchar *message) -{ - GError* err; - - g_return_val_if_fail (message != NULL, NULL); - g_return_val_if_fail (domain != 0, NULL); - - err = g_slice_new (GError); - - err->domain = domain; - err->code = code; - err->message = g_strdup (message); - - return err; -} - -/** - * g_error_free: - * @error: a #GError - * - * Frees a #GError and associated resources. - */ -void -g_error_free (GError *error) -{ - g_return_if_fail (error != NULL); - - g_free (error->message); - - g_slice_free (GError, error); -} - -/** - * g_error_copy: - * @error: a #GError - * - * Makes a copy of @error. - * - * Return value: a new #GError - */ -GError* -g_error_copy (const GError *error) -{ - GError *copy; - - g_return_val_if_fail (error != NULL, NULL); - - copy = g_slice_new (GError); - - *copy = *error; - - copy->message = g_strdup (error->message); - - return copy; -} - -/** - * g_error_matches: - * @error: a #GError or %NULL - * @domain: an error domain - * @code: an error code - * - * Returns %TRUE if @error matches @domain and @code, %FALSE - * otherwise. In particular, when @error is %NULL, %FALSE will - * be returned. - * - * Return value: whether @error has @domain and @code - */ -gboolean -g_error_matches (const GError *error, - GQuark domain, - gint code) -{ - return error && - error->domain == domain && - error->code == code; -} - -#define ERROR_OVERWRITTEN_WARNING "GError set over the top of a previous GError or uninitialized memory.\n" \ - "This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n" \ - "The overwriting error message was: %s" - -/** - * g_set_error: - * @err: a return location for a #GError, or %NULL - * @domain: error domain - * @code: error code - * @format: printf()-style format - * @...: args for @format - * - * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err - * must be %NULL. A new #GError is created and assigned to *@err. - */ -void -g_set_error (GError **err, - GQuark domain, - gint code, - const gchar *format, - ...) -{ - GError *new; - - va_list args; - - if (err == NULL) - return; - - va_start (args, format); - new = g_error_new_valist (domain, code, format, args); - va_end (args); - - if (*err == NULL) - *err = new; - else - g_warning (ERROR_OVERWRITTEN_WARNING, new->message); -} - -/** - * g_set_error_literal: - * @err: a return location for a #GError, or %NULL - * @domain: error domain - * @code: error code - * @message: error message - * - * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err - * must be %NULL. A new #GError is created and assigned to *@err. - * Unlike g_set_error(), @message is not a printf()-style format string. - * Use this function if @message contains text you don't have control over, - * that could include printf() escape sequences. - * - * Since: 2.18 - */ -void -g_set_error_literal (GError **err, - GQuark domain, - gint code, - const gchar *message) -{ - GError *new; - - if (err == NULL) - return; - - new = g_error_new_literal (domain, code, message); - if (*err == NULL) - *err = new; - else - g_warning (ERROR_OVERWRITTEN_WARNING, new->message); -} - -/** - * g_propagate_error: - * @dest: error return location - * @src: error to move into the return location - * - * If @dest is %NULL, free @src; otherwise, moves @src into *@dest. - * The error variable @dest points to must be %NULL. - */ -void -g_propagate_error (GError **dest, - GError *src) -{ - g_return_if_fail (src != NULL); - - if (dest == NULL) - { - if (src) - g_error_free (src); - return; - } - else - { - if (*dest != NULL) - g_warning (ERROR_OVERWRITTEN_WARNING, src->message); - else - *dest = src; - } -} - -/** - * g_clear_error: - * @err: a #GError return location - * - * If @err is %NULL, does nothing. If @err is non-%NULL, - * calls g_error_free() on *@err and sets *@err to %NULL. - */ -void -g_clear_error (GError **err) -{ - if (err && *err) - { - g_error_free (*err); - *err = NULL; - } -} - -static void -g_error_add_prefix (gchar **string, - const gchar *format, - va_list ap) -{ - gchar *oldstring; - gchar *prefix; - - prefix = g_strdup_vprintf (format, ap); - oldstring = *string; - *string = g_strconcat (prefix, oldstring, NULL); - g_free (oldstring); - g_free (prefix); -} - -/** - * g_prefix_error: - * @err: a return location for a #GError, or %NULL - * @format: printf()-style format string - * @...: arguments to @format - * - * Formats a string according to @format and - * prefix it to an existing error message. If - * @err is %NULL (ie: no error variable) then do - * nothing. - * - * If *@err is %NULL (ie: an error variable is - * present but there is no error condition) then - * also do nothing. Whether or not it makes - * sense to take advantage of this feature is up - * to you. - * - * Since: 2.16 - */ -void -g_prefix_error (GError **err, - const gchar *format, - ...) -{ - if (err && *err) - { - va_list ap; - - va_start (ap, format); - g_error_add_prefix (&(*err)->message, format, ap); - va_end (ap); - } -} - -/** - * g_propagate_prefixed_error: - * @dest: error return location - * @src: error to move into the return location - * @format: printf()-style format string - * @...: arguments to @format - * - * If @dest is %NULL, free @src; otherwise, - * moves @src into *@dest. *@dest must be %NULL. - * After the move, add a prefix as with - * g_prefix_error(). - * - * Since: 2.16 - **/ -void -g_propagate_prefixed_error (GError **dest, - GError *src, - const gchar *format, - ...) -{ - g_propagate_error (dest, src); - - if (dest && *dest) - { - va_list ap; - - va_start (ap, format); - g_error_add_prefix (&(*dest)->message, format, ap); - va_end (ap); - } -} diff --git a/deps/glib/gerror.h b/deps/glib/gerror.h deleted file mode 100644 index aaa8d99a..00000000 --- a/deps/glib/gerror.h +++ /dev/null @@ -1,106 +0,0 @@ -/* gerror.h - Error reporting system - * - * Copyright 2000 Red Hat, Inc. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_ERROR_H__ -#define __G_ERROR_H__ - -#include <stdarg.h> - -#include <glib/gquark.h> - -G_BEGIN_DECLS - -/** - * GError: - * @domain: error domain, e.g. #G_FILE_ERROR - * @code: error code, e.g. %G_FILE_ERROR_NOENT - * @message: human-readable informative error message - * - * The <structname>GError</structname> structure contains - * information about an error that has occurred. - */ -typedef struct _GError GError; - -struct _GError -{ - GQuark domain; - gint code; - gchar *message; -}; - -GError* g_error_new (GQuark domain, - gint code, - const gchar *format, - ...) G_GNUC_PRINTF (3, 4); - -GError* g_error_new_literal (GQuark domain, - gint code, - const gchar *message); -GError* g_error_new_valist (GQuark domain, - gint code, - const gchar *format, - va_list args); - -void g_error_free (GError *error); -GError* g_error_copy (const GError *error); - -gboolean g_error_matches (const GError *error, - GQuark domain, - gint code); - -/* if (err) *err = g_error_new(domain, code, format, ...), also has - * some sanity checks. - */ -void g_set_error (GError **err, - GQuark domain, - gint code, - const gchar *format, - ...) G_GNUC_PRINTF (4, 5); - -void g_set_error_literal (GError **err, - GQuark domain, - gint code, - const gchar *message); - -/* if (dest) *dest = src; also has some sanity checks. - */ -void g_propagate_error (GError **dest, - GError *src); - -/* if (err && *err) { g_error_free(*err); *err = NULL; } */ -void g_clear_error (GError **err); - -/* if (err) prefix the formatted string to the ->message */ -void g_prefix_error (GError **err, - const gchar *format, - ...) G_GNUC_PRINTF (2, 3); - -/* g_propagate_error then g_error_prefix on dest */ -void g_propagate_prefixed_error (GError **dest, - GError *src, - const gchar *format, - ...) G_GNUC_PRINTF (3, 4); - -G_END_DECLS - -#endif /* __G_ERROR_H__ */ diff --git a/deps/glib/gfileutils.c b/deps/glib/gfileutils.c deleted file mode 100644 index 55963014..00000000 --- a/deps/glib/gfileutils.c +++ /dev/null @@ -1,2327 +0,0 @@ -/* gfileutils.c - File utility functions - * - * Copyright 2000 Red Hat, Inc. - * - * GLib is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * GLib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with GLib; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" -#include "glibconfig.h" - -#include <sys/stat.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdlib.h> - -#ifdef G_OS_WIN32 -#include <windows.h> -#include <io.h> -#endif /* G_OS_WIN32 */ - -#ifndef S_ISLNK -#define S_ISLNK(x) 0 -#endif - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#include "gfileutils.h" - -#include "gstdio.h" -#include "glibintl.h" -#include "gconvert.h" -#include "gmain.h" - -#ifdef HAVE_LINUX_MAGIC_H /* for btrfs check */ -#include <linux/magic.h> -#include <sys/vfs.h> -#endif - -/** - * g_mkdir_with_parents: - * @pathname: a pathname in the GLib file name encoding - * @mode: permissions to use for newly created directories - * - * Create a directory if it doesn't already exist. Create intermediate - * parent directories as needed, too. - * - * Returns: 0 if the directory already exists, or was successfully - * created. Returns -1 if an error occurred, with errno set. - * - * Since: 2.8 - */ -int -g_mkdir_with_parents (const gchar *pathname, - int mode) -{ - gchar *fn, *p; - - if (pathname == NULL || *pathname == '\0') - { - errno = EINVAL; - return -1; - } - - fn = g_strdup (pathname); - - if (g_path_is_absolute (fn)) - p = (gchar *) g_path_skip_root (fn); - else - p = fn; - - do - { - while (*p && !G_IS_DIR_SEPARATOR (*p)) - p++; - - if (!*p) - p = NULL; - else - *p = '\0'; - - if (!g_file_test (fn, G_FILE_TEST_EXISTS)) - { - if (g_mkdir (fn, mode) == -1 && errno != EEXIST) - { - int errno_save = errno; - g_free (fn); - errno = errno_save; - return -1; - } - } - else if (!g_file_test (fn, G_FILE_TEST_IS_DIR)) - { - g_free (fn); - errno = ENOTDIR; - return -1; - } - if (p) - { - *p++ = G_DIR_SEPARATOR; - while (*p && G_IS_DIR_SEPARATOR (*p)) - p++; - } - } - while (p); - - g_free (fn); - - return 0; -} - -/** - * g_file_test: - * @filename: a filename to test in the GLib file name encoding - * @test: bitfield of #GFileTest flags - * - * Returns %TRUE if any of the tests in the bitfield @test are - * %TRUE. For example, <literal>(G_FILE_TEST_EXISTS | - * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists; - * the check whether it's a directory doesn't matter since the existence - * test is %TRUE. With the current set of available tests, there's no point - * passing in more than one test at a time. - * - * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links, - * so for a symbolic link to a regular file g_file_test() will return - * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR. - * - * Note, that for a dangling symbolic link g_file_test() will return - * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags. - * - * You should never use g_file_test() to test whether it is safe - * to perform an operation, because there is always the possibility - * of the condition changing before you actually perform the operation. - * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK - * to know whether it is safe to write to a file without being - * tricked into writing into a different location. It doesn't work! - * |[ - * /* DON'T DO THIS */ - * if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) - * { - * fd = g_open (filename, O_WRONLY); - * /* write to fd */ - * } - * ]| - * - * Another thing to note is that %G_FILE_TEST_EXISTS and - * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access() - * system call. This usually doesn't matter, but if your program - * is setuid or setgid it means that these tests will give you - * the answer for the real user ID and group ID, rather than the - * effective user ID and group ID. - * - * On Windows, there are no symlinks, so testing for - * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for - * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and - * its name indicates that it is executable, checking for well-known - * extensions and those listed in the %PATHEXT environment variable. - * - * Return value: whether a test was %TRUE - **/ -gboolean -g_file_test (const gchar *filename, - GFileTest test) -{ -#ifdef G_OS_WIN32 -/* stuff missing in std vc6 api */ -# ifndef INVALID_FILE_ATTRIBUTES -# define INVALID_FILE_ATTRIBUTES -1 -# endif -# ifndef FILE_ATTRIBUTE_DEVICE -# define FILE_ATTRIBUTE_DEVICE 64 -# endif - int attributes; - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - - if (wfilename == NULL) - return FALSE; - - attributes = GetFileAttributesW (wfilename); - - g_free (wfilename); - - if (attributes == INVALID_FILE_ATTRIBUTES) - return FALSE; - - if (test & G_FILE_TEST_EXISTS) - return TRUE; - - if (test & G_FILE_TEST_IS_REGULAR) - { - if ((attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) - return TRUE; - } - - if (test & G_FILE_TEST_IS_DIR) - { - if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) - return TRUE; - } - - /* "while" so that we can exit this "loop" with a simple "break" */ - while (test & G_FILE_TEST_IS_EXECUTABLE) - { - const gchar *lastdot = strrchr (filename, '.'); - const gchar *pathext = NULL, *p; - int extlen; - - if (lastdot == NULL) - break; - - if (_stricmp (lastdot, ".exe") == 0 || - _stricmp (lastdot, ".cmd") == 0 || - _stricmp (lastdot, ".bat") == 0 || - _stricmp (lastdot, ".com") == 0) - return TRUE; - - /* Check if it is one of the types listed in %PATHEXT% */ - - pathext = g_getenv ("PATHEXT"); - if (pathext == NULL) - break; - - pathext = g_utf8_casefold (pathext, -1); - - lastdot = g_utf8_casefold (lastdot, -1); - extlen = strlen (lastdot); - - p = pathext; - while (TRUE) - { - const gchar *q = strchr (p, ';'); - if (q == NULL) - q = p + strlen (p); - if (extlen == q - p && - memcmp (lastdot, p, extlen) == 0) - { - g_free ((gchar *) pathext); - g_free ((gchar *) lastdot); - return TRUE; - } - if (*q) - p = q + 1; - else - break; - } - - g_free ((gchar *) pathext); - g_free ((gchar *) lastdot); - break; - } - - return FALSE; -#else - if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0)) - return TRUE; - - if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0)) - { - if (getuid () != 0) - return TRUE; - - /* For root, on some POSIX systems, access (filename, X_OK) - * will succeed even if no executable bits are set on the - * file. We fall through to a stat test to avoid that. - */ - } - else - test &= ~G_FILE_TEST_IS_EXECUTABLE; - - if (test & G_FILE_TEST_IS_SYMLINK) - { - struct stat s; - - if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode)) - return TRUE; - } - - if (test & (G_FILE_TEST_IS_REGULAR | - G_FILE_TEST_IS_DIR | - G_FILE_TEST_IS_EXECUTABLE)) - { - struct stat s; - - if (stat (filename, &s) == 0) - { - if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode)) - return TRUE; - - if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode)) - return TRUE; - - /* The extra test for root when access (file, X_OK) succeeds. - */ - if ((test & G_FILE_TEST_IS_EXECUTABLE) && - ((s.st_mode & S_IXOTH) || - (s.st_mode & S_IXUSR) || - (s.st_mode & S_IXGRP))) - return TRUE; - } - } - - return FALSE; -#endif -} - -GQuark -g_file_error_quark (void) -{ - return g_quark_from_static_string ("g-file-error-quark"); -} - -/** - * g_file_error_from_errno: - * @err_no: an "errno" value - * - * Gets a #GFileError constant based on the passed-in @errno. - * For example, if you pass in %EEXIST this function returns - * #G_FILE_ERROR_EXIST. Unlike @errno values, you can portably - * assume that all #GFileError values will exist. - * - * Normally a #GFileError value goes into a #GError returned - * from a function that manipulates files. So you would use - * g_file_error_from_errno() when constructing a #GError. - * - * Return value: #GFileError corresponding to the given @errno - **/ -GFileError -g_file_error_from_errno (gint err_no) -{ - switch (err_no) - { -#ifdef EEXIST - case EEXIST: - return G_FILE_ERROR_EXIST; - break; -#endif - -#ifdef EISDIR - case EISDIR: - return G_FILE_ERROR_ISDIR; - break; -#endif - -#ifdef EACCES - case EACCES: - return G_FILE_ERROR_ACCES; - break; -#endif - -#ifdef ENAMETOOLONG - case ENAMETOOLONG: - return G_FILE_ERROR_NAMETOOLONG; - break; -#endif - -#ifdef ENOENT - case ENOENT: - return G_FILE_ERROR_NOENT; - break; -#endif - -#ifdef ENOTDIR - case ENOTDIR: - return G_FILE_ERROR_NOTDIR; - break; -#endif - -#ifdef ENXIO - case ENXIO: - return G_FILE_ERROR_NXIO; - break; -#endif - -#ifdef ENODEV - case ENODEV: - return G_FILE_ERROR_NODEV; - break; -#endif - -#ifdef EROFS - case EROFS: - return G_FILE_ERROR_ROFS; - break; -#endif - -#ifdef ETXTBSY - case ETXTBSY: - return G_FILE_ERROR_TXTBSY; - break; -#endif - -#ifdef EFAULT - case EFAULT: - return G_FILE_ERROR_FAULT; - break; -#endif - -#ifdef ELOOP - case ELOOP: - return G_FILE_ERROR_LOOP; - break; -#endif - -#ifdef ENOSPC - case ENOSPC: - return G_FILE_ERROR_NOSPC; - break; -#endif - -#ifdef ENOMEM - case ENOMEM: - return G_FILE_ERROR_NOMEM; - break; -#endif - -#ifdef EMFILE - case EMFILE: - return G_FILE_ERROR_MFILE; - break; -#endif - -#ifdef ENFILE - case ENFILE: - return G_FILE_ERROR_NFILE; - break; -#endif - -#ifdef EBADF - case EBADF: - return G_FILE_ERROR_BADF; - break; -#endif - -#ifdef EINVAL - case EINVAL: - return G_FILE_ERROR_INVAL; - break; -#endif - -#ifdef EPIPE - case EPIPE: - return G_FILE_ERROR_PIPE; - break; -#endif - -#ifdef EAGAIN - case EAGAIN: - return G_FILE_ERROR_AGAIN; - break; -#endif - -#ifdef EINTR - case EINTR: - return G_FILE_ERROR_INTR; - break; -#endif - -#ifdef EIO - case EIO: - return G_FILE_ERROR_IO; - break; -#endif - -#ifdef EPERM - case EPERM: - return G_FILE_ERROR_PERM; - break; -#endif - -#ifdef ENOSYS - case ENOSYS: - return G_FILE_ERROR_NOSYS; - break; -#endif - - default: - return G_FILE_ERROR_FAILED; - break; - } -} - -static gboolean -get_contents_stdio (const gchar *display_filename, - FILE *f, - gchar **contents, - gsize *length, - GError **error) -{ - gchar buf[4096]; - gsize bytes; - gchar *str = NULL; - gsize total_bytes = 0; - gsize total_allocated = 0; - gchar *tmp; - - g_assert (f != NULL); - - while (!feof (f)) - { - gint save_errno; - - bytes = fread (buf, 1, sizeof (buf), f); - save_errno = errno; - - while ((total_bytes + bytes + 1) > total_allocated) - { - if (str) - total_allocated *= 2; - else - total_allocated = MIN (bytes + 1, sizeof (buf)); - - tmp = g_try_realloc (str, total_allocated); - - if (tmp == NULL) - { - g_set_error (error, - G_FILE_ERROR, - G_FILE_ERROR_NOMEM, - _("Could not allocate %lu bytes to read file \"%s\""), - (gulong) total_allocated, - display_filename); - - goto error; - } - - str = tmp; - } - - if (ferror (f)) - { - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Error reading file '%s': %s"), - display_filename, - g_strerror (save_errno)); - - goto error; - } - - memcpy (str + total_bytes, buf, bytes); - - if (total_bytes + bytes < total_bytes) - { - g_set_error (error, - G_FILE_ERROR, - G_FILE_ERROR_FAILED, - _("File \"%s\" is too large"), - display_filename); - - goto error; - } - - total_bytes += bytes; - } - - fclose (f); - - if (total_allocated == 0) - { - str = g_new (gchar, 1); - total_bytes = 0; - } - - str[total_bytes] = '\0'; - - if (length) - *length = total_bytes; - - *contents = str; - - return TRUE; - - error: - - g_free (str); - fclose (f); - - return FALSE; -} - -#ifndef G_OS_WIN32 - -static gboolean -get_contents_regfile (const gchar *display_filename, - struct stat *stat_buf, - gint fd, - gchar **contents, - gsize *length, - GError **error) -{ - gchar *buf; - gsize bytes_read; - gsize size; - gsize alloc_size; - - size = stat_buf->st_size; - - alloc_size = size + 1; - buf = g_try_malloc (alloc_size); - - if (buf == NULL) - { - g_set_error (error, - G_FILE_ERROR, - G_FILE_ERROR_NOMEM, - _("Could not allocate %lu bytes to read file \"%s\""), - (gulong) alloc_size, - display_filename); - - goto error; - } - - bytes_read = 0; - while (bytes_read < size) - { - gssize rc; - - rc = read (fd, buf + bytes_read, size - bytes_read); - - if (rc < 0) - { - if (errno != EINTR) - { - int save_errno = errno; - - g_free (buf); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to read from file '%s': %s"), - display_filename, - g_strerror (save_errno)); - - goto error; - } - } - else if (rc == 0) - break; - else - bytes_read += rc; - } - - buf[bytes_read] = '\0'; - - if (length) - *length = bytes_read; - - *contents = buf; - - close (fd); - - return TRUE; - - error: - - close (fd); - - return FALSE; -} - -static gboolean -get_contents_posix (const gchar *filename, - gchar **contents, - gsize *length, - GError **error) -{ - struct stat stat_buf; - gint fd; - gchar *display_filename = g_filename_display_name (filename); - - /* O_BINARY useful on Cygwin */ - fd = open (filename, O_RDONLY|O_BINARY); - - if (fd < 0) - { - int save_errno = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s': %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); - - return FALSE; - } - - /* I don't think this will ever fail, aside from ENOMEM, but. */ - if (fstat (fd, &stat_buf) < 0) - { - int save_errno = errno; - - close (fd); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to get attributes of file '%s': fstat() failed: %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); - - return FALSE; - } - - if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode)) - { - gboolean retval = get_contents_regfile (display_filename, - &stat_buf, - fd, - contents, - length, - error); - g_free (display_filename); - - return retval; - } - else - { - FILE *f; - gboolean retval; - - f = fdopen (fd, "r"); - - if (f == NULL) - { - int save_errno = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s': fdopen() failed: %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); - - return FALSE; - } - - retval = get_contents_stdio (display_filename, f, contents, length, error); - g_free (display_filename); - - return retval; - } -} - -#else /* G_OS_WIN32 */ - -static gboolean -get_contents_win32 (const gchar *filename, - gchar **contents, - gsize *length, - GError **error) -{ - FILE *f; - gboolean retval; - gchar *display_filename = g_filename_display_name (filename); - int save_errno; - - f = g_fopen (filename, "rb"); - save_errno = errno; - - if (f == NULL) - { - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s': %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); - - return FALSE; - } - - retval = get_contents_stdio (display_filename, f, contents, length, error); - g_free (display_filename); - - return retval; -} - -#endif - -/** - * g_file_get_contents: - * @filename: (type filename): name of a file to read contents from, in the GLib file name encoding - * @contents: (out) (array length=length) (element-type guint8): location to store an allocated string, use g_free() to free - * the returned string - * @length: (allow-none): location to store length in bytes of the contents, or %NULL - * @error: return location for a #GError, or %NULL - * - * Reads an entire file into allocated memory, with good error - * checking. - * - * If the call was successful, it returns %TRUE and sets @contents to the file - * contents and @length to the length of the file contents in bytes. The string - * stored in @contents will be nul-terminated, so for text files you can pass - * %NULL for the @length argument. If the call was not successful, it returns - * %FALSE and sets @error. The error domain is #G_FILE_ERROR. Possible error - * codes are those in the #GFileError enumeration. In the error case, - * @contents is set to %NULL and @length is set to zero. - * - * Return value: %TRUE on success, %FALSE if an error occurred - **/ -gboolean -g_file_get_contents (const gchar *filename, - gchar **contents, - gsize *length, - GError **error) -{ - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (contents != NULL, FALSE); - - *contents = NULL; - if (length) - *length = 0; - -#ifdef G_OS_WIN32 - return get_contents_win32 (filename, contents, length, error); -#else - return get_contents_posix (filename, contents, length, error); -#endif -} - -static gboolean -rename_file (const char *old_name, - const char *new_name, - GError **err) -{ - errno = 0; - if (g_rename (old_name, new_name) == -1) - { - int save_errno = errno; - gchar *display_old_name = g_filename_display_name (old_name); - gchar *display_new_name = g_filename_display_name (new_name); - - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to rename file '%s' to '%s': g_rename() failed: %s"), - display_old_name, - display_new_name, - g_strerror (save_errno)); - - g_free (display_old_name); - g_free (display_new_name); - - return FALSE; - } - - return TRUE; -} - -static gchar * -write_to_temp_file (const gchar *contents, - gssize length, - const gchar *dest_file, - GError **err) -{ - gchar *tmp_name; - gchar *display_name; - gchar *retval; - FILE *file; - gint fd; - int save_errno; - - retval = NULL; - - tmp_name = g_strdup_printf ("%s.XXXXXX", dest_file); - - errno = 0; - fd = g_mkstemp_full (tmp_name, O_RDWR | O_BINARY, 0666); - save_errno = errno; - - display_name = g_filename_display_name (tmp_name); - - if (fd == -1) - { - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to create file '%s': %s"), - display_name, g_strerror (save_errno)); - - goto out; - } - - errno = 0; - file = fdopen (fd, "wb"); - if (!file) - { - save_errno = errno; - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to open file '%s' for writing: fdopen() failed: %s"), - display_name, - g_strerror (save_errno)); - - close (fd); - g_unlink (tmp_name); - - goto out; - } - - if (length > 0) - { - gsize n_written; - - errno = 0; - - n_written = fwrite (contents, 1, length, file); - - if (n_written < length) - { - save_errno = errno; - - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to write file '%s': fwrite() failed: %s"), - display_name, - g_strerror (save_errno)); - - fclose (file); - g_unlink (tmp_name); - - goto out; - } - } - - errno = 0; - if (fflush (file) != 0) - { - save_errno = errno; - - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to write file '%s': fflush() failed: %s"), - display_name, - g_strerror (save_errno)); - - fclose (file); - g_unlink (tmp_name); - - goto out; - } - -#ifdef BTRFS_SUPER_MAGIC - { - struct statfs buf; - - /* On Linux, on btrfs, skip the fsync since rename-over-existing is - * guaranteed to be atomic and this is the only case in which we - * would fsync() anyway. - */ - - if (fstatfs (fd, &buf) == 0 && buf.f_type == BTRFS_SUPER_MAGIC) - goto no_fsync; - } -#endif - -#ifdef HAVE_FSYNC - { - struct stat statbuf; - - errno = 0; - /* If the final destination exists and is > 0 bytes, we want to sync the - * newly written file to ensure the data is on disk when we rename over - * the destination. Otherwise if we get a system crash we can lose both - * the new and the old file on some filesystems. (I.E. those that don't - * guarantee the data is written to the disk before the metadata.) - */ - if (g_lstat (dest_file, &statbuf) == 0 && - statbuf.st_size > 0 && - fsync (fileno (file)) != 0) - { - save_errno = errno; - - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to write file '%s': fsync() failed: %s"), - display_name, - g_strerror (save_errno)); - - fclose (file); - g_unlink (tmp_name); - - goto out; - } - } -#endif - -#ifdef BTRFS_SUPER_MAGIC - no_fsync: -#endif - - errno = 0; - if (fclose (file) == EOF) - { - save_errno = errno; - - g_set_error (err, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to close file '%s': fclose() failed: %s"), - display_name, - g_strerror (save_errno)); - - fclose (file); - g_unlink (tmp_name); - - goto out; - } - - retval = g_strdup (tmp_name); - - out: - g_free (tmp_name); - g_free (display_name); - - return retval; -} - -/** - * g_file_set_contents: - * @filename: (type filename): name of a file to write @contents to, in the GLib file name - * encoding - * @contents: (array length=length) (element-type guint8): string to write to the file - * @length: length of @contents, or -1 if @contents is a nul-terminated string - * @error: return location for a #GError, or %NULL - * - * Writes all of @contents to a file named @filename, with good error checking. - * If a file called @filename already exists it will be overwritten. - * - * This write is atomic in the sense that it is first written to a temporary - * file which is then renamed to the final name. Notes: - * <itemizedlist> - * <listitem> - * On Unix, if @filename already exists hard links to @filename will break. - * Also since the file is recreated, existing permissions, access control - * lists, metadata etc. may be lost. If @filename is a symbolic link, - * the link itself will be replaced, not the linked file. - * </listitem> - * <listitem> - * On Windows renaming a file will not remove an existing file with the - * new name, so on Windows there is a race condition between the existing - * file being removed and the temporary file being renamed. - * </listitem> - * <listitem> - * On Windows there is no way to remove a file that is open to some - * process, or mapped into memory. Thus, this function will fail if - * @filename already exists and is open. - * </listitem> - * </itemizedlist> - * - * If the call was successful, it returns %TRUE. If the call was not successful, - * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR. - * Possible error codes are those in the #GFileError enumeration. - * - * Note that the name for the temporary file is constructed by appending up - * to 7 characters to @filename. - * - * Return value: %TRUE on success, %FALSE if an error occurred - * - * Since: 2.8 - **/ -gboolean -g_file_set_contents (const gchar *filename, - const gchar *contents, - gssize length, - GError **error) -{ - gchar *tmp_filename; - gboolean retval; - GError *rename_error = NULL; - - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - g_return_val_if_fail (contents != NULL || length == 0, FALSE); - g_return_val_if_fail (length >= -1, FALSE); - - if (length == -1) - length = strlen (contents); - - tmp_filename = write_to_temp_file (contents, length, filename, error); - - if (!tmp_filename) - { - retval = FALSE; - goto out; - } - - if (!rename_file (tmp_filename, filename, &rename_error)) - { -#ifndef G_OS_WIN32 - - g_unlink (tmp_filename); - g_propagate_error (error, rename_error); - retval = FALSE; - goto out; - -#else /* G_OS_WIN32 */ - - /* Renaming failed, but on Windows this may just mean - * the file already exists. So if the target file - * exists, try deleting it and do the rename again. - */ - if (!g_file_test (filename, G_FILE_TEST_EXISTS)) - { - g_unlink (tmp_filename); - g_propagate_error (error, rename_error); - retval = FALSE; - goto out; - } - - g_error_free (rename_error); - - if (g_unlink (filename) == -1) - { - gchar *display_filename = g_filename_display_name (filename); - - int save_errno = errno; - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Existing file '%s' could not be removed: g_unlink() failed: %s"), - display_filename, - g_strerror (save_errno)); - - g_free (display_filename); - g_unlink (tmp_filename); - retval = FALSE; - goto out; - } - - if (!rename_file (tmp_filename, filename, error)) - { - g_unlink (tmp_filename); - retval = FALSE; - goto out; - } - -#endif - } - - retval = TRUE; - - out: - g_free (tmp_filename); - return retval; -} - -/* - * get_tmp_file based on the mkstemp implementation from the GNU C library. - * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. - */ -typedef gint (*GTmpFileCallback) (gchar *, gint, gint); - -static gint -get_tmp_file (gchar *tmpl, - GTmpFileCallback f, - int flags, - int mode) -{ - char *XXXXXX; - int count, fd; - static const char letters[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static const int NLETTERS = sizeof (letters) - 1; - glong value; - GTimeVal tv; - static int counter = 0; - - g_return_val_if_fail (tmpl != NULL, -1); - - /* find the last occurrence of "XXXXXX" */ - XXXXXX = g_strrstr (tmpl, "XXXXXX"); - - if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6)) - { - errno = EINVAL; - return -1; - } - - /* Get some more or less random data. */ - g_get_current_time (&tv); - value = (tv.tv_usec ^ tv.tv_sec) + counter++; - - for (count = 0; count < 100; value += 7777, ++count) - { - glong v = value; - - /* Fill in the random bits. */ - XXXXXX[0] = letters[v % NLETTERS]; - v /= NLETTERS; - XXXXXX[1] = letters[v % NLETTERS]; - v /= NLETTERS; - XXXXXX[2] = letters[v % NLETTERS]; - v /= NLETTERS; - XXXXXX[3] = letters[v % NLETTERS]; - v /= NLETTERS; - XXXXXX[4] = letters[v % NLETTERS]; - v /= NLETTERS; - XXXXXX[5] = letters[v % NLETTERS]; - - fd = f (tmpl, flags, mode); - - if (fd >= 0) - return fd; - else if (errno != EEXIST) - /* Any other error will apply also to other names we might - * try, and there are 2^32 or so of them, so give up now. - */ - return -1; - } - - /* We got out of the loop because we ran out of combinations to try. */ - errno = EEXIST; - return -1; -} - -gint -wrap_mkdir (gchar *tmpl, - int flags G_GNUC_UNUSED, - int mode) -{ - /* tmpl is in UTF-8 on Windows, thus use g_mkdir() */ - return g_mkdir (tmpl, mode); -} - -/** - * g_mkdtemp_full: - * @tmpl: (type filename): template directory name - * @mode: permissions to create the temporary directory with - * - * Creates a temporary directory. See the mkdtemp() documentation - * on most UNIX-like systems. - * - * The parameter is a string that should follow the rules for - * mkdtemp() templates, i.e. contain the string "XXXXXX". - * g_mkdtemp() is slightly more flexible than mkdtemp() in that the - * sequence does not have to occur at the very end of the template - * and you can pass a @mode. The X string will be modified to form - * the name of a directory that didn't exist. The string should be - * in the GLib file name encoding. Most importantly, on Windows it - * should be in UTF-8. - * - * Return value: A pointer to @tmpl, which has been modified - * to hold the directory name. In case of errors, %NULL is - * returned, and %errno will be set. - * - * Since: 2.26 - */ -gchar * -g_mkdtemp_full (gchar *tmpl, - gint mode) -{ - if (get_tmp_file (tmpl, wrap_mkdir, 0, mode) == -1) - return NULL; - else - return tmpl; -} - -/** - * g_mkdtemp: - * @tmpl: (type filename): template directory name - * - * Creates a temporary directory. See the mkdtemp() documentation - * on most UNIX-like systems. - * - * The parameter is a string that should follow the rules for - * mkdtemp() templates, i.e. contain the string "XXXXXX". - * g_mkdtemp() is slightly more flexible than mkdtemp() in that the - * sequence does not have to occur at the very end of the template - * and you can pass a @mode and additional @flags. The X string will - * be modified to form the name of a directory that didn't exist. - * The string should be in the GLib file name encoding. Most importantly, - * on Windows it should be in UTF-8. - * - * Return value: A pointer to @tmpl, which has been modified - * to hold the directory name. In case of errors, %NULL is - * returned and %errno will be set. - * - * Since: 2.26 - */ -gchar * -g_mkdtemp (gchar *tmpl) -{ - return g_mkdtemp_full (tmpl, 0700); -} - -/** - * g_mkstemp_full: - * @tmpl: (type filename): template filename - * @flags: flags to pass to an open() call in addition to O_EXCL - * and O_CREAT, which are passed automatically - * @mode: permissions to create the temporary file with - * - * Opens a temporary file. See the mkstemp() documentation - * on most UNIX-like systems. - * - * The parameter is a string that should follow the rules for - * mkstemp() templates, i.e. contain the string "XXXXXX". - * g_mkstemp_full() is slightly more flexible than mkstemp() - * in that the sequence does not have to occur at the very end of the - * template and you can pass a @mode and additional @flags. The X - * string will be modified to form the name of a file that didn't exist. - * The string should be in the GLib file name encoding. Most importantly, - * on Windows it should be in UTF-8. - * - * Return value: A file handle (as from open()) to the file - * opened for reading and writing. The file handle should be - * closed with close(). In case of errors, -1 is returned - * and %errno will be set. - * - * Since: 2.22 - */ -gint -g_mkstemp_full (gchar *tmpl, - gint flags, - gint mode) -{ - /* tmpl is in UTF-8 on Windows, thus use g_open() */ - return get_tmp_file (tmpl, (GTmpFileCallback) g_open, - flags | O_CREAT | O_EXCL, mode); -} - -/** - * g_mkstemp: - * @tmpl: (type filename): template filename - * - * Opens a temporary file. See the mkstemp() documentation - * on most UNIX-like systems. - * - * The parameter is a string that should follow the rules for - * mkstemp() templates, i.e. contain the string "XXXXXX". - * g_mkstemp() is slightly more flexible than mkstemp() in that the - * sequence does not have to occur at the very end of the template. - * The X string will be modified to form the name of a file that - * didn't exist. The string should be in the GLib file name encoding. - * Most importantly, on Windows it should be in UTF-8. - * - * Return value: A file handle (as from open()) to the file - * opened for reading and writing. The file is opened in binary - * mode on platforms where there is a difference. The file handle - * should be closed with close(). In case of errors, -1 is - * returned and %errno will be set. - */ -gint -g_mkstemp (gchar *tmpl) -{ - return g_mkstemp_full (tmpl, O_RDWR | O_BINARY, 0600); -} - -static gint -g_get_tmp_name (const gchar *tmpl, - gchar **name_used, - GTmpFileCallback f, - gint flags, - gint mode, - GError **error) -{ - int retval; - const char *tmpdir; - const char *sep; - char *fulltemplate; - const char *slash; - - if (tmpl == NULL) - tmpl = ".XXXXXX"; - - if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL -#ifdef G_OS_WIN32 - || (strchr (tmpl, '/') != NULL && (slash = "/")) -#endif - ) - { - gchar *display_tmpl = g_filename_display_name (tmpl); - char c[2]; - c[0] = *slash; - c[1] = '\0'; - - g_set_error (error, - G_FILE_ERROR, - G_FILE_ERROR_FAILED, - _("Template '%s' invalid, should not contain a '%s'"), - display_tmpl, c); - g_free (display_tmpl); - - return -1; - } - - if (strstr (tmpl, "XXXXXX") == NULL) - { - gchar *display_tmpl = g_filename_display_name (tmpl); - g_set_error (error, - G_FILE_ERROR, - G_FILE_ERROR_FAILED, - _("Template '%s' doesn't contain XXXXXX"), - display_tmpl); - g_free (display_tmpl); - return -1; - } - - tmpdir = g_get_tmp_dir (); - - if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1])) - sep = ""; - else - sep = G_DIR_SEPARATOR_S; - - fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL); - - retval = get_tmp_file (fulltemplate, f, flags, mode); - if (retval == -1) - { - int save_errno = errno; - gchar *display_fulltemplate = g_filename_display_name (fulltemplate); - - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to create file '%s': %s"), - display_fulltemplate, g_strerror (save_errno)); - g_free (display_fulltemplate); - g_free (fulltemplate); - return -1; - } - - *name_used = fulltemplate; - - return retval; -} - -/** - * g_file_open_tmp: - * @tmpl: (type filename) (allow-none): Template for file name, as in - * g_mkstemp(), basename only, or %NULL for a default template - * @name_used: (out) (type filename): location to store actual name used, - * or %NULL - * @error: return location for a #GError - * - * Opens a file for writing in the preferred directory for temporary - * files (as returned by g_get_tmp_dir()). - * - * @tmpl should be a string in the GLib file name encoding containing - * a sequence of six 'X' characters, as the parameter to g_mkstemp(). - * However, unlike these functions, the template should only be a - * basename, no directory components are allowed. If template is - * %NULL, a default template is used. - * - * Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not - * modified, and might thus be a read-only literal string. - * - * Upon success, and if @name_used is non-%NULL, the actual name used - * is returned in @name_used. This string should be freed with g_free() - * when not needed any longer. The returned name is in the GLib file - * name encoding. - * - * Return value: A file handle (as from open()) to the file opened for - * reading and writing. The file is opened in binary mode on platforms - * where there is a difference. The file handle should be closed with - * close(). In case of errors, -1 is returned and @error will be set. - */ -gint -g_file_open_tmp (const gchar *tmpl, - gchar **name_used, - GError **error) -{ - gchar *fulltemplate; - gint result; - - result = g_get_tmp_name (tmpl, &fulltemplate, - (GTmpFileCallback) g_open, - O_CREAT | O_EXCL | O_RDWR | O_BINARY, - 0600, - error); - if (result != -1) - { - if (name_used) - *name_used = fulltemplate; - else - g_free (fulltemplate); - } - - return result; -} - -/** - * g_dir_make_tmp: - * @tmpl: (type filename) (allow-none): Template for directory name, - * as in g_mkdtemp(), basename only, or %NULL for a default template - * @error: return location for a #GError - * - * Creates a subdirectory in the preferred directory for temporary - * files (as returned by g_get_tmp_dir()). - * - * @tmpl should be a string in the GLib file name encoding containing - * a sequence of six 'X' characters, as the parameter to g_mkstemp(). - * However, unlike these functions, the template should only be a - * basename, no directory components are allowed. If template is - * %NULL, a default template is used. - * - * Note that in contrast to g_mkdtemp() (and mkdtemp()) @tmpl is not - * modified, and might thus be a read-only literal string. - * - * Return value: (type filename): The actual name used. This string - * should be freed with g_free() when not needed any longer and is - * is in the GLib file name encoding. In case of errors, %NULL is - * returned and @error will be set. - * - * Since: 2.30 - */ -gchar * -g_dir_make_tmp (const gchar *tmpl, - GError **error) -{ - gchar *fulltemplate; - - if (g_get_tmp_name (tmpl, &fulltemplate, wrap_mkdir, 0, 0700, error) == -1) - return NULL; - else - return fulltemplate; -} - -static gchar * -g_build_path_va (const gchar *separator, - const gchar *first_element, - va_list *args, - gchar **str_array) -{ - GString *result; - gint separator_len = strlen (separator); - gboolean is_first = TRUE; - gboolean have_leading = FALSE; - const gchar *single_element = NULL; - const gchar *next_element; - const gchar *last_trailing = NULL; - gint i = 0; - - result = g_string_new (NULL); - - if (str_array) - next_element = str_array[i++]; - else - next_element = first_element; - - while (TRUE) - { - const gchar *element; - const gchar *start; - const gchar *end; - - if (next_element) - { - element = next_element; - if (str_array) - next_element = str_array[i++]; - else - next_element = va_arg (*args, gchar *); - } - else - break; - - /* Ignore empty elements */ - if (!*element) - continue; - - start = element; - - if (separator_len) - { - while (strncmp (start, separator, separator_len) == 0) - start += separator_len; - } - - end = start + strlen (start); - - if (separator_len) - { - while (end >= start + separator_len && - strncmp (end - separator_len, separator, separator_len) == 0) - end -= separator_len; - - last_trailing = end; - while (last_trailing >= element + separator_len && - strncmp (last_trailing - separator_len, separator, separator_len) == 0) - last_trailing -= separator_len; - - if (!have_leading) - { - /* If the leading and trailing separator strings are in the - * same element and overlap, the result is exactly that element - */ - if (last_trailing <= start) - single_element = element; - - g_string_append_len (result, element, start - element); - have_leading = TRUE; - } - else - single_element = NULL; - } - - if (end == start) - continue; - - if (!is_first) - g_string_append (result, separator); - - g_string_append_len (result, start, end - start); - is_first = FALSE; - } - - if (single_element) - { - g_string_free (result, TRUE); - return g_strdup (single_element); - } - else - { - if (last_trailing) - g_string_append (result, last_trailing); - - return g_string_free (result, FALSE); - } -} - -/** - * g_build_pathv: - * @separator: a string used to separator the elements of the path. - * @args: (array zero-terminated=1): %NULL-terminated array of strings containing the path elements. - * - * Behaves exactly like g_build_path(), but takes the path elements - * as a string array, instead of varargs. This function is mainly - * meant for language bindings. - * - * Return value: a newly-allocated string that must be freed with g_free(). - * - * Since: 2.8 - */ -gchar * -g_build_pathv (const gchar *separator, - gchar **args) -{ - if (!args) - return NULL; - - return g_build_path_va (separator, NULL, NULL, args); -} - - -/** - * g_build_path: - * @separator: a string used to separator the elements of the path. - * @first_element: the first element in the path - * @...: remaining elements in path, terminated by %NULL - * - * Creates a path from a series of elements using @separator as the - * separator between elements. At the boundary between two elements, - * any trailing occurrences of separator in the first element, or - * leading occurrences of separator in the second element are removed - * and exactly one copy of the separator is inserted. - * - * Empty elements are ignored. - * - * The number of leading copies of the separator on the result is - * the same as the number of leading copies of the separator on - * the first non-empty element. - * - * The number of trailing copies of the separator on the result is - * the same as the number of trailing copies of the separator on - * the last non-empty element. (Determination of the number of - * trailing copies is done without stripping leading copies, so - * if the separator is <literal>ABA</literal>, <literal>ABABA</literal> - * has 1 trailing copy.) - * - * However, if there is only a single non-empty element, and there - * are no characters in that element not part of the leading or - * trailing separators, then the result is exactly the original value - * of that element. - * - * Other than for determination of the number of leading and trailing - * copies of the separator, elements consisting only of copies - * of the separator are ignored. - * - * Return value: a newly-allocated string that must be freed with g_free(). - **/ -gchar * -g_build_path (const gchar *separator, - const gchar *first_element, - ...) -{ - gchar *str; - va_list args; - - g_return_val_if_fail (separator != NULL, NULL); - - va_start (args, first_element); - str = g_build_path_va (separator, first_element, &args, NULL); - va_end (args); - - return str; -} - -#ifdef G_OS_WIN32 - -static gchar * -g_build_pathname_va (const gchar *first_element, - va_list *args, - gchar **str_array) -{ - /* Code copied from g_build_pathv(), and modified to use two - * alternative single-character separators. - */ - GString *result; - gboolean is_first = TRUE; - gboolean have_leading = FALSE; - const gchar *single_element = NULL; - const gchar *next_element; - const gchar *last_trailing = NULL; - gchar current_separator = '\\'; - gint i = 0; - - result = g_string_new (NULL); - - if (str_array) - next_element = str_array[i++]; - else - next_element = first_element; - - while (TRUE) - { - const gchar *element; - const gchar *start; - const gchar *end; - - if (next_element) - { - element = next_element; - if (str_array) - next_element = str_array[i++]; - else - next_element = va_arg (*args, gchar *); - } - else - break; - - /* Ignore empty elements */ - if (!*element) - continue; - - start = element; - - if (TRUE) - { - while (start && - (*start == '\\' || *start == '/')) - { - current_separator = *start; - start++; - } - } - - end = start + strlen (start); - - if (TRUE) - { - while (end >= start + 1 && - (end[-1] == '\\' || end[-1] == '/')) - { - current_separator = end[-1]; - end--; - } - - last_trailing = end; - while (last_trailing >= element + 1 && - (last_trailing[-1] == '\\' || last_trailing[-1] == '/')) - last_trailing--; - - if (!have_leading) - { - /* If the leading and trailing separator strings are in the - * same element and overlap, the result is exactly that element - */ - if (last_trailing <= start) - single_element = element; - - g_string_append_len (result, element, start - element); - have_leading = TRUE; - } - else - single_element = NULL; - } - - if (end == start) - continue; - - if (!is_first) - g_string_append_len (result, ¤t_separator, 1); - - g_string_append_len (result, start, end - start); - is_first = FALSE; - } - - if (single_element) - { - g_string_free (result, TRUE); - return g_strdup (single_element); - } - else - { - if (last_trailing) - g_string_append (result, last_trailing); - - return g_string_free (result, FALSE); - } -} - -#endif - -/** - * g_build_filenamev: - * @args: (array zero-terminated=1): %NULL-terminated array of strings containing the path elements. - * - * Behaves exactly like g_build_filename(), but takes the path elements - * as a string array, instead of varargs. This function is mainly - * meant for language bindings. - * - * Return value: a newly-allocated string that must be freed with g_free(). - * - * Since: 2.8 - */ -gchar * -g_build_filenamev (gchar **args) -{ - gchar *str; - -#ifndef G_OS_WIN32 - str = g_build_path_va (G_DIR_SEPARATOR_S, NULL, NULL, args); -#else - str = g_build_pathname_va (NULL, NULL, args); -#endif - - return str; -} - -/** - * g_build_filename: - * @first_element: the first element in the path - * @...: remaining elements in path, terminated by %NULL - * - * Creates a filename from a series of elements using the correct - * separator for filenames. - * - * On Unix, this function behaves identically to <literal>g_build_path - * (G_DIR_SEPARATOR_S, first_element, ....)</literal>. - * - * On Windows, it takes into account that either the backslash - * (<literal>\</literal> or slash (<literal>/</literal>) can be used - * as separator in filenames, but otherwise behaves as on Unix. When - * file pathname separators need to be inserted, the one that last - * previously occurred in the parameters (reading from left to right) - * is used. - * - * No attempt is made to force the resulting filename to be an absolute - * path. If the first element is a relative path, the result will - * be a relative path. - * - * Return value: a newly-allocated string that must be freed with g_free(). - **/ -gchar * -g_build_filename (const gchar *first_element, - ...) -{ - gchar *str; - va_list args; - - va_start (args, first_element); -#ifndef G_OS_WIN32 - str = g_build_path_va (G_DIR_SEPARATOR_S, first_element, &args, NULL); -#else - str = g_build_pathname_va (first_element, &args, NULL); -#endif - va_end (args); - - return str; -} - -#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000)) -#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR) -#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR) -#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR) -#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR) -#define EXABYTE_FACTOR (PETABYTE_FACTOR * KILOBYTE_FACTOR) - -#define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024)) -#define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR) -#define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR) -#define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR) -#define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR) -#define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR) - -/** - * g_format_size: - * @size: a size in bytes - * - * Formats a size (for example the size of a file) into a human readable - * string. Sizes are rounded to the nearest size prefix (kB, MB, GB) - * and are displayed rounded to the nearest tenth. E.g. the file size - * 3292528 bytes will be converted into the string "3.2 MB". - * - * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes). - * - * This string should be freed with g_free() when not needed any longer. - * - * See g_format_size_full() for more options about how the size might be - * formatted. - * - * Returns: a newly-allocated formatted string containing a human readable - * file size. - * - * Since: 2.30 - **/ -gchar * -g_format_size (guint64 size) -{ - return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT); -} - -/** - * g_format_size_full: - * @size: a size in bytes - * @flags: #GFormatSizeFlags to modify the output - * - * Formats a size. - * - * This function is similar to g_format_size() but allows for flags that - * modify the output. See #GFormatSizeFlags. - * - * Returns: a newly-allocated formatted string containing a human - * readable file size. - * - * Since: 2.30 - **/ -/** - * GFormatSizeFlags: - * @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size() - * @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part - * of the returned string. For example, - * "45.6 kB (45,612 bytes)". - * @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style - * suffixes. IEC units should only be used - * for reporting things with a strong "power - * of 2" basis, like RAM sizes or RAID stripe - * sizes. Network and storage sizes should - * be reported in the normal SI units. - * - * Flags to modify the format of the string returned by - * g_format_size_full(). - **/ -gchar * -g_format_size_full (guint64 size, - GFormatSizeFlags flags) -{ - GString *string; - - string = g_string_new (NULL); - - if (flags & G_FORMAT_SIZE_IEC_UNITS) - { - if (size < KIBIBYTE_FACTOR) - { - g_string_printf (string, - g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size), - (guint) size); - flags &= ~G_FORMAT_SIZE_LONG_FORMAT; - } - - else if (size < MEBIBYTE_FACTOR) - g_string_printf (string, _("%.1f KiB"), (gdouble) size / (gdouble) KIBIBYTE_FACTOR); - - else if (size < GIBIBYTE_FACTOR) - g_string_printf (string, _("%.1f MiB"), (gdouble) size / (gdouble) MEBIBYTE_FACTOR); - - else if (size < TEBIBYTE_FACTOR) - g_string_printf (string, _("%.1f GiB"), (gdouble) size / (gdouble) GIBIBYTE_FACTOR); - - else if (size < PEBIBYTE_FACTOR) - g_string_printf (string, _("%.1f TiB"), (gdouble) size / (gdouble) TEBIBYTE_FACTOR); - - else if (size < EXBIBYTE_FACTOR) - g_string_printf (string, _("%.1f PiB"), (gdouble) size / (gdouble) PEBIBYTE_FACTOR); - - else - g_string_printf (string, _("%.1f EiB"), (gdouble) size / (gdouble) EXBIBYTE_FACTOR); - } - else - { - if (size < KILOBYTE_FACTOR) - { - g_string_printf (string, - g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size), - (guint) size); - flags &= ~G_FORMAT_SIZE_LONG_FORMAT; - } - - else if (size < MEGABYTE_FACTOR) - g_string_printf (string, _("%.1f kB"), (gdouble) size / (gdouble) KILOBYTE_FACTOR); - - else if (size < GIGABYTE_FACTOR) - g_string_printf (string, _("%.1f MB"), (gdouble) size / (gdouble) MEGABYTE_FACTOR); - - else if (size < TERABYTE_FACTOR) - g_string_printf (string, _("%.1f GB"), (gdouble) size / (gdouble) GIGABYTE_FACTOR); - - else if (size < PETABYTE_FACTOR) - g_string_printf (string, _("%.1f TB"), (gdouble) size / (gdouble) TERABYTE_FACTOR); - - else if (size < EXABYTE_FACTOR) - g_string_printf (string, _("%.1f PB"), (gdouble) size / (gdouble) PETABYTE_FACTOR); - - else - g_string_printf (string, _("%.1f EB"), (gdouble) size / (gdouble) EXABYTE_FACTOR); - } - - if (flags & G_FORMAT_SIZE_LONG_FORMAT) - { - /* First problem: we need to use the number of bytes to decide on - * the plural form that is used for display, but the number of - * bytes potentially exceeds the size of a guint (which is what - * ngettext() takes). - * - * From a pragmatic standpoint, it seems that all known languages - * base plural forms on one or both of the following: - * - * - the lowest digits of the number - * - * - if the number if greater than some small value - * - * Here's how we fake it: Draw an arbitrary line at one thousand. - * If the number is below that, then fine. If it is above it, - * then we take the modulus of the number by one thousand (in - * order to keep the lowest digits) and add one thousand to that - * (in order to ensure that 1001 is not treated the same as 1). - */ - guint plural_form = size < 1000 ? size : size % 1000 + 1000; - - /* Second problem: we need to translate the string "%u byte" and - * "%u bytes" for pluralisation, but the correct number format to - * use for a gsize is different depending on which architecture - * we're on. - * - * Solution: format the number separately and use "%s bytes" on - * all platforms. - */ - const gchar *translated_format; - gchar *formatted_number; - - /* Translators: the %s in "%s bytes" will always be replaced by a number. */ - translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form); - - /* XXX: Windows doesn't support the "'" format modifier, so we - * must not use it there. Instead, just display the number - * without separation. Bug #655336 is open until a solution is - * found. - */ -#ifndef G_OS_WIN32 - formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size); -#else - formatted_number = g_strdup_printf ("%"G_GUINT64_FORMAT, size); -#endif - - g_string_append (string, " ("); - g_string_append_printf (string, translated_format, formatted_number); - g_free (formatted_number); - g_string_append (string, ")"); - } - - return g_string_free (string, FALSE); -} - -/** - * g_format_size_for_display: - * @size: a size in bytes. - * - * Formats a size (for example the size of a file) into a human readable string. - * Sizes are rounded to the nearest size prefix (KB, MB, GB) and are displayed - * rounded to the nearest tenth. E.g. the file size 3292528 bytes will be - * converted into the string "3.1 MB". - * - * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes). - * - * This string should be freed with g_free() when not needed any longer. - * - * Returns: a newly-allocated formatted string containing a human readable - * file size. - * - * Deprecated:2.30: This function is broken due to its use of SI - * suffixes to denote IEC units. Use g_format_size() - * instead. - * Since: 2.16 - **/ -char * -g_format_size_for_display (goffset size) -{ - if (size < (goffset) KIBIBYTE_FACTOR) - return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size); - else - { - gdouble displayed_size; - - if (size < (goffset) MEBIBYTE_FACTOR) - { - displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR; - return g_strdup_printf (_("%.1f KB"), displayed_size); - } - else if (size < (goffset) GIBIBYTE_FACTOR) - { - displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR; - return g_strdup_printf (_("%.1f MB"), displayed_size); - } - else if (size < (goffset) TEBIBYTE_FACTOR) - { - displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR; - return g_strdup_printf (_("%.1f GB"), displayed_size); - } - else if (size < (goffset) PEBIBYTE_FACTOR) - { - displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR; - return g_strdup_printf (_("%.1f TB"), displayed_size); - } - else if (size < (goffset) EXBIBYTE_FACTOR) - { - displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR; - return g_strdup_printf (_("%.1f PB"), displayed_size); - } - else - { - displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR; - return g_strdup_printf (_("%.1f EB"), displayed_size); - } - } -} - - -/** - * g_file_read_link: - * @filename: the symbolic link - * @error: return location for a #GError - * - * Reads the contents of the symbolic link @filename like the POSIX - * readlink() function. The returned string is in the encoding used - * for filenames. Use g_filename_to_utf8() to convert it to UTF-8. - * - * Returns: A newly-allocated string with the contents of the symbolic link, - * or %NULL if an error occurred. - * - * Since: 2.4 - */ -gchar * -g_file_read_link (const gchar *filename, - GError **error) -{ -#ifdef HAVE_READLINK - gchar *buffer; - guint size; - gint read_size; - - size = 256; - buffer = g_malloc (size); - - while (TRUE) - { - read_size = readlink (filename, buffer, size); - if (read_size < 0) { - int save_errno = errno; - gchar *display_filename = g_filename_display_name (filename); - - g_free (buffer); - g_set_error (error, - G_FILE_ERROR, - g_file_error_from_errno (save_errno), - _("Failed to read the symbolic link '%s': %s"), - display_filename, - g_strerror (save_errno)); - g_free (display_filename); - - return NULL; - } - - if (read_size < size) - { - buffer[read_size] = 0; - return buffer; - } - - size *= 2; - buffer = g_realloc (buffer, size); - } -#else - g_set_error_literal (error, - G_FILE_ERROR, - G_FILE_ERROR_INVAL, - _("Symbolic links not supported")); - - return NULL; -#endif -} - -/* NOTE : Keep this part last to ensure nothing in this file uses the - * below binary compatibility versions. - */ -#if defined (G_OS_WIN32) && !defined (_WIN64) - -/* Binary compatibility versions. Will be called by code compiled - * against quite old (pre-2.8, I think) headers only, not from more - * recently compiled code. - */ - -#undef g_file_test - -gboolean -g_file_test (const gchar *filename, - GFileTest test) -{ - gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL); - gboolean retval; - - if (utf8_filename == NULL) - return FALSE; - - retval = g_file_test_utf8 (utf8_filename, test); - - g_free (utf8_filename); - - return retval; -} - -#undef g_file_get_contents - -gboolean -g_file_get_contents (const gchar *filename, - gchar **contents, - gsize *length, - GError **error) -{ - gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error); - gboolean retval; - - if (utf8_filename == NULL) - return FALSE; - - retval = g_file_get_contents_utf8 (utf8_filename, contents, length, error); - - g_free (utf8_filename); - - return retval; -} - -#undef g_mkstemp - -gint -g_mkstemp (gchar *tmpl) -{ - /* This is the backward compatibility system codepage version, - * thus use normal open(). - */ - return get_tmp_file (tmpl, (GTmpFileCallback) open, - O_RDWR | O_CREAT | O_EXCL, 0600); -} - -#undef g_file_open_tmp - -gint -g_file_open_tmp (const gchar *tmpl, - gchar **name_used, - GError **error) -{ - gchar *utf8_tmpl = g_locale_to_utf8 (tmpl, -1, NULL, NULL, error); - gchar *utf8_name_used; - gint retval; - - if (utf8_tmpl == NULL) - return -1; - - retval = g_file_open_tmp_utf8 (utf8_tmpl, &utf8_name_used, error); - - if (retval == -1) - return -1; - - if (name_used) - *name_used = g_locale_from_utf8 (utf8_name_used, -1, NULL, NULL, NULL); - - g_free (utf8_name_used); - - return retval; -} - -#endif diff --git a/deps/glib/gfileutils.h b/deps/glib/gfileutils.h deleted file mode 100644 index 870100bf..00000000 --- a/deps/glib/gfileutils.h +++ /dev/null @@ -1,149 +0,0 @@ -/* gfileutils.h - File utility functions - * - * Copyright 2000 Red Hat, Inc. - * - * GLib is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * GLib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with GLib; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_FILEUTILS_H__ -#define __G_FILEUTILS_H__ - -#include <glib/gerror.h> - -G_BEGIN_DECLS - -#define G_FILE_ERROR g_file_error_quark () - -typedef enum -{ - G_FILE_ERROR_EXIST, - G_FILE_ERROR_ISDIR, - G_FILE_ERROR_ACCES, - G_FILE_ERROR_NAMETOOLONG, - G_FILE_ERROR_NOENT, - G_FILE_ERROR_NOTDIR, - G_FILE_ERROR_NXIO, - G_FILE_ERROR_NODEV, - G_FILE_ERROR_ROFS, - G_FILE_ERROR_TXTBSY, - G_FILE_ERROR_FAULT, - G_FILE_ERROR_LOOP, - G_FILE_ERROR_NOSPC, - G_FILE_ERROR_NOMEM, - G_FILE_ERROR_MFILE, - G_FILE_ERROR_NFILE, - G_FILE_ERROR_BADF, - G_FILE_ERROR_INVAL, - G_FILE_ERROR_PIPE, - G_FILE_ERROR_AGAIN, - G_FILE_ERROR_INTR, - G_FILE_ERROR_IO, - G_FILE_ERROR_PERM, - G_FILE_ERROR_NOSYS, - G_FILE_ERROR_FAILED -} GFileError; - -/* For backward-compat reasons, these are synced to an old - * anonymous enum in libgnome. But don't use that enum - * in new code. - */ -typedef enum -{ - G_FILE_TEST_IS_REGULAR = 1 << 0, - G_FILE_TEST_IS_SYMLINK = 1 << 1, - G_FILE_TEST_IS_DIR = 1 << 2, - G_FILE_TEST_IS_EXECUTABLE = 1 << 3, - G_FILE_TEST_EXISTS = 1 << 4 -} GFileTest; - -GQuark g_file_error_quark (void); -/* So other code can generate a GFileError */ -GFileError g_file_error_from_errno (gint err_no); - -#ifndef __GTK_DOC_IGNORE__ -#ifdef G_OS_WIN32 -#define g_file_test g_file_test_utf8 -#define g_file_get_contents g_file_get_contents_utf8 -#define g_mkstemp g_mkstemp_utf8 -#define g_file_open_tmp g_file_open_tmp_utf8 -#endif -#endif - -gboolean g_file_test (const gchar *filename, - GFileTest test); -gboolean g_file_get_contents (const gchar *filename, - gchar **contents, - gsize *length, - GError **error); -gboolean g_file_set_contents (const gchar *filename, - const gchar *contents, - gssize length, - GError **error); -gchar *g_file_read_link (const gchar *filename, - GError **error); - -/* Wrapper / workalike for mkdtemp() */ -gchar *g_mkdtemp (gchar *tmpl); -gchar *g_mkdtemp_full (gchar *tmpl, - gint mode); - -/* Wrapper / workalike for mkstemp() */ -gint g_mkstemp (gchar *tmpl); -gint g_mkstemp_full (gchar *tmpl, - gint flags, - gint mode); - -/* Wrappers for g_mkstemp and g_mkdtemp() */ -gint g_file_open_tmp (const gchar *tmpl, - gchar **name_used, - GError **error); -gchar *g_dir_make_tmp (const gchar *tmpl, - GError **error); - -typedef enum -{ - G_FORMAT_SIZE_DEFAULT = 0, - G_FORMAT_SIZE_LONG_FORMAT = 1 << 0, - G_FORMAT_SIZE_IEC_UNITS = 1 << 1 -} GFormatSizeFlags; - -gchar * g_format_size_full (guint64 size, - GFormatSizeFlags flags); -gchar * g_format_size (guint64 size); - -#ifndef G_DISABLE_DEPRECATED -char *g_format_size_for_display (goffset size); -#endif - -gchar *g_build_path (const gchar *separator, - const gchar *first_element, - ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; -gchar *g_build_pathv (const gchar *separator, - gchar **args) G_GNUC_MALLOC; - -gchar *g_build_filename (const gchar *first_element, - ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; -gchar *g_build_filenamev (gchar **args) G_GNUC_MALLOC; - -int g_mkdir_with_parents (const gchar *pathname, - int mode); - -G_END_DECLS - -#endif /* __G_FILEUTILS_H__ */ diff --git a/deps/glib/ghash.c b/deps/glib/ghash.c deleted file mode 100644 index 14ae487c..00000000 --- a/deps/glib/ghash.c +++ /dev/null @@ -1,1573 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include <string.h> /* memset */ - -#include "ghash.h" - -#include "gstrfuncs.h" -#include "gatomic.h" -#include "gtestutils.h" - - -/** - * SECTION:hash_tables - * @title: Hash Tables - * @short_description: associations between keys and values so that - * given a key the value can be found quickly - * - * A #GHashTable provides associations between keys and values which is - * optimized so that given a key, the associated value can be found - * very quickly. - * - * Note that neither keys nor values are copied when inserted into the - * #GHashTable, so they must exist for the lifetime of the #GHashTable. - * This means that the use of static strings is OK, but temporary - * strings (i.e. those created in buffers and those returned by GTK+ - * widgets) should be copied with g_strdup() before being inserted. - * - * If keys or values are dynamically allocated, you must be careful to - * ensure that they are freed when they are removed from the - * #GHashTable, and also when they are overwritten by new insertions - * into the #GHashTable. It is also not advisable to mix static strings - * and dynamically-allocated strings in a #GHashTable, because it then - * becomes difficult to determine whether the string should be freed. - * - * To create a #GHashTable, use g_hash_table_new(). - * - * To insert a key and value into a #GHashTable, use - * g_hash_table_insert(). - * - * To lookup a value corresponding to a given key, use - * g_hash_table_lookup() and g_hash_table_lookup_extended(). - * - * g_hash_table_lookup_extended() can also be used to simply - * check if a key is present in the hash table. - * - * To remove a key and value, use g_hash_table_remove(). - * - * To call a function for each key and value pair use - * g_hash_table_foreach() or use a iterator to iterate over the - * key/value pairs in the hash table, see #GHashTableIter. - * - * To destroy a #GHashTable use g_hash_table_destroy(). - * - * <example> - * <title>Using a GHashTable as a set</title> - * <para> - * A common use-case for hash tables is to store information about - * a set of keys, without associating any particular value with each - * key. GHashTable optimizes one way of doing so: If you store only - * key-value pairs where key == value, then GHashTable does not - * allocate memory to store the values, which can be a considerable - * space saving, if your set is large. - * </para> - * <programlisting> - * GHashTable * - * set_new (GHashFunc hash_func, - * GEqualFunc equal_func, - * GDestroyNotify destroy) - * { - * return g_hash_table_new_full (hash_func, equal_func, destroy, NULL); - * } - * - * void - * set_insert (GHashTable *set, - * gpointer element) - * { - * g_hash_table_insert (set, element, element); - * } - * - * gboolean - * set_contains (GHashTable *set, - * gpointer element) - * { - * return g_hash_table_lookup_extended (set, element, NULL, NULL); - * } - * - * gboolean - * set_remove (GHashTable *set, - * gpointer element) - * { - * return g_hash_table_remove (set, element); - * } - * </programlisting> - * </example> - */ - -/** - * GHashTable: - * - * The #GHashTable struct is an opaque data structure to represent a - * <link linkend="glib-Hash-Tables">Hash Table</link>. It should only be - * accessed via the following functions. - **/ - -/** - * GHashFunc: - * @key: a key. - * @Returns: the hash value corresponding to the key. - * - * Specifies the type of the hash function which is passed to - * g_hash_table_new() when a #GHashTable is created. - * - * The function is passed a key and should return a #guint hash value. - * The functions g_direct_hash(), g_int_hash() and g_str_hash() provide - * hash functions which can be used when the key is a #gpointer, #gint, - * and #gchar* respectively. - * - * <!-- FIXME: Need more here. --> The hash values should be evenly - * distributed over a fairly large range? The modulus is taken with the - * hash table size (a prime number) to find the 'bucket' to place each - * key into. The function should also be very fast, since it is called - * for each key lookup. - **/ - -/** - * GHFunc: - * @key: a key. - * @value: the value corresponding to the key. - * @user_data: user data passed to g_hash_table_foreach(). - * - * Specifies the type of the function passed to g_hash_table_foreach(). - * It is called with each key/value pair, together with the @user_data - * parameter which is passed to g_hash_table_foreach(). - **/ - -/** - * GHRFunc: - * @key: a key. - * @value: the value associated with the key. - * @user_data: user data passed to g_hash_table_remove(). - * @Returns: %TRUE if the key/value pair should be removed from the - * #GHashTable. - * - * Specifies the type of the function passed to - * g_hash_table_foreach_remove(). It is called with each key/value - * pair, together with the @user_data parameter passed to - * g_hash_table_foreach_remove(). It should return %TRUE if the - * key/value pair should be removed from the #GHashTable. - **/ - -/** - * GEqualFunc: - * @a: a value. - * @b: a value to compare with. - * @Returns: %TRUE if @a = @b; %FALSE otherwise. - * - * Specifies the type of a function used to test two values for - * equality. The function should return %TRUE if both values are equal - * and %FALSE otherwise. - **/ - -/** - * GHashTableIter: - * - * A GHashTableIter structure represents an iterator that can be used - * to iterate over the elements of a #GHashTable. GHashTableIter - * structures are typically allocated on the stack and then initialized - * with g_hash_table_iter_init(). - **/ - -#define HASH_TABLE_MIN_SHIFT 3 /* 1 << 3 == 8 buckets */ - -#define UNUSED_HASH_VALUE 0 -#define TOMBSTONE_HASH_VALUE 1 -#define HASH_IS_UNUSED(h_) ((h_) == UNUSED_HASH_VALUE) -#define HASH_IS_TOMBSTONE(h_) ((h_) == TOMBSTONE_HASH_VALUE) -#define HASH_IS_REAL(h_) ((h_) >= 2) - -struct _GHashTable -{ - gint size; - gint mod; - guint mask; - gint nnodes; - gint noccupied; /* nnodes + tombstones */ - - gpointer *keys; - guint *hashes; - gpointer *values; - - GHashFunc hash_func; - GEqualFunc key_equal_func; - gint ref_count; -#ifndef G_DISABLE_ASSERT - /* - * Tracks the structure of the hash table, not its contents: is only - * incremented when a node is added or removed (is not incremented - * when the key or data of a node is modified). - */ - int version; -#endif - GDestroyNotify key_destroy_func; - GDestroyNotify value_destroy_func; -}; - -typedef struct -{ - GHashTable *hash_table; - gpointer dummy1; - gpointer dummy2; - int position; - gboolean dummy3; - int version; -} RealIter; - -/* Each table size has an associated prime modulo (the first prime - * lower than the table size) used to find the initial bucket. Probing - * then works modulo 2^n. The prime modulo is necessary to get a - * good distribution with poor hash functions. */ -static const gint prime_mod [] = -{ - 1, /* For 1 << 0 */ - 2, - 3, - 7, - 13, - 31, - 61, - 127, - 251, - 509, - 1021, - 2039, - 4093, - 8191, - 16381, - 32749, - 65521, /* For 1 << 16 */ - 131071, - 262139, - 524287, - 1048573, - 2097143, - 4194301, - 8388593, - 16777213, - 33554393, - 67108859, - 134217689, - 268435399, - 536870909, - 1073741789, - 2147483647 /* For 1 << 31 */ -}; - -static void -g_hash_table_set_shift (GHashTable *hash_table, gint shift) -{ - gint i; - guint mask = 0; - - hash_table->size = 1 << shift; - hash_table->mod = prime_mod [shift]; - - for (i = 0; i < shift; i++) - { - mask <<= 1; - mask |= 1; - } - - hash_table->mask = mask; -} - -static gint -g_hash_table_find_closest_shift (gint n) -{ - gint i; - - for (i = 0; n; i++) - n >>= 1; - - return i; -} - -static void -g_hash_table_set_shift_from_size (GHashTable *hash_table, gint size) -{ - gint shift; - - shift = g_hash_table_find_closest_shift (size); - shift = MAX (shift, HASH_TABLE_MIN_SHIFT); - - g_hash_table_set_shift (hash_table, shift); -} - -/* - * g_hash_table_lookup_node: - * @hash_table: our #GHashTable - * @key: the key to lookup against - * @hash_return: key hash return location - * Return value: index of the described node - * - * Performs a lookup in the hash table, preserving extra information - * usually needed for insertion. - * - * This function first computes the hash value of the key using the - * user's hash function. - * - * If an entry in the table matching @key is found then this function - * returns the index of that entry in the table, and if not, the - * index of an unused node (empty or tombstone) where the key can be - * inserted. - * - * The computed hash value is returned in the variable pointed to - * by @hash_return. This is to save insertions from having to compute - * the hash record again for the new record. - */ -static inline guint -g_hash_table_lookup_node (GHashTable *hash_table, - gconstpointer key, - guint *hash_return) -{ - guint node_index; - guint node_hash; - guint hash_value; - guint first_tombstone = 0; - gboolean have_tombstone = FALSE; - guint step = 0; - - hash_value = hash_table->hash_func (key); - if (G_UNLIKELY (!HASH_IS_REAL (hash_value))) - hash_value = 2; - - *hash_return = hash_value; - - node_index = hash_value % hash_table->mod; - node_hash = hash_table->hashes[node_index]; - - while (!HASH_IS_UNUSED (node_hash)) - { - /* We first check if our full hash values - * are equal so we can avoid calling the full-blown - * key equality function in most cases. - */ - if (node_hash == hash_value) - { - gpointer node_key = hash_table->keys[node_index]; - - if (hash_table->key_equal_func) - { - if (hash_table->key_equal_func (node_key, key)) - return node_index; - } - else if (node_key == key) - { - return node_index; - } - } - else if (HASH_IS_TOMBSTONE (node_hash) && !have_tombstone) - { - first_tombstone = node_index; - have_tombstone = TRUE; - } - - step++; - node_index += step; - node_index &= hash_table->mask; - node_hash = hash_table->hashes[node_index]; - } - - if (have_tombstone) - return first_tombstone; - - return node_index; -} - -/* - * g_hash_table_remove_node: - * @hash_table: our #GHashTable - * @node: pointer to node to remove - * @notify: %TRUE if the destroy notify handlers are to be called - * - * Removes a node from the hash table and updates the node count. - * The node is replaced by a tombstone. No table resize is performed. - * - * If @notify is %TRUE then the destroy notify functions are called - * for the key and value of the hash node. - */ -static void -g_hash_table_remove_node (GHashTable *hash_table, - int i, - gboolean notify) -{ - gpointer key; - gpointer value; - - key = hash_table->keys[i]; - value = hash_table->values[i]; - - /* Erect tombstone */ - hash_table->hashes[i] = TOMBSTONE_HASH_VALUE; - - /* Be GC friendly */ - hash_table->keys[i] = NULL; - hash_table->values[i] = NULL; - - hash_table->nnodes--; - - if (notify && hash_table->key_destroy_func) - hash_table->key_destroy_func (key); - - if (notify && hash_table->value_destroy_func) - hash_table->value_destroy_func (value); - -} - -/* - * g_hash_table_remove_all_nodes: - * @hash_table: our #GHashTable - * @notify: %TRUE if the destroy notify handlers are to be called - * - * Removes all nodes from the table. Since this may be a precursor to - * freeing the table entirely, no resize is performed. - * - * If @notify is %TRUE then the destroy notify functions are called - * for the key and value of the hash node. - */ -static void -g_hash_table_remove_all_nodes (GHashTable *hash_table, - gboolean notify) -{ - int i; - gpointer key; - gpointer value; - - hash_table->nnodes = 0; - hash_table->noccupied = 0; - - if (!notify || - (hash_table->key_destroy_func == NULL && - hash_table->value_destroy_func == NULL)) - { - memset (hash_table->hashes, 0, hash_table->size * sizeof (guint)); - memset (hash_table->keys, 0, hash_table->size * sizeof (gpointer)); - memset (hash_table->values, 0, hash_table->size * sizeof (gpointer)); - - return; - } - - for (i = 0; i < hash_table->size; i++) - { - if (HASH_IS_REAL (hash_table->hashes[i])) - { - key = hash_table->keys[i]; - value = hash_table->values[i]; - - hash_table->hashes[i] = UNUSED_HASH_VALUE; - hash_table->keys[i] = NULL; - hash_table->values[i] = NULL; - - if (hash_table->key_destroy_func != NULL) - hash_table->key_destroy_func (key); - - if (hash_table->value_destroy_func != NULL) - hash_table->value_destroy_func (value); - } - else if (HASH_IS_TOMBSTONE (hash_table->hashes[i])) - { - hash_table->hashes[i] = UNUSED_HASH_VALUE; - } - } -} - -/* - * g_hash_table_resize: - * @hash_table: our #GHashTable - * - * Resizes the hash table to the optimal size based on the number of - * nodes currently held. If you call this function then a resize will - * occur, even if one does not need to occur. Use - * g_hash_table_maybe_resize() instead. - * - * This function may "resize" the hash table to its current size, with - * the side effect of cleaning up tombstones and otherwise optimizing - * the probe sequences. - */ -static void -g_hash_table_resize (GHashTable *hash_table) -{ - gpointer *new_keys; - gpointer *new_values; - guint *new_hashes; - gint old_size; - gint i; - - old_size = hash_table->size; - g_hash_table_set_shift_from_size (hash_table, hash_table->nnodes * 2); - - new_keys = g_new0 (gpointer, hash_table->size); - if (hash_table->keys == hash_table->values) - new_values = new_keys; - else - new_values = g_new0 (gpointer, hash_table->size); - new_hashes = g_new0 (guint, hash_table->size); - - for (i = 0; i < old_size; i++) - { - guint node_hash = hash_table->hashes[i]; - guint hash_val; - guint step = 0; - - if (!HASH_IS_REAL (node_hash)) - continue; - - hash_val = node_hash % hash_table->mod; - - while (!HASH_IS_UNUSED (new_hashes[hash_val])) - { - step++; - hash_val += step; - hash_val &= hash_table->mask; - } - - new_hashes[hash_val] = hash_table->hashes[i]; - new_keys[hash_val] = hash_table->keys[i]; - new_values[hash_val] = hash_table->values[i]; - } - - if (hash_table->keys != hash_table->values) - g_free (hash_table->values); - - g_free (hash_table->keys); - g_free (hash_table->hashes); - - hash_table->keys = new_keys; - hash_table->values = new_values; - hash_table->hashes = new_hashes; - - hash_table->noccupied = hash_table->nnodes; -} - -/* - * g_hash_table_maybe_resize: - * @hash_table: our #GHashTable - * - * Resizes the hash table, if needed. - * - * Essentially, calls g_hash_table_resize() if the table has strayed - * too far from its ideal size for its number of nodes. - */ -static inline void -g_hash_table_maybe_resize (GHashTable *hash_table) -{ - gint noccupied = hash_table->noccupied; - gint size = hash_table->size; - - if ((size > hash_table->nnodes * 4 && size > 1 << HASH_TABLE_MIN_SHIFT) || - (size <= noccupied + (noccupied / 16))) - g_hash_table_resize (hash_table); -} - -/** - * g_hash_table_new: - * @hash_func: a function to create a hash value from a key. - * Hash values are used to determine where keys are stored within the - * #GHashTable data structure. The g_direct_hash(), g_int_hash(), - * g_int64_hash(), g_double_hash() and g_str_hash() functions are provided - * for some common types of keys. - * If hash_func is %NULL, g_direct_hash() is used. - * @key_equal_func: a function to check two keys for equality. This is - * used when looking up keys in the #GHashTable. The g_direct_equal(), - * g_int_equal(), g_int64_equal(), g_double_equal() and g_str_equal() - * functions are provided for the most common types of keys. - * If @key_equal_func is %NULL, keys are compared directly in a similar - * fashion to g_direct_equal(), but without the overhead of a function call. - * - * Creates a new #GHashTable with a reference count of 1. - * - * Return value: a new #GHashTable. - **/ -GHashTable* -g_hash_table_new (GHashFunc hash_func, - GEqualFunc key_equal_func) -{ - return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL); -} - - -/** - * g_hash_table_new_full: - * @hash_func: a function to create a hash value from a key. - * @key_equal_func: a function to check two keys for equality. - * @key_destroy_func: a function to free the memory allocated for the key - * used when removing the entry from the #GHashTable or %NULL if you - * don't want to supply such a function. - * @value_destroy_func: a function to free the memory allocated for the - * value used when removing the entry from the #GHashTable or %NULL if - * you don't want to supply such a function. - * - * Creates a new #GHashTable like g_hash_table_new() with a reference count - * of 1 and allows to specify functions to free the memory allocated for the - * key and value that get called when removing the entry from the #GHashTable. - * - * Return value: a new #GHashTable. - **/ -GHashTable* -g_hash_table_new_full (GHashFunc hash_func, - GEqualFunc key_equal_func, - GDestroyNotify key_destroy_func, - GDestroyNotify value_destroy_func) -{ - GHashTable *hash_table; - - hash_table = g_slice_new (GHashTable); - g_hash_table_set_shift (hash_table, HASH_TABLE_MIN_SHIFT); - hash_table->nnodes = 0; - hash_table->noccupied = 0; - hash_table->hash_func = hash_func ? hash_func : g_direct_hash; - hash_table->key_equal_func = key_equal_func; - hash_table->ref_count = 1; -#ifndef G_DISABLE_ASSERT - hash_table->version = 0; -#endif - hash_table->key_destroy_func = key_destroy_func; - hash_table->value_destroy_func = value_destroy_func; - hash_table->keys = g_new0 (gpointer, hash_table->size); - hash_table->values = hash_table->keys; - hash_table->hashes = g_new0 (guint, hash_table->size); - - return hash_table; -} - -/** - * g_hash_table_iter_init: - * @iter: an uninitialized #GHashTableIter. - * @hash_table: a #GHashTable. - * - * Initializes a key/value pair iterator and associates it with - * @hash_table. Modifying the hash table after calling this function - * invalidates the returned iterator. - * |[ - * GHashTableIter iter; - * gpointer key, value; - * - * g_hash_table_iter_init (&iter, hash_table); - * while (g_hash_table_iter_next (&iter, &key, &value)) - * { - * /* do something with key and value */ - * } - * ]| - * - * Since: 2.16 - **/ -void -g_hash_table_iter_init (GHashTableIter *iter, - GHashTable *hash_table) -{ - RealIter *ri = (RealIter *) iter; - - g_return_if_fail (iter != NULL); - g_return_if_fail (hash_table != NULL); - - ri->hash_table = hash_table; - ri->position = -1; -#ifndef G_DISABLE_ASSERT - ri->version = hash_table->version; -#endif -} - -/** - * g_hash_table_iter_next: - * @iter: an initialized #GHashTableIter. - * @key: a location to store the key, or %NULL. - * @value: a location to store the value, or %NULL. - * - * Advances @iter and retrieves the key and/or value that are now - * pointed to as a result of this advancement. If %FALSE is returned, - * @key and @value are not set, and the iterator becomes invalid. - * - * Return value: %FALSE if the end of the #GHashTable has been reached. - * - * Since: 2.16 - **/ -gboolean -g_hash_table_iter_next (GHashTableIter *iter, - gpointer *key, - gpointer *value) -{ - RealIter *ri = (RealIter *) iter; - gint position; - - g_return_val_if_fail (iter != NULL, FALSE); -#ifndef G_DISABLE_ASSERT - g_return_val_if_fail (ri->version == ri->hash_table->version, FALSE); -#endif - g_return_val_if_fail (ri->position < ri->hash_table->size, FALSE); - - position = ri->position; - - do - { - position++; - if (position >= ri->hash_table->size) - { - ri->position = position; - return FALSE; - } - } - while (!HASH_IS_REAL (ri->hash_table->hashes[position])); - - if (key != NULL) - *key = ri->hash_table->keys[position]; - if (value != NULL) - *value = ri->hash_table->values[position]; - - ri->position = position; - return TRUE; -} - -/** - * g_hash_table_iter_get_hash_table: - * @iter: an initialized #GHashTableIter. - * - * Returns the #GHashTable associated with @iter. - * - * Return value: the #GHashTable associated with @iter. - * - * Since: 2.16 - **/ -GHashTable * -g_hash_table_iter_get_hash_table (GHashTableIter *iter) -{ - g_return_val_if_fail (iter != NULL, NULL); - - return ((RealIter *) iter)->hash_table; -} - -static void -iter_remove_or_steal (RealIter *ri, gboolean notify) -{ - g_return_if_fail (ri != NULL); -#ifndef G_DISABLE_ASSERT - g_return_if_fail (ri->version == ri->hash_table->version); -#endif - g_return_if_fail (ri->position >= 0); - g_return_if_fail (ri->position < ri->hash_table->size); - - g_hash_table_remove_node (ri->hash_table, ri->position, notify); - -#ifndef G_DISABLE_ASSERT - ri->version++; - ri->hash_table->version++; -#endif -} - -/** - * g_hash_table_iter_remove: - * @iter: an initialized #GHashTableIter. - * - * Removes the key/value pair currently pointed to by the iterator - * from its associated #GHashTable. Can only be called after - * g_hash_table_iter_next() returned %TRUE, and cannot be called more - * than once for the same key/value pair. - * - * If the #GHashTable was created using g_hash_table_new_full(), the - * key and value are freed using the supplied destroy functions, otherwise - * you have to make sure that any dynamically allocated values are freed - * yourself. - * - * Since: 2.16 - **/ -void -g_hash_table_iter_remove (GHashTableIter *iter) -{ - iter_remove_or_steal ((RealIter *) iter, TRUE); -} - -/* - * g_hash_table_insert_node: - * @hash_table: our #GHashTable - * @node_index: pointer to node to insert/replace - * @key_hash: key hash - * @key: key to replace with, or %NULL - * @value: value to replace with - * @keep_new_key: whether to replace the key in the node with @key - * @reusing_key: whether @key was taken out of the existing node - * - * Inserts a value at @node_index in the hash table and updates it. - * - * If @key has been taken out of the existing node (ie it is not - * passed in via a g_hash_table_insert/replace) call, then @reusing_key - * should be %TRUE. - */ -static void -g_hash_table_insert_node (GHashTable *hash_table, - guint node_index, - guint key_hash, - gpointer key, - gpointer value, - gboolean keep_new_key, - gboolean reusing_key) -{ - guint old_hash; - gpointer old_key; - gpointer old_value; - - if (G_UNLIKELY (hash_table->keys == hash_table->values && key != value)) - hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size); - - old_hash = hash_table->hashes[node_index]; - old_key = hash_table->keys[node_index]; - old_value = hash_table->values[node_index]; - - if (HASH_IS_REAL (old_hash)) - { - if (keep_new_key) - hash_table->keys[node_index] = key; - hash_table->values[node_index] = value; - } - else - { - hash_table->keys[node_index] = key; - hash_table->values[node_index] = value; - hash_table->hashes[node_index] = key_hash; - - hash_table->nnodes++; - - if (HASH_IS_UNUSED (old_hash)) - { - /* We replaced an empty node, and not a tombstone */ - hash_table->noccupied++; - g_hash_table_maybe_resize (hash_table); - } - -#ifndef G_DISABLE_ASSERT - hash_table->version++; -#endif - } - - if (HASH_IS_REAL (old_hash)) - { - if (hash_table->key_destroy_func && !reusing_key) - hash_table->key_destroy_func (keep_new_key ? old_key : key); - if (hash_table->value_destroy_func) - hash_table->value_destroy_func (old_value); - } -} - -/** - * g_hash_table_iter_replace: - * @iter: an initialized #GHashTableIter. - * @value: the value to replace with - * - * Replaces the value currently pointed to by the iterator - * from its associated #GHashTable. Can only be called after - * g_hash_table_iter_next() returned %TRUE. - * - * If you supplied a @value_destroy_func when creating the #GHashTable, - * the old value is freed using that function. - * - * Since: 2.29.9 - **/ -void -g_hash_table_iter_replace (GHashTableIter *iter, - gpointer value) -{ - RealIter *ri; - guint node_hash; - gpointer key; - - ri = (RealIter *) iter; - - g_return_if_fail (ri != NULL); -#ifndef G_DISABLE_ASSERT - g_return_if_fail (ri->version == ri->hash_table->version); -#endif - g_return_if_fail (ri->position >= 0); - g_return_if_fail (ri->position < ri->hash_table->size); - - node_hash = ri->hash_table->hashes[ri->position]; - key = ri->hash_table->keys[ri->position]; - - g_hash_table_insert_node (ri->hash_table, ri->position, node_hash, key, value, TRUE, TRUE); - -#ifndef G_DISABLE_ASSERT - ri->version++; - ri->hash_table->version++; -#endif -} - -/** - * g_hash_table_iter_steal: - * @iter: an initialized #GHashTableIter. - * - * Removes the key/value pair currently pointed to by the iterator - * from its associated #GHashTable, without calling the key and value - * destroy functions. Can only be called after - * g_hash_table_iter_next() returned %TRUE, and cannot be called more - * than once for the same key/value pair. - * - * Since: 2.16 - **/ -void -g_hash_table_iter_steal (GHashTableIter *iter) -{ - iter_remove_or_steal ((RealIter *) iter, FALSE); -} - - -/** - * g_hash_table_ref: - * @hash_table: a valid #GHashTable. - * - * Atomically increments the reference count of @hash_table by one. - * This function is MT-safe and may be called from any thread. - * - * Return value: the passed in #GHashTable. - * - * Since: 2.10 - **/ -GHashTable* -g_hash_table_ref (GHashTable *hash_table) -{ - g_return_val_if_fail (hash_table != NULL, NULL); - - g_atomic_int_inc (&hash_table->ref_count); - - return hash_table; -} - -/** - * g_hash_table_unref: - * @hash_table: a valid #GHashTable. - * - * Atomically decrements the reference count of @hash_table by one. - * If the reference count drops to 0, all keys and values will be - * destroyed, and all memory allocated by the hash table is released. - * This function is MT-safe and may be called from any thread. - * - * Since: 2.10 - **/ -void -g_hash_table_unref (GHashTable *hash_table) -{ - g_return_if_fail (hash_table != NULL); - - if (g_atomic_int_dec_and_test (&hash_table->ref_count)) - { - g_hash_table_remove_all_nodes (hash_table, TRUE); - if (hash_table->keys != hash_table->values) - g_free (hash_table->values); - g_free (hash_table->keys); - g_free (hash_table->hashes); - g_slice_free (GHashTable, hash_table); - } -} - -/** - * g_hash_table_destroy: - * @hash_table: a #GHashTable. - * - * Destroys all keys and values in the #GHashTable and decrements its - * reference count by 1. If keys and/or values are dynamically allocated, - * you should either free them first or create the #GHashTable with destroy - * notifiers using g_hash_table_new_full(). In the latter case the destroy - * functions you supplied will be called on all keys and values during the - * destruction phase. - **/ -void -g_hash_table_destroy (GHashTable *hash_table) -{ - g_return_if_fail (hash_table != NULL); - - g_hash_table_remove_all (hash_table); - g_hash_table_unref (hash_table); -} - -/** - * g_hash_table_lookup: - * @hash_table: a #GHashTable. - * @key: the key to look up. - * - * Looks up a key in a #GHashTable. Note that this function cannot - * distinguish between a key that is not present and one which is present - * and has the value %NULL. If you need this distinction, use - * g_hash_table_lookup_extended(). - * - * Return value: the associated value, or %NULL if the key is not found. - **/ -gpointer -g_hash_table_lookup (GHashTable *hash_table, - gconstpointer key) -{ - guint node_index; - guint node_hash; - - g_return_val_if_fail (hash_table != NULL, NULL); - - node_index = g_hash_table_lookup_node (hash_table, key, &node_hash); - - return HASH_IS_REAL (hash_table->hashes[node_index]) - ? hash_table->values[node_index] - : NULL; -} - -/** - * g_hash_table_lookup_extended: - * @hash_table: a #GHashTable - * @lookup_key: the key to look up - * @orig_key: return location for the original key, or %NULL - * @value: return location for the value associated with the key, or %NULL - * - * Looks up a key in the #GHashTable, returning the original key and the - * associated value and a #gboolean which is %TRUE if the key was found. This - * is useful if you need to free the memory allocated for the original key, - * for example before calling g_hash_table_remove(). - * - * You can actually pass %NULL for @lookup_key to test - * whether the %NULL key exists, provided the hash and equal functions - * of @hash_table are %NULL-safe. - * - * Return value: %TRUE if the key was found in the #GHashTable. - **/ -gboolean -g_hash_table_lookup_extended (GHashTable *hash_table, - gconstpointer lookup_key, - gpointer *orig_key, - gpointer *value) -{ - guint node_index; - guint node_hash; - - g_return_val_if_fail (hash_table != NULL, FALSE); - - node_index = g_hash_table_lookup_node (hash_table, lookup_key, &node_hash); - - if (!HASH_IS_REAL (hash_table->hashes[node_index])) - return FALSE; - - if (orig_key) - *orig_key = hash_table->keys[node_index]; - - if (value) - *value = hash_table->values[node_index]; - - return TRUE; -} - -/* - * g_hash_table_insert_internal: - * @hash_table: our #GHashTable - * @key: the key to insert - * @value: the value to insert - * @keep_new_key: if %TRUE and this key already exists in the table - * then call the destroy notify function on the old key. If %FALSE - * then call the destroy notify function on the new key. - * - * Implements the common logic for the g_hash_table_insert() and - * g_hash_table_replace() functions. - * - * Do a lookup of @key. If it is found, replace it with the new - * @value (and perhaps the new @key). If it is not found, create a - * new node. - */ -static void -g_hash_table_insert_internal (GHashTable *hash_table, - gpointer key, - gpointer value, - gboolean keep_new_key) -{ - guint key_hash; - guint node_index; - - g_return_if_fail (hash_table != NULL); - - node_index = g_hash_table_lookup_node (hash_table, key, &key_hash); - - g_hash_table_insert_node (hash_table, node_index, key_hash, key, value, keep_new_key, FALSE); -} - -/** - * g_hash_table_insert: - * @hash_table: a #GHashTable. - * @key: a key to insert. - * @value: the value to associate with the key. - * - * Inserts a new key and value into a #GHashTable. - * - * If the key already exists in the #GHashTable its current value is replaced - * with the new value. If you supplied a @value_destroy_func when creating the - * #GHashTable, the old value is freed using that function. If you supplied - * a @key_destroy_func when creating the #GHashTable, the passed key is freed - * using that function. - **/ -void -g_hash_table_insert (GHashTable *hash_table, - gpointer key, - gpointer value) -{ - g_hash_table_insert_internal (hash_table, key, value, FALSE); -} - -/** - * g_hash_table_replace: - * @hash_table: a #GHashTable. - * @key: a key to insert. - * @value: the value to associate with the key. - * - * Inserts a new key and value into a #GHashTable similar to - * g_hash_table_insert(). The difference is that if the key already exists - * in the #GHashTable, it gets replaced by the new key. If you supplied a - * @value_destroy_func when creating the #GHashTable, the old value is freed - * using that function. If you supplied a @key_destroy_func when creating the - * #GHashTable, the old key is freed using that function. - **/ -void -g_hash_table_replace (GHashTable *hash_table, - gpointer key, - gpointer value) -{ - g_hash_table_insert_internal (hash_table, key, value, TRUE); -} - -/* - * g_hash_table_remove_internal: - * @hash_table: our #GHashTable - * @key: the key to remove - * @notify: %TRUE if the destroy notify handlers are to be called - * Return value: %TRUE if a node was found and removed, else %FALSE - * - * Implements the common logic for the g_hash_table_remove() and - * g_hash_table_steal() functions. - * - * Do a lookup of @key and remove it if it is found, calling the - * destroy notify handlers only if @notify is %TRUE. - */ -static gboolean -g_hash_table_remove_internal (GHashTable *hash_table, - gconstpointer key, - gboolean notify) -{ - guint node_index; - guint node_hash; - - g_return_val_if_fail (hash_table != NULL, FALSE); - - node_index = g_hash_table_lookup_node (hash_table, key, &node_hash); - - if (!HASH_IS_REAL (hash_table->hashes[node_index])) - return FALSE; - - g_hash_table_remove_node (hash_table, node_index, notify); - g_hash_table_maybe_resize (hash_table); - -#ifndef G_DISABLE_ASSERT - hash_table->version++; -#endif - - return TRUE; -} - -/** - * g_hash_table_remove: - * @hash_table: a #GHashTable. - * @key: the key to remove. - * - * Removes a key and its associated value from a #GHashTable. - * - * If the #GHashTable was created using g_hash_table_new_full(), the - * key and value are freed using the supplied destroy functions, otherwise - * you have to make sure that any dynamically allocated values are freed - * yourself. - * - * Return value: %TRUE if the key was found and removed from the #GHashTable. - **/ -gboolean -g_hash_table_remove (GHashTable *hash_table, - gconstpointer key) -{ - return g_hash_table_remove_internal (hash_table, key, TRUE); -} - -/** - * g_hash_table_steal: - * @hash_table: a #GHashTable. - * @key: the key to remove. - * - * Removes a key and its associated value from a #GHashTable without - * calling the key and value destroy functions. - * - * Return value: %TRUE if the key was found and removed from the #GHashTable. - **/ -gboolean -g_hash_table_steal (GHashTable *hash_table, - gconstpointer key) -{ - return g_hash_table_remove_internal (hash_table, key, FALSE); -} - -/** - * g_hash_table_remove_all: - * @hash_table: a #GHashTable - * - * Removes all keys and their associated values from a #GHashTable. - * - * If the #GHashTable was created using g_hash_table_new_full(), the keys - * and values are freed using the supplied destroy functions, otherwise you - * have to make sure that any dynamically allocated values are freed - * yourself. - * - * Since: 2.12 - **/ -void -g_hash_table_remove_all (GHashTable *hash_table) -{ - g_return_if_fail (hash_table != NULL); - -#ifndef G_DISABLE_ASSERT - if (hash_table->nnodes != 0) - hash_table->version++; -#endif - - g_hash_table_remove_all_nodes (hash_table, TRUE); - g_hash_table_maybe_resize (hash_table); -} - -/** - * g_hash_table_steal_all: - * @hash_table: a #GHashTable. - * - * Removes all keys and their associated values from a #GHashTable - * without calling the key and value destroy functions. - * - * Since: 2.12 - **/ -void -g_hash_table_steal_all (GHashTable *hash_table) -{ - g_return_if_fail (hash_table != NULL); - -#ifndef G_DISABLE_ASSERT - if (hash_table->nnodes != 0) - hash_table->version++; -#endif - - g_hash_table_remove_all_nodes (hash_table, FALSE); - g_hash_table_maybe_resize (hash_table); -} - -/* - * g_hash_table_foreach_remove_or_steal: - * @hash_table: our #GHashTable - * @func: the user's callback function - * @user_data: data for @func - * @notify: %TRUE if the destroy notify handlers are to be called - * - * Implements the common logic for g_hash_table_foreach_remove() and - * g_hash_table_foreach_steal(). - * - * Iterates over every node in the table, calling @func with the key - * and value of the node (and @user_data). If @func returns %TRUE the - * node is removed from the table. - * - * If @notify is true then the destroy notify handlers will be called - * for each removed node. - */ -static guint -g_hash_table_foreach_remove_or_steal (GHashTable *hash_table, - GHRFunc func, - gpointer user_data, - gboolean notify) -{ - guint deleted = 0; - gint i; -#ifndef G_DISABLE_ASSERT - gint version = hash_table->version; -#endif - - for (i = 0; i < hash_table->size; i++) - { - guint node_hash = hash_table->hashes[i]; - gpointer node_key = hash_table->keys[i]; - gpointer node_value = hash_table->values[i]; - - if (HASH_IS_REAL (node_hash) && - (* func) (node_key, node_value, user_data)) - { - g_hash_table_remove_node (hash_table, i, notify); - deleted++; - } - -#ifndef G_DISABLE_ASSERT - g_return_val_if_fail (version == hash_table->version, 0); -#endif - } - - g_hash_table_maybe_resize (hash_table); - -#ifndef G_DISABLE_ASSERT - if (deleted > 0) - hash_table->version++; -#endif - - return deleted; -} - -/** - * g_hash_table_foreach_remove: - * @hash_table: a #GHashTable. - * @func: the function to call for each key/value pair. - * @user_data: user data to pass to the function. - * - * Calls the given function for each key/value pair in the #GHashTable. - * If the function returns %TRUE, then the key/value pair is removed from the - * #GHashTable. If you supplied key or value destroy functions when creating - * the #GHashTable, they are used to free the memory allocated for the removed - * keys and values. - * - * See #GHashTableIter for an alternative way to loop over the - * key/value pairs in the hash table. - * - * Return value: the number of key/value pairs removed. - **/ -guint -g_hash_table_foreach_remove (GHashTable *hash_table, - GHRFunc func, - gpointer user_data) -{ - g_return_val_if_fail (hash_table != NULL, 0); - g_return_val_if_fail (func != NULL, 0); - - return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE); -} - -/** - * g_hash_table_foreach_steal: - * @hash_table: a #GHashTable. - * @func: the function to call for each key/value pair. - * @user_data: user data to pass to the function. - * - * Calls the given function for each key/value pair in the #GHashTable. - * If the function returns %TRUE, then the key/value pair is removed from the - * #GHashTable, but no key or value destroy functions are called. - * - * See #GHashTableIter for an alternative way to loop over the - * key/value pairs in the hash table. - * - * Return value: the number of key/value pairs removed. - **/ -guint -g_hash_table_foreach_steal (GHashTable *hash_table, - GHRFunc func, - gpointer user_data) -{ - g_return_val_if_fail (hash_table != NULL, 0); - g_return_val_if_fail (func != NULL, 0); - - return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE); -} - -/** - * g_hash_table_foreach: - * @hash_table: a #GHashTable. - * @func: the function to call for each key/value pair. - * @user_data: user data to pass to the function. - * - * Calls the given function for each of the key/value pairs in the - * #GHashTable. The function is passed the key and value of each - * pair, and the given @user_data parameter. The hash table may not - * be modified while iterating over it (you can't add/remove - * items). To remove all items matching a predicate, use - * g_hash_table_foreach_remove(). - * - * See g_hash_table_find() for performance caveats for linear - * order searches in contrast to g_hash_table_lookup(). - **/ -void -g_hash_table_foreach (GHashTable *hash_table, - GHFunc func, - gpointer user_data) -{ - gint i; -#ifndef G_DISABLE_ASSERT - gint version = hash_table->version; -#endif - - g_return_if_fail (hash_table != NULL); - g_return_if_fail (func != NULL); - - for (i = 0; i < hash_table->size; i++) - { - guint node_hash = hash_table->hashes[i]; - gpointer node_key = hash_table->keys[i]; - gpointer node_value = hash_table->values[i]; - - if (HASH_IS_REAL (node_hash)) - (* func) (node_key, node_value, user_data); - -#ifndef G_DISABLE_ASSERT - g_return_if_fail (version == hash_table->version); -#endif - } -} - -/** - * g_hash_table_find: - * @hash_table: a #GHashTable. - * @predicate: function to test the key/value pairs for a certain property. - * @user_data: user data to pass to the function. - * - * Calls the given function for key/value pairs in the #GHashTable until - * @predicate returns %TRUE. The function is passed the key and value of - * each pair, and the given @user_data parameter. The hash table may not - * be modified while iterating over it (you can't add/remove items). - * - * Note, that hash tables are really only optimized for forward lookups, - * i.e. g_hash_table_lookup(). - * So code that frequently issues g_hash_table_find() or - * g_hash_table_foreach() (e.g. in the order of once per every entry in a - * hash table) should probably be reworked to use additional or different - * data structures for reverse lookups (keep in mind that an O(n) find/foreach - * operation issued for all n values in a hash table ends up needing O(n*n) - * operations). - * - * Return value: The value of the first key/value pair is returned, - * for which @predicate evaluates to %TRUE. If no pair with the - * requested property is found, %NULL is returned. - * - * Since: 2.4 - **/ -gpointer -g_hash_table_find (GHashTable *hash_table, - GHRFunc predicate, - gpointer user_data) -{ - gint i; -#ifndef G_DISABLE_ASSERT - gint version = hash_table->version; -#endif - gboolean match; - - g_return_val_if_fail (hash_table != NULL, NULL); - g_return_val_if_fail (predicate != NULL, NULL); - - match = FALSE; - - for (i = 0; i < hash_table->size; i++) - { - guint node_hash = hash_table->hashes[i]; - gpointer node_key = hash_table->keys[i]; - gpointer node_value = hash_table->values[i]; - - if (HASH_IS_REAL (node_hash)) - match = predicate (node_key, node_value, user_data); - -#ifndef G_DISABLE_ASSERT - g_return_val_if_fail (version == hash_table->version, NULL); -#endif - - if (match) - return node_value; - } - - return NULL; -} - -/** - * g_hash_table_size: - * @hash_table: a #GHashTable. - * - * Returns the number of elements contained in the #GHashTable. - * - * Return value: the number of key/value pairs in the #GHashTable. - **/ -guint -g_hash_table_size (GHashTable *hash_table) -{ - g_return_val_if_fail (hash_table != NULL, 0); - - return hash_table->nnodes; -} - -/** - * g_hash_table_get_keys: - * @hash_table: a #GHashTable - * - * Retrieves every key inside @hash_table. The returned data is valid - * until @hash_table is modified. - * - * Return value: a #GList containing all the keys inside the hash - * table. The content of the list is owned by the hash table and - * should not be modified or freed. Use g_list_free() when done - * using the list. - * - * Since: 2.14 - */ -GList * -g_hash_table_get_keys (GHashTable *hash_table) -{ - gint i; - GList *retval; - - g_return_val_if_fail (hash_table != NULL, NULL); - - retval = NULL; - for (i = 0; i < hash_table->size; i++) - { - if (HASH_IS_REAL (hash_table->hashes[i])) - retval = g_list_prepend (retval, hash_table->keys[i]); - } - - return retval; -} - -/** - * g_hash_table_get_values: - * @hash_table: a #GHashTable - * - * Retrieves every value inside @hash_table. The returned data is - * valid until @hash_table is modified. - * - * Return value: a #GList containing all the values inside the hash - * table. The content of the list is owned by the hash table and - * should not be modified or freed. Use g_list_free() when done - * using the list. - * - * Since: 2.14 - */ -GList * -g_hash_table_get_values (GHashTable *hash_table) -{ - gint i; - GList *retval; - - g_return_val_if_fail (hash_table != NULL, NULL); - - retval = NULL; - for (i = 0; i < hash_table->size; i++) - { - if (HASH_IS_REAL (hash_table->hashes[i])) - retval = g_list_prepend (retval, hash_table->values[i]); - } - - return retval; -} diff --git a/deps/glib/ghash.h b/deps/glib/ghash.h deleted file mode 100644 index 4a026fae..00000000 --- a/deps/glib/ghash.h +++ /dev/null @@ -1,166 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_HASH_H__ -#define __G_HASH_H__ - -#include <glib/gtypes.h> -#include <glib/glist.h> - -G_BEGIN_DECLS - -typedef struct _GHashTable GHashTable; - -typedef gboolean (*GHRFunc) (gpointer key, - gpointer value, - gpointer user_data); - -typedef struct _GHashTableIter GHashTableIter; - -struct _GHashTableIter -{ - /*< private >*/ - gpointer dummy1; - gpointer dummy2; - gpointer dummy3; - int dummy4; - gboolean dummy5; - gpointer dummy6; -}; - -/* Hash tables - */ -GHashTable* g_hash_table_new (GHashFunc hash_func, - GEqualFunc key_equal_func); -GHashTable* g_hash_table_new_full (GHashFunc hash_func, - GEqualFunc key_equal_func, - GDestroyNotify key_destroy_func, - GDestroyNotify value_destroy_func); -void g_hash_table_destroy (GHashTable *hash_table); -void g_hash_table_insert (GHashTable *hash_table, - gpointer key, - gpointer value); -void g_hash_table_replace (GHashTable *hash_table, - gpointer key, - gpointer value); -gboolean g_hash_table_remove (GHashTable *hash_table, - gconstpointer key); -void g_hash_table_remove_all (GHashTable *hash_table); -gboolean g_hash_table_steal (GHashTable *hash_table, - gconstpointer key); -void g_hash_table_steal_all (GHashTable *hash_table); -gpointer g_hash_table_lookup (GHashTable *hash_table, - gconstpointer key); -gboolean g_hash_table_lookup_extended (GHashTable *hash_table, - gconstpointer lookup_key, - gpointer *orig_key, - gpointer *value); -void g_hash_table_foreach (GHashTable *hash_table, - GHFunc func, - gpointer user_data); -gpointer g_hash_table_find (GHashTable *hash_table, - GHRFunc predicate, - gpointer user_data); -guint g_hash_table_foreach_remove (GHashTable *hash_table, - GHRFunc func, - gpointer user_data); -guint g_hash_table_foreach_steal (GHashTable *hash_table, - GHRFunc func, - gpointer user_data); -guint g_hash_table_size (GHashTable *hash_table); -GList * g_hash_table_get_keys (GHashTable *hash_table); -GList * g_hash_table_get_values (GHashTable *hash_table); - -void g_hash_table_iter_init (GHashTableIter *iter, - GHashTable *hash_table); -gboolean g_hash_table_iter_next (GHashTableIter *iter, - gpointer *key, - gpointer *value); -GHashTable* g_hash_table_iter_get_hash_table (GHashTableIter *iter); -void g_hash_table_iter_remove (GHashTableIter *iter); -void g_hash_table_iter_replace (GHashTableIter *iter, - gpointer value); -void g_hash_table_iter_steal (GHashTableIter *iter); - -/* keeping hash tables alive */ -GHashTable* g_hash_table_ref (GHashTable *hash_table); -void g_hash_table_unref (GHashTable *hash_table); - -#ifndef G_DISABLE_DEPRECATED - -/** - * g_hash_table_freeze: - * @hash_table: a #GHashTable - * - * This function is deprecated and will be removed in the next major - * release of GLib. It does nothing. - **/ -#define g_hash_table_freeze(hash_table) ((void)0) - -/** - * g_hash_table_thaw: - * @hash_table: a #GHashTable - * - * This function is deprecated and will be removed in the next major - * release of GLib. It does nothing. - **/ -#define g_hash_table_thaw(hash_table) ((void)0) - -#endif /* G_DISABLE_DEPRECATED */ - -/* Hash Functions - */ -gboolean g_str_equal (gconstpointer v1, - gconstpointer v2); -guint g_str_hash (gconstpointer v); - -gboolean g_int_equal (gconstpointer v1, - gconstpointer v2); -guint g_int_hash (gconstpointer v); - -gboolean g_int64_equal (gconstpointer v1, - gconstpointer v2); -guint g_int64_hash (gconstpointer v); - -gboolean g_double_equal (gconstpointer v1, - gconstpointer v2); -guint g_double_hash (gconstpointer v); - -/* This "hash" function will just return the key's address as an - * unsigned integer. Useful for hashing on plain addresses or - * simple integer values. - * Passing NULL into g_hash_table_new() as GHashFunc has the - * same effect as passing g_direct_hash(). - */ -guint g_direct_hash (gconstpointer v) G_GNUC_CONST; -gboolean g_direct_equal (gconstpointer v1, - gconstpointer v2) G_GNUC_CONST; - -G_END_DECLS - -#endif /* __G_HASH_H__ */ diff --git a/deps/glib/ghook.c b/deps/glib/ghook.c deleted file mode 100644 index 5b10afcb..00000000 --- a/deps/glib/ghook.c +++ /dev/null @@ -1,634 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * GHook: Callback maintenance functions - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include "ghook.h" - -#include "gtestutils.h" - - -/* --- functions --- */ -static void -default_finalize_hook (GHookList *hook_list, - GHook *hook) -{ - GDestroyNotify destroy = hook->destroy; - - if (destroy) - { - hook->destroy = NULL; - destroy (hook->data); - } -} - -void -g_hook_list_init (GHookList *hook_list, - guint hook_size) -{ - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_size >= sizeof (GHook)); - - hook_list->seq_id = 1; - hook_list->hook_size = hook_size; - hook_list->is_setup = TRUE; - hook_list->hooks = NULL; - hook_list->dummy3 = NULL; - hook_list->finalize_hook = default_finalize_hook; - hook_list->dummy[0] = NULL; - hook_list->dummy[1] = NULL; -} - -void -g_hook_list_clear (GHookList *hook_list) -{ - g_return_if_fail (hook_list != NULL); - - if (hook_list->is_setup) - { - GHook *hook; - - hook_list->is_setup = FALSE; - - hook = hook_list->hooks; - if (!hook) - { - /* destroy hook_list->hook_memchunk */ - } - else - do - { - GHook *tmp; - - g_hook_ref (hook_list, hook); - g_hook_destroy_link (hook_list, hook); - tmp = hook->next; - g_hook_unref (hook_list, hook); - hook = tmp; - } - while (hook); - } -} - -GHook* -g_hook_alloc (GHookList *hook_list) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - g_return_val_if_fail (hook_list->is_setup, NULL); - - hook = g_slice_alloc0 (hook_list->hook_size); - hook->data = NULL; - hook->next = NULL; - hook->prev = NULL; - hook->flags = G_HOOK_FLAG_ACTIVE; - hook->ref_count = 0; - hook->hook_id = 0; - hook->func = NULL; - hook->destroy = NULL; - - return hook; -} - -void -g_hook_free (GHookList *hook_list, - GHook *hook) -{ - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - g_return_if_fail (hook != NULL); - g_return_if_fail (G_HOOK_IS_UNLINKED (hook)); - g_return_if_fail (!G_HOOK_IN_CALL (hook)); - - if(hook_list->finalize_hook != NULL) - hook_list->finalize_hook (hook_list, hook); - g_slice_free1 (hook_list->hook_size, hook); -} - -void -g_hook_destroy_link (GHookList *hook_list, - GHook *hook) -{ - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook != NULL); - - hook->flags &= ~G_HOOK_FLAG_ACTIVE; - if (hook->hook_id) - { - hook->hook_id = 0; - g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */ - } -} - -gboolean -g_hook_destroy (GHookList *hook_list, - gulong hook_id) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, FALSE); - g_return_val_if_fail (hook_id > 0, FALSE); - - hook = g_hook_get (hook_list, hook_id); - if (hook) - { - g_hook_destroy_link (hook_list, hook); - return TRUE; - } - - return FALSE; -} - -void -g_hook_unref (GHookList *hook_list, - GHook *hook) -{ - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook != NULL); - g_return_if_fail (hook->ref_count > 0); - - hook->ref_count--; - if (!hook->ref_count) - { - g_return_if_fail (hook->hook_id == 0); - g_return_if_fail (!G_HOOK_IN_CALL (hook)); - - if (hook->prev) - hook->prev->next = hook->next; - else - hook_list->hooks = hook->next; - if (hook->next) - { - hook->next->prev = hook->prev; - hook->next = NULL; - } - hook->prev = NULL; - - if (!hook_list->is_setup) - { - hook_list->is_setup = TRUE; - g_hook_free (hook_list, hook); - hook_list->is_setup = FALSE; - - if (!hook_list->hooks) - { - /* destroy hook_list->hook_memchunk */ - } - } - else - g_hook_free (hook_list, hook); - } -} - -GHook * -g_hook_ref (GHookList *hook_list, - GHook *hook) -{ - g_return_val_if_fail (hook_list != NULL, NULL); - g_return_val_if_fail (hook != NULL, NULL); - g_return_val_if_fail (hook->ref_count > 0, NULL); - - hook->ref_count++; - - return hook; -} - -void -g_hook_prepend (GHookList *hook_list, - GHook *hook) -{ - g_return_if_fail (hook_list != NULL); - - g_hook_insert_before (hook_list, hook_list->hooks, hook); -} - -void -g_hook_insert_before (GHookList *hook_list, - GHook *sibling, - GHook *hook) -{ - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - g_return_if_fail (hook != NULL); - g_return_if_fail (G_HOOK_IS_UNLINKED (hook)); - g_return_if_fail (hook->ref_count == 0); - - hook->hook_id = hook_list->seq_id++; - hook->ref_count = 1; /* counterpart to g_hook_destroy_link */ - - if (sibling) - { - if (sibling->prev) - { - hook->prev = sibling->prev; - hook->prev->next = hook; - hook->next = sibling; - sibling->prev = hook; - } - else - { - hook_list->hooks = hook; - hook->next = sibling; - sibling->prev = hook; - } - } - else - { - if (hook_list->hooks) - { - sibling = hook_list->hooks; - while (sibling->next) - sibling = sibling->next; - hook->prev = sibling; - sibling->next = hook; - } - else - hook_list->hooks = hook; - } -} - -void -g_hook_list_invoke (GHookList *hook_list, - gboolean may_recurse) -{ - GHook *hook; - - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - - hook = g_hook_first_valid (hook_list, may_recurse); - while (hook) - { - GHookFunc func; - gboolean was_in_call; - - func = (GHookFunc) hook->func; - - was_in_call = G_HOOK_IN_CALL (hook); - hook->flags |= G_HOOK_FLAG_IN_CALL; - func (hook->data); - if (!was_in_call) - hook->flags &= ~G_HOOK_FLAG_IN_CALL; - - hook = g_hook_next_valid (hook_list, hook, may_recurse); - } -} - -void -g_hook_list_invoke_check (GHookList *hook_list, - gboolean may_recurse) -{ - GHook *hook; - - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - - hook = g_hook_first_valid (hook_list, may_recurse); - while (hook) - { - GHookCheckFunc func; - gboolean was_in_call; - gboolean need_destroy; - - func = (GHookCheckFunc) hook->func; - - was_in_call = G_HOOK_IN_CALL (hook); - hook->flags |= G_HOOK_FLAG_IN_CALL; - need_destroy = !func (hook->data); - if (!was_in_call) - hook->flags &= ~G_HOOK_FLAG_IN_CALL; - if (need_destroy) - g_hook_destroy_link (hook_list, hook); - - hook = g_hook_next_valid (hook_list, hook, may_recurse); - } -} - -void -g_hook_list_marshal_check (GHookList *hook_list, - gboolean may_recurse, - GHookCheckMarshaller marshaller, - gpointer data) -{ - GHook *hook; - - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - g_return_if_fail (marshaller != NULL); - - hook = g_hook_first_valid (hook_list, may_recurse); - while (hook) - { - gboolean was_in_call; - gboolean need_destroy; - - was_in_call = G_HOOK_IN_CALL (hook); - hook->flags |= G_HOOK_FLAG_IN_CALL; - need_destroy = !marshaller (hook, data); - if (!was_in_call) - hook->flags &= ~G_HOOK_FLAG_IN_CALL; - if (need_destroy) - g_hook_destroy_link (hook_list, hook); - - hook = g_hook_next_valid (hook_list, hook, may_recurse); - } -} - -void -g_hook_list_marshal (GHookList *hook_list, - gboolean may_recurse, - GHookMarshaller marshaller, - gpointer data) -{ - GHook *hook; - - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - g_return_if_fail (marshaller != NULL); - - hook = g_hook_first_valid (hook_list, may_recurse); - while (hook) - { - gboolean was_in_call; - - was_in_call = G_HOOK_IN_CALL (hook); - hook->flags |= G_HOOK_FLAG_IN_CALL; - marshaller (hook, data); - if (!was_in_call) - hook->flags &= ~G_HOOK_FLAG_IN_CALL; - - hook = g_hook_next_valid (hook_list, hook, may_recurse); - } -} - -GHook* -g_hook_first_valid (GHookList *hook_list, - gboolean may_be_in_call) -{ - g_return_val_if_fail (hook_list != NULL, NULL); - - if (hook_list->is_setup) - { - GHook *hook; - - hook = hook_list->hooks; - if (hook) - { - g_hook_ref (hook_list, hook); - if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook))) - return hook; - else - return g_hook_next_valid (hook_list, hook, may_be_in_call); - } - } - - return NULL; -} - -GHook* -g_hook_next_valid (GHookList *hook_list, - GHook *hook, - gboolean may_be_in_call) -{ - GHook *ohook = hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - - if (!hook) - return NULL; - - hook = hook->next; - while (hook) - { - if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook))) - { - g_hook_ref (hook_list, hook); - g_hook_unref (hook_list, ohook); - - return hook; - } - hook = hook->next; - } - g_hook_unref (hook_list, ohook); - - return NULL; -} - -GHook* -g_hook_get (GHookList *hook_list, - gulong hook_id) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - g_return_val_if_fail (hook_id > 0, NULL); - - hook = hook_list->hooks; - while (hook) - { - if (hook->hook_id == hook_id) - return hook; - hook = hook->next; - } - - return NULL; -} - -GHook* -g_hook_find (GHookList *hook_list, - gboolean need_valids, - GHookFindFunc func, - gpointer data) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - - hook = hook_list->hooks; - while (hook) - { - GHook *tmp; - - /* test only non-destroyed hooks */ - if (!hook->hook_id) - { - hook = hook->next; - continue; - } - - g_hook_ref (hook_list, hook); - - if (func (hook, data) && hook->hook_id && (!need_valids || G_HOOK_ACTIVE (hook))) - { - g_hook_unref (hook_list, hook); - - return hook; - } - - tmp = hook->next; - g_hook_unref (hook_list, hook); - hook = tmp; - } - - return NULL; -} - -GHook* -g_hook_find_data (GHookList *hook_list, - gboolean need_valids, - gpointer data) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - - hook = hook_list->hooks; - while (hook) - { - /* test only non-destroyed hooks */ - if (hook->data == data && - hook->hook_id && - (!need_valids || G_HOOK_ACTIVE (hook))) - return hook; - - hook = hook->next; - } - - return NULL; -} - -GHook* -g_hook_find_func (GHookList *hook_list, - gboolean need_valids, - gpointer func) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - - hook = hook_list->hooks; - while (hook) - { - /* test only non-destroyed hooks */ - if (hook->func == func && - hook->hook_id && - (!need_valids || G_HOOK_ACTIVE (hook))) - return hook; - - hook = hook->next; - } - - return NULL; -} - -GHook* -g_hook_find_func_data (GHookList *hook_list, - gboolean need_valids, - gpointer func, - gpointer data) -{ - GHook *hook; - - g_return_val_if_fail (hook_list != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - - hook = hook_list->hooks; - while (hook) - { - /* test only non-destroyed hooks */ - if (hook->data == data && - hook->func == func && - hook->hook_id && - (!need_valids || G_HOOK_ACTIVE (hook))) - return hook; - - hook = hook->next; - } - - return NULL; -} - -void -g_hook_insert_sorted (GHookList *hook_list, - GHook *hook, - GHookCompareFunc func) -{ - GHook *sibling; - - g_return_if_fail (hook_list != NULL); - g_return_if_fail (hook_list->is_setup); - g_return_if_fail (hook != NULL); - g_return_if_fail (G_HOOK_IS_UNLINKED (hook)); - g_return_if_fail (hook->func != NULL); - g_return_if_fail (func != NULL); - - /* first non-destroyed hook */ - sibling = hook_list->hooks; - while (sibling && !sibling->hook_id) - sibling = sibling->next; - - while (sibling) - { - GHook *tmp; - - g_hook_ref (hook_list, sibling); - if (func (hook, sibling) <= 0 && sibling->hook_id) - { - g_hook_unref (hook_list, sibling); - break; - } - - /* next non-destroyed hook */ - tmp = sibling->next; - while (tmp && !tmp->hook_id) - tmp = tmp->next; - - g_hook_unref (hook_list, sibling); - sibling = tmp; - } - - g_hook_insert_before (hook_list, sibling, hook); -} - -gint -g_hook_compare_ids (GHook *new_hook, - GHook *sibling) -{ - if (new_hook->hook_id < sibling->hook_id) - return -1; - else if (new_hook->hook_id > sibling->hook_id) - return 1; - - return 0; -} diff --git a/deps/glib/ghook.h b/deps/glib/ghook.h deleted file mode 100644 index e53c43ca..00000000 --- a/deps/glib/ghook.h +++ /dev/null @@ -1,179 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_HOOK_H__ -#define __G_HOOK_H__ - -#include <glib/gmem.h> - -G_BEGIN_DECLS - - -/* --- typedefs --- */ -typedef struct _GHook GHook; -typedef struct _GHookList GHookList; - -typedef gint (*GHookCompareFunc) (GHook *new_hook, - GHook *sibling); -typedef gboolean (*GHookFindFunc) (GHook *hook, - gpointer data); -typedef void (*GHookMarshaller) (GHook *hook, - gpointer marshal_data); -typedef gboolean (*GHookCheckMarshaller) (GHook *hook, - gpointer marshal_data); -typedef void (*GHookFunc) (gpointer data); -typedef gboolean (*GHookCheckFunc) (gpointer data); -typedef void (*GHookFinalizeFunc) (GHookList *hook_list, - GHook *hook); -typedef enum -{ - G_HOOK_FLAG_ACTIVE = 1 << 0, - G_HOOK_FLAG_IN_CALL = 1 << 1, - G_HOOK_FLAG_MASK = 0x0f -} GHookFlagMask; -#define G_HOOK_FLAG_USER_SHIFT (4) - - -/* --- structures --- */ -struct _GHookList -{ - gulong seq_id; - guint hook_size : 16; - guint is_setup : 1; - GHook *hooks; - gpointer dummy3; - GHookFinalizeFunc finalize_hook; - gpointer dummy[2]; -}; -struct _GHook -{ - gpointer data; - GHook *next; - GHook *prev; - guint ref_count; - gulong hook_id; - guint flags; - gpointer func; - GDestroyNotify destroy; -}; - - -/* --- macros --- */ -#define G_HOOK(hook) ((GHook*) (hook)) -#define G_HOOK_FLAGS(hook) (G_HOOK (hook)->flags) -#define G_HOOK_ACTIVE(hook) ((G_HOOK_FLAGS (hook) & \ - G_HOOK_FLAG_ACTIVE) != 0) -#define G_HOOK_IN_CALL(hook) ((G_HOOK_FLAGS (hook) & \ - G_HOOK_FLAG_IN_CALL) != 0) -#define G_HOOK_IS_VALID(hook) (G_HOOK (hook)->hook_id != 0 && \ - (G_HOOK_FLAGS (hook) & \ - G_HOOK_FLAG_ACTIVE)) -#define G_HOOK_IS_UNLINKED(hook) (G_HOOK (hook)->next == NULL && \ - G_HOOK (hook)->prev == NULL && \ - G_HOOK (hook)->hook_id == 0 && \ - G_HOOK (hook)->ref_count == 0) - - -/* --- prototypes --- */ -/* callback maintenance functions */ -void g_hook_list_init (GHookList *hook_list, - guint hook_size); -void g_hook_list_clear (GHookList *hook_list); -GHook* g_hook_alloc (GHookList *hook_list); -void g_hook_free (GHookList *hook_list, - GHook *hook); -GHook * g_hook_ref (GHookList *hook_list, - GHook *hook); -void g_hook_unref (GHookList *hook_list, - GHook *hook); -gboolean g_hook_destroy (GHookList *hook_list, - gulong hook_id); -void g_hook_destroy_link (GHookList *hook_list, - GHook *hook); -void g_hook_prepend (GHookList *hook_list, - GHook *hook); -void g_hook_insert_before (GHookList *hook_list, - GHook *sibling, - GHook *hook); -void g_hook_insert_sorted (GHookList *hook_list, - GHook *hook, - GHookCompareFunc func); -GHook* g_hook_get (GHookList *hook_list, - gulong hook_id); -GHook* g_hook_find (GHookList *hook_list, - gboolean need_valids, - GHookFindFunc func, - gpointer data); -GHook* g_hook_find_data (GHookList *hook_list, - gboolean need_valids, - gpointer data); -GHook* g_hook_find_func (GHookList *hook_list, - gboolean need_valids, - gpointer func); -GHook* g_hook_find_func_data (GHookList *hook_list, - gboolean need_valids, - gpointer func, - gpointer data); -/* return the first valid hook, and increment its reference count */ -GHook* g_hook_first_valid (GHookList *hook_list, - gboolean may_be_in_call); -/* return the next valid hook with incremented reference count, and - * decrement the reference count of the original hook - */ -GHook* g_hook_next_valid (GHookList *hook_list, - GHook *hook, - gboolean may_be_in_call); -/* GHookCompareFunc implementation to insert hooks sorted by their id */ -gint g_hook_compare_ids (GHook *new_hook, - GHook *sibling); -/* convenience macros */ -#define g_hook_append( hook_list, hook ) \ - g_hook_insert_before ((hook_list), NULL, (hook)) -/* invoke all valid hooks with the (*GHookFunc) signature. - */ -void g_hook_list_invoke (GHookList *hook_list, - gboolean may_recurse); -/* invoke all valid hooks with the (*GHookCheckFunc) signature, - * and destroy the hook if FALSE is returned. - */ -void g_hook_list_invoke_check (GHookList *hook_list, - gboolean may_recurse); -/* invoke a marshaller on all valid hooks. - */ -void g_hook_list_marshal (GHookList *hook_list, - gboolean may_recurse, - GHookMarshaller marshaller, - gpointer marshal_data); -void g_hook_list_marshal_check (GHookList *hook_list, - gboolean may_recurse, - GHookCheckMarshaller marshaller, - gpointer marshal_data); - -G_END_DECLS - -#endif /* __G_HOOK_H__ */ diff --git a/deps/glib/gi18n-lib.h b/deps/glib/gi18n-lib.h deleted file mode 100644 index 150a2686..00000000 --- a/deps/glib/gi18n-lib.h +++ /dev/null @@ -1,36 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __G_I18N_LIB_H__ -#define __G_I18N_LIB_H__ - -#include <glib.h> - -#include <libintl.h> -#include <string.h> - -#ifndef GETTEXT_PACKAGE -#error You must define GETTEXT_PACKAGE before including gi18n-lib.h. Did you forget to include config.h? -#endif - -#define _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String)) -#define Q_(String) g_dpgettext (GETTEXT_PACKAGE, String, 0) -#define N_(String) (String) -#define C_(Context,String) g_dpgettext (GETTEXT_PACKAGE, Context "\004" String, strlen (Context) + 1) -#define NC_(Context, String) (String) - -#endif /* __G_I18N_LIB_H__ */ diff --git a/deps/glib/glib-object.h b/deps/glib/glib-object.h deleted file mode 100644 index 88a65829..00000000 --- a/deps/glib/glib-object.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __GLIB_OBJECT_H__ -#define __GLIB_OBJECT_H__ - -#include "glib.h" - -#endif /* __GLIB_OBJECT_H__ */ diff --git a/deps/glib/glib.h b/deps/glib/glib.h deleted file mode 100644 index 2b06acb9..00000000 --- a/deps/glib/glib.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __GLIB_H__ -#define __GLIB_H__ - -#define __GLIB_H_INSIDE__ - -#include "gtypes.h" -#include "glibconfig.h" -#include "gmacros.h" -#include "gquark.h" -#include "gstrfuncs.h" -#include "gmessages.h" -#include "gmem.h" -#include "galloca.h" -#include "gslice.h" -#include "gstring.h" -#include "ghook.h" -#include "garray.h" -#include "gslist.h" -#include "glist.h" -#include "gqueue.h" -#include "gtestutils.h" -#include "gqsort.h" -#include "gatomic.h" -#include "gthread.h" -#include "ghash.h" -#include "gfileutils.h" -#include "gconvert.h" - -#endif /* __GLIB_H__ */ diff --git a/deps/glib/glib_trace.h b/deps/glib/glib_trace.h deleted file mode 100644 index 3818374c..00000000 --- a/deps/glib/glib_trace.h +++ /dev/null @@ -1,41 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * - * Copyright (C) 2009,2010 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General - * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. - * - * Author: Alexander Larsson <alexl@redhat.com> - */ - -#ifndef __GLIBTRACE_H__ -#define __GLIBTRACE_H__ - -#ifndef SIZEOF_CHAR -#error "config.h must be included prior to glib_trace.h" -#endif - -#ifdef HAVE_DTRACE - -/* include the generated probes header and put markers in code */ -#include "glib_probes.h" -#define TRACE(probe) probe - -#else - -/* Wrap the probe to allow it to be removed when no systemtap available */ -#define TRACE(probe) - -#endif - -#endif /* __GLIBTRACE_H__ */ diff --git a/deps/glib/glibintl.h b/deps/glib/glibintl.h deleted file mode 100644 index 9dc9a0f3..00000000 --- a/deps/glib/glibintl.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __GLIBINTL_H__ -#define __GLIBINTL_H__ - -#ifndef SIZEOF_CHAR -#error "config.h must be included prior to glibintl.h" -#endif - -const gchar * glib_gettext (const gchar *str) G_GNUC_FORMAT(1); -const gchar * glib_pgettext (const gchar *msgctxtid, - gsize msgidoffset) G_GNUC_FORMAT(1); - -#ifdef ENABLE_NLS - -#include <libintl.h> -#define _(String) glib_gettext(String) -/* Split out this in the code, but keep it in the same domain for now */ -#define P_(String) glib_gettext(String) -#define C_(Context,String) glib_pgettext (Context "\004" String, strlen (Context) + 1) - -#ifdef gettext_noop -#define N_(String) gettext_noop(String) -#else -#define N_(String) (String) -#endif -#else /* NLS is disabled */ -#define _(String) (String) -#define N_(String) (String) -#define P_(String) (String) -#define C_(Context,String) (String) -#define textdomain(String) ((String) ? (String) : "messages") -#define gettext(String) (String) -#define dgettext(Domain,String) (String) -#define dcgettext(Domain,String,Type) (String) -#define dngettext(Domain,String1,String2,N) ((N) == 1 ? (String1) : (String2)) -#define bindtextdomain(Domain,Directory) -#define bind_textdomain_codeset(Domain,Codeset) -#endif - -/* not really I18N-related, but also a string marker macro */ -#define I_(string) g_intern_static_string (string) - -#endif /* __GLIBINTL_H__ */ diff --git a/deps/glib/glist.c b/deps/glib/glist.c deleted file mode 100644 index f01e9bfa..00000000 --- a/deps/glib/glist.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include "glist.h" - -#include "gtestutils.h" - -/** - * SECTION:linked_lists_double - * @title: Doubly-Linked Lists - * @short_description: linked lists containing integer values or - * pointers to data, with the ability to iterate - * over the list in both directions - * - * The #GList structure and its associated functions provide a standard - * doubly-linked list data structure. - * - * Each element in the list contains a piece of data, together with - * pointers which link to the previous and next elements in the list. - * Using these pointers it is possible to move through the list in both - * directions (unlike the <link - * linkend="glib-Singly-Linked-Lists">Singly-Linked Lists</link> which - * only allows movement through the list in the forward direction). - * - * The data contained in each element can be either integer values, by - * using one of the <link linkend="glib-Type-Conversion-Macros">Type - * Conversion Macros</link>, or simply pointers to any type of data. - * - * List elements are allocated from the <link - * linkend="glib-Memory-Slices">slice allocator</link>, which is more - * efficient than allocating elements individually. - * - * Note that most of the #GList functions expect to be passed a pointer - * to the first element in the list. The functions which insert - * elements return the new start of the list, which may have changed. - * - * There is no function to create a #GList. %NULL is considered to be - * the empty list so you simply set a #GList* to %NULL. - * - * To add elements, use g_list_append(), g_list_prepend(), - * g_list_insert() and g_list_insert_sorted(). - * - * To remove elements, use g_list_remove(). - * - * To find elements in the list use g_list_first(), g_list_last(), - * g_list_next(), g_list_previous(), g_list_nth(), g_list_nth_data(), - * g_list_find() and g_list_find_custom(). - * - * To find the index of an element use g_list_position() and - * g_list_index(). - * - * To call a function for each element in the list use g_list_foreach(). - * - * To free the entire list, use g_list_free(). - **/ - -/** - * GList: - * @data: holds the element's data, which can be a pointer to any kind - * of data, or any integer value using the <link - * linkend="glib-Type-Conversion-Macros">Type Conversion - * Macros</link>. - * @next: contains the link to the next element in the list. - * @prev: contains the link to the previous element in the list. - * - * The #GList struct is used for each element in a doubly-linked list. - **/ - -/** - * g_list_previous: - * @list: an element in a #GList. - * @Returns: the previous element, or %NULL if there are no previous - * elements. - * - * A convenience macro to get the previous element in a #GList. - **/ - -/** - * g_list_next: - * @list: an element in a #GList. - * @Returns: the next element, or %NULL if there are no more elements. - * - * A convenience macro to get the next element in a #GList. - **/ - - - -/** - * g_list_push_allocator: - * @allocator: the #GAllocator to use when allocating #GList elements. - * - * Sets the allocator to use to allocate #GList elements. Use - * g_list_pop_allocator() to restore the previous allocator. - * - * Note that this function is not available if GLib has been compiled - * with <option>--disable-mem-pools</option> - * - * Deprecated:2.10: It does nothing, since #GList has been converted - * to the <link linkend="glib-Memory-Slices">slice - * allocator</link> - **/ -void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ } - -/** - * g_list_pop_allocator: - * - * Restores the previous #GAllocator, used when allocating #GList - * elements. - * - * Note that this function is not available if GLib has been compiled - * with <option>--disable-mem-pools</option> - * - * Deprecated:2.10: It does nothing, since #GList has been converted - * to the <link linkend="glib-Memory-Slices">slice - * allocator</link> - **/ -void g_list_pop_allocator (void) { /* present for binary compat only */ } - -#define _g_list_alloc() g_slice_new (GList) -#define _g_list_alloc0() g_slice_new0 (GList) -#define _g_list_free1(list) g_slice_free (GList, list) - -/** - * g_list_alloc: - * @Returns: a pointer to the newly-allocated #GList element. - * - * Allocates space for one #GList element. It is called by - * g_list_append(), g_list_prepend(), g_list_insert() and - * g_list_insert_sorted() and so is rarely used on its own. - **/ -GList* -g_list_alloc (void) -{ - return _g_list_alloc0 (); -} - -/** - * g_list_free: - * @list: a #GList - * - * Frees all of the memory used by a #GList. - * The freed elements are returned to the slice allocator. - * - * <note><para> - * If list elements contain dynamically-allocated memory, - * you should either use g_list_free_full() or free them manually - * first. - * </para></note> - */ -void -g_list_free (GList *list) -{ - g_slice_free_chain (GList, list, next); -} - -/** - * g_list_free_1: - * @list: a #GList element - * - * Frees one #GList element. - * It is usually used after g_list_remove_link(). - */ -/** - * g_list_free1: - * - * Another name for g_list_free_1(). - **/ -void -g_list_free_1 (GList *list) -{ - _g_list_free1 (list); -} - -/** - * g_list_free_full: - * @list: a pointer to a #GList - * @free_func: the function to be called to free each element's data - * - * Convenience method, which frees all the memory used by a #GList, and - * calls the specified destroy function on every element's data. - * - * Since: 2.28 - */ -void -g_list_free_full (GList *list, - GDestroyNotify free_func) -{ - g_list_foreach (list, (GFunc) free_func, NULL); - g_list_free (list); -} - -/** - * g_list_append: - * @list: a pointer to a #GList - * @data: the data for the new element - * - * Adds a new element on to the end of the list. - * - * <note><para> - * The return value is the new start of the list, which - * may have changed, so make sure you store the new value. - * </para></note> - * - * <note><para> - * Note that g_list_append() has to traverse the entire list - * to find the end, which is inefficient when adding multiple - * elements. A common idiom to avoid the inefficiency is to prepend - * the elements and reverse the list when all elements have been added. - * </para></note> - * - * |[ - * /* Notice that these are initialized to the empty list. */ - * GList *list = NULL, *number_list = NULL; - * - * /* This is a list of strings. */ - * list = g_list_append (list, "first"); - * list = g_list_append (list, "second"); - * - * /* This is a list of integers. */ - * number_list = g_list_append (number_list, GINT_TO_POINTER (27)); - * number_list = g_list_append (number_list, GINT_TO_POINTER (14)); - * ]| - * - * Returns: the new start of the #GList - */ -GList* -g_list_append (GList *list, - gpointer data) -{ - GList *new_list; - GList *last; - - new_list = _g_list_alloc (); - new_list->data = data; - new_list->next = NULL; - - if (list) - { - last = g_list_last (list); - /* g_assert (last != NULL); */ - last->next = new_list; - new_list->prev = last; - - return list; - } - else - { - new_list->prev = NULL; - return new_list; - } -} - -/** - * g_list_prepend: - * @list: a pointer to a #GList - * @data: the data for the new element - * - * Adds a new element on to the start of the list. - * - * <note><para> - * The return value is the new start of the list, which - * may have changed, so make sure you store the new value. - * </para></note> - * - * |[ - * /* Notice that it is initialized to the empty list. */ - * GList *list = NULL; - * list = g_list_prepend (list, "last"); - * list = g_list_prepend (list, "first"); - * ]| - * - * Returns: the new start of the #GList - */ -GList* -g_list_prepend (GList *list, - gpointer data) -{ - GList *new_list; - - new_list = _g_list_alloc (); - new_list->data = data; - new_list->next = list; - - if (list) - { - new_list->prev = list->prev; - if (list->prev) - list->prev->next = new_list; - list->prev = new_list; - } - else - new_list->prev = NULL; - - return new_list; -} - -/** - * g_list_insert: - * @list: a pointer to a #GList - * @data: the data for the new element - * @position: the position to insert the element. If this is - * negative, or is larger than the number of elements in the - * list, the new element is added on to the end of the list. - * - * Inserts a new element into the list at the given position. - * - * Returns: the new start of the #GList - */ -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; - new_list->prev = tmp_list->prev; - if (tmp_list->prev) - tmp_list->prev->next = new_list; - new_list->next = tmp_list; - tmp_list->prev = new_list; - - if (tmp_list == list) - return new_list; - else - return list; -} - -/** - * g_list_insert_before: - * @list: a pointer to a #GList - * @sibling: the list element before which the new element - * is inserted or %NULL to insert at the end of the list - * @data: the data for the new element - * - * Inserts a new element into the list before the given position. - * - * Returns: the new start of the #GList - */ -GList* -g_list_insert_before (GList *list, - GList *sibling, - gpointer data) -{ - if (!list) - { - list = g_list_alloc (); - list->data = data; - g_return_val_if_fail (sibling == NULL, list); - return list; - } - else if (sibling) - { - GList *node; - - node = _g_list_alloc (); - node->data = data; - node->prev = sibling->prev; - node->next = sibling; - sibling->prev = node; - if (node->prev) - { - node->prev->next = node; - return list; - } - else - { - g_return_val_if_fail (sibling == list, node); - return node; - } - } - else - { - GList *last; - - last = list; - while (last->next) - last = last->next; - - last->next = _g_list_alloc (); - last->next->data = data; - last->next->prev = last; - last->next->next = NULL; - - return list; - } -} - -/** - * g_list_concat: - * @list1: a #GList - * @list2: the #GList to add to the end of the first #GList - * - * Adds the second #GList onto the end of the first #GList. - * Note that the elements of the second #GList are not copied. - * They are used directly. - * - * Returns: the start of the new #GList - */ -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; -} - -/** - * g_list_remove: - * @list: a #GList - * @data: the data of the element to remove - * - * Removes an element from a #GList. - * If two elements contain the same data, only the first is removed. - * If none of the elements contain the data, the #GList is unchanged. - * - * Returns: the new start of the #GList - */ -GList* -g_list_remove (GList *list, - gconstpointer data) -{ - GList *tmp; - - tmp = list; - while (tmp) - { - if (tmp->data != data) - tmp = tmp->next; - else - { - if (tmp->prev) - tmp->prev->next = tmp->next; - if (tmp->next) - tmp->next->prev = tmp->prev; - - if (list == tmp) - list = list->next; - - _g_list_free1 (tmp); - - break; - } - } - return list; -} - -/** - * g_list_remove_all: - * @list: a #GList - * @data: data to remove - * - * Removes all list nodes with data equal to @data. - * Returns the new head of the list. Contrast with - * g_list_remove() which removes only the first node - * matching the given data. - * - * Returns: new head of @list - */ -GList* -g_list_remove_all (GList *list, - gconstpointer data) -{ - GList *tmp = list; - - while (tmp) - { - if (tmp->data != data) - tmp = tmp->next; - else - { - GList *next = tmp->next; - - if (tmp->prev) - tmp->prev->next = next; - else - list = next; - if (next) - next->prev = tmp->prev; - - _g_list_free1 (tmp); - tmp = next; - } - } - return list; -} - -static inline GList* -_g_list_remove_link (GList *list, - GList *link) -{ - if (link) - { - if (link->prev) - link->prev->next = link->next; - if (link->next) - link->next->prev = link->prev; - - if (link == list) - list = list->next; - - link->next = NULL; - link->prev = NULL; - } - - return list; -} - -/** - * g_list_remove_link: - * @list: a #GList - * @llink: an element in the #GList - * - * Removes an element from a #GList, without freeing the element. - * The removed element's prev and next links are set to %NULL, so - * that it becomes a self-contained list with one element. - * - * Returns: the new start of the #GList, without the element - */ -GList* -g_list_remove_link (GList *list, - GList *llink) -{ - return _g_list_remove_link (list, llink); -} - -/** - * g_list_delete_link: - * @list: a #GList - * @link_: node to delete from @list - * - * Removes the node link_ from the list and frees it. - * Compare this to g_list_remove_link() which removes the node - * without freeing it. - * - * Returns: the new head of @list - */ -GList* -g_list_delete_link (GList *list, - GList *link_) -{ - list = _g_list_remove_link (list, link_); - _g_list_free1 (link_); - - return list; -} - -/** - * g_list_copy: - * @list: a #GList - * - * Copies a #GList. - * - * <note><para> - * Note that this is a "shallow" copy. If the list elements - * consist of pointers to data, the pointers are copied but - * the actual data is not. - * </para></note> - * - * Returns: a copy of @list - */ -GList* -g_list_copy (GList *list) -{ - GList *new_list = NULL; - - if (list) - { - GList *last; - - new_list = _g_list_alloc (); - new_list->data = list->data; - new_list->prev = NULL; - last = new_list; - list = list->next; - while (list) - { - last->next = _g_list_alloc (); - last->next->prev = last; - last = last->next; - last->data = list->data; - list = list->next; - } - last->next = NULL; - } - - return new_list; -} - -/** - * g_list_reverse: - * @list: a #GList - * - * Reverses a #GList. - * It simply switches the next and prev pointers of each element. - * - * Returns: the start of the reversed #GList - */ -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; -} - -/** - * g_list_nth: - * @list: a #GList - * @n: the position of the element, counting from 0 - * - * Gets the element at the given position in a #GList. - * - * Returns: the element, or %NULL if the position is off - * the end of the #GList - */ -GList* -g_list_nth (GList *list, - guint n) -{ - while ((n-- > 0) && list) - list = list->next; - - return list; -} - -/** - * g_list_nth_prev: - * @list: a #GList - * @n: the position of the element, counting from 0 - * - * Gets the element @n places before @list. - * - * Returns: the element, or %NULL if the position is - * off the end of the #GList - */ -GList* -g_list_nth_prev (GList *list, - guint n) -{ - while ((n-- > 0) && list) - list = list->prev; - - return list; -} - -/** - * g_list_nth_data: - * @list: a #GList - * @n: the position of the element - * - * Gets the data of the element at the given position. - * - * Returns: the element's data, or %NULL if the position - * is off the end of the #GList - */ -gpointer -g_list_nth_data (GList *list, - guint n) -{ - while ((n-- > 0) && list) - list = list->next; - - return list ? list->data : NULL; -} - -/** - * g_list_find: - * @list: a #GList - * @data: the element data to find - * - * Finds the element in a #GList which - * contains the given data. - * - * Returns: the found #GList element, - * or %NULL if it is not found - */ -GList* -g_list_find (GList *list, - gconstpointer data) -{ - while (list) - { - if (list->data == data) - break; - list = list->next; - } - - return list; -} - -/** - * g_list_find_custom: - * @list: a #GList - * @data: user data passed to the function - * @func: the function to call for each element. - * It should return 0 when the desired element is found - * - * Finds an element in a #GList, using a supplied function to - * find the desired element. It iterates over the list, calling - * the given function which should return 0 when the desired - * element is found. The function takes two #gconstpointer arguments, - * the #GList element's data as the first argument and the - * given user data. - * - * Returns: the found #GList element, or %NULL if it is not found - */ -GList* -g_list_find_custom (GList *list, - gconstpointer data, - GCompareFunc func) -{ - g_return_val_if_fail (func != NULL, list); - - while (list) - { - if (! func (list->data, data)) - return list; - list = list->next; - } - - return NULL; -} - - -/** - * g_list_position: - * @list: a #GList - * @llink: an element in the #GList - * - * Gets the position of the given element - * in the #GList (starting from 0). - * - * Returns: the position of the element in the #GList, - * or -1 if the element is not found - */ -gint -g_list_position (GList *list, - GList *llink) -{ - gint i; - - i = 0; - while (list) - { - if (list == llink) - return i; - i++; - list = list->next; - } - - return -1; -} - -/** - * g_list_index: - * @list: a #GList - * @data: the data to find - * - * Gets the position of the element containing - * the given data (starting from 0). - * - * Returns: the index of the element containing the data, - * or -1 if the data is not found - */ -gint -g_list_index (GList *list, - gconstpointer data) -{ - gint i; - - i = 0; - while (list) - { - if (list->data == data) - return i; - i++; - list = list->next; - } - - return -1; -} - -/** - * g_list_last: - * @list: a #GList - * - * Gets the last element in a #GList. - * - * Returns: the last element in the #GList, - * or %NULL if the #GList has no elements - */ -GList* -g_list_last (GList *list) -{ - if (list) - { - while (list->next) - list = list->next; - } - - return list; -} - -/** - * g_list_first: - * @list: a #GList - * - * Gets the first element in a #GList. - * - * Returns: the first element in the #GList, - * or %NULL if the #GList has no elements - */ -GList* -g_list_first (GList *list) -{ - if (list) - { - while (list->prev) - list = list->prev; - } - - return list; -} - -/** - * g_list_length: - * @list: a #GList - * - * Gets the number of elements in a #GList. - * - * <note><para> - * This function iterates over the whole list to - * count its elements. - * </para></note> - * - * Returns: the number of elements in the #GList - */ -guint -g_list_length (GList *list) -{ - guint length; - - length = 0; - while (list) - { - length++; - list = list->next; - } - - return length; -} - -/** - * g_list_foreach: - * @list: a #GList - * @func: the function to call with each element's data - * @user_data: user data to pass to the function - * - * Calls a function for each element of a #GList. - */ -/** - * GFunc: - * @data: the element's data. - * @user_data: user data passed to g_list_foreach() or - * g_slist_foreach(). - * - * Specifies the type of functions passed to g_list_foreach() and - * g_slist_foreach(). - **/ -void -g_list_foreach (GList *list, - GFunc func, - gpointer user_data) -{ - while (list) - { - GList *next = list->next; - (*func) (list->data, user_data); - list = next; - } -} - -static GList* -g_list_insert_sorted_real (GList *list, - gpointer data, - GFunc func, - gpointer user_data) -{ - GList *tmp_list = list; - GList *new_list; - gint cmp; - - g_return_val_if_fail (func != NULL, list); - - if (!list) - { - new_list = _g_list_alloc0 (); - new_list->data = data; - return new_list; - } - - cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); - - while ((tmp_list->next) && (cmp > 0)) - { - tmp_list = tmp_list->next; - - cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); - } - - new_list = _g_list_alloc0 (); - 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; -} - -/** - * g_list_insert_sorted: - * @list: a pointer to a #GList - * @data: the data for the new element - * @func: the function to compare elements in the list. It should - * return a number > 0 if the first parameter comes after the - * second parameter in the sort order. - * - * Inserts a new element into the list, using the given comparison - * function to determine its position. - * - * Returns: the new start of the #GList - */ -GList* -g_list_insert_sorted (GList *list, - gpointer data, - GCompareFunc func) -{ - return g_list_insert_sorted_real (list, data, (GFunc) func, NULL); -} - -/** - * g_list_insert_sorted_with_data: - * @list: a pointer to a #GList - * @data: the data for the new element - * @func: the function to compare elements in the list. - * It should return a number > 0 if the first parameter - * comes after the second parameter in the sort order. - * @user_data: user data to pass to comparison function. - * - * Inserts a new element into the list, using the given comparison - * function to determine its position. - * - * Returns: the new start of the #GList - * - * Since: 2.10 - */ -GList* -g_list_insert_sorted_with_data (GList *list, - gpointer data, - GCompareDataFunc func, - gpointer user_data) -{ - return g_list_insert_sorted_real (list, data, (GFunc) func, user_data); -} - -static GList * -g_list_sort_merge (GList *l1, - GList *l2, - GFunc compare_func, - gpointer user_data) -{ - GList list, *l, *lprev; - gint cmp; - - l = &list; - lprev = NULL; - - while (l1 && l2) - { - cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); - - if (cmp <= 0) - { - l->next = l1; - l1 = l1->next; - } - else - { - l->next = l2; - l2 = l2->next; - } - l = l->next; - l->prev = lprev; - lprev = l; - } - l->next = l1 ? l1 : l2; - l->next->prev = l; - - return list.next; -} - -static GList* -g_list_sort_real (GList *list, - GFunc compare_func, - gpointer user_data) -{ - GList *l1, *l2; - - if (!list) - return NULL; - if (!list->next) - return list; - - l1 = list; - l2 = list->next; - - while ((l2 = l2->next) != NULL) - { - if ((l2 = l2->next) == NULL) - break; - l1 = l1->next; - } - l2 = l1->next; - l1->next = NULL; - - return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data), - g_list_sort_real (l2, compare_func, user_data), - compare_func, - user_data); -} - -/** - * g_list_sort: - * @list: a #GList - * @compare_func: the comparison function used to sort the #GList. - * This function is passed the data from 2 elements of the #GList - * and should return 0 if they are equal, a negative value if the - * first element comes before the second, or a positive value if - * the first element comes after the second. - * - * Sorts a #GList using the given comparison function. - * - * Returns: the start of the sorted #GList - */ -/** - * GCompareFunc: - * @a: a value. - * @b: a value to compare with. - * @Returns: negative value if @a < @b; zero if @a = @b; positive - * value if @a > @b. - * - * Specifies the type of a comparison function used to compare two - * values. The function should return a negative integer if the first - * value comes before the second, 0 if they are equal, or a positive - * integer if the first value comes after the second. - **/ -GList * -g_list_sort (GList *list, - GCompareFunc compare_func) -{ - return g_list_sort_real (list, (GFunc) compare_func, NULL); - -} - -/** - * g_list_sort_with_data: - * @list: a #GList - * @compare_func: comparison function - * @user_data: user data to pass to comparison function - * - * Like g_list_sort(), but the comparison function accepts - * a user data argument. - * - * Returns: the new head of @list - */ -/** - * GCompareDataFunc: - * @a: a value. - * @b: a value to compare with. - * @user_data: user data to pass to comparison function. - * @Returns: negative value if @a < @b; zero if @a = @b; positive - * value if @a > @b. - * - * Specifies the type of a comparison function used to compare two - * values. The function should return a negative integer if the first - * value comes before the second, 0 if they are equal, or a positive - * integer if the first value comes after the second. - **/ -GList * -g_list_sort_with_data (GList *list, - GCompareDataFunc compare_func, - gpointer user_data) -{ - return g_list_sort_real (list, (GFunc) compare_func, user_data); -} diff --git a/deps/glib/glist.h b/deps/glib/glist.h deleted file mode 100644 index 25a4f66f..00000000 --- a/deps/glib/glist.h +++ /dev/null @@ -1,120 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_LIST_H__ -#define __G_LIST_H__ - -#include <glib/gmem.h> - -G_BEGIN_DECLS - -typedef struct _GList GList; - -struct _GList -{ - gpointer data; - GList *next; - GList *prev; -}; - -/* Doubly linked lists - */ -GList* g_list_alloc (void) G_GNUC_WARN_UNUSED_RESULT; -void g_list_free (GList *list); -void g_list_free_1 (GList *list); -#define g_list_free1 g_list_free_1 -void g_list_free_full (GList *list, - GDestroyNotify free_func); -GList* g_list_append (GList *list, - gpointer data) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_prepend (GList *list, - gpointer data) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_insert (GList *list, - gpointer data, - gint position) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_insert_sorted (GList *list, - gpointer data, - GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_insert_sorted_with_data (GList *list, - gpointer data, - GCompareDataFunc func, - gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_insert_before (GList *list, - GList *sibling, - gpointer data) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_concat (GList *list1, - GList *list2) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_remove (GList *list, - gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_remove_all (GList *list, - gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_remove_link (GList *list, - GList *llink) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_delete_link (GList *list, - GList *link_) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_reverse (GList *list) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_copy (GList *list) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_nth (GList *list, - guint n); -GList* g_list_nth_prev (GList *list, - guint n); -GList* g_list_find (GList *list, - gconstpointer data); -GList* g_list_find_custom (GList *list, - gconstpointer data, - GCompareFunc func); -gint g_list_position (GList *list, - GList *llink); -gint g_list_index (GList *list, - gconstpointer data); -GList* g_list_last (GList *list); -GList* g_list_first (GList *list); -guint g_list_length (GList *list); -void g_list_foreach (GList *list, - GFunc func, - gpointer user_data); -GList* g_list_sort (GList *list, - GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT; -GList* g_list_sort_with_data (GList *list, - GCompareDataFunc compare_func, - gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; -gpointer g_list_nth_data (GList *list, - guint n); - - -#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL) -#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL) - -#ifndef G_DISABLE_DEPRECATED -void g_list_push_allocator (gpointer allocator); -void g_list_pop_allocator (void); -#endif - -G_END_DECLS - -#endif /* __G_LIST_H__ */ diff --git a/deps/glib/gmacros.h b/deps/glib/gmacros.h deleted file mode 100644 index 115d5d79..00000000 --- a/deps/glib/gmacros.h +++ /dev/null @@ -1,291 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* This file must not include any other glib header file and must thus - * not refer to variables from glibconfig.h - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_MACROS_H__ -#define __G_MACROS_H__ - -/* We include stddef.h to get the system's definition of NULL - */ -#include <stddef.h> - -/* Here we provide G_GNUC_EXTENSION as an alias for __extension__, - * where this is valid. This allows for warningless compilation of - * "long long" types even in the presence of '-ansi -pedantic'. - */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) -# define G_GNUC_EXTENSION __extension__ -#else -# define G_GNUC_EXTENSION -#endif - -/* Provide macros to feature the GCC function attribute. - */ -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) -#define G_GNUC_PURE \ - __attribute__((__pure__)) -#define G_GNUC_MALLOC \ - __attribute__((__malloc__)) -#else -#define G_GNUC_PURE -#define G_GNUC_MALLOC -#endif - -#if __GNUC__ >= 4 -#define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__)) -#else -#define G_GNUC_NULL_TERMINATED -#endif - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) -#define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) -#define G_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y))) -#else -#define G_GNUC_ALLOC_SIZE(x) -#define G_GNUC_ALLOC_SIZE2(x,y) -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define G_GNUC_PRINTF( format_idx, arg_idx ) \ - __attribute__((__format__ (__printf__, format_idx, arg_idx))) -#define G_GNUC_SCANF( format_idx, arg_idx ) \ - __attribute__((__format__ (__scanf__, format_idx, arg_idx))) -#define G_GNUC_FORMAT( arg_idx ) \ - __attribute__((__format_arg__ (arg_idx))) -#define G_GNUC_NORETURN \ - __attribute__((__noreturn__)) -#define G_GNUC_CONST \ - __attribute__((__const__)) -#define G_GNUC_UNUSED \ - __attribute__((__unused__)) -#define G_GNUC_NO_INSTRUMENT \ - __attribute__((__no_instrument_function__)) -#else /* !__GNUC__ */ -#define G_GNUC_PRINTF( format_idx, arg_idx ) -#define G_GNUC_SCANF( format_idx, arg_idx ) -#define G_GNUC_FORMAT( arg_idx ) -#define G_GNUC_NORETURN -#define G_GNUC_CONST -#define G_GNUC_UNUSED -#define G_GNUC_NO_INSTRUMENT -#endif /* !__GNUC__ */ - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) -#define G_GNUC_DEPRECATED \ - __attribute__((__deprecated__)) -#else -#define G_GNUC_DEPRECATED -#endif /* __GNUC__ */ - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#define G_GNUC_DEPRECATED_FOR(f) \ - __attribute__((deprecated("Use " #f " instead"))) -#else -#define G_GNUC_DEPRECATED_FOR(f) G_GNUC_DEPRECATED -#endif /* __GNUC__ */ - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) -# define G_GNUC_MAY_ALIAS __attribute__((may_alias)) -#else -# define G_GNUC_MAY_ALIAS -#endif - -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define G_GNUC_WARN_UNUSED_RESULT \ - __attribute__((warn_unused_result)) -#else -#define G_GNUC_WARN_UNUSED_RESULT -#endif /* __GNUC__ */ - -#ifndef G_DISABLE_DEPRECATED -/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with - * macros, so we can refer to them as strings unconditionally. - * usage not-recommended since gcc-3.0 - */ -#if defined (__GNUC__) && (__GNUC__ < 3) -#define G_GNUC_FUNCTION __FUNCTION__ -#define G_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__ -#else /* !__GNUC__ */ -#define G_GNUC_FUNCTION "" -#define G_GNUC_PRETTY_FUNCTION "" -#endif /* !__GNUC__ */ -#endif /* !G_DISABLE_DEPRECATED */ - -#define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string) -#define G_STRINGIFY_ARG(contents) #contents - -#ifndef __GI_SCANNER__ /* The static assert macro really confuses the introspection parser */ -#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2 -#define G_PASTE(identifier1,identifier2) G_PASTE_ARGS (identifier1, identifier2) - -#if defined (__GNUC__) -#define G_STATIC_ASSERT(EXPRESSION) \ - _Static_assert (EXPRESSION, "Static assertion failed: " G_STRINGIFY(EXPRESSION)) -#else -#define G_STATIC_ASSERT(EXPRESSION) -#endif - -#define G_STATIC_ASSERT_EXPR(expr) ((void) sizeof (char[(expr) ? 1 : -1])) -#endif - -/* Provide a string identifying the current code position */ -#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__cplusplus) -# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) ":" __PRETTY_FUNCTION__ "()" -#else -# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) -#endif - -/* Provide a string identifying the current function, non-concatenatable */ -#if defined (__GNUC__) -# define G_STRFUNC ((const char*) (__PRETTY_FUNCTION__)) -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L -# define G_STRFUNC ((const char*) (__func__)) -#else -# define G_STRFUNC ((const char*) ("???")) -#endif - -/* Guard C code in headers, while including them from C++ */ -#ifdef __cplusplus -# define G_BEGIN_DECLS extern "C" { -# define G_END_DECLS } -#else -# define G_BEGIN_DECLS -# define G_END_DECLS -#endif - -/* Provide definitions for some commonly used macros. - * Some of them are only provided if they haven't already - * been defined. It is assumed that if they are already - * defined then the current definition is correct. - */ -#ifndef NULL -# ifdef __cplusplus -# define NULL (0L) -# else /* !__cplusplus */ -# define NULL ((void*) 0) -# endif /* !__cplusplus */ -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -#undef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) - -#undef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#undef ABS -#define ABS(a) (((a) < 0) ? -(a) : (a)) - -#undef CLAMP -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) - -/* Count the number of elements in an array. The array must be defined - * as such; using this with a dynamically allocated array will give - * incorrect results. - */ -#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) - -/* Macros by analogy to GINT_TO_POINTER, GPOINTER_TO_INT - */ -#define GPOINTER_TO_SIZE(p) ((gsize) (p)) -#define GSIZE_TO_POINTER(s) ((gpointer) (gsize) (s)) - -/* Provide convenience macros for handling structure - * fields through their offsets. - */ - -#if defined(__GNUC__) && __GNUC__ >= 4 -# define G_STRUCT_OFFSET(struct_type, member) \ - ((glong) offsetof (struct_type, member)) -#else -# define G_STRUCT_OFFSET(struct_type, member) \ - ((glong) ((guint8*) &((struct_type*) 0)->member)) -#endif - -#define G_STRUCT_MEMBER_P(struct_p, struct_offset) \ - ((gpointer) ((guint8*) (struct_p) + (glong) (struct_offset))) -#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \ - (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset))) - -/* Provide simple macro statement wrappers: - * G_STMT_START { statements; } G_STMT_END; - * This can be used as a single statement, like: - * if (x) G_STMT_START { ... } G_STMT_END; else ... - * This intentionally does not use compiler extensions like GCC's '({...})' to - * avoid portability issue or side effects when compiled with different compilers. - */ -#if !(defined (G_STMT_START) && defined (G_STMT_END)) -# define G_STMT_START do -# define G_STMT_END while (0) -#endif - -/* Deprecated -- do not use. */ -#ifndef G_DISABLE_DEPRECATED -#ifdef G_DISABLE_CONST_RETURNS -#define G_CONST_RETURN -#else -#define G_CONST_RETURN const -#endif -#endif - -/* - * The G_LIKELY and G_UNLIKELY macros let the programmer give hints to - * the compiler about the expected result of an expression. Some compilers - * can use this information for optimizations. - * - * The _G_BOOLEAN_EXPR macro is intended to trigger a gcc warning when - * putting assignments in g_return_if_fail (). - */ -#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) -#define _G_BOOLEAN_EXPR(expr) \ - G_GNUC_EXTENSION ({ \ - int _g_boolean_var_; \ - if (expr) \ - _g_boolean_var_ = 1; \ - else \ - _g_boolean_var_ = 0; \ - _g_boolean_var_; \ -}) -#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1)) -#define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0)) -#else -#define G_LIKELY(expr) (expr) -#define G_UNLIKELY(expr) (expr) -#endif - -#endif /* __G_MACROS_H__ */ diff --git a/deps/glib/gmain.c b/deps/glib/gmain.c deleted file mode 100644 index 0075346d..00000000 --- a/deps/glib/gmain.c +++ /dev/null @@ -1,86 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * gmain.c: Main loop abstraction, timeouts, and idle functions - * Copyright 1998 Owen Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" -#include "glibconfig.h" - -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif /* HAVE_SYS_TIME_H */ - -#ifdef G_OS_WIN32 -#define STRICT -#include <windows.h> -#endif /* G_OS_WIN32 */ - -#include "gmessages.h" -#include "gmain.h" - -/** - * g_get_current_time: - * @result: #GTimeVal structure in which to store current time. - * - * Equivalent to the UNIX gettimeofday() function, but portable. - * - * You may find g_get_real_time() to be more convenient. - **/ -void -g_get_current_time (GTimeVal *result) -{ -#ifndef G_OS_WIN32 - struct timeval r; - - g_return_if_fail (result != NULL); - - /*this is required on alpha, there the timeval structs are int's - not longs and a cast only would fail horribly*/ - gettimeofday (&r, NULL); - result->tv_sec = r.tv_sec; - result->tv_usec = r.tv_usec; -#else - FILETIME ft; - guint64 time64; - - g_return_if_fail (result != NULL); - - GetSystemTimeAsFileTime (&ft); - memmove (&time64, &ft, sizeof (FILETIME)); - - /* Convert from 100s of nanoseconds since 1601-01-01 - * to Unix epoch. Yes, this is Y2038 unsafe. - */ - time64 -= G_GINT64_CONSTANT (116444736000000000); - time64 /= 10; - - result->tv_sec = time64 / 1000000; - result->tv_usec = time64 % 1000000; -#endif -} diff --git a/deps/glib/gmain.h b/deps/glib/gmain.h deleted file mode 100644 index c9eeb821..00000000 --- a/deps/glib/gmain.h +++ /dev/null @@ -1,35 +0,0 @@ -/* gmain.h - the GLib Main loop - * Copyright (C) 1998-2000 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_MAIN_H__ -#define __G_MAIN_H__ - -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -/* Miscellaneous functions - */ -void g_get_current_time (GTimeVal *result); - -G_END_DECLS - -#endif /* __G_MAIN_H__ */ diff --git a/deps/glib/gmem.c b/deps/glib/gmem.c deleted file mode 100644 index d38fcdf7..00000000 --- a/deps/glib/gmem.c +++ /dev/null @@ -1,1395 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include "gmem.h" - -#include <stdlib.h> -#include <string.h> -#include <signal.h> - -#include "gbacktrace.h" -#include "gtestutils.h" -#include "gthread.h" -#include "glib_trace.h" - - -#define MEM_PROFILE_TABLE_SIZE 4096 - - -/* notes on macros: - * having G_DISABLE_CHECKS defined disables use of glib_mem_profiler_table and - * g_mem_profile(). - * REALLOC_0_WORKS is defined if g_realloc (NULL, x) works. - * SANE_MALLOC_PROTOS is defined if the systems malloc() and friends functions - * match the corresponding GLib prototypes, keep configure.ac and gmem.h in sync here. - * g_mem_gc_friendly is TRUE, freed memory should be 0-wiped. - */ - -/* --- prototypes --- */ -static gboolean g_mem_initialized = FALSE; -static void g_mem_init_nomessage (void); - - -/* --- malloc wrappers --- */ -#ifndef REALLOC_0_WORKS -static gpointer -standard_realloc (gpointer mem, - gsize n_bytes) -{ - if (!mem) - return malloc (n_bytes); - else - return realloc (mem, n_bytes); -} -#endif /* !REALLOC_0_WORKS */ - -#ifdef SANE_MALLOC_PROTOS -# define standard_malloc malloc -# ifdef REALLOC_0_WORKS -# define standard_realloc realloc -# endif /* REALLOC_0_WORKS */ -# define standard_free free -# define standard_calloc calloc -# define standard_try_malloc malloc -# define standard_try_realloc realloc -#else /* !SANE_MALLOC_PROTOS */ -static gpointer -standard_malloc (gsize n_bytes) -{ - return malloc (n_bytes); -} -# ifdef REALLOC_0_WORKS -static gpointer -standard_realloc (gpointer mem, - gsize n_bytes) -{ - return realloc (mem, n_bytes); -} -# endif /* REALLOC_0_WORKS */ -static void -standard_free (gpointer mem) -{ - free (mem); -} -static gpointer -standard_calloc (gsize n_blocks, - gsize n_bytes) -{ - return calloc (n_blocks, n_bytes); -} -#define standard_try_malloc standard_malloc -#define standard_try_realloc standard_realloc -#endif /* !SANE_MALLOC_PROTOS */ - - -/* --- variables --- */ -static GMemVTable glib_mem_vtable = { - standard_malloc, - standard_realloc, - standard_free, - standard_calloc, - standard_try_malloc, - standard_try_realloc, -}; - -/** - * SECTION:memory - * @Short_Description: general memory-handling - * @Title: Memory Allocation - * - * These functions provide support for allocating and freeing memory. - * - * <note> - * If any call to allocate memory fails, the application is terminated. - * This also means that there is no need to check if the call succeeded. - * </note> - * - * <note> - * It's important to match g_malloc() with g_free(), plain malloc() with free(), - * and (if you're using C++) new with delete and new[] with delete[]. Otherwise - * bad things can happen, since these allocators may use different memory - * pools (and new/delete call constructors and destructors). See also - * g_mem_set_vtable(). - * </note> - */ - -/* --- functions --- */ -/** - * g_malloc: - * @n_bytes: the number of bytes to allocate - * - * Allocates @n_bytes bytes of memory. - * If @n_bytes is 0 it returns %NULL. - * - * Returns: a pointer to the allocated memory - */ -gpointer -g_malloc (gsize n_bytes) -{ - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (n_bytes)) - { - gpointer mem; - - mem = glib_mem_vtable.malloc (n_bytes); - TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0)); - if (mem) - return mem; - - g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes", - G_STRLOC, n_bytes); - } - - TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0)); - - return NULL; -} - -/** - * g_malloc0: - * @n_bytes: the number of bytes to allocate - * - * Allocates @n_bytes bytes of memory, initialized to 0's. - * If @n_bytes is 0 it returns %NULL. - * - * Returns: a pointer to the allocated memory - */ -gpointer -g_malloc0 (gsize n_bytes) -{ - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (n_bytes)) - { - gpointer mem; - - mem = glib_mem_vtable.calloc (1, n_bytes); - TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0)); - if (mem) - return mem; - - g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes", - G_STRLOC, n_bytes); - } - - TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0)); - - return NULL; -} - -/** - * g_realloc: - * @mem: the memory to reallocate - * @n_bytes: new size of the memory in bytes - * - * Reallocates the memory pointed to by @mem, so that it now has space for - * @n_bytes bytes of memory. It returns the new address of the memory, which may - * have been moved. @mem may be %NULL, in which case it's considered to - * have zero-length. @n_bytes may be 0, in which case %NULL will be returned - * and @mem will be freed unless it is %NULL. - * - * Returns: the new address of the allocated memory - */ -gpointer -g_realloc (gpointer mem, - gsize n_bytes) -{ - gpointer newmem; - - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (n_bytes)) - { - newmem = glib_mem_vtable.realloc (mem, n_bytes); - TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0)); - if (newmem) - return newmem; - - g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes", - G_STRLOC, n_bytes); - } - - if (mem) - glib_mem_vtable.free (mem); - - TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0)); - - return NULL; -} - -/** - * g_free: - * @mem: the memory to free - * - * Frees the memory pointed to by @mem. - * If @mem is %NULL it simply returns. - */ -void -g_free (gpointer mem) -{ - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (mem)) - glib_mem_vtable.free (mem); - TRACE(GLIB_MEM_FREE((void*) mem)); -} - -/** - * g_try_malloc: - * @n_bytes: number of bytes to allocate. - * - * Attempts to allocate @n_bytes, and returns %NULL on failure. - * Contrast with g_malloc(), which aborts the program on failure. - * - * Returns: the allocated memory, or %NULL. - */ -gpointer -g_try_malloc (gsize n_bytes) -{ - gpointer mem; - - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (n_bytes)) - mem = glib_mem_vtable.try_malloc (n_bytes); - else - mem = NULL; - - TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 1)); - - return mem; -} - -/** - * g_try_malloc0: - * @n_bytes: number of bytes to allocate - * - * Attempts to allocate @n_bytes, initialized to 0's, and returns %NULL on - * failure. Contrast with g_malloc0(), which aborts the program on failure. - * - * Since: 2.8 - * Returns: the allocated memory, or %NULL - */ -gpointer -g_try_malloc0 (gsize n_bytes) -{ - gpointer mem; - - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (n_bytes)) - mem = glib_mem_vtable.try_malloc (n_bytes); - else - mem = NULL; - - if (mem) - memset (mem, 0, n_bytes); - - return mem; -} - -/** - * g_try_realloc: - * @mem: previously-allocated memory, or %NULL. - * @n_bytes: number of bytes to allocate. - * - * Attempts to realloc @mem to a new size, @n_bytes, and returns %NULL - * on failure. Contrast with g_realloc(), which aborts the program - * on failure. If @mem is %NULL, behaves the same as g_try_malloc(). - * - * Returns: the allocated memory, or %NULL. - */ -gpointer -g_try_realloc (gpointer mem, - gsize n_bytes) -{ - gpointer newmem; - - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - if (G_LIKELY (n_bytes)) - newmem = glib_mem_vtable.try_realloc (mem, n_bytes); - else - { - newmem = NULL; - if (mem) - glib_mem_vtable.free (mem); - } - - TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 1)); - - return newmem; -} - - -#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b))) - -/** - * g_malloc_n: - * @n_blocks: the number of blocks to allocate - * @n_block_bytes: the size of each block in bytes - * - * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes, - * but care is taken to detect possible overflow during multiplication. - * - * Since: 2.24 - * Returns: a pointer to the allocated memory - */ -gpointer -g_malloc_n (gsize n_blocks, - gsize n_block_bytes) -{ - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) - { - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - - g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes", - G_STRLOC, n_blocks, n_block_bytes); - } - - return g_malloc (n_blocks * n_block_bytes); -} - -/** - * g_malloc0_n: - * @n_blocks: the number of blocks to allocate - * @n_block_bytes: the size of each block in bytes - * - * This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes, - * but care is taken to detect possible overflow during multiplication. - * - * Since: 2.24 - * Returns: a pointer to the allocated memory - */ -gpointer -g_malloc0_n (gsize n_blocks, - gsize n_block_bytes) -{ - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) - { - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - - g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes", - G_STRLOC, n_blocks, n_block_bytes); - } - - return g_malloc0 (n_blocks * n_block_bytes); -} - -/** - * g_realloc_n: - * @mem: the memory to reallocate - * @n_blocks: the number of blocks to allocate - * @n_block_bytes: the size of each block in bytes - * - * This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes, - * but care is taken to detect possible overflow during multiplication. - * - * Since: 2.24 - * Returns: the new address of the allocated memory - */ -gpointer -g_realloc_n (gpointer mem, - gsize n_blocks, - gsize n_block_bytes) -{ - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) - { - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - - g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes", - G_STRLOC, n_blocks, n_block_bytes); - } - - return g_realloc (mem, n_blocks * n_block_bytes); -} - -/** - * g_try_malloc_n: - * @n_blocks: the number of blocks to allocate - * @n_block_bytes: the size of each block in bytes - * - * This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes, - * but care is taken to detect possible overflow during multiplication. - * - * Since: 2.24 - * Returns: the allocated memory, or %NULL. - */ -gpointer -g_try_malloc_n (gsize n_blocks, - gsize n_block_bytes) -{ - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) - return NULL; - - return g_try_malloc (n_blocks * n_block_bytes); -} - -/** - * g_try_malloc0_n: - * @n_blocks: the number of blocks to allocate - * @n_block_bytes: the size of each block in bytes - * - * This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes, - * but care is taken to detect possible overflow during multiplication. - * - * Since: 2.24 - * Returns: the allocated memory, or %NULL - */ -gpointer -g_try_malloc0_n (gsize n_blocks, - gsize n_block_bytes) -{ - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) - return NULL; - - return g_try_malloc0 (n_blocks * n_block_bytes); -} - -/** - * g_try_realloc_n: - * @mem: previously-allocated memory, or %NULL. - * @n_blocks: the number of blocks to allocate - * @n_block_bytes: the size of each block in bytes - * - * This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes, - * but care is taken to detect possible overflow during multiplication. - * - * Since: 2.24 - * Returns: the allocated memory, or %NULL. - */ -gpointer -g_try_realloc_n (gpointer mem, - gsize n_blocks, - gsize n_block_bytes) -{ - if (SIZE_OVERFLOWS (n_blocks, n_block_bytes)) - return NULL; - - return g_try_realloc (mem, n_blocks * n_block_bytes); -} - - - -static gpointer -fallback_calloc (gsize n_blocks, - gsize n_block_bytes) -{ - gsize l = n_blocks * n_block_bytes; - gpointer mem = glib_mem_vtable.malloc (l); - - if (mem) - memset (mem, 0, l); - - return mem; -} - -static gboolean vtable_set = FALSE; - -/** - * g_mem_is_system_malloc - * - * Checks whether the allocator used by g_malloc() is the system's - * malloc implementation. If it returns %TRUE memory allocated with - * malloc() can be used interchangeable with memory allocated using g_malloc(). - * This function is useful for avoiding an extra copy of allocated memory returned - * by a non-GLib-based API. - * - * A different allocator can be set using g_mem_set_vtable(). - * - * Return value: if %TRUE, malloc() and g_malloc() can be mixed. - **/ -gboolean -g_mem_is_system_malloc (void) -{ - return !vtable_set; -} - -/** - * g_mem_set_vtable: - * @vtable: table of memory allocation routines. - * - * Sets the #GMemVTable to use for memory allocation. You can use this to provide - * custom memory allocation routines. <emphasis>This function must be called - * before using any other GLib functions.</emphasis> The @vtable only needs to - * provide malloc(), realloc(), and free() functions; GLib can provide default - * implementations of the others. The malloc() and realloc() implementations - * should return %NULL on failure, GLib will handle error-checking for you. - * @vtable is copied, so need not persist after this function has been called. - */ -void -g_mem_set_vtable (GMemVTable *vtable) -{ - if (!vtable_set) - { - if (vtable->malloc && vtable->realloc && vtable->free) - { - glib_mem_vtable.malloc = vtable->malloc; - glib_mem_vtable.realloc = vtable->realloc; - glib_mem_vtable.free = vtable->free; - glib_mem_vtable.calloc = vtable->calloc ? vtable->calloc : fallback_calloc; - glib_mem_vtable.try_malloc = vtable->try_malloc ? vtable->try_malloc : glib_mem_vtable.malloc; - glib_mem_vtable.try_realloc = vtable->try_realloc ? vtable->try_realloc : glib_mem_vtable.realloc; - vtable_set = TRUE; - } - else - g_warning (G_STRLOC ": memory allocation vtable lacks one of malloc(), realloc() or free()"); - } - else - g_warning (G_STRLOC ": memory allocation vtable can only be set once at startup"); -} - - -/* --- memory profiling and checking --- */ -#ifdef G_DISABLE_CHECKS -/** - * glib_mem_profiler_table: - * - * A #GMemVTable containing profiling variants of the memory - * allocation functions. Use them together with g_mem_profile() - * in order to get information about the memory allocation pattern - * of your program. - */ -GMemVTable *glib_mem_profiler_table = &glib_mem_vtable; -void -g_mem_profile (void) -{ -} -#else /* !G_DISABLE_CHECKS */ -typedef enum { - PROFILER_FREE = 0, - PROFILER_ALLOC = 1, - PROFILER_RELOC = 2, - PROFILER_ZINIT = 4 -} ProfilerJob; -static guint *profile_data = NULL; -static gsize profile_allocs = 0; -static gsize profile_zinit = 0; -static gsize profile_frees = 0; -static GMutex *gmem_profile_mutex = NULL; -#ifdef G_ENABLE_DEBUG -static volatile gsize g_trap_free_size = 0; -static volatile gsize g_trap_realloc_size = 0; -static volatile gsize g_trap_malloc_size = 0; -#endif /* G_ENABLE_DEBUG */ - -#define PROFILE_TABLE(f1,f2,f3) ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1)) - -static void -profiler_log (ProfilerJob job, - gsize n_bytes, - gboolean success) -{ - g_mutex_lock (gmem_profile_mutex); - if (!profile_data) - { - profile_data = standard_calloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8, - sizeof (profile_data[0])); - if (!profile_data) /* memory system kiddin' me, eh? */ - { - g_mutex_unlock (gmem_profile_mutex); - return; - } - } - - if (n_bytes < MEM_PROFILE_TABLE_SIZE) - profile_data[n_bytes + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0, - (job & PROFILER_RELOC) != 0, - success != 0)] += 1; - else - profile_data[MEM_PROFILE_TABLE_SIZE + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0, - (job & PROFILER_RELOC) != 0, - success != 0)] += 1; - if (success) - { - if (job & PROFILER_ALLOC) - { - profile_allocs += n_bytes; - if (job & PROFILER_ZINIT) - profile_zinit += n_bytes; - } - else - profile_frees += n_bytes; - } - g_mutex_unlock (gmem_profile_mutex); -} - -static void -profile_print_locked (guint *local_data, - gboolean success) -{ - gboolean need_header = TRUE; - guint i; - - for (i = 0; i <= MEM_PROFILE_TABLE_SIZE; i++) - { - glong t_malloc = local_data[i + PROFILE_TABLE (1, 0, success)]; - glong t_realloc = local_data[i + PROFILE_TABLE (1, 1, success)]; - glong t_free = local_data[i + PROFILE_TABLE (0, 0, success)]; - glong t_refree = local_data[i + PROFILE_TABLE (0, 1, success)]; - - if (!t_malloc && !t_realloc && !t_free && !t_refree) - continue; - else if (need_header) - { - need_header = FALSE; - g_print (" blocks of | allocated | freed | allocated | freed | n_bytes \n"); - g_print (" n_bytes | n_times by | n_times by | n_times by | n_times by | remaining \n"); - g_print (" | malloc() | free() | realloc() | realloc() | \n"); - g_print ("===========|============|============|============|============|===========\n"); - } - if (i < MEM_PROFILE_TABLE_SIZE) - g_print ("%10u | %10ld | %10ld | %10ld | %10ld |%+11ld\n", - i, t_malloc, t_free, t_realloc, t_refree, - (t_malloc - t_free + t_realloc - t_refree) * i); - else if (i >= MEM_PROFILE_TABLE_SIZE) - g_print (" >%6u | %10ld | %10ld | %10ld | %10ld | ***\n", - i, t_malloc, t_free, t_realloc, t_refree); - } - if (need_header) - g_print (" --- none ---\n"); -} - -/** - * g_mem_profile: - * @void: - * - * Outputs a summary of memory usage. - * - * It outputs the frequency of allocations of different sizes, - * the total number of bytes which have been allocated, - * the total number of bytes which have been freed, - * and the difference between the previous two values, i.e. the number of bytes - * still in use. - * - * Note that this function will not output anything unless you have - * previously installed the #glib_mem_profiler_table with g_mem_set_vtable(). - */ - -void -g_mem_profile (void) -{ - guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])]; - gsize local_allocs; - gsize local_zinit; - gsize local_frees; - - if (G_UNLIKELY (!g_mem_initialized)) - g_mem_init_nomessage(); - - g_mutex_lock (gmem_profile_mutex); - - local_allocs = profile_allocs; - local_zinit = profile_zinit; - local_frees = profile_frees; - - if (!profile_data) - { - g_mutex_unlock (gmem_profile_mutex); - return; - } - - memcpy (local_data, profile_data, - (MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])); - - g_mutex_unlock (gmem_profile_mutex); - - g_print ("GLib Memory statistics (successful operations):\n"); - profile_print_locked (local_data, TRUE); - g_print ("GLib Memory statistics (failing operations):\n"); - profile_print_locked (local_data, FALSE); - g_print ("Total bytes: allocated=%"G_GSIZE_FORMAT", " - "zero-initialized=%"G_GSIZE_FORMAT" (%.2f%%), " - "freed=%"G_GSIZE_FORMAT" (%.2f%%), " - "remaining=%"G_GSIZE_FORMAT"\n", - local_allocs, - local_zinit, - ((gdouble) local_zinit) / local_allocs * 100.0, - local_frees, - ((gdouble) local_frees) / local_allocs * 100.0, - local_allocs - local_frees); -} - -static gpointer -profiler_try_malloc (gsize n_bytes) -{ - gsize *p; - -#ifdef G_ENABLE_DEBUG - if (g_trap_malloc_size == n_bytes) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ - - p = standard_malloc (sizeof (gsize) * 2 + n_bytes); - - if (p) - { - p[0] = 0; /* free count */ - p[1] = n_bytes; /* length */ - profiler_log (PROFILER_ALLOC, n_bytes, TRUE); - p += 2; - } - else - profiler_log (PROFILER_ALLOC, n_bytes, FALSE); - - return p; -} - -static gpointer -profiler_malloc (gsize n_bytes) -{ - gpointer mem = profiler_try_malloc (n_bytes); - - if (!mem) - g_mem_profile (); - - return mem; -} - -static gpointer -profiler_calloc (gsize n_blocks, - gsize n_block_bytes) -{ - gsize l = n_blocks * n_block_bytes; - gsize *p; - -#ifdef G_ENABLE_DEBUG - if (g_trap_malloc_size == l) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ - - p = standard_calloc (1, sizeof (gsize) * 2 + l); - - if (p) - { - p[0] = 0; /* free count */ - p[1] = l; /* length */ - profiler_log (PROFILER_ALLOC | PROFILER_ZINIT, l, TRUE); - p += 2; - } - else - { - profiler_log (PROFILER_ALLOC | PROFILER_ZINIT, l, FALSE); - g_mem_profile (); - } - - return p; -} - -static void -profiler_free (gpointer mem) -{ - gsize *p = mem; - - p -= 2; - if (p[0]) /* free count */ - { - g_warning ("free(%p): memory has been freed %"G_GSIZE_FORMAT" times already", - p + 2, p[0]); - profiler_log (PROFILER_FREE, - p[1], /* length */ - FALSE); - } - else - { -#ifdef G_ENABLE_DEBUG - if (g_trap_free_size == p[1]) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ - - profiler_log (PROFILER_FREE, - p[1], /* length */ - TRUE); - memset (p + 2, 0xaa, p[1]); - - /* for all those that miss standard_free (p); in this place, yes, - * we do leak all memory when profiling, and that is intentional - * to catch double frees. patch submissions are futile. - */ - } - p[0] += 1; -} - -static gpointer -profiler_try_realloc (gpointer mem, - gsize n_bytes) -{ - gsize *p = mem; - - p -= 2; - -#ifdef G_ENABLE_DEBUG - if (g_trap_realloc_size == n_bytes) - G_BREAKPOINT (); -#endif /* G_ENABLE_DEBUG */ - - if (mem && p[0]) /* free count */ - { - g_warning ("realloc(%p, %"G_GSIZE_FORMAT"): " - "memory has been freed %"G_GSIZE_FORMAT" times already", - p + 2, (gsize) n_bytes, p[0]); - profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE); - - return NULL; - } - else - { - p = standard_realloc (mem ? p : NULL, sizeof (gsize) * 2 + n_bytes); - - if (p) - { - if (mem) - profiler_log (PROFILER_FREE | PROFILER_RELOC, p[1], TRUE); - p[0] = 0; - p[1] = n_bytes; - profiler_log (PROFILER_ALLOC | PROFILER_RELOC, p[1], TRUE); - p += 2; - } - else - profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE); - - return p; - } -} - -static gpointer -profiler_realloc (gpointer mem, - gsize n_bytes) -{ - mem = profiler_try_realloc (mem, n_bytes); - - if (!mem) - g_mem_profile (); - - return mem; -} - -static GMemVTable profiler_table = { - profiler_malloc, - profiler_realloc, - profiler_free, - profiler_calloc, - profiler_try_malloc, - profiler_try_realloc, -}; -GMemVTable *glib_mem_profiler_table = &profiler_table; - -#endif /* !G_DISABLE_CHECKS */ - -/* --- MemChunks --- */ -/** - * SECTION:allocators - * @title: Memory Allocators - * @short_description: deprecated way to allocate chunks of memory for - * GList, GSList and GNode - * - * Prior to 2.10, #GAllocator was used as an efficient way to allocate - * small pieces of memory for use with the #GList, #GSList and #GNode - * data structures. Since 2.10, it has been completely replaced by the - * <link linkend="glib-Memory-Slices">slice allocator</link> and - * deprecated. - **/ - -/** - * SECTION:memory_chunks - * @title: Memory Chunks - * @short_description: deprecated way to allocate groups of equal-sized - * chunks of memory - * - * Memory chunks provide an space-efficient way to allocate equal-sized - * pieces of memory, called atoms. However, due to the administrative - * overhead (in particular for #G_ALLOC_AND_FREE, and when used from - * multiple threads), they are in practise often slower than direct use - * of g_malloc(). Therefore, memory chunks have been deprecated in - * favor of the <link linkend="glib-Memory-Slices">slice - * allocator</link>, which has been added in 2.10. All internal uses of - * memory chunks in GLib have been converted to the - * <literal>g_slice</literal> API. - * - * There are two types of memory chunks, #G_ALLOC_ONLY, and - * #G_ALLOC_AND_FREE. <itemizedlist> <listitem><para> #G_ALLOC_ONLY - * chunks only allow allocation of atoms. The atoms can never be freed - * individually. The memory chunk can only be free in its entirety. - * </para></listitem> <listitem><para> #G_ALLOC_AND_FREE chunks do - * allow atoms to be freed individually. The disadvantage of this is - * that the memory chunk has to keep track of which atoms have been - * freed. This results in more memory being used and a slight - * degradation in performance. </para></listitem> </itemizedlist> - * - * To create a memory chunk use g_mem_chunk_new() or the convenience - * macro g_mem_chunk_create(). - * - * To allocate a new atom use g_mem_chunk_alloc(), - * g_mem_chunk_alloc0(), or the convenience macros g_chunk_new() or - * g_chunk_new0(). - * - * To free an atom use g_mem_chunk_free(), or the convenience macro - * g_chunk_free(). (Atoms can only be freed if the memory chunk is - * created with the type set to #G_ALLOC_AND_FREE.) - * - * To free any blocks of memory which are no longer being used, use - * g_mem_chunk_clean(). To clean all memory chunks, use g_blow_chunks(). - * - * To reset the memory chunk, freeing all of the atoms, use - * g_mem_chunk_reset(). - * - * To destroy a memory chunk, use g_mem_chunk_destroy(). - * - * To help debug memory chunks, use g_mem_chunk_info() and - * g_mem_chunk_print(). - * - * <example> - * <title>Using a #GMemChunk</title> - * <programlisting> - * GMemChunk *mem_chunk; - * gchar *mem[10000]; - * gint i; - * - * /<!-- -->* Create a GMemChunk with atoms 50 bytes long, and memory - * blocks holding 100 bytes. Note that this means that only 2 atoms - * fit into each memory block and so isn't very efficient. *<!-- -->/ - * mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE); - * /<!-- -->* Now allocate 10000 atoms. *<!-- -->/ - * for (i = 0; i < 10000; i++) - * { - * mem[i] = g_chunk_new (gchar, mem_chunk); - * /<!-- -->* Fill in the atom memory with some junk. *<!-- -->/ - * for (j = 0; j < 50; j++) - * mem[i][j] = i * j; - * } - * /<!-- -->* Now free all of the atoms. Note that since we are going to - * destroy the GMemChunk, this wouldn't normally be used. *<!-- -->/ - * for (i = 0; i < 10000; i++) - * { - * g_mem_chunk_free (mem_chunk, mem[i]); - * } - * /<!-- -->* We are finished with the GMemChunk, so we destroy it. *<!-- -->/ - * g_mem_chunk_destroy (mem_chunk); - * </programlisting> - * </example> - * - * <example> - * <title>Using a #GMemChunk with data structures</title> - * <programlisting> - * GMemChunk *array_mem_chunk; - * GRealArray *array; - * /<!-- -->* Create a GMemChunk to hold GRealArray structures, using - * the g_mem_chunk_create(<!-- -->) convenience macro. We want 1024 atoms in each - * memory block, and we want to be able to free individual atoms. *<!-- -->/ - * array_mem_chunk = g_mem_chunk_create (GRealArray, 1024, G_ALLOC_AND_FREE); - * /<!-- -->* Allocate one atom, using the g_chunk_new(<!-- -->) convenience macro. *<!-- -->/ - * array = g_chunk_new (GRealArray, array_mem_chunk); - * /<!-- -->* We can now use array just like a normal pointer to a structure. *<!-- -->/ - * array->data = NULL; - * array->len = 0; - * array->alloc = 0; - * array->zero_terminated = (zero_terminated ? 1 : 0); - * array->clear = (clear ? 1 : 0); - * array->elt_size = elt_size; - * /<!-- -->* We can free the element, so it can be reused. *<!-- -->/ - * g_chunk_free (array, array_mem_chunk); - * /<!-- -->* We destroy the GMemChunk when we are finished with it. *<!-- -->/ - * g_mem_chunk_destroy (array_mem_chunk); - * </programlisting> - * </example> - **/ - -#ifndef G_ALLOC_AND_FREE - -/** - * GAllocator: - * - * The #GAllocator struct contains private data. and should only be - * accessed using the following functions. - **/ -typedef struct _GAllocator GAllocator; - -/** - * GMemChunk: - * - * The #GMemChunk struct is an opaque data structure representing a - * memory chunk. It should be accessed only through the use of the - * following functions. - **/ -typedef struct _GMemChunk GMemChunk; - -/** - * G_ALLOC_ONLY: - * - * Specifies the type of a #GMemChunk. Used in g_mem_chunk_new() and - * g_mem_chunk_create() to specify that atoms will never be freed - * individually. - **/ -#define G_ALLOC_ONLY 1 - -/** - * G_ALLOC_AND_FREE: - * - * Specifies the type of a #GMemChunk. Used in g_mem_chunk_new() and - * g_mem_chunk_create() to specify that atoms will be freed - * individually. - **/ -#define G_ALLOC_AND_FREE 2 -#endif - -struct _GMemChunk { - guint alloc_size; /* the size of an atom */ -}; - -/** - * g_mem_chunk_new: - * @name: a string to identify the #GMemChunk. It is not copied so it - * should be valid for the lifetime of the #GMemChunk. It is - * only used in g_mem_chunk_print(), which is used for debugging. - * @atom_size: the size, in bytes, of each element in the #GMemChunk. - * @area_size: the size, in bytes, of each block of memory allocated to - * contain the atoms. - * @type: the type of the #GMemChunk. #G_ALLOC_AND_FREE is used if the - * atoms will be freed individually. #G_ALLOC_ONLY should be - * used if atoms will never be freed individually. - * #G_ALLOC_ONLY is quicker, since it does not need to track - * free atoms, but it obviously wastes memory if you no longer - * need many of the atoms. - * @Returns: the new #GMemChunk. - * - * Creates a new #GMemChunk. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -GMemChunk* -g_mem_chunk_new (const gchar *name, - gint atom_size, - gsize area_size, - gint type) -{ - GMemChunk *mem_chunk; - g_return_val_if_fail (atom_size > 0, NULL); - - mem_chunk = g_slice_new (GMemChunk); - mem_chunk->alloc_size = atom_size; - return mem_chunk; -} - -/** - * g_mem_chunk_destroy: - * @mem_chunk: a #GMemChunk. - * - * Frees all of the memory allocated for a #GMemChunk. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void -g_mem_chunk_destroy (GMemChunk *mem_chunk) -{ - g_return_if_fail (mem_chunk != NULL); - - g_slice_free (GMemChunk, mem_chunk); -} - -/** - * g_mem_chunk_alloc: - * @mem_chunk: a #GMemChunk. - * @Returns: a pointer to the allocated atom. - * - * Allocates an atom of memory from a #GMemChunk. - * - * Deprecated:2.10: Use g_slice_alloc() instead - **/ -gpointer -g_mem_chunk_alloc (GMemChunk *mem_chunk) -{ - g_return_val_if_fail (mem_chunk != NULL, NULL); - - return g_slice_alloc (mem_chunk->alloc_size); -} - -/** - * g_mem_chunk_alloc0: - * @mem_chunk: a #GMemChunk. - * @Returns: a pointer to the allocated atom. - * - * Allocates an atom of memory from a #GMemChunk, setting the memory to - * 0. - * - * Deprecated:2.10: Use g_slice_alloc0() instead - **/ -gpointer -g_mem_chunk_alloc0 (GMemChunk *mem_chunk) -{ - g_return_val_if_fail (mem_chunk != NULL, NULL); - - return g_slice_alloc0 (mem_chunk->alloc_size); -} - -/** - * g_mem_chunk_free: - * @mem_chunk: a #GMemChunk. - * @mem: a pointer to the atom to free. - * - * Frees an atom in a #GMemChunk. This should only be called if the - * #GMemChunk was created with #G_ALLOC_AND_FREE. Otherwise it will - * simply return. - * - * Deprecated:2.10: Use g_slice_free1() instead - **/ -void -g_mem_chunk_free (GMemChunk *mem_chunk, - gpointer mem) -{ - g_return_if_fail (mem_chunk != NULL); - - g_slice_free1 (mem_chunk->alloc_size, mem); -} - -/** - * g_mem_chunk_clean: - * @mem_chunk: a #GMemChunk. - * - * Frees any blocks in a #GMemChunk which are no longer being used. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void g_mem_chunk_clean (GMemChunk *mem_chunk) {} - -/** - * g_mem_chunk_reset: - * @mem_chunk: a #GMemChunk. - * - * Resets a GMemChunk to its initial state. It frees all of the - * currently allocated blocks of memory. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void g_mem_chunk_reset (GMemChunk *mem_chunk) {} - - -/** - * g_mem_chunk_print: - * @mem_chunk: a #GMemChunk. - * - * Outputs debugging information for a #GMemChunk. It outputs the name - * of the #GMemChunk (set with g_mem_chunk_new()), the number of bytes - * used, and the number of blocks of memory allocated. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void g_mem_chunk_print (GMemChunk *mem_chunk) {} - - -/** - * g_mem_chunk_info: - * - * Outputs debugging information for all #GMemChunk objects currently - * in use. It outputs the number of #GMemChunk objects currently - * allocated, and calls g_mem_chunk_print() to output information on - * each one. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void g_mem_chunk_info (void) {} - -/** - * g_blow_chunks: - * - * Calls g_mem_chunk_clean() on all #GMemChunk objects. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void g_blow_chunks (void) {} - -/** - * g_chunk_new0: - * @type: the type of the #GMemChunk atoms, typically a structure name. - * @chunk: a #GMemChunk. - * @Returns: a pointer to the allocated atom, cast to a pointer to - * @type. - * - * A convenience macro to allocate an atom of memory from a #GMemChunk. - * It calls g_mem_chunk_alloc0() and casts the returned atom to a - * pointer to the given type, avoiding a type cast in the source code. - * - * Deprecated:2.10: Use g_slice_new0() instead - **/ - -/** - * g_chunk_free: - * @mem: a pointer to the atom to be freed. - * @mem_chunk: a #GMemChunk. - * - * A convenience macro to free an atom of memory from a #GMemChunk. It - * simply switches the arguments and calls g_mem_chunk_free() It is - * included simply to complement the other convenience macros, - * g_chunk_new() and g_chunk_new0(). - * - * Deprecated:2.10: Use g_slice_free() instead - **/ - -/** - * g_chunk_new: - * @type: the type of the #GMemChunk atoms, typically a structure name. - * @chunk: a #GMemChunk. - * @Returns: a pointer to the allocated atom, cast to a pointer to - * @type. - * - * A convenience macro to allocate an atom of memory from a #GMemChunk. - * It calls g_mem_chunk_alloc() and casts the returned atom to a - * pointer to the given type, avoiding a type cast in the source code. - * - * Deprecated:2.10: Use g_slice_new() instead - **/ - -/** - * g_mem_chunk_create: - * @type: the type of the atoms, typically a structure name. - * @pre_alloc: the number of atoms to store in each block of memory. - * @alloc_type: the type of the #GMemChunk. #G_ALLOC_AND_FREE is used - * if the atoms will be freed individually. #G_ALLOC_ONLY - * should be used if atoms will never be freed - * individually. #G_ALLOC_ONLY is quicker, since it does - * not need to track free atoms, but it obviously wastes - * memory if you no longer need many of the atoms. - * @Returns: the new #GMemChunk. - * - * A convenience macro for creating a new #GMemChunk. It calls - * g_mem_chunk_new(), using the given type to create the #GMemChunk - * name. The atom size is determined using - * <function>sizeof()</function>, and the area size is calculated by - * multiplying the @pre_alloc parameter with the atom size. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ - - -/** - * g_allocator_new: - * @name: the name of the #GAllocator. This name is used to set the - * name of the #GMemChunk used by the #GAllocator, and is only - * used for debugging. - * @n_preallocs: the number of elements in each block of memory - * allocated. Larger blocks mean less calls to - * g_malloc(), but some memory may be wasted. (GLib uses - * 128 elements per block by default.) The value must be - * between 1 and 65535. - * @Returns: a new #GAllocator. - * - * Creates a new #GAllocator. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -GAllocator* -g_allocator_new (const gchar *name, - guint n_preallocs) -{ - static struct _GAllocator { - gchar *name; - guint16 n_preallocs; - guint is_unused : 1; - guint type : 4; - GAllocator *last; - GMemChunk *mem_chunk; - gpointer free_list; - } dummy = { - "GAllocator is deprecated", 1, TRUE, 0, NULL, NULL, NULL, - }; - /* some (broken) GAllocator uses depend on non-NULL allocators */ - return (void*) &dummy; -} - -/** - * g_allocator_free: - * @allocator: a #GAllocator. - * - * Frees all of the memory allocated by the #GAllocator. - * - * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice - * allocator</link> instead - **/ -void -g_allocator_free (GAllocator *allocator) -{ -} - -#ifdef ENABLE_GC_FRIENDLY_DEFAULT -gboolean g_mem_gc_friendly = TRUE; -#else -/** - * g_mem_gc_friendly: - * - * This variable is %TRUE if the <envar>G_DEBUG</envar> environment variable - * includes the key <link linkend="G_DEBUG">gc-friendly</link>. - */ -gboolean g_mem_gc_friendly = FALSE; -#endif - -static void -g_mem_init_nomessage (void) -{ - gchar buffer[1024]; - const gchar *val; - const GDebugKey keys[] = { - { "gc-friendly", 1 }, - }; - gint flags; - if (g_mem_initialized) - return; - /* don't use g_malloc/g_message here */ - val = _g_getenv_nomalloc ("G_DEBUG", buffer); - flags = !val ? 0 : g_parse_debug_string (val, keys, G_N_ELEMENTS (keys)); - if (flags & 1) /* gc-friendly */ - { - g_mem_gc_friendly = TRUE; - } - g_mem_initialized = TRUE; -} - -void -_g_mem_thread_init_noprivate_nomessage (void) -{ - /* we may only create mutexes here, locking/ - * unlocking a mutex does not yet work. - */ - g_mem_init_nomessage(); -#ifndef G_DISABLE_CHECKS - gmem_profile_mutex = g_mutex_new (); -#endif -} diff --git a/deps/glib/gmem.h b/deps/glib/gmem.h deleted file mode 100644 index ca22786a..00000000 --- a/deps/glib/gmem.h +++ /dev/null @@ -1,307 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_MEM_H__ -#define __G_MEM_H__ - -#include <glib/gslice.h> -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -/** - * GMemVTable: - * @malloc: function to use for allocating memory. - * @realloc: function to use for reallocating memory. - * @free: function to use to free memory. - * @calloc: function to use for allocating zero-filled memory. - * @try_malloc: function to use for allocating memory without a default error handler. - * @try_realloc: function to use for reallocating memory without a default error handler. - * - * A set of functions used to perform memory allocation. The same #GMemVTable must - * be used for all allocations in the same program; a call to g_mem_set_vtable(), - * if it exists, should be prior to any use of GLib. - */ -typedef struct _GMemVTable GMemVTable; - - -#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG -/** - * G_MEM_ALIGN: - * - * Indicates the number of bytes to which memory will be aligned on the - * current platform. - */ -# define G_MEM_ALIGN GLIB_SIZEOF_VOID_P -#else /* GLIB_SIZEOF_VOID_P <= GLIB_SIZEOF_LONG */ -# define G_MEM_ALIGN GLIB_SIZEOF_LONG -#endif /* GLIB_SIZEOF_VOID_P <= GLIB_SIZEOF_LONG */ - - -/* Memory allocation functions - */ - -void g_free (gpointer mem); - -gpointer g_malloc (gsize n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -gpointer g_malloc0 (gsize n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -gpointer g_realloc (gpointer mem, - gsize n_bytes) G_GNUC_WARN_UNUSED_RESULT; -gpointer g_try_malloc (gsize n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -gpointer g_try_malloc0 (gsize n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -gpointer g_try_realloc (gpointer mem, - gsize n_bytes) G_GNUC_WARN_UNUSED_RESULT; - -gpointer g_malloc_n (gsize n_blocks, - gsize n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2); -gpointer g_malloc0_n (gsize n_blocks, - gsize n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2); -gpointer g_realloc_n (gpointer mem, - gsize n_blocks, - gsize n_block_bytes) G_GNUC_WARN_UNUSED_RESULT; -gpointer g_try_malloc_n (gsize n_blocks, - gsize n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2); -gpointer g_try_malloc0_n (gsize n_blocks, - gsize n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2); -gpointer g_try_realloc_n (gpointer mem, - gsize n_blocks, - gsize n_block_bytes) G_GNUC_WARN_UNUSED_RESULT; - - -/* Optimise: avoid the call to the (slower) _n function if we can - * determine at compile-time that no overflow happens. - */ -#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__) -# define _G_NEW(struct_type, n_structs, func) \ - (struct_type *) (G_GNUC_EXTENSION ({ \ - gsize __n = (gsize) (n_structs); \ - gsize __s = sizeof (struct_type); \ - gpointer __p; \ - if (__s == 1) \ - __p = g_##func (__n); \ - else if (__builtin_constant_p (__n) && \ - (__s == 0 || __n <= G_MAXSIZE / __s)) \ - __p = g_##func (__n * __s); \ - else \ - __p = g_##func##_n (__n, __s); \ - __p; \ - })) -# define _G_RENEW(struct_type, mem, n_structs, func) \ - (struct_type *) (G_GNUC_EXTENSION ({ \ - gsize __n = (gsize) (n_structs); \ - gsize __s = sizeof (struct_type); \ - gpointer __p = (gpointer) (mem); \ - if (__s == 1) \ - __p = g_##func (__p, __n); \ - else if (__builtin_constant_p (__n) && \ - (__s == 0 || __n <= G_MAXSIZE / __s)) \ - __p = g_##func (__p, __n * __s); \ - else \ - __p = g_##func##_n (__p, __n, __s); \ - __p; \ - })) - -#else - -/* Unoptimised version: always call the _n() function. */ - -#define _G_NEW(struct_type, n_structs, func) \ - ((struct_type *) g_##func##_n ((n_structs), sizeof (struct_type))) -#define _G_RENEW(struct_type, mem, n_structs, func) \ - ((struct_type *) g_##func##_n (mem, (n_structs), sizeof (struct_type))) - -#endif - -/** - * g_new: - * @struct_type: the type of the elements to allocate - * @n_structs: the number of elements to allocate - * - * Allocates @n_structs elements of type @struct_type. - * The returned pointer is cast to a pointer to the given type. - * If @n_structs is 0 it returns %NULL. - * Care is taken to avoid overflow when calculating the size of the allocated block. - * - * Since the returned pointer is already casted to the right type, - * it is normally unnecessary to cast it explicitly, and doing - * so might hide memory allocation errors. - * - * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type - */ -#define g_new(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc) -/** - * g_new0: - * @struct_type: the type of the elements to allocate. - * @n_structs: the number of elements to allocate. - * - * Allocates @n_structs elements of type @struct_type, initialized to 0's. - * The returned pointer is cast to a pointer to the given type. - * If @n_structs is 0 it returns %NULL. - * Care is taken to avoid overflow when calculating the size of the allocated block. - * - * Since the returned pointer is already casted to the right type, - * it is normally unnecessary to cast it explicitly, and doing - * so might hide memory allocation errors. - * - * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type. - */ -#define g_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, malloc0) -/** - * g_renew: - * @struct_type: the type of the elements to allocate - * @mem: the currently allocated memory - * @n_structs: the number of elements to allocate - * - * Reallocates the memory pointed to by @mem, so that it now has space for - * @n_structs elements of type @struct_type. It returns the new address of - * the memory, which may have been moved. - * Care is taken to avoid overflow when calculating the size of the allocated block. - * - * Returns: a pointer to the new allocated memory, cast to a pointer to @struct_type - */ -#define g_renew(struct_type, mem, n_structs) _G_RENEW (struct_type, mem, n_structs, realloc) -/** - * g_try_new: - * @struct_type: the type of the elements to allocate - * @n_structs: the number of elements to allocate - * - * Attempts to allocate @n_structs elements of type @struct_type, and returns - * %NULL on failure. Contrast with g_new(), which aborts the program on failure. - * The returned pointer is cast to a pointer to the given type. - * The function returns %NULL when @n_structs is 0 of if an overflow occurs. - * - * Since: 2.8 - * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type - */ -#define g_try_new(struct_type, n_structs) _G_NEW (struct_type, n_structs, try_malloc) -/** - * g_try_new0: - * @struct_type: the type of the elements to allocate - * @n_structs: the number of elements to allocate - * - * Attempts to allocate @n_structs elements of type @struct_type, initialized - * to 0's, and returns %NULL on failure. Contrast with g_new0(), which aborts - * the program on failure. - * The returned pointer is cast to a pointer to the given type. - * The function returns %NULL when @n_structs is 0 of if an overflow occurs. - * - * Since: 2.8 - * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type - */ -#define g_try_new0(struct_type, n_structs) _G_NEW (struct_type, n_structs, try_malloc0) -/** - * g_try_renew: - * @struct_type: the type of the elements to allocate - * @mem: the currently allocated memory - * @n_structs: the number of elements to allocate - * - * Attempts to reallocate the memory pointed to by @mem, so that it now has - * space for @n_structs elements of type @struct_type, and returns %NULL on - * failure. Contrast with g_renew(), which aborts the program on failure. - * It returns the new address of the memory, which may have been moved. - * The function returns %NULL if an overflow occurs. - * - * Since: 2.8 - * Returns: a pointer to the new allocated memory, cast to a pointer to @struct_type - */ -#define g_try_renew(struct_type, mem, n_structs) _G_RENEW (struct_type, mem, n_structs, try_realloc) - - -/* Memory allocation virtualization for debugging purposes - * g_mem_set_vtable() has to be the very first GLib function called - * if being used - */ -struct _GMemVTable { - gpointer (*malloc) (gsize n_bytes); - gpointer (*realloc) (gpointer mem, - gsize n_bytes); - void (*free) (gpointer mem); - /* optional; set to NULL if not used ! */ - gpointer (*calloc) (gsize n_blocks, - gsize n_block_bytes); - gpointer (*try_malloc) (gsize n_bytes); - gpointer (*try_realloc) (gpointer mem, - gsize n_bytes); -}; -void g_mem_set_vtable (GMemVTable *vtable); -gboolean g_mem_is_system_malloc (void); - -GLIB_VAR gboolean g_mem_gc_friendly; - -/* Memory profiler and checker, has to be enabled via g_mem_set_vtable() - */ -GLIB_VAR GMemVTable *glib_mem_profiler_table; -void g_mem_profile (void); - - -/* deprecated memchunks and allocators */ -#if !defined (G_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) || defined (GDK_COMPILATION) -typedef struct _GAllocator GAllocator; -typedef struct _GMemChunk GMemChunk; -#define g_mem_chunk_create(type, pre_alloc, alloc_type) ( \ - g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \ - sizeof (type), \ - sizeof (type) * (pre_alloc), \ - (alloc_type)) \ -) -#define g_chunk_new(type, chunk) ( \ - (type *) g_mem_chunk_alloc (chunk) \ -) -#define g_chunk_new0(type, chunk) ( \ - (type *) g_mem_chunk_alloc0 (chunk) \ -) -#define g_chunk_free(mem, mem_chunk) G_STMT_START { \ - g_mem_chunk_free ((mem_chunk), (mem)); \ -} G_STMT_END -#define G_ALLOC_ONLY 1 -#define G_ALLOC_AND_FREE 2 -GMemChunk* g_mem_chunk_new (const gchar *name, - gint atom_size, - gsize area_size, - gint type); -void g_mem_chunk_destroy (GMemChunk *mem_chunk); -gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk); -gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk); -void g_mem_chunk_free (GMemChunk *mem_chunk, - gpointer mem); -void g_mem_chunk_clean (GMemChunk *mem_chunk); -void g_mem_chunk_reset (GMemChunk *mem_chunk); -void g_mem_chunk_print (GMemChunk *mem_chunk); -void g_mem_chunk_info (void); -void g_blow_chunks (void); -GAllocator*g_allocator_new (const gchar *name, - guint n_preallocs); -void g_allocator_free (GAllocator *allocator); -#define G_ALLOCATOR_LIST (1) -#define G_ALLOCATOR_SLIST (2) -#define G_ALLOCATOR_NODE (3) -#endif /* G_DISABLE_DEPRECATED */ - -G_END_DECLS - -#endif /* __G_MEM_H__ */ diff --git a/deps/glib/gmessages.c b/deps/glib/gmessages.c deleted file mode 100644 index 8b6f5357..00000000 --- a/deps/glib/gmessages.c +++ /dev/null @@ -1,1082 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -/** - * SECTION:warnings - * @Title: Message Output and Debugging Functions - * @Short_description: functions to output messages and help debug applications - * - * These functions provide support for outputting messages. - * - * The <function>g_return</function> family of macros (g_return_if_fail(), - * g_return_val_if_fail(), g_return_if_reached(), g_return_val_if_reached()) - * should only be used for programming errors, a typical use case is - * checking for invalid parameters at the beginning of a public function. - * They should not be used if you just mean "if (error) return", they - * should only be used if you mean "if (bug in program) return". - * The program behavior is generally considered undefined after one - * of these checks fails. They are not intended for normal control - * flow, only to give a perhaps-helpful warning before giving up. - */ - -#include "config.h" - -#include <stdlib.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <signal.h> -#include <locale.h> -#include <errno.h> - -#include "gmessages.h" - -#include "gbacktrace.h" -#include "gconvert.h" -#include "gdebug.h" -#include "gmem.h" -#include "gprintfint.h" -#include "gtestutils.h" -#include "gthread.h" -#include "gthreadprivate.h" -#include "gstrfuncs.h" -#include "gstring.h" - -#ifdef G_OS_WIN32 -#include <process.h> /* For getpid() */ -#include <io.h> -# define STRICT /* Strict typing, please */ -# define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */ -# include <windows.h> -# undef STRICT -#endif - - -/* --- structures --- */ -typedef struct _GLogDomain GLogDomain; -typedef struct _GLogHandler GLogHandler; -struct _GLogDomain -{ - gchar *log_domain; - GLogLevelFlags fatal_mask; - GLogHandler *handlers; - GLogDomain *next; -}; -struct _GLogHandler -{ - guint id; - GLogLevelFlags log_level; - GLogFunc log_func; - gpointer data; - GLogHandler *next; -}; - - -/* --- variables --- */ -static GMutex *g_messages_lock = NULL; -static GLogDomain *g_log_domains = NULL; -static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK; -static GPrintFunc glib_print_func = NULL; -static GPrintFunc glib_printerr_func = NULL; -static GPrivate *g_log_depth = NULL; -static GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG; -static GLogFunc default_log_func = g_log_default_handler; -static gpointer default_log_data = NULL; -static GTestLogFatalFunc fatal_log_func = NULL; -static gpointer fatal_log_data; - -/* --- functions --- */ -#ifdef G_OS_WIN32 -# define STRICT -# include <windows.h> -# undef STRICT -static gboolean win32_keep_fatal_message = FALSE; - -/* This default message will usually be overwritten. */ -/* Yes, a fixed size buffer is bad. So sue me. But g_error() is never - * called with huge strings, is it? - */ -static gchar fatal_msg_buf[1000] = "Unspecified fatal error encountered, aborting."; -static gchar *fatal_msg_ptr = fatal_msg_buf; - -#undef write -static inline int -dowrite (int fd, - const void *buf, - unsigned int len) -{ - if (win32_keep_fatal_message) - { - memcpy (fatal_msg_ptr, buf, len); - fatal_msg_ptr += len; - *fatal_msg_ptr = 0; - return len; - } - - write (fd, buf, len); - - return len; -} -#define write(fd, buf, len) dowrite(fd, buf, len) - -#endif - -static void -write_string (int fd, - const gchar *string) -{ - write (fd, string, strlen (string)); -} - -static void -g_messages_prefixed_init (void) -{ - static gboolean initialized = FALSE; - - if (!initialized) - { - const gchar *val; - - initialized = TRUE; - val = g_getenv ("G_MESSAGES_PREFIXED"); - - if (val) - { - const GDebugKey keys[] = { - { "error", G_LOG_LEVEL_ERROR }, - { "critical", G_LOG_LEVEL_CRITICAL }, - { "warning", G_LOG_LEVEL_WARNING }, - { "message", G_LOG_LEVEL_MESSAGE }, - { "info", G_LOG_LEVEL_INFO }, - { "debug", G_LOG_LEVEL_DEBUG } - }; - - g_log_msg_prefix = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys)); - } - } -} - -static GLogDomain* -g_log_find_domain_L (const gchar *log_domain) -{ - register GLogDomain *domain; - - domain = g_log_domains; - while (domain) - { - if (strcmp (domain->log_domain, log_domain) == 0) - return domain; - domain = domain->next; - } - return NULL; -} - -static GLogDomain* -g_log_domain_new_L (const gchar *log_domain) -{ - register GLogDomain *domain; - - domain = g_new (GLogDomain, 1); - domain->log_domain = g_strdup (log_domain); - domain->fatal_mask = G_LOG_FATAL_MASK; - domain->handlers = NULL; - - domain->next = g_log_domains; - g_log_domains = domain; - - return domain; -} - -static void -g_log_domain_check_free_L (GLogDomain *domain) -{ - if (domain->fatal_mask == G_LOG_FATAL_MASK && - domain->handlers == NULL) - { - register GLogDomain *last, *work; - - last = NULL; - - work = g_log_domains; - while (work) - { - if (work == domain) - { - if (last) - last->next = domain->next; - else - g_log_domains = domain->next; - g_free (domain->log_domain); - g_free (domain); - break; - } - last = work; - work = last->next; - } - } -} - -static GLogFunc -g_log_domain_get_handler_L (GLogDomain *domain, - GLogLevelFlags log_level, - gpointer *data) -{ - if (domain && log_level) - { - register GLogHandler *handler; - - handler = domain->handlers; - while (handler) - { - if ((handler->log_level & log_level) == log_level) - { - *data = handler->data; - return handler->log_func; - } - handler = handler->next; - } - } - - *data = default_log_data; - return default_log_func; -} - -GLogLevelFlags -g_log_set_always_fatal (GLogLevelFlags fatal_mask) -{ - GLogLevelFlags old_mask; - - /* restrict the global mask to levels that are known to glib - * since this setting applies to all domains - */ - fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1; - /* force errors to be fatal */ - fatal_mask |= G_LOG_LEVEL_ERROR; - /* remove bogus flag */ - fatal_mask &= ~G_LOG_FLAG_FATAL; - - g_mutex_lock (g_messages_lock); - old_mask = g_log_always_fatal; - g_log_always_fatal = fatal_mask; - g_mutex_unlock (g_messages_lock); - - return old_mask; -} - -GLogLevelFlags -g_log_set_fatal_mask (const gchar *log_domain, - GLogLevelFlags fatal_mask) -{ - GLogLevelFlags old_flags; - register GLogDomain *domain; - - if (!log_domain) - log_domain = ""; - - /* force errors to be fatal */ - fatal_mask |= G_LOG_LEVEL_ERROR; - /* remove bogus flag */ - fatal_mask &= ~G_LOG_FLAG_FATAL; - - g_mutex_lock (g_messages_lock); - - domain = g_log_find_domain_L (log_domain); - if (!domain) - domain = g_log_domain_new_L (log_domain); - old_flags = domain->fatal_mask; - - domain->fatal_mask = fatal_mask; - g_log_domain_check_free_L (domain); - - g_mutex_unlock (g_messages_lock); - - return old_flags; -} - -guint -g_log_set_handler (const gchar *log_domain, - GLogLevelFlags log_levels, - GLogFunc log_func, - gpointer user_data) -{ - static guint handler_id = 0; - GLogDomain *domain; - GLogHandler *handler; - - g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0); - g_return_val_if_fail (log_func != NULL, 0); - - if (!log_domain) - log_domain = ""; - - handler = g_new (GLogHandler, 1); - - g_mutex_lock (g_messages_lock); - - domain = g_log_find_domain_L (log_domain); - if (!domain) - domain = g_log_domain_new_L (log_domain); - - handler->id = ++handler_id; - handler->log_level = log_levels; - handler->log_func = log_func; - handler->data = user_data; - handler->next = domain->handlers; - domain->handlers = handler; - - g_mutex_unlock (g_messages_lock); - - return handler_id; -} - -GLogFunc -g_log_set_default_handler (GLogFunc log_func, - gpointer user_data) -{ - GLogFunc old_log_func; - - g_mutex_lock (g_messages_lock); - old_log_func = default_log_func; - default_log_func = log_func; - default_log_data = user_data; - g_mutex_unlock (g_messages_lock); - - return old_log_func; -} - -/** - * g_test_log_set_fatal_handler: - * @log_func: the log handler function. - * @user_data: data passed to the log handler. - * - * Installs a non-error fatal log handler which can be - * used to decide whether log messages which are counted - * as fatal abort the program. - * - * The use case here is that you are running a test case - * that depends on particular libraries or circumstances - * and cannot prevent certain known critical or warning - * messages. So you install a handler that compares the - * domain and message to precisely not abort in such a case. - * - * Note that the handler is reset at the beginning of - * any test case, so you have to set it inside each test - * function which needs the special behavior. - * - * This handler has no effect on g_error messages. - * - * Since: 2.22 - **/ -void -g_test_log_set_fatal_handler (GTestLogFatalFunc log_func, - gpointer user_data) -{ - g_mutex_lock (g_messages_lock); - fatal_log_func = log_func; - fatal_log_data = user_data; - g_mutex_unlock (g_messages_lock); -} - -void -g_log_remove_handler (const gchar *log_domain, - guint handler_id) -{ - register GLogDomain *domain; - - g_return_if_fail (handler_id > 0); - - if (!log_domain) - log_domain = ""; - - g_mutex_lock (g_messages_lock); - domain = g_log_find_domain_L (log_domain); - if (domain) - { - GLogHandler *work, *last; - - last = NULL; - work = domain->handlers; - while (work) - { - if (work->id == handler_id) - { - if (last) - last->next = work->next; - else - domain->handlers = work->next; - g_log_domain_check_free_L (domain); - g_mutex_unlock (g_messages_lock); - g_free (work); - return; - } - last = work; - work = last->next; - } - } - g_mutex_unlock (g_messages_lock); - g_warning ("%s: could not find handler with id `%d' for domain \"%s\"", - G_STRLOC, handler_id, log_domain); -} - -void -g_logv (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *format, - va_list args1) -{ - gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0; - gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0; - gint i; - - log_level &= G_LOG_LEVEL_MASK; - if (!log_level) - return; - - for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i)) - { - register GLogLevelFlags test_level; - - test_level = 1 << i; - if (log_level & test_level) - { - guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth)); - GLogDomain *domain; - GLogFunc log_func; - GLogLevelFlags domain_fatal_mask; - gpointer data = NULL; - gboolean masquerade_fatal = FALSE; - - if (was_fatal) - test_level |= G_LOG_FLAG_FATAL; - if (was_recursion) - test_level |= G_LOG_FLAG_RECURSION; - - /* check recursion and lookup handler */ - g_mutex_lock (g_messages_lock); - domain = g_log_find_domain_L (log_domain ? log_domain : ""); - if (depth) - test_level |= G_LOG_FLAG_RECURSION; - depth++; - domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK; - if ((domain_fatal_mask | g_log_always_fatal) & test_level) - test_level |= G_LOG_FLAG_FATAL; - if (test_level & G_LOG_FLAG_RECURSION) - log_func = _g_log_fallback_handler; - else - log_func = g_log_domain_get_handler_L (domain, test_level, &data); - domain = NULL; - g_mutex_unlock (g_messages_lock); - - g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); - - /* had to defer debug initialization until we can keep track of recursion */ - if (!(test_level & G_LOG_FLAG_RECURSION) && !_g_debug_initialized) - { - GLogLevelFlags orig_test_level = test_level; - - _g_debug_init (); - if ((domain_fatal_mask | g_log_always_fatal) & test_level) - test_level |= G_LOG_FLAG_FATAL; - if (test_level != orig_test_level) - { - /* need a relookup, not nice, but not too bad either */ - g_mutex_lock (g_messages_lock); - domain = g_log_find_domain_L (log_domain ? log_domain : ""); - log_func = g_log_domain_get_handler_L (domain, test_level, &data); - domain = NULL; - g_mutex_unlock (g_messages_lock); - } - } - - if (test_level & G_LOG_FLAG_RECURSION) - { - /* we use a stack buffer of fixed size, since we're likely - * in an out-of-memory situation - */ - gchar buffer[1025]; - gsize size G_GNUC_UNUSED; - va_list args2; - - G_VA_COPY (args2, args1); - size = _g_vsnprintf (buffer, 1024, format, args2); - va_end (args2); - - log_func (log_domain, test_level, buffer, data); - } - else - { - gchar *msg; - va_list args2; - - G_VA_COPY (args2, args1); - msg = g_strdup_vprintf (format, args2); - va_end (args2); - - log_func (log_domain, test_level, msg, data); - - if ((test_level & G_LOG_FLAG_FATAL) - && !(test_level & G_LOG_LEVEL_ERROR)) - { - masquerade_fatal = fatal_log_func - && !fatal_log_func (log_domain, test_level, msg, fatal_log_data); - } - - g_free (msg); - } - - if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal) - { -#ifdef G_OS_WIN32 - gchar *locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL); - - MessageBox (NULL, locale_msg, NULL, - MB_ICONERROR|MB_SETFOREGROUND); - if (IsDebuggerPresent () && !(test_level & G_LOG_FLAG_RECURSION)) - G_BREAKPOINT (); - else - abort (); -#else - if (!(test_level & G_LOG_FLAG_RECURSION)) - G_BREAKPOINT (); - else - abort (); -#endif /* !G_OS_WIN32 */ - } - - depth--; - g_private_set (g_log_depth, GUINT_TO_POINTER (depth)); - } - } -} - -void -g_log (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *format, - ...) -{ - va_list args; - - va_start (args, format); - g_logv (log_domain, log_level, format, args); - va_end (args); -} - -void -g_return_if_fail_warning (const char *log_domain, - const char *pretty_function, - const char *expression) -{ - g_log (log_domain, - G_LOG_LEVEL_CRITICAL, - "%s: assertion `%s' failed", - pretty_function, - expression); -} - -void -g_warn_message (const char *domain, - const char *file, - int line, - const char *func, - const char *warnexpr) -{ - char *s, lstr[32]; - g_snprintf (lstr, 32, "%d", line); - if (warnexpr) - s = g_strconcat ("(", file, ":", lstr, "):", - func, func[0] ? ":" : "", - " runtime check failed: (", warnexpr, ")", NULL); - else - s = g_strconcat ("(", file, ":", lstr, "):", - func, func[0] ? ":" : "", - " ", "code should not be reached", NULL); - g_log (domain, G_LOG_LEVEL_WARNING, "%s", s); - g_free (s); -} - -void -g_assert_warning (const char *log_domain, - const char *file, - const int line, - const char *pretty_function, - const char *expression) -{ - g_log (log_domain, - G_LOG_LEVEL_ERROR, - expression - ? "file %s: line %d (%s): assertion failed: (%s)" - : "file %s: line %d (%s): should not be reached", - file, - line, - pretty_function, - expression); - abort (); -} - -#define CHAR_IS_SAFE(wc) (!((wc < 0x20 && wc != '\t' && wc != '\n' && wc != '\r') || \ - (wc == 0x7f) || \ - (wc >= 0x80 && wc < 0xa0))) - -/* For a radix of 8 we need at most 3 output bytes for 1 input - * byte. Additionally we might need up to 2 output bytes for the - * readix prefix and 1 byte for the trailing NULL. - */ -#define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3) - -static void -format_unsigned (gchar *buf, - gulong num, - guint radix) -{ - gulong tmp; - gchar c; - gint i, n; - - /* we may not call _any_ GLib functions here (or macros like g_return_if_fail()) */ - - if (radix != 8 && radix != 10 && radix != 16) - { - *buf = '\000'; - return; - } - - if (!num) - { - *buf++ = '0'; - *buf = '\000'; - return; - } - - if (radix == 16) - { - *buf++ = '0'; - *buf++ = 'x'; - } - else if (radix == 8) - { - *buf++ = '0'; - } - - n = 0; - tmp = num; - while (tmp) - { - tmp /= radix; - n++; - } - - i = n; - - /* Again we can't use g_assert; actually this check should _never_ fail. */ - if (n > FORMAT_UNSIGNED_BUFSIZE - 3) - { - *buf = '\000'; - return; - } - - while (num) - { - i--; - c = (num % radix); - if (c < 10) - buf[i] = c + '0'; - else - buf[i] = c + 'a' - 10; - num /= radix; - } - - buf[n] = '\000'; -} - -/* string size big enough to hold level prefix */ -#define STRING_BUFFER_SIZE (FORMAT_UNSIGNED_BUFSIZE + 32) - -#define ALERT_LEVELS (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING) - -static int -mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE], - GLogLevelFlags log_level) -{ - gboolean to_stdout = TRUE; - - /* we may not call _any_ GLib functions here */ - - switch (log_level & G_LOG_LEVEL_MASK) - { - case G_LOG_LEVEL_ERROR: - strcpy (level_prefix, "ERROR"); - to_stdout = FALSE; - break; - case G_LOG_LEVEL_CRITICAL: - strcpy (level_prefix, "CRITICAL"); - to_stdout = FALSE; - break; - case G_LOG_LEVEL_WARNING: - strcpy (level_prefix, "WARNING"); - to_stdout = FALSE; - break; - case G_LOG_LEVEL_MESSAGE: - strcpy (level_prefix, "Message"); - to_stdout = FALSE; - break; - case G_LOG_LEVEL_INFO: - strcpy (level_prefix, "INFO"); - break; - case G_LOG_LEVEL_DEBUG: - strcpy (level_prefix, "DEBUG"); - break; - default: - if (log_level) - { - strcpy (level_prefix, "LOG-"); - format_unsigned (level_prefix + 4, log_level & G_LOG_LEVEL_MASK, 16); - } - else - strcpy (level_prefix, "LOG"); - break; - } - if (log_level & G_LOG_FLAG_RECURSION) - strcat (level_prefix, " (recursed)"); - if (log_level & ALERT_LEVELS) - strcat (level_prefix, " **"); - -#ifdef G_OS_WIN32 - win32_keep_fatal_message = (log_level & G_LOG_FLAG_FATAL) != 0; -#endif - return to_stdout ? 1 : 2; -} - -void -_g_log_fallback_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer unused_data) -{ - gchar level_prefix[STRING_BUFFER_SIZE]; -#ifndef G_OS_WIN32 - gchar pid_string[FORMAT_UNSIGNED_BUFSIZE]; -#endif - int fd; - - /* we cannot call _any_ GLib functions in this fallback handler, - * which is why we skip UTF-8 conversion, etc. - * since we either recursed or ran out of memory, we're in a pretty - * pathologic situation anyways, what we can do is giving the - * the process ID unconditionally however. - */ - - fd = mklevel_prefix (level_prefix, log_level); - if (!message) - message = "(NULL) message"; - -#ifndef G_OS_WIN32 - format_unsigned (pid_string, getpid (), 10); -#endif - - if (log_domain) - write_string (fd, "\n"); - else - write_string (fd, "\n** "); - -#ifndef G_OS_WIN32 - write_string (fd, "(process:"); - write_string (fd, pid_string); - write_string (fd, "): "); -#endif - - if (log_domain) - { - write_string (fd, log_domain); - write_string (fd, "-"); - } - write_string (fd, level_prefix); - write_string (fd, ": "); - write_string (fd, message); -} - -void -g_log_default_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer unused_data) -{ - gchar level_prefix[STRING_BUFFER_SIZE], *string; - GString *gstring; - int fd; - - /* we can be called externally with recursion for whatever reason */ - if (log_level & G_LOG_FLAG_RECURSION) - { - _g_log_fallback_handler (log_domain, log_level, message, unused_data); - return; - } - - g_messages_prefixed_init (); - - fd = mklevel_prefix (level_prefix, log_level); - - gstring = g_string_new (NULL); - if (log_level & ALERT_LEVELS) - g_string_append (gstring, "\n"); - if (!log_domain) - g_string_append (gstring, "** "); - - if ((g_log_msg_prefix & log_level) == log_level) - { - const gchar *prg_name = g_get_prgname (); - - if (!prg_name) - g_string_append_printf (gstring, "(process:%lu): ", (gulong)getpid ()); - else - g_string_append_printf (gstring, "(%s:%lu): ", prg_name, (gulong)getpid ()); - } - - if (log_domain) - { - g_string_append (gstring, log_domain); - g_string_append_c (gstring, '-'); - } - g_string_append (gstring, level_prefix); - - g_string_append (gstring, ": "); - if (!message) - g_string_append (gstring, "(NULL) message"); - else - { - GString *msg; - - msg = g_string_new (message); - - g_string_append (gstring, msg->str); /* assume UTF-8 */ - - g_string_free (msg, TRUE); - } - g_string_append (gstring, "\n"); - - string = g_string_free (gstring, FALSE); - - write_string (fd, string); - g_free (string); -} - -/** - * g_set_print_handler: - * @func: the new print handler - * - * Sets the print handler. - * - * Any messages passed to g_print() will be output via - * the new handler. The default handler simply outputs - * the message to stdout. By providing your own handler - * you can redirect the output, to a GTK+ widget or a - * log file for example. - * - * Returns: the old print handler - */ -GPrintFunc -g_set_print_handler (GPrintFunc func) -{ - GPrintFunc old_print_func; - - g_mutex_lock (g_messages_lock); - old_print_func = glib_print_func; - glib_print_func = func; - g_mutex_unlock (g_messages_lock); - - return old_print_func; -} - -/** - * g_print: - * @format: the message format. See the printf() documentation - * @...: the parameters to insert into the format string - * - * Outputs a formatted message via the print handler. - * The default print handler simply outputs the message to stdout. - * - * g_print() should not be used from within libraries for debugging - * messages, since it may be redirected by applications to special - * purpose message windows or even files. Instead, libraries should - * use g_log(), or the convenience functions g_message(), g_warning() - * and g_error(). - */ -void -g_print (const gchar *format, - ...) -{ - va_list args; - gchar *string; - GPrintFunc local_glib_print_func; - - g_return_if_fail (format != NULL); - - va_start (args, format); - string = g_strdup_vprintf (format, args); - va_end (args); - - g_mutex_lock (g_messages_lock); - local_glib_print_func = glib_print_func; - g_mutex_unlock (g_messages_lock); - - if (local_glib_print_func) - local_glib_print_func (string); - else - { - fputs (string, stdout); /* assume UTF-8 */ - fflush (stdout); - } - g_free (string); -} - -/** - * g_set_printerr_handler: - * @func: the new error message handler - * - * Sets the handler for printing error messages. - * - * Any messages passed to g_printerr() will be output via - * the new handler. The default handler simply outputs the - * message to stderr. By providing your own handler you can - * redirect the output, to a GTK+ widget or a log file for - * example. - * - * Returns: the old error message handler - */ -GPrintFunc -g_set_printerr_handler (GPrintFunc func) -{ - GPrintFunc old_printerr_func; - - g_mutex_lock (g_messages_lock); - old_printerr_func = glib_printerr_func; - glib_printerr_func = func; - g_mutex_unlock (g_messages_lock); - - return old_printerr_func; -} - -/** - * g_printerr: - * @format: the message format. See the printf() documentation - * @...: the parameters to insert into the format string - * - * Outputs a formatted message via the error message handler. - * The default handler simply outputs the message to stderr. - * - * g_printerr() should not be used from within libraries. - * Instead g_log() should be used, or the convenience functions - * g_message(), g_warning() and g_error(). - */ -void -g_printerr (const gchar *format, - ...) -{ - va_list args; - gchar *string; - GPrintFunc local_glib_printerr_func; - - g_return_if_fail (format != NULL); - - va_start (args, format); - string = g_strdup_vprintf (format, args); - va_end (args); - - g_mutex_lock (g_messages_lock); - local_glib_printerr_func = glib_printerr_func; - g_mutex_unlock (g_messages_lock); - - if (local_glib_printerr_func) - local_glib_printerr_func (string); - else - { - fputs (string, stderr); /* assume UTF-8 */ - fflush (stderr); - } - g_free (string); -} - -gsize -g_printf_string_upper_bound (const gchar *format, - va_list args) -{ - gchar c; - return _g_vsnprintf (&c, 1, format, args) + 1; -} - -void -_g_messages_thread_init_nomessage (void) -{ - g_messages_lock = g_mutex_new (); - g_log_depth = g_private_new (NULL); - g_messages_prefixed_init (); - _g_debug_init (); -} - -gboolean _g_debug_initialized = FALSE; -guint _g_debug_flags = 0; - -void -_g_debug_init (void) -{ - const gchar *val; - - _g_debug_initialized = TRUE; - - val = g_getenv ("G_DEBUG"); - if (val != NULL) - { - const GDebugKey keys[] = { - {"fatal_warnings", G_DEBUG_FATAL_WARNINGS}, - {"fatal_criticals", G_DEBUG_FATAL_CRITICALS} - }; - - _g_debug_flags = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys)); - } - - if (_g_debug_flags & G_DEBUG_FATAL_WARNINGS) - { - GLogLevelFlags fatal_mask; - - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } - - if (_g_debug_flags & G_DEBUG_FATAL_CRITICALS) - { - GLogLevelFlags fatal_mask; - - fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); - fatal_mask |= G_LOG_LEVEL_CRITICAL; - g_log_set_always_fatal (fatal_mask); - } -} diff --git a/deps/glib/gmessages.h b/deps/glib/gmessages.h deleted file mode 100644 index 87f380d9..00000000 --- a/deps/glib/gmessages.h +++ /dev/null @@ -1,403 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_MESSAGES_H__ -#define __G_MESSAGES_H__ - -#include <stdarg.h> -#include <glib/gtypes.h> -#include <glib/gmacros.h> - -/* Suppress warnings when GCC is in -pedantic mode and not -std=c99 - */ -#if (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) -#pragma GCC system_header -#endif - -G_BEGIN_DECLS - -/* calculate a string size, guaranteed to fit format + args. - */ -gsize g_printf_string_upper_bound (const gchar* format, - va_list args); - -/* Log level shift offset for user defined - * log levels (0-7 are used by GLib). - */ -#define G_LOG_LEVEL_USER_SHIFT (8) - -/* Glib log levels and flags. - */ -typedef enum -{ - /* log flags */ - G_LOG_FLAG_RECURSION = 1 << 0, - G_LOG_FLAG_FATAL = 1 << 1, - - /* GLib log levels */ - G_LOG_LEVEL_ERROR = 1 << 2, /* always fatal */ - G_LOG_LEVEL_CRITICAL = 1 << 3, - G_LOG_LEVEL_WARNING = 1 << 4, - G_LOG_LEVEL_MESSAGE = 1 << 5, - G_LOG_LEVEL_INFO = 1 << 6, - G_LOG_LEVEL_DEBUG = 1 << 7, - - G_LOG_LEVEL_MASK = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL) -} GLogLevelFlags; - -/* GLib log levels that are considered fatal by default */ -#define G_LOG_FATAL_MASK (G_LOG_FLAG_RECURSION | G_LOG_LEVEL_ERROR) - -typedef void (*GLogFunc) (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer user_data); - -/* Logging mechanism - */ -guint g_log_set_handler (const gchar *log_domain, - GLogLevelFlags log_levels, - GLogFunc log_func, - gpointer user_data); -void g_log_remove_handler (const gchar *log_domain, - guint handler_id); -void g_log_default_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer unused_data); -GLogFunc g_log_set_default_handler (GLogFunc log_func, - gpointer user_data); -void g_log (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *format, - ...) G_GNUC_PRINTF (3, 4); -void g_logv (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *format, - va_list args); -GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain, - GLogLevelFlags fatal_mask); -GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask); - -/* internal */ -G_GNUC_INTERNAL void _g_log_fallback_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer unused_data); - -/* Internal functions, used to implement the following macros */ -void g_return_if_fail_warning (const char *log_domain, - const char *pretty_function, - const char *expression); -void g_warn_message (const char *domain, - const char *file, - int line, - const char *func, - const char *warnexpr); -#ifndef G_DISABLE_DEPRECATED -void g_assert_warning (const char *log_domain, - const char *file, - const int line, - const char *pretty_function, - const char *expression) G_GNUC_NORETURN; -#endif /* !G_DISABLE_DEPRECATED */ - - -#ifndef G_LOG_DOMAIN -#define G_LOG_DOMAIN ((gchar*) 0) -#endif /* G_LOG_DOMAIN */ -#ifdef G_HAVE_ISO_VARARGS -/* for(;;) ; so that GCC knows that control doesn't go past g_error(). - * Put space before ending semicolon to avoid C++ build warnings. - */ -#define g_error(...) G_STMT_START { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_ERROR, \ - __VA_ARGS__); \ - for (;;) ; \ - } G_STMT_END - -#define g_message(...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_MESSAGE, \ - __VA_ARGS__) -#define g_critical(...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - __VA_ARGS__) -#define g_warning(...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_WARNING, \ - __VA_ARGS__) -#define g_debug(...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_DEBUG, \ - __VA_ARGS__) -#elif defined(G_HAVE_GNUC_VARARGS) -#define g_error(format...) G_STMT_START { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_ERROR, \ - format); \ - for (;;) ; \ - } G_STMT_END - -#define g_message(format...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_MESSAGE, \ - format) -#define g_critical(format...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - format) -#define g_warning(format...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_WARNING, \ - format) -#define g_debug(format...) g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_DEBUG, \ - format) -#else /* no varargs macros */ -static void -g_error (const gchar *format, - ...) -{ - va_list args; - va_start (args, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args); - va_end (args); - - for(;;) ; -} -static void -g_message (const gchar *format, - ...) -{ - va_list args; - va_start (args, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args); - va_end (args); -} -static void -g_critical (const gchar *format, - ...) -{ - va_list args; - va_start (args, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, format, args); - va_end (args); -} -static void -g_warning (const gchar *format, - ...) -{ - va_list args; - va_start (args, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, args); - va_end (args); -} -static void -g_debug (const gchar *format, - ...) -{ - va_list args; - va_start (args, format); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args); - va_end (args); -} -#endif /* !__GNUC__ */ - -/** - * GPrintFunc: - * @string: the message to output - * - * Specifies the type of the print handler functions. - * These are called with the complete formatted string to output. - */ -typedef void (*GPrintFunc) (const gchar *string); -void g_print (const gchar *format, - ...) G_GNUC_PRINTF (1, 2); -GPrintFunc g_set_print_handler (GPrintFunc func); -void g_printerr (const gchar *format, - ...) G_GNUC_PRINTF (1, 2); -GPrintFunc g_set_printerr_handler (GPrintFunc func); - -/** - * g_warn_if_reached: - * - * Logs a critical warning. - * - * Since: 2.16 - */ -#define g_warn_if_reached() \ - do { \ - g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, NULL); \ - } while (0) - -/** - * g_warn_if_fail: - * @expr: the expression to check - * - * Logs a warning if the expression is not true. - * - * Since: 2.16 - */ -#define g_warn_if_fail(expr) \ - do { \ - if G_LIKELY (expr) ; \ - else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, #expr); \ - } while (0) - -#ifdef G_DISABLE_CHECKS - -/** - * g_return_if_fail: - * @expr: the expression to check - * - * Verifies that the expression evaluates to %TRUE. If the expression - * evaluates to %FALSE, a critical message is logged and the current - * function returns. This can only be used in functions which do not - * return a value. - * - * If G_DISABLE_CHECKS is defined then the check is not performed. You - * should therefore not depend on any side effects of @expr. - */ -#define g_return_if_fail(expr) G_STMT_START{ (void)0; }G_STMT_END - -/** - * g_return_val_if_fail: - * @expr: the expression to check - * @val: the value to return from the current function - * if the expression is not true - * - * Verifies that the expression evaluates to %TRUE. If the expression - * evaluates to %FALSE, a critical message is logged and @val is - * returned from the current function. - * - * If G_DISABLE_CHECKS is defined then the check is not performed. You - * should therefore not depend on any side effects of @expr. - */ -#define g_return_val_if_fail(expr,val) G_STMT_START{ (void)0; }G_STMT_END - -/** - * g_return_if_reached: - * - * Logs a critical message and returns from the current function. - * This can only be used in functions which do not return a value. - */ -#define g_return_if_reached() G_STMT_START{ return; }G_STMT_END - -/** - * g_return_val_if_reached: - * @val: the value to return from the current function - * - * Logs a critical message and returns @val. - */ -#define g_return_val_if_reached(val) G_STMT_START{ return (val); }G_STMT_END - -#else /* !G_DISABLE_CHECKS */ - -#ifdef __GNUC__ - -#define g_return_if_fail(expr) G_STMT_START{ \ - if G_LIKELY(expr) { } else \ - { \ - g_return_if_fail_warning (G_LOG_DOMAIN, \ - __PRETTY_FUNCTION__, \ - #expr); \ - return; \ - }; }G_STMT_END - -#define g_return_val_if_fail(expr,val) G_STMT_START{ \ - if G_LIKELY(expr) { } else \ - { \ - g_return_if_fail_warning (G_LOG_DOMAIN, \ - __PRETTY_FUNCTION__, \ - #expr); \ - return (val); \ - }; }G_STMT_END - -#define g_return_if_reached() G_STMT_START{ \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d (%s): should not be reached", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__); \ - return; }G_STMT_END - -#define g_return_val_if_reached(val) G_STMT_START{ \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d (%s): should not be reached", \ - __FILE__, \ - __LINE__, \ - __PRETTY_FUNCTION__); \ - return (val); }G_STMT_END - -#else /* !__GNUC__ */ - -#define g_return_if_fail(expr) G_STMT_START{ \ - if (expr) { } else \ - { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d: assertion `%s' failed", \ - __FILE__, \ - __LINE__, \ - #expr); \ - return; \ - }; }G_STMT_END - -#define g_return_val_if_fail(expr, val) G_STMT_START{ \ - if (expr) { } else \ - { \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d: assertion `%s' failed", \ - __FILE__, \ - __LINE__, \ - #expr); \ - return (val); \ - }; }G_STMT_END - -#define g_return_if_reached() G_STMT_START{ \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d: should not be reached", \ - __FILE__, \ - __LINE__); \ - return; }G_STMT_END - -#define g_return_val_if_reached(val) G_STMT_START{ \ - g_log (G_LOG_DOMAIN, \ - G_LOG_LEVEL_CRITICAL, \ - "file %s: line %d: should not be reached", \ - __FILE__, \ - __LINE__); \ - return (val); }G_STMT_END - -#endif /* !__GNUC__ */ - -#endif /* !G_DISABLE_CHECKS */ - -G_END_DECLS - -#endif /* __G_MESSAGES_H__ */ diff --git a/deps/glib/gprintf.c b/deps/glib/gprintf.c deleted file mode 100644 index c19a237b..00000000 --- a/deps/glib/gprintf.c +++ /dev/null @@ -1,338 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> - -#include "gprintf.h" -#include "gprintfint.h" - - -/** - * g_printf: - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @...: the arguments to insert in the output. - * - * An implementation of the standard printf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * - * Returns: the number of bytes printed. - * - * Since: 2.2 - **/ -gint -g_printf (gchar const *format, - ...) -{ - va_list args; - gint retval; - - va_start (args, format); - retval = g_vprintf (format, args); - va_end (args); - - return retval; -} - -/** - * g_fprintf: - * @file: the stream to write to. - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @...: the arguments to insert in the output. - * - * An implementation of the standard fprintf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * - * Returns: the number of bytes printed. - * - * Since: 2.2 - **/ -gint -g_fprintf (FILE *file, - gchar const *format, - ...) -{ - va_list args; - gint retval; - - va_start (args, format); - retval = g_vfprintf (file, format, args); - va_end (args); - - return retval; -} - -/** - * g_sprintf: - * @string: A pointer to a memory buffer to contain the resulting string. It - * is up to the caller to ensure that the allocated buffer is large - * enough to hold the formatted result - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @...: the arguments to insert in the output. - * - * An implementation of the standard sprintf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * - * Note that it is usually better to use g_snprintf(), to avoid the - * risk of buffer overflow. - * - * See also g_strdup_printf(). - * - * Returns: the number of bytes printed. - * - * Since: 2.2 - **/ -gint -g_sprintf (gchar *string, - gchar const *format, - ...) -{ - va_list args; - gint retval; - - va_start (args, format); - retval = g_vsprintf (string, format, args); - va_end (args); - - return retval; -} - -/** - * g_snprintf: - * @string: the buffer to hold the output. - * @n: the maximum number of bytes to produce (including the - * terminating nul character). - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @...: the arguments to insert in the output. - * - * A safer form of the standard sprintf() function. The output is guaranteed - * to not exceed @n characters (including the terminating nul character), so - * it is easy to ensure that a buffer overflow cannot occur. - * - * See also g_strdup_printf(). - * - * In versions of GLib prior to 1.2.3, this function may return -1 if the - * output was truncated, and the truncated string may not be nul-terminated. - * In versions prior to 1.3.12, this function returns the length of the output - * string. - * - * The return value of g_snprintf() conforms to the snprintf() - * function as standardized in ISO C99. Note that this is different from - * traditional snprintf(), which returns the length of the output string. - * - * The format string may contain positional parameters, as specified in - * the Single Unix Specification. - * - * Returns: the number of bytes which would be produced if the buffer - * was large enough. - **/ -gint -g_snprintf (gchar *string, - gulong n, - gchar const *format, - ...) -{ - va_list args; - gint retval; - - va_start (args, format); - retval = g_vsnprintf (string, n, format, args); - va_end (args); - - return retval; -} - -/** - * g_vprintf: - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @args: the list of arguments to insert in the output. - * - * An implementation of the standard vprintf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * - * Returns: the number of bytes printed. - * - * Since: 2.2 - **/ -gint -g_vprintf (gchar const *format, - va_list args) -{ - g_return_val_if_fail (format != NULL, -1); - - return _g_vprintf (format, args); -} - -/** - * g_vfprintf: - * @file: the stream to write to. - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @args: the list of arguments to insert in the output. - * - * An implementation of the standard fprintf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * - * Returns: the number of bytes printed. - * - * Since: 2.2 - **/ -gint -g_vfprintf (FILE *file, - gchar const *format, - va_list args) -{ - g_return_val_if_fail (format != NULL, -1); - - return _g_vfprintf (file, format, args); -} - -/** - * g_vsprintf: - * @string: the buffer to hold the output. - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @args: the list of arguments to insert in the output. - * - * An implementation of the standard vsprintf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * - * Returns: the number of bytes printed. - * - * Since: 2.2 - **/ -gint -g_vsprintf (gchar *string, - gchar const *format, - va_list args) -{ - g_return_val_if_fail (string != NULL, -1); - g_return_val_if_fail (format != NULL, -1); - - return _g_vsprintf (string, format, args); -} - -/** - * g_vsnprintf: - * @string: the buffer to hold the output. - * @n: the maximum number of bytes to produce (including the - * terminating nul character). - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @args: the list of arguments to insert in the output. - * - * A safer form of the standard vsprintf() function. The output is guaranteed - * to not exceed @n characters (including the terminating nul character), so - * it is easy to ensure that a buffer overflow cannot occur. - * - * See also g_strdup_vprintf(). - * - * In versions of GLib prior to 1.2.3, this function may return -1 if the - * output was truncated, and the truncated string may not be nul-terminated. - * In versions prior to 1.3.12, this function returns the length of the output - * string. - * - * The return value of g_vsnprintf() conforms to the vsnprintf() function - * as standardized in ISO C99. Note that this is different from traditional - * vsnprintf(), which returns the length of the output string. - * - * The format string may contain positional parameters, as specified in - * the Single Unix Specification. - * - * Returns: the number of bytes which would be produced if the buffer - * was large enough. - */ -gint -g_vsnprintf (gchar *string, - gulong n, - gchar const *format, - va_list args) -{ - g_return_val_if_fail (n == 0 || string != NULL, -1); - g_return_val_if_fail (format != NULL, -1); - - return _g_vsnprintf (string, n, format, args); -} - -/** - * g_vasprintf: - * @string: the return location for the newly-allocated string. - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link>. - * @args: the list of arguments to insert in the output. - * - * An implementation of the GNU vasprintf() function which supports - * positional parameters, as specified in the Single Unix Specification. - * This function is similar to g_vsprintf(), except that it allocates a - * string to hold the output, instead of putting the output in a buffer - * you allocate in advance. - * - * Returns: the number of bytes printed. - * - * Since: 2.4 - **/ -gint -g_vasprintf (gchar **string, - gchar const *format, - va_list args) -{ - gint len; - g_return_val_if_fail (string != NULL, -1); - -#if !defined(HAVE_GOOD_PRINTF) - - len = _g_gnulib_vasprintf (string, format, args); - if (len < 0) - *string = NULL; - -#elif defined (HAVE_VASPRINTF) - - len = vasprintf (string, format, args); - if (len < 0) - *string = NULL; - else if (!g_mem_is_system_malloc ()) - { - /* vasprintf returns malloc-allocated memory */ - gchar *string1 = g_strndup (*string, len); - free (*string); - *string = string1; - } - -#else - - { - va_list args2; - - G_VA_COPY (args2, args); - - *string = g_new (gchar, g_printf_string_upper_bound (format, args)); - - len = _g_vsprintf (*string, format, args2); - va_end (args2); - } -#endif - - return len; -} diff --git a/deps/glib/gprintf.h b/deps/glib/gprintf.h deleted file mode 100644 index 09185396..00000000 --- a/deps/glib/gprintf.h +++ /dev/null @@ -1,50 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __G_PRINTF_H__ -#define __G_PRINTF_H__ - -#include <glib.h> -#include <stdio.h> -#include <stdarg.h> - -G_BEGIN_DECLS - -gint g_printf (gchar const *format, - ...) G_GNUC_PRINTF (1, 2); -gint g_fprintf (FILE *file, - gchar const *format, - ...) G_GNUC_PRINTF (2, 3); -gint g_sprintf (gchar *string, - gchar const *format, - ...) G_GNUC_PRINTF (2, 3); - -gint g_vprintf (gchar const *format, - va_list args); -gint g_vfprintf (FILE *file, - gchar const *format, - va_list args); -gint g_vsprintf (gchar *string, - gchar const *format, - va_list args); -gint g_vasprintf (gchar **string, - gchar const *format, - va_list args); - -G_END_DECLS - -#endif /* __G_PRINTF_H__ */ diff --git a/deps/glib/gprintfint.h b/deps/glib/gprintfint.h deleted file mode 100644 index 88c6170e..00000000 --- a/deps/glib/gprintfint.h +++ /dev/null @@ -1,57 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 2002. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __G_PRINTFINT_H__ -#define __G_PRINTFINT_H__ - -#ifdef HAVE_GOOD_PRINTF - -#define _g_printf printf -#define _g_fprintf fprintf -#define _g_sprintf sprintf -#define _g_snprintf snprintf - -#define _g_vprintf vprintf -#define _g_vfprintf vfprintf -#define _g_vsprintf vsprintf -#define _g_vsnprintf vsnprintf - -#else - -#include "gnulib/printf.h" - -#define _g_printf _g_gnulib_printf -#define _g_fprintf _g_gnulib_fprintf -#define _g_sprintf _g_gnulib_sprintf -#define _g_snprintf _g_gnulib_snprintf - -#define _g_vprintf _g_gnulib_vprintf -#define _g_vfprintf _g_gnulib_vfprintf -#define _g_vsprintf _g_gnulib_vsprintf -#define _g_vsnprintf _g_gnulib_vsnprintf - -#endif - -#endif /* __G_PRINTF_H__ */ - diff --git a/deps/glib/gqsort.c b/deps/glib/gqsort.c deleted file mode 100644 index ba2c5b7c..00000000 --- a/deps/glib/gqsort.c +++ /dev/null @@ -1,298 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1991, 1992, 1996, 1997,1999,2004 Free Software Foundation, Inc. - * Copyright (C) 2000 Eazel, Inc. - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * This file was originally part of the GNU C Library, and was modified to allow - * user data to be passed in to the sorting function. - * - * Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - * Modified by Maciej Stachowiak (mjs@eazel.com) - * - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with GLib - * at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" - -#include <limits.h> -#include <stdlib.h> -#include <string.h> - -#include "gqsort.h" - -#include "gtestutils.h" - -#ifdef HAVE_QSORT_R - -/** - * g_qsort_with_data: - * @pbase: start of array to sort - * @total_elems: elements in the array - * @size: size of each element - * @compare_func: function to compare elements - * @user_data: data to pass to @compare_func - * - * This is just like the standard C qsort() function, but - * the comparison routine accepts a user data argument. - */ -void -g_qsort_with_data (gconstpointer pbase, - gint total_elems, - gsize size, - GCompareDataFunc compare_func, - gpointer user_data) -{ - qsort_r ((gpointer)pbase, total_elems, size, compare_func, user_data); -} - -#else - -/* Byte-wise swap two items of size SIZE. */ -#define SWAP(a, b, size) \ - do \ - { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do \ - { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (--__size > 0); \ - } while (0) - -/* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ -#define MAX_THRESH 4 - -/* Stack node declarations used to store unfulfilled partition obligations. */ -typedef struct - { - char *lo; - char *hi; - } stack_node; - -/* The next 4 #defines implement a very fast in-line stack abstraction. */ -/* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type size_t, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(size_t). */ -#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) -#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) -#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) -#define STACK_NOT_EMPTY (stack < top) - - -/* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: - - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. - - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. - - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. - - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ - -void -g_qsort_with_data (gconstpointer pbase, - gint total_elems, - gsize size, - GCompareDataFunc compare_func, - gpointer user_data) -{ - register char *base_ptr = (char *) pbase; - - const size_t max_thresh = MAX_THRESH * size; - - g_return_if_fail (total_elems >= 0); - g_return_if_fail (pbase != NULL || total_elems == 0); - g_return_if_fail (compare_func != NULL); - - if (total_elems == 0) - /* Avoid lossage with unsigned arithmetic below. */ - return; - - if (total_elems > MAX_THRESH) - { - char *lo = base_ptr; - char *hi = &lo[size * (total_elems - 1)]; - stack_node stack[STACK_SIZE]; - stack_node *top = stack; - - PUSH (NULL, NULL); - - while (STACK_NOT_EMPTY) - { - char *left_ptr; - char *right_ptr; - - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR in - the while loops. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*compare_func) ((void *) mid, (void *) lo, user_data) < 0) - SWAP (mid, lo, size); - if ((*compare_func) ((void *) hi, (void *) mid, user_data) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*compare_func) ((void *) mid, (void *) lo, user_data) < 0) - SWAP (mid, lo, size); - jump_over:; - - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*compare_func) ((void *) left_ptr, (void *) mid, user_data) < 0) - left_ptr += size; - - while ((*compare_func) ((void *) mid, (void *) right_ptr, user_data) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; - } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; - } - } - while (left_ptr <= right_ptr); - - /* Set up pointers for next iteration. First determine whether - left and right partitions are below the threshold size. If so, - ignore one or both. Otherwise, push the larger partition's - bounds on the stack and continue sorting the smaller one. */ - - if ((size_t) (right_ptr - lo) <= max_thresh) - { - if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ - POP (lo, hi); - else - /* Ignore small left partition. */ - lo = left_ptr; - } - else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ - hi = right_ptr; - else if ((right_ptr - lo) > (hi - left_ptr)) - { - /* Push larger left partition indices. */ - PUSH (lo, right_ptr); - lo = left_ptr; - } - else - { - /* Push larger right partition indices. */ - PUSH (left_ptr, hi); - hi = right_ptr; - } - } - } - - /* Once the BASE_PTR array is partially sorted by quicksort the rest - is completely sorted using insertion sort, since this is efficient - for partitions below MAX_THRESH size. BASE_PTR points to the beginning - of the array to sort, and END_PTR points at the very last element in - the array (*not* one beyond it!). */ - -#define min(x, y) ((x) < (y) ? (x) : (y)) - - { - char *const end_ptr = &base_ptr[size * (total_elems - 1)]; - char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); - register char *run_ptr; - - /* Find smallest element in first threshold and place it at the - array's beginning. This is the smallest array element, - and the operation speeds up insertion sort's inner loop. */ - - for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) - if ((*compare_func) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) - tmp_ptr = run_ptr; - - if (tmp_ptr != base_ptr) - SWAP (tmp_ptr, base_ptr, size); - - /* Insertion sort, running from left-hand-side up to right-hand-side. */ - - run_ptr = base_ptr + size; - while ((run_ptr += size) <= end_ptr) - { - tmp_ptr = run_ptr - size; - while ((*compare_func) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) - tmp_ptr -= size; - - tmp_ptr += size; - if (tmp_ptr != run_ptr) - { - char *trav; - - trav = run_ptr + size; - while (--trav >= run_ptr) - { - char c = *trav; - char *hi, *lo; - - for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) - *hi = *lo; - *hi = c; - } - } - } - } -} - -#endif /* HAVE_QSORT_R */ diff --git a/deps/glib/gqsort.h b/deps/glib/gqsort.h deleted file mode 100644 index c7467c35..00000000 --- a/deps/glib/gqsort.h +++ /dev/null @@ -1,44 +0,0 @@ - /* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_QSORT_H__ -#define __G_QSORT_H__ - -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -void g_qsort_with_data (gconstpointer pbase, - gint total_elems, - gsize size, - GCompareDataFunc compare_func, - gpointer user_data); - -G_END_DECLS - -#endif /* __G_QSORT_H__ */ diff --git a/deps/glib/gquark.h b/deps/glib/gquark.h deleted file mode 100644 index 4570d4fd..00000000 --- a/deps/glib/gquark.h +++ /dev/null @@ -1,50 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_QUARK_H__ -#define __G_QUARK_H__ - -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -typedef guint32 GQuark; - -/* Quarks (string<->id association) - */ -GQuark g_quark_try_string (const gchar *string); -GQuark g_quark_from_static_string (const gchar *string); -GQuark g_quark_from_string (const gchar *string); -const gchar * g_quark_to_string (GQuark quark) G_GNUC_CONST; - -const gchar * g_intern_string (const gchar *string); -const gchar * g_intern_static_string (const gchar *string); - -G_END_DECLS - -#endif /* __G_QUARK_H__ */ diff --git a/deps/glib/gqueue.c b/deps/glib/gqueue.c deleted file mode 100644 index 85f31d78..00000000 --- a/deps/glib/gqueue.c +++ /dev/null @@ -1,1045 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * GQueue: Double ended queue implementation, piggy backed on GList. - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * MT safe - */ - -/** - * SECTION:queue - * @Title: Double-ended Queues - * @Short_description: double-ended queue data structure - * - * The #GQueue structure and its associated functions provide a standard - * queue data structure. Internally, GQueue uses the same data structure - * as #GList to store elements. - * - * The data contained in each element can be either integer values, by - * using one of the <link linkend="glib-Type-Conversion-Macros">Type - * Conversion Macros</link>, or simply pointers to any type of data. - * - * To create a new GQueue, use g_queue_new(). - * - * To initialize a statically-allocated GQueue, use #G_QUEUE_INIT or - * g_queue_init(). - * - * To add elements, use g_queue_push_head(), g_queue_push_head_link(), - * g_queue_push_tail() and g_queue_push_tail_link(). - * - * To remove elements, use g_queue_pop_head() and g_queue_pop_tail(). - * - * To free the entire queue, use g_queue_free(). - */ -#include "config.h" - -#include "gqueue.h" - -#include "gtestutils.h" - -/** - * g_queue_new: - * - * Creates a new #GQueue. - * - * Returns: a new #GQueue. - **/ -GQueue* -g_queue_new (void) -{ - return g_slice_new0 (GQueue); -} - -/** - * g_queue_free: - * @queue: a #GQueue. - * - * Frees the memory allocated for the #GQueue. Only call this function if - * @queue was created with g_queue_new(). If queue elements contain - * dynamically-allocated memory, they should be freed first. - **/ -void -g_queue_free (GQueue *queue) -{ - g_return_if_fail (queue != NULL); - - g_list_free (queue->head); - g_slice_free (GQueue, queue); -} - -/** - * g_queue_init: - * @queue: an uninitialized #GQueue - * - * A statically-allocated #GQueue must be initialized with this function - * before it can be used. Alternatively you can initialize it with - * #G_QUEUE_INIT. It is not necessary to initialize queues created with - * g_queue_new(). - * - * Since: 2.14 - **/ -void -g_queue_init (GQueue *queue) -{ - g_return_if_fail (queue != NULL); - - queue->head = queue->tail = NULL; - queue->length = 0; -} - -/** - * g_queue_clear: - * @queue: a #GQueue - * - * Removes all the elements in @queue. If queue elements contain - * dynamically-allocated memory, they should be freed first. - * - * Since: 2.14 - */ -void -g_queue_clear (GQueue *queue) -{ - g_return_if_fail (queue != NULL); - - g_list_free (queue->head); - g_queue_init (queue); -} - -/** - * g_queue_is_empty: - * @queue: a #GQueue. - * - * Returns %TRUE if the queue is empty. - * - * Returns: %TRUE if the queue is empty. - **/ -gboolean -g_queue_is_empty (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, TRUE); - - return queue->head == NULL; -} - -/** - * g_queue_get_length: - * @queue: a #GQueue - * - * Returns the number of items in @queue. - * - * Return value: The number of items in @queue. - * - * Since: 2.4 - **/ -guint -g_queue_get_length (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, 0); - - return queue->length; -} - -/** - * g_queue_reverse: - * @queue: a #GQueue - * - * Reverses the order of the items in @queue. - * - * Since: 2.4 - **/ -void -g_queue_reverse (GQueue *queue) -{ - g_return_if_fail (queue != NULL); - - queue->tail = queue->head; - queue->head = g_list_reverse (queue->head); -} - -/** - * g_queue_copy: - * @queue: a #GQueue - * - * Copies a @queue. Note that is a shallow copy. If the elements in the - * queue consist of pointers to data, the pointers are copied, but the - * actual data is not. - * - * Return value: A copy of @queue - * - * Since: 2.4 - **/ -GQueue * -g_queue_copy (GQueue *queue) -{ - GQueue *result; - GList *list; - - g_return_val_if_fail (queue != NULL, NULL); - - result = g_queue_new (); - - for (list = queue->head; list != NULL; list = list->next) - g_queue_push_tail (result, list->data); - - return result; -} - -/** - * g_queue_foreach: - * @queue: a #GQueue - * @func: the function to call for each element's data - * @user_data: user data to pass to @func - * - * Calls @func for each element in the queue passing @user_data to the - * function. - * - * Since: 2.4 - **/ -void -g_queue_foreach (GQueue *queue, - GFunc func, - gpointer user_data) -{ - GList *list; - - g_return_if_fail (queue != NULL); - g_return_if_fail (func != NULL); - - list = queue->head; - while (list) - { - GList *next = list->next; - func (list->data, user_data); - list = next; - } -} - -/** - * g_queue_find: - * @queue: a #GQueue - * @data: data to find - * - * Finds the first link in @queue which contains @data. - * - * Return value: The first link in @queue which contains @data. - * - * Since: 2.4 - **/ -GList * -g_queue_find (GQueue *queue, - gconstpointer data) -{ - g_return_val_if_fail (queue != NULL, NULL); - - return g_list_find (queue->head, data); -} - -/** - * g_queue_find_custom: - * @queue: a #GQueue - * @data: user data passed to @func - * @func: a #GCompareFunc to call for each element. It should return 0 - * when the desired element is found - * - * Finds an element in a #GQueue, using a supplied function to find the - * desired element. It iterates over the queue, calling the given function - * which should return 0 when the desired element is found. The function - * takes two gconstpointer arguments, the #GQueue element's data as the - * first argument and the given user data as the second argument. - * - * Return value: The found link, or %NULL if it wasn't found - * - * Since: 2.4 - **/ -GList * -g_queue_find_custom (GQueue *queue, - gconstpointer data, - GCompareFunc func) -{ - g_return_val_if_fail (queue != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - - return g_list_find_custom (queue->head, data, func); -} - -/** - * g_queue_sort: - * @queue: a #GQueue - * @compare_func: the #GCompareDataFunc used to sort @queue. This function - * is passed two elements of the queue and should return 0 if they are - * equal, a negative value if the first comes before the second, and - * a positive value if the second comes before the first. - * @user_data: user data passed to @compare_func - * - * Sorts @queue using @compare_func. - * - * Since: 2.4 - **/ -void -g_queue_sort (GQueue *queue, - GCompareDataFunc compare_func, - gpointer user_data) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (compare_func != NULL); - - queue->head = g_list_sort_with_data (queue->head, compare_func, user_data); - queue->tail = g_list_last (queue->head); -} - -/** - * g_queue_push_head: - * @queue: a #GQueue. - * @data: the data for the new element. - * - * Adds a new element at the head of the queue. - **/ -void -g_queue_push_head (GQueue *queue, - gpointer data) -{ - g_return_if_fail (queue != NULL); - - queue->head = g_list_prepend (queue->head, data); - if (!queue->tail) - queue->tail = queue->head; - queue->length++; -} - -/** - * g_queue_push_nth: - * @queue: a #GQueue - * @data: the data for the new element - * @n: the position to insert the new element. If @n is negative or - * larger than the number of elements in the @queue, the element is - * added to the end of the queue. - * - * Inserts a new element into @queue at the given position - * - * Since: 2.4 - **/ -void -g_queue_push_nth (GQueue *queue, - gpointer data, - gint n) -{ - g_return_if_fail (queue != NULL); - - if (n < 0 || n >= queue->length) - { - g_queue_push_tail (queue, data); - return; - } - - g_queue_insert_before (queue, g_queue_peek_nth_link (queue, n), data); -} - -/** - * g_queue_push_head_link: - * @queue: a #GQueue. - * @link_: a single #GList element, <emphasis>not</emphasis> a list with - * more than one element. - * - * Adds a new element at the head of the queue. - **/ -void -g_queue_push_head_link (GQueue *queue, - GList *link) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (link != NULL); - g_return_if_fail (link->prev == NULL); - g_return_if_fail (link->next == NULL); - - link->next = queue->head; - if (queue->head) - queue->head->prev = link; - else - queue->tail = link; - queue->head = link; - queue->length++; -} - -/** - * g_queue_push_tail: - * @queue: a #GQueue. - * @data: the data for the new element. - * - * Adds a new element at the tail of the queue. - **/ -void -g_queue_push_tail (GQueue *queue, - gpointer data) -{ - g_return_if_fail (queue != NULL); - - queue->tail = g_list_append (queue->tail, data); - if (queue->tail->next) - queue->tail = queue->tail->next; - else - queue->head = queue->tail; - queue->length++; -} - -/** - * g_queue_push_tail_link: - * @queue: a #GQueue. - * @link_: a single #GList element, <emphasis>not</emphasis> a list with - * more than one element. - * - * Adds a new element at the tail of the queue. - **/ -void -g_queue_push_tail_link (GQueue *queue, - GList *link) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (link != NULL); - g_return_if_fail (link->prev == NULL); - g_return_if_fail (link->next == NULL); - - link->prev = queue->tail; - if (queue->tail) - queue->tail->next = link; - else - queue->head = link; - queue->tail = link; - queue->length++; -} - -/** - * g_queue_push_nth_link: - * @queue: a #GQueue - * @n: the position to insert the link. If this is negative or larger than - * the number of elements in @queue, the link is added to the end of - * @queue. - * @link_: the link to add to @queue - * - * Inserts @link into @queue at the given position. - * - * Since: 2.4 - **/ -void -g_queue_push_nth_link (GQueue *queue, - gint n, - GList *link_) -{ - GList *next; - GList *prev; - - g_return_if_fail (queue != NULL); - g_return_if_fail (link_ != NULL); - - if (n < 0 || n >= queue->length) - { - g_queue_push_tail_link (queue, link_); - return; - } - - g_assert (queue->head); - g_assert (queue->tail); - - next = g_queue_peek_nth_link (queue, n); - prev = next->prev; - - if (prev) - prev->next = link_; - next->prev = link_; - - link_->next = next; - link_->prev = prev; - - if (queue->head->prev) - queue->head = queue->head->prev; - - if (queue->tail->next) - queue->tail = queue->tail->next; - - queue->length++; -} - -/** - * g_queue_pop_head: - * @queue: a #GQueue. - * - * Removes the first element of the queue. - * - * Returns: the data of the first element in the queue, or %NULL if the queue - * is empty. - **/ -gpointer -g_queue_pop_head (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - if (queue->head) - { - GList *node = queue->head; - gpointer data = node->data; - - queue->head = node->next; - if (queue->head) - queue->head->prev = NULL; - else - queue->tail = NULL; - g_list_free_1 (node); - queue->length--; - - return data; - } - - return NULL; -} - -/** - * g_queue_pop_head_link: - * @queue: a #GQueue. - * - * Removes the first element of the queue. - * - * Returns: the #GList element at the head of the queue, or %NULL if the queue - * is empty. - **/ -GList* -g_queue_pop_head_link (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - if (queue->head) - { - GList *node = queue->head; - - queue->head = node->next; - if (queue->head) - { - queue->head->prev = NULL; - node->next = NULL; - } - else - queue->tail = NULL; - queue->length--; - - return node; - } - - return NULL; -} - -/** - * g_queue_peek_head_link: - * @queue: a #GQueue - * - * Returns the first link in @queue - * - * Return value: the first link in @queue, or %NULL if @queue is empty - * - * Since: 2.4 - **/ -GList* -g_queue_peek_head_link (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - return queue->head; -} - -/** - * g_queue_peek_tail_link: - * @queue: a #GQueue - * - * Returns the last link @queue. - * - * Return value: the last link in @queue, or %NULL if @queue is empty - * - * Since: 2.4 - **/ -GList* -g_queue_peek_tail_link (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - return queue->tail; -} - -/** - * g_queue_pop_tail: - * @queue: a #GQueue. - * - * Removes the last element of the queue. - * - * Returns: the data of the last element in the queue, or %NULL if the queue - * is empty. - **/ -gpointer -g_queue_pop_tail (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - if (queue->tail) - { - GList *node = queue->tail; - gpointer data = node->data; - - queue->tail = node->prev; - if (queue->tail) - queue->tail->next = NULL; - else - queue->head = NULL; - queue->length--; - g_list_free_1 (node); - - return data; - } - - return NULL; -} - -/** - * g_queue_pop_nth: - * @queue: a #GQueue - * @n: the position of the element. - * - * Removes the @n'th element of @queue. - * - * Return value: the element's data, or %NULL if @n is off the end of @queue. - * - * Since: 2.4 - **/ -gpointer -g_queue_pop_nth (GQueue *queue, - guint n) -{ - GList *nth_link; - gpointer result; - - g_return_val_if_fail (queue != NULL, NULL); - - if (n >= queue->length) - return NULL; - - nth_link = g_queue_peek_nth_link (queue, n); - result = nth_link->data; - - g_queue_delete_link (queue, nth_link); - - return result; -} - -/** - * g_queue_pop_tail_link: - * @queue: a #GQueue. - * - * Removes the last element of the queue. - * - * Returns: the #GList element at the tail of the queue, or %NULL if the queue - * is empty. - **/ -GList* -g_queue_pop_tail_link (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - if (queue->tail) - { - GList *node = queue->tail; - - queue->tail = node->prev; - if (queue->tail) - { - queue->tail->next = NULL; - node->prev = NULL; - } - else - queue->head = NULL; - queue->length--; - - return node; - } - - return NULL; -} - -/** - * g_queue_pop_nth_link: - * @queue: a #GQueue - * @n: the link's position - * - * Removes and returns the link at the given position. - * - * Return value: The @n'th link, or %NULL if @n is off the end of @queue. - * - * Since: 2.4 - **/ -GList* -g_queue_pop_nth_link (GQueue *queue, - guint n) -{ - GList *link; - - g_return_val_if_fail (queue != NULL, NULL); - - if (n >= queue->length) - return NULL; - - link = g_queue_peek_nth_link (queue, n); - g_queue_unlink (queue, link); - - return link; -} - -/** - * g_queue_peek_nth_link: - * @queue: a #GQueue - * @n: the position of the link - * - * Returns the link at the given position - * - * Return value: The link at the @n'th position, or %NULL if @n is off the - * end of the list - * - * Since: 2.4 - **/ -GList * -g_queue_peek_nth_link (GQueue *queue, - guint n) -{ - GList *link; - gint i; - - g_return_val_if_fail (queue != NULL, NULL); - - if (n >= queue->length) - return NULL; - - if (n > queue->length / 2) - { - n = queue->length - n - 1; - - link = queue->tail; - for (i = 0; i < n; ++i) - link = link->prev; - } - else - { - link = queue->head; - for (i = 0; i < n; ++i) - link = link->next; - } - - return link; -} - -/** - * g_queue_link_index: - * @queue: a #GQueue - * @link_: A #GList link - * - * Returns the position of @link_ in @queue. - * - * Return value: The position of @link_, or -1 if the link is - * not part of @queue - * - * Since: 2.4 - **/ -gint -g_queue_link_index (GQueue *queue, - GList *link_) -{ - g_return_val_if_fail (queue != NULL, -1); - - return g_list_position (queue->head, link_); -} - -/** - * g_queue_unlink - * @queue: a #GQueue - * @link_: a #GList link that <emphasis>must</emphasis> be part of @queue - * - * Unlinks @link_ so that it will no longer be part of @queue. The link is - * not freed. - * - * @link_ must be part of @queue, - * - * Since: 2.4 - **/ -void -g_queue_unlink (GQueue *queue, - GList *link_) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (link_ != NULL); - - if (link_ == queue->tail) - queue->tail = queue->tail->prev; - - queue->head = g_list_remove_link (queue->head, link_); - queue->length--; -} - -/** - * g_queue_delete_link: - * @queue: a #GQueue - * @link_: a #GList link that <emphasis>must</emphasis> be part of @queue - * - * Removes @link_ from @queue and frees it. - * - * @link_ must be part of @queue. - * - * Since: 2.4 - **/ -void -g_queue_delete_link (GQueue *queue, - GList *link_) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (link_ != NULL); - - g_queue_unlink (queue, link_); - g_list_free (link_); -} - -/** - * g_queue_peek_head: - * @queue: a #GQueue. - * - * Returns the first element of the queue. - * - * Returns: the data of the first element in the queue, or %NULL if the queue - * is empty. - **/ -gpointer -g_queue_peek_head (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - return queue->head ? queue->head->data : NULL; -} - -/** - * g_queue_peek_tail: - * @queue: a #GQueue. - * - * Returns the last element of the queue. - * - * Returns: the data of the last element in the queue, or %NULL if the queue - * is empty. - **/ -gpointer -g_queue_peek_tail (GQueue *queue) -{ - g_return_val_if_fail (queue != NULL, NULL); - - return queue->tail ? queue->tail->data : NULL; -} - -/** - * g_queue_peek_nth: - * @queue: a #GQueue - * @n: the position of the element. - * - * Returns the @n'th element of @queue. - * - * Return value: The data for the @n'th element of @queue, or %NULL if @n is - * off the end of @queue. - * - * Since: 2.4 - **/ -gpointer -g_queue_peek_nth (GQueue *queue, - guint n) -{ - GList *link; - - g_return_val_if_fail (queue != NULL, NULL); - - link = g_queue_peek_nth_link (queue, n); - - if (link) - return link->data; - - return NULL; -} - -/** - * g_queue_index: - * @queue: a #GQueue - * @data: the data to find. - * - * Returns the position of the first element in @queue which contains @data. - * - * Return value: The position of the first element in @queue which contains @data, or -1 if no element in @queue contains @data. - * - * Since: 2.4 - **/ -gint -g_queue_index (GQueue *queue, - gconstpointer data) -{ - g_return_val_if_fail (queue != NULL, -1); - - return g_list_index (queue->head, data); -} - -/** - * g_queue_remove: - * @queue: a #GQueue - * @data: data to remove. - * - * Removes the first element in @queue that contains @data. - * - * Return value: %TRUE if @data was found and removed from @queue - * - * Since: 2.4 - **/ -gboolean -g_queue_remove (GQueue *queue, - gconstpointer data) -{ - GList *link; - - g_return_val_if_fail (queue != NULL, FALSE); - - link = g_list_find (queue->head, data); - - if (link) - g_queue_delete_link (queue, link); - - return (link != NULL); -} - -/** - * g_queue_remove_all: - * @queue: a #GQueue - * @data: data to remove - * - * Remove all elements whose data equals @data from @queue. - * - * Return value: the number of elements removed from @queue - * - * Since: 2.4 - **/ -guint -g_queue_remove_all (GQueue *queue, - gconstpointer data) -{ - GList *list; - guint old_length; - - g_return_val_if_fail (queue != NULL, 0); - - old_length = queue->length; - - list = queue->head; - while (list) - { - GList *next = list->next; - - if (list->data == data) - g_queue_delete_link (queue, list); - - list = next; - } - - return (old_length - queue->length); -} - -/** - * g_queue_insert_before: - * @queue: a #GQueue - * @sibling: a #GList link that <emphasis>must</emphasis> be part of @queue - * @data: the data to insert - * - * Inserts @data into @queue before @sibling. - * - * @sibling must be part of @queue. - * - * Since: 2.4 - **/ -void -g_queue_insert_before (GQueue *queue, - GList *sibling, - gpointer data) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (sibling != NULL); - - queue->head = g_list_insert_before (queue->head, sibling, data); - queue->length++; -} - -/** - * g_queue_insert_after: - * @queue: a #GQueue - * @sibling: a #GList link that <emphasis>must</emphasis> be part of @queue - * @data: the data to insert - * - * Inserts @data into @queue after @sibling - * - * @sibling must be part of @queue - * - * Since: 2.4 - **/ -void -g_queue_insert_after (GQueue *queue, - GList *sibling, - gpointer data) -{ - g_return_if_fail (queue != NULL); - g_return_if_fail (sibling != NULL); - - if (sibling == queue->tail) - g_queue_push_tail (queue, data); - else - g_queue_insert_before (queue, sibling->next, data); -} - -/** - * g_queue_insert_sorted: - * @queue: a #GQueue - * @data: the data to insert - * @func: the #GCompareDataFunc used to compare elements in the queue. It is - * called with two elements of the @queue and @user_data. It should - * return 0 if the elements are equal, a negative value if the first - * element comes before the second, and a positive value if the second - * element comes before the first. - * @user_data: user data passed to @func. - * - * Inserts @data into @queue using @func to determine the new position. - * - * Since: 2.4 - **/ -void -g_queue_insert_sorted (GQueue *queue, - gpointer data, - GCompareDataFunc func, - gpointer user_data) -{ - GList *list; - - g_return_if_fail (queue != NULL); - - list = queue->head; - while (list && func (list->data, data, user_data) < 0) - list = list->next; - - if (list) - g_queue_insert_before (queue, list, data); - else - g_queue_push_tail (queue, data); -} diff --git a/deps/glib/gqueue.h b/deps/glib/gqueue.h deleted file mode 100644 index 31abaaec..00000000 --- a/deps/glib/gqueue.h +++ /dev/null @@ -1,148 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_QUEUE_H__ -#define __G_QUEUE_H__ - -#include <glib/glist.h> - -G_BEGIN_DECLS - -typedef struct _GQueue GQueue; - -/** - * GQueue: - * @head: a pointer to the first element of the queue - * @tail: a pointer to the last element of the queue - * @length: the number of elements in the queue - * - * Contains the public fields of a - * <link linkend="glib-Double-ended-Queues">Queue</link>. - */ -struct _GQueue -{ - GList *head; - GList *tail; - guint length; -}; - -/** - * G_QUEUE_INIT: - * - * A statically-allocated #GQueue must be initialized with this - * macro before it can be used. This macro can be used to initialize - * a variable, but it cannot be assigned to a variable. In that case - * you have to use g_queue_init(). - * - * |[ - * GQueue my_queue = G_QUEUE_INIT; - * ]| - * - * Since: 2.14 - */ -#define G_QUEUE_INIT { NULL, NULL, 0 } - -/* Queues - */ -GQueue* g_queue_new (void); -void g_queue_free (GQueue *queue); -void g_queue_init (GQueue *queue); -void g_queue_clear (GQueue *queue); -gboolean g_queue_is_empty (GQueue *queue); -guint g_queue_get_length (GQueue *queue); -void g_queue_reverse (GQueue *queue); -GQueue * g_queue_copy (GQueue *queue); -void g_queue_foreach (GQueue *queue, - GFunc func, - gpointer user_data); -GList * g_queue_find (GQueue *queue, - gconstpointer data); -GList * g_queue_find_custom (GQueue *queue, - gconstpointer data, - GCompareFunc func); -void g_queue_sort (GQueue *queue, - GCompareDataFunc compare_func, - gpointer user_data); - -void g_queue_push_head (GQueue *queue, - gpointer data); -void g_queue_push_tail (GQueue *queue, - gpointer data); -void g_queue_push_nth (GQueue *queue, - gpointer data, - gint n); -gpointer g_queue_pop_head (GQueue *queue); -gpointer g_queue_pop_tail (GQueue *queue); -gpointer g_queue_pop_nth (GQueue *queue, - guint n); -gpointer g_queue_peek_head (GQueue *queue); -gpointer g_queue_peek_tail (GQueue *queue); -gpointer g_queue_peek_nth (GQueue *queue, - guint n); -gint g_queue_index (GQueue *queue, - gconstpointer data); -gboolean g_queue_remove (GQueue *queue, - gconstpointer data); -guint g_queue_remove_all (GQueue *queue, - gconstpointer data); -void g_queue_insert_before (GQueue *queue, - GList *sibling, - gpointer data); -void g_queue_insert_after (GQueue *queue, - GList *sibling, - gpointer data); -void g_queue_insert_sorted (GQueue *queue, - gpointer data, - GCompareDataFunc func, - gpointer user_data); - -void g_queue_push_head_link (GQueue *queue, - GList *link_); -void g_queue_push_tail_link (GQueue *queue, - GList *link_); -void g_queue_push_nth_link (GQueue *queue, - gint n, - GList *link_); -GList* g_queue_pop_head_link (GQueue *queue); -GList* g_queue_pop_tail_link (GQueue *queue); -GList* g_queue_pop_nth_link (GQueue *queue, - guint n); -GList* g_queue_peek_head_link (GQueue *queue); -GList* g_queue_peek_tail_link (GQueue *queue); -GList* g_queue_peek_nth_link (GQueue *queue, - guint n); -gint g_queue_link_index (GQueue *queue, - GList *link_); -void g_queue_unlink (GQueue *queue, - GList *link_); -void g_queue_delete_link (GQueue *queue, - GList *link_); - -G_END_DECLS - -#endif /* __G_QUEUE_H__ */ diff --git a/deps/glib/gslice.c b/deps/glib/gslice.c deleted file mode 100644 index 8fda83fa..00000000 --- a/deps/glib/gslice.c +++ /dev/null @@ -1,1493 +0,0 @@ -/* GLIB sliced memory - fast concurrent memory chunk allocator - * Copyright (C) 2005 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ -/* MT safe */ - -#include "config.h" -#include "glibconfig.h" - -#if defined HAVE_POSIX_MEMALIGN && defined POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS -# define HAVE_COMPLIANT_POSIX_MEMALIGN 1 -#endif - -#if defined(HAVE_COMPLIANT_POSIX_MEMALIGN) && !defined(_XOPEN_SOURCE) -#define _XOPEN_SOURCE 600 /* posix_memalign() */ -#endif -#include <stdlib.h> /* posix_memalign() */ -#include <string.h> -#include <errno.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> /* sysconf() */ -#endif -#ifdef G_OS_WIN32 -#include <windows.h> -#include <process.h> -#endif - -#include <stdio.h> /* fputs/fprintf */ - -#include "gslice.h" - -#include "gmain.h" -#include "gmem.h" /* gslice.h */ -#include "gstrfuncs.h" -#include "gutils.h" -#include "gtestutils.h" -#include "gthread.h" -#include "gthreadprivate.h" -#include "glib_trace.h" - -/* the GSlice allocator is split up into 4 layers, roughly modelled after the slab - * allocator and magazine extensions as outlined in: - * + [Bonwick94] Jeff Bonwick, The slab allocator: An object-caching kernel - * memory allocator. USENIX 1994, http://citeseer.ist.psu.edu/bonwick94slab.html - * + [Bonwick01] Bonwick and Jonathan Adams, Magazines and vmem: Extending the - * slab allocator to many cpu's and arbitrary resources. - * USENIX 2001, http://citeseer.ist.psu.edu/bonwick01magazines.html - * the layers are: - * - the thread magazines. for each (aligned) chunk size, a magazine (a list) - * of recently freed and soon to be allocated chunks is maintained per thread. - * this way, most alloc/free requests can be quickly satisfied from per-thread - * free lists which only require one g_private_get() call to retrive the - * thread handle. - * - the magazine cache. allocating and freeing chunks to/from threads only - * occours at magazine sizes from a global depot of magazines. the depot - * maintaines a 15 second working set of allocated magazines, so full - * magazines are not allocated and released too often. - * the chunk size dependent magazine sizes automatically adapt (within limits, - * see [3]) to lock contention to properly scale performance across a variety - * of SMP systems. - * - the slab allocator. this allocator allocates slabs (blocks of memory) close - * to the system page size or multiples thereof which have to be page aligned. - * the blocks are divided into smaller chunks which are used to satisfy - * allocations from the upper layers. the space provided by the reminder of - * the chunk size division is used for cache colorization (random distribution - * of chunk addresses) to improve processor cache utilization. multiple slabs - * with the same chunk size are kept in a partially sorted ring to allow O(1) - * freeing and allocation of chunks (as long as the allocation of an entirely - * new slab can be avoided). - * - the page allocator. on most modern systems, posix_memalign(3) or - * memalign(3) should be available, so this is used to allocate blocks with - * system page size based alignments and sizes or multiples thereof. - * if no memalign variant is provided, valloc() is used instead and - * block sizes are limited to the system page size (no multiples thereof). - * as a fallback, on system without even valloc(), a malloc(3)-based page - * allocator with alloc-only behaviour is used. - * - * NOTES: - * [1] some systems memalign(3) implementations may rely on boundary tagging for - * the handed out memory chunks. to avoid excessive page-wise fragmentation, - * we reserve 2 * sizeof (void*) per block size for the systems memalign(3), - * specified in NATIVE_MALLOC_PADDING. - * [2] using the slab allocator alone already provides for a fast and efficient - * allocator, it doesn't properly scale beyond single-threaded uses though. - * also, the slab allocator implements eager free(3)-ing, i.e. does not - * provide any form of caching or working set maintenance. so if used alone, - * it's vulnerable to trashing for sequences of balanced (alloc, free) pairs - * at certain thresholds. - * [3] magazine sizes are bound by an implementation specific minimum size and - * a chunk size specific maximum to limit magazine storage sizes to roughly - * 16KB. - * [4] allocating ca. 8 chunks per block/page keeps a good balance between - * external and internal fragmentation (<= 12.5%). [Bonwick94] - */ - -/* --- macros and constants --- */ -#define LARGEALIGNMENT (256) -#define P2ALIGNMENT (2 * sizeof (gsize)) /* fits 2 pointers (assumed to be 2 * GLIB_SIZEOF_SIZE_T below) */ -#define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base))) -#define NATIVE_MALLOC_PADDING P2ALIGNMENT /* per-page padding left for native malloc(3) see [1] */ -#define SLAB_INFO_SIZE P2ALIGN (sizeof (SlabInfo) + NATIVE_MALLOC_PADDING) -#define MAX_MAGAZINE_SIZE (256) /* see [3] and allocator_get_magazine_threshold() for this */ -#define MIN_MAGAZINE_SIZE (4) -#define MAX_STAMP_COUNTER (7) /* distributes the load of gettimeofday() */ -#define MAX_SLAB_CHUNK_SIZE(al) (((al)->max_page_size - SLAB_INFO_SIZE) / 8) /* we want at last 8 chunks per page, see [4] */ -#define MAX_SLAB_INDEX(al) (SLAB_INDEX (al, MAX_SLAB_CHUNK_SIZE (al)) + 1) -#define SLAB_INDEX(al, asize) ((asize) / P2ALIGNMENT - 1) /* asize must be P2ALIGNMENT aligned */ -#define SLAB_CHUNK_SIZE(al, ix) (((ix) + 1) * P2ALIGNMENT) -#define SLAB_BPAGE_SIZE(al,csz) (8 * (csz) + SLAB_INFO_SIZE) - -/* optimized version of ALIGN (size, P2ALIGNMENT) */ -#if GLIB_SIZEOF_SIZE_T * 2 == 8 /* P2ALIGNMENT */ -#define P2ALIGN(size) (((size) + 0x7) & ~(gsize) 0x7) -#elif GLIB_SIZEOF_SIZE_T * 2 == 16 /* P2ALIGNMENT */ -#define P2ALIGN(size) (((size) + 0xf) & ~(gsize) 0xf) -#else -#define P2ALIGN(size) ALIGN (size, P2ALIGNMENT) -#endif - -/* special helpers to avoid gmessage.c dependency */ -static void mem_error (const char *format, ...) G_GNUC_PRINTF (1,2); -#define mem_assert(cond) do { if (G_LIKELY (cond)) ; else mem_error ("assertion failed: %s", #cond); } while (0) - -/* --- structures --- */ -typedef struct _ChunkLink ChunkLink; -typedef struct _SlabInfo SlabInfo; -typedef struct _CachedMagazine CachedMagazine; -struct _ChunkLink { - ChunkLink *next; - ChunkLink *data; -}; -struct _SlabInfo { - ChunkLink *chunks; - guint n_allocated; - SlabInfo *next, *prev; -}; -typedef struct { - ChunkLink *chunks; - gsize count; /* approximative chunks list length */ -} Magazine; -typedef struct { - Magazine *magazine1; /* array of MAX_SLAB_INDEX (allocator) */ - Magazine *magazine2; /* array of MAX_SLAB_INDEX (allocator) */ -} ThreadMemory; -typedef struct { - gboolean always_malloc; - gboolean bypass_magazines; - gboolean debug_blocks; - gsize working_set_msecs; - guint color_increment; -} SliceConfig; -typedef struct { - /* const after initialization */ - gsize min_page_size, max_page_size; - SliceConfig config; - gsize max_slab_chunk_size_for_magazine_cache; - /* magazine cache */ - GMutex *magazine_mutex; - ChunkLink **magazines; /* array of MAX_SLAB_INDEX (allocator) */ - guint *contention_counters; /* array of MAX_SLAB_INDEX (allocator) */ - gint mutex_counter; - guint stamp_counter; - guint last_stamp; - /* slab allocator */ - GMutex *slab_mutex; - SlabInfo **slab_stack; /* array of MAX_SLAB_INDEX (allocator) */ - guint color_accu; -} Allocator; - -/* --- g-slice prototypes --- */ -static gpointer slab_allocator_alloc_chunk (gsize chunk_size); -static void slab_allocator_free_chunk (gsize chunk_size, - gpointer mem); -static void private_thread_memory_cleanup (gpointer data); -static gpointer allocator_memalign (gsize alignment, - gsize memsize); -static void allocator_memfree (gsize memsize, - gpointer mem); -static inline void magazine_cache_update_stamp (void); -static inline gsize allocator_get_magazine_threshold (Allocator *allocator, - guint ix); - -/* --- g-slice memory checker --- */ -static void smc_notify_alloc (void *pointer, - size_t size); -static int smc_notify_free (void *pointer, - size_t size); - -/* --- variables --- */ -static GPrivate *private_thread_memory = NULL; -static gsize sys_page_size = 0; -static Allocator allocator[1] = { { 0, }, }; -static SliceConfig slice_config = { - FALSE, /* always_malloc */ - FALSE, /* bypass_magazines */ - FALSE, /* debug_blocks */ - 15 * 1000, /* working_set_msecs */ - 1, /* color increment, alt: 0x7fffffff */ -}; -static GMutex *smc_tree_mutex = NULL; /* mutex for G_SLICE=debug-blocks */ - -/* --- auxiliary funcitons --- */ -void -g_slice_set_config (GSliceConfig ckey, - gint64 value) -{ - g_return_if_fail (sys_page_size == 0); - switch (ckey) - { - case G_SLICE_CONFIG_ALWAYS_MALLOC: - slice_config.always_malloc = value != 0; - break; - case G_SLICE_CONFIG_BYPASS_MAGAZINES: - slice_config.bypass_magazines = value != 0; - break; - case G_SLICE_CONFIG_WORKING_SET_MSECS: - slice_config.working_set_msecs = value; - break; - case G_SLICE_CONFIG_COLOR_INCREMENT: - slice_config.color_increment = value; - default: ; - } -} - -gint64 -g_slice_get_config (GSliceConfig ckey) -{ - switch (ckey) - { - case G_SLICE_CONFIG_ALWAYS_MALLOC: - return slice_config.always_malloc; - case G_SLICE_CONFIG_BYPASS_MAGAZINES: - return slice_config.bypass_magazines; - case G_SLICE_CONFIG_WORKING_SET_MSECS: - return slice_config.working_set_msecs; - case G_SLICE_CONFIG_CHUNK_SIZES: - return MAX_SLAB_INDEX (allocator); - case G_SLICE_CONFIG_COLOR_INCREMENT: - return slice_config.color_increment; - default: - return 0; - } -} - -gint64* -g_slice_get_config_state (GSliceConfig ckey, - gint64 address, - guint *n_values) -{ - guint i = 0; - g_return_val_if_fail (n_values != NULL, NULL); - *n_values = 0; - switch (ckey) - { - gint64 array[64]; - case G_SLICE_CONFIG_CONTENTION_COUNTER: - array[i++] = SLAB_CHUNK_SIZE (allocator, address); - array[i++] = allocator->contention_counters[address]; - array[i++] = allocator_get_magazine_threshold (allocator, address); - *n_values = i; - return g_memdup (array, sizeof (array[0]) * *n_values); - default: - return NULL; - } -} - -static void -slice_config_init (SliceConfig *config) -{ - /* don't use g_malloc/g_message here */ - gchar buffer[1024]; - const gchar *val = _g_getenv_nomalloc ("G_SLICE", buffer); - const GDebugKey keys[] = { - { "always-malloc", 1 << 0 }, - { "debug-blocks", 1 << 1 }, - }; - gint flags = !val ? 0 : g_parse_debug_string (val, keys, G_N_ELEMENTS (keys)); - *config = slice_config; - if (flags & (1 << 0)) /* always-malloc */ - config->always_malloc = TRUE; - if (flags & (1 << 1)) /* debug-blocks */ - config->debug_blocks = TRUE; -} - -static void -g_slice_init_nomessage (void) -{ - /* we may not use g_error() or friends here */ - mem_assert (sys_page_size == 0); - mem_assert (MIN_MAGAZINE_SIZE >= 4); - -#ifdef G_OS_WIN32 - { - SYSTEM_INFO system_info; - GetSystemInfo (&system_info); - sys_page_size = system_info.dwPageSize; - } -#else - sys_page_size = sysconf (_SC_PAGESIZE); /* = sysconf (_SC_PAGE_SIZE); = getpagesize(); */ -#endif - mem_assert (sys_page_size >= 2 * LARGEALIGNMENT); - mem_assert ((sys_page_size & (sys_page_size - 1)) == 0); - slice_config_init (&allocator->config); - allocator->min_page_size = sys_page_size; -#if HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN - /* allow allocation of pages up to 8KB (with 8KB alignment). - * this is useful because many medium to large sized structures - * fit less than 8 times (see [4]) into 4KB pages. - * we allow very small page sizes here, to reduce wastage in - * threads if only small allocations are required (this does - * bear the risk of incresing allocation times and fragmentation - * though). - */ - allocator->min_page_size = MAX (allocator->min_page_size, 4096); - allocator->max_page_size = MAX (allocator->min_page_size, 8192); - allocator->min_page_size = MIN (allocator->min_page_size, 128); -#else - /* we can only align to system page size */ - allocator->max_page_size = sys_page_size; -#endif - if (allocator->config.always_malloc) - { - allocator->contention_counters = NULL; - allocator->magazines = NULL; - allocator->slab_stack = NULL; - } - else - { - allocator->contention_counters = g_new0 (guint, MAX_SLAB_INDEX (allocator)); - allocator->magazines = g_new0 (ChunkLink*, MAX_SLAB_INDEX (allocator)); - allocator->slab_stack = g_new0 (SlabInfo*, MAX_SLAB_INDEX (allocator)); - } - - allocator->magazine_mutex = NULL; /* _g_slice_thread_init_nomessage() */ - allocator->mutex_counter = 0; - allocator->stamp_counter = MAX_STAMP_COUNTER; /* force initial update */ - allocator->last_stamp = 0; - allocator->slab_mutex = NULL; /* _g_slice_thread_init_nomessage() */ - allocator->color_accu = 0; - magazine_cache_update_stamp(); - /* values cached for performance reasons */ - allocator->max_slab_chunk_size_for_magazine_cache = MAX_SLAB_CHUNK_SIZE (allocator); - if (allocator->config.always_malloc || allocator->config.bypass_magazines) - allocator->max_slab_chunk_size_for_magazine_cache = 0; /* non-optimized cases */ - /* at this point, g_mem_gc_friendly() should be initialized, this - * should have been accomplished by the above g_malloc/g_new calls - */ -} - -static inline guint -allocator_categorize (gsize aligned_chunk_size) -{ - /* speed up the likely path */ - if (G_LIKELY (aligned_chunk_size && aligned_chunk_size <= allocator->max_slab_chunk_size_for_magazine_cache)) - return 1; /* use magazine cache */ - - /* the above will fail (max_slab_chunk_size_for_magazine_cache == 0) if the - * allocator is still uninitialized, or if we are not configured to use the - * magazine cache. - */ - if (!sys_page_size) - g_slice_init_nomessage (); - if (!allocator->config.always_malloc && - aligned_chunk_size && - aligned_chunk_size <= MAX_SLAB_CHUNK_SIZE (allocator)) - { - if (allocator->config.bypass_magazines) - return 2; /* use slab allocator, see [2] */ - return 1; /* use magazine cache */ - } - return 0; /* use malloc() */ -} - -void -_g_slice_thread_init_nomessage (void) -{ - /* we may not use g_error() or friends here */ - if (!sys_page_size) - g_slice_init_nomessage(); - else - { - /* g_slice_init_nomessage() has been called already, probably due - * to a g_slice_alloc1() before g_thread_init(). - */ - } - private_thread_memory = g_private_new (private_thread_memory_cleanup); - allocator->magazine_mutex = g_mutex_new(); - allocator->slab_mutex = g_mutex_new(); - if (allocator->config.debug_blocks) - smc_tree_mutex = g_mutex_new(); -} - -static inline void -g_mutex_lock_a (GMutex *mutex, - guint *contention_counter) -{ - gboolean contention = FALSE; - if (!g_mutex_trylock (mutex)) - { - g_mutex_lock (mutex); - contention = TRUE; - } - if (contention) - { - allocator->mutex_counter++; - if (allocator->mutex_counter >= 1) /* quickly adapt to contention */ - { - allocator->mutex_counter = 0; - *contention_counter = MIN (*contention_counter + 1, MAX_MAGAZINE_SIZE); - } - } - else /* !contention */ - { - allocator->mutex_counter--; - if (allocator->mutex_counter < -11) /* moderately recover magazine sizes */ - { - allocator->mutex_counter = 0; - *contention_counter = MAX (*contention_counter, 1) - 1; - } - } -} - -static inline ThreadMemory* -thread_memory_from_self (void) -{ - ThreadMemory *tmem = g_private_get (private_thread_memory); - if (G_UNLIKELY (!tmem)) - { - static ThreadMemory *single_thread_memory = NULL; /* remember single-thread info for multi-threaded case */ - if (single_thread_memory && g_thread_supported ()) - { - g_mutex_lock (allocator->slab_mutex); - if (single_thread_memory) - { - /* GSlice has been used before g_thread_init(), and now - * we are running threaded. to cope with it, use the saved - * thread memory structure from when we weren't threaded. - */ - tmem = single_thread_memory; - single_thread_memory = NULL; /* slab_mutex protected when multi-threaded */ - } - g_mutex_unlock (allocator->slab_mutex); - } - if (!tmem) - { - const guint n_magazines = MAX_SLAB_INDEX (allocator); - tmem = g_malloc0 (sizeof (ThreadMemory) + sizeof (Magazine) * 2 * n_magazines); - tmem->magazine1 = (Magazine*) (tmem + 1); - tmem->magazine2 = &tmem->magazine1[n_magazines]; - } - /* g_private_get/g_private_set works in the single-threaded xor the multi- - * threaded case. but not *across* g_thread_init(), after multi-thread - * initialization it returns NULL for previously set single-thread data. - */ - g_private_set (private_thread_memory, tmem); - /* save single-thread thread memory structure, in case we need to - * pick it up again after multi-thread initialization happened. - */ - if (!single_thread_memory && !g_thread_supported ()) - single_thread_memory = tmem; /* no slab_mutex created yet */ - } - return tmem; -} - -static inline ChunkLink* -magazine_chain_pop_head (ChunkLink **magazine_chunks) -{ - /* magazine chains are linked via ChunkLink->next. - * each ChunkLink->data of the toplevel chain may point to a subchain, - * linked via ChunkLink->next. ChunkLink->data of the subchains just - * contains uninitialized junk. - */ - ChunkLink *chunk = (*magazine_chunks)->data; - if (G_UNLIKELY (chunk)) - { - /* allocating from freed list */ - (*magazine_chunks)->data = chunk->next; - } - else - { - chunk = *magazine_chunks; - *magazine_chunks = chunk->next; - } - return chunk; -} - -#if 0 /* useful for debugging */ -static guint -magazine_count (ChunkLink *head) -{ - guint count = 0; - if (!head) - return 0; - while (head) - { - ChunkLink *child = head->data; - count += 1; - for (child = head->data; child; child = child->next) - count += 1; - head = head->next; - } - return count; -} -#endif - -static inline gsize -allocator_get_magazine_threshold (Allocator *allocator, - guint ix) -{ - /* the magazine size calculated here has a lower bound of MIN_MAGAZINE_SIZE, - * which is required by the implementation. also, for moderately sized chunks - * (say >= 64 bytes), magazine sizes shouldn't be much smaller then the number - * of chunks available per page/2 to avoid excessive traffic in the magazine - * cache for small to medium sized structures. - * the upper bound of the magazine size is effectively provided by - * MAX_MAGAZINE_SIZE. for larger chunks, this number is scaled down so that - * the content of a single magazine doesn't exceed ca. 16KB. - */ - gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); - guint threshold = MAX (MIN_MAGAZINE_SIZE, allocator->max_page_size / MAX (5 * chunk_size, 5 * 32)); - guint contention_counter = allocator->contention_counters[ix]; - if (G_UNLIKELY (contention_counter)) /* single CPU bias */ - { - /* adapt contention counter thresholds to chunk sizes */ - contention_counter = contention_counter * 64 / chunk_size; - threshold = MAX (threshold, contention_counter); - } - return threshold; -} - -/* --- magazine cache --- */ -static inline void -magazine_cache_update_stamp (void) -{ - if (allocator->stamp_counter >= MAX_STAMP_COUNTER) - { - GTimeVal tv; - g_get_current_time (&tv); - allocator->last_stamp = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* milli seconds */ - allocator->stamp_counter = 0; - } - else - allocator->stamp_counter++; -} - -static inline ChunkLink* -magazine_chain_prepare_fields (ChunkLink *magazine_chunks) -{ - ChunkLink *chunk1; - ChunkLink *chunk2; - ChunkLink *chunk3; - ChunkLink *chunk4; - /* checked upon initialization: mem_assert (MIN_MAGAZINE_SIZE >= 4); */ - /* ensure a magazine with at least 4 unused data pointers */ - chunk1 = magazine_chain_pop_head (&magazine_chunks); - chunk2 = magazine_chain_pop_head (&magazine_chunks); - chunk3 = magazine_chain_pop_head (&magazine_chunks); - chunk4 = magazine_chain_pop_head (&magazine_chunks); - chunk4->next = magazine_chunks; - chunk3->next = chunk4; - chunk2->next = chunk3; - chunk1->next = chunk2; - return chunk1; -} - -/* access the first 3 fields of a specially prepared magazine chain */ -#define magazine_chain_prev(mc) ((mc)->data) -#define magazine_chain_stamp(mc) ((mc)->next->data) -#define magazine_chain_uint_stamp(mc) GPOINTER_TO_UINT ((mc)->next->data) -#define magazine_chain_next(mc) ((mc)->next->next->data) -#define magazine_chain_count(mc) ((mc)->next->next->next->data) - -static void -magazine_cache_trim (Allocator *allocator, - guint ix, - guint stamp) -{ - /* g_mutex_lock (allocator->mutex); done by caller */ - /* trim magazine cache from tail */ - ChunkLink *current = magazine_chain_prev (allocator->magazines[ix]); - ChunkLink *trash = NULL; - while (ABS (stamp - magazine_chain_uint_stamp (current)) >= allocator->config.working_set_msecs) - { - /* unlink */ - ChunkLink *prev = magazine_chain_prev (current); - ChunkLink *next = magazine_chain_next (current); - magazine_chain_next (prev) = next; - magazine_chain_prev (next) = prev; - /* clear special fields, put on trash stack */ - magazine_chain_next (current) = NULL; - magazine_chain_count (current) = NULL; - magazine_chain_stamp (current) = NULL; - magazine_chain_prev (current) = trash; - trash = current; - /* fixup list head if required */ - if (current == allocator->magazines[ix]) - { - allocator->magazines[ix] = NULL; - break; - } - current = prev; - } - g_mutex_unlock (allocator->magazine_mutex); - /* free trash */ - if (trash) - { - const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); - g_mutex_lock (allocator->slab_mutex); - while (trash) - { - current = trash; - trash = magazine_chain_prev (current); - magazine_chain_prev (current) = NULL; /* clear special field */ - while (current) - { - ChunkLink *chunk = magazine_chain_pop_head (¤t); - slab_allocator_free_chunk (chunk_size, chunk); - } - } - g_mutex_unlock (allocator->slab_mutex); - } -} - -static void -magazine_cache_push_magazine (guint ix, - ChunkLink *magazine_chunks, - gsize count) /* must be >= MIN_MAGAZINE_SIZE */ -{ - ChunkLink *current = magazine_chain_prepare_fields (magazine_chunks); - ChunkLink *next, *prev; - g_mutex_lock (allocator->magazine_mutex); - /* add magazine at head */ - next = allocator->magazines[ix]; - if (next) - prev = magazine_chain_prev (next); - else - next = prev = current; - magazine_chain_next (prev) = current; - magazine_chain_prev (next) = current; - magazine_chain_prev (current) = prev; - magazine_chain_next (current) = next; - magazine_chain_count (current) = (gpointer) count; - /* stamp magazine */ - magazine_cache_update_stamp(); - magazine_chain_stamp (current) = GUINT_TO_POINTER (allocator->last_stamp); - allocator->magazines[ix] = current; - /* free old magazines beyond a certain threshold */ - magazine_cache_trim (allocator, ix, allocator->last_stamp); - /* g_mutex_unlock (allocator->mutex); was done by magazine_cache_trim() */ -} - -static ChunkLink* -magazine_cache_pop_magazine (guint ix, - gsize *countp) -{ - g_mutex_lock_a (allocator->magazine_mutex, &allocator->contention_counters[ix]); - if (!allocator->magazines[ix]) - { - guint magazine_threshold = allocator_get_magazine_threshold (allocator, ix); - gsize i, chunk_size = SLAB_CHUNK_SIZE (allocator, ix); - ChunkLink *chunk, *head; - g_mutex_unlock (allocator->magazine_mutex); - g_mutex_lock (allocator->slab_mutex); - head = slab_allocator_alloc_chunk (chunk_size); - head->data = NULL; - chunk = head; - for (i = 1; i < magazine_threshold; i++) - { - chunk->next = slab_allocator_alloc_chunk (chunk_size); - chunk = chunk->next; - chunk->data = NULL; - } - chunk->next = NULL; - g_mutex_unlock (allocator->slab_mutex); - *countp = i; - return head; - } - else - { - ChunkLink *current = allocator->magazines[ix]; - ChunkLink *prev = magazine_chain_prev (current); - ChunkLink *next = magazine_chain_next (current); - /* unlink */ - magazine_chain_next (prev) = next; - magazine_chain_prev (next) = prev; - allocator->magazines[ix] = next == current ? NULL : next; - g_mutex_unlock (allocator->magazine_mutex); - /* clear special fields and hand out */ - *countp = (gsize) magazine_chain_count (current); - magazine_chain_prev (current) = NULL; - magazine_chain_next (current) = NULL; - magazine_chain_count (current) = NULL; - magazine_chain_stamp (current) = NULL; - return current; - } -} - -/* --- thread magazines --- */ -static void -private_thread_memory_cleanup (gpointer data) -{ - ThreadMemory *tmem = data; - const guint n_magazines = MAX_SLAB_INDEX (allocator); - guint ix; - for (ix = 0; ix < n_magazines; ix++) - { - Magazine *mags[2]; - guint j; - mags[0] = &tmem->magazine1[ix]; - mags[1] = &tmem->magazine2[ix]; - for (j = 0; j < 2; j++) - { - Magazine *mag = mags[j]; - if (mag->count >= MIN_MAGAZINE_SIZE) - magazine_cache_push_magazine (ix, mag->chunks, mag->count); - else - { - const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); - g_mutex_lock (allocator->slab_mutex); - while (mag->chunks) - { - ChunkLink *chunk = magazine_chain_pop_head (&mag->chunks); - slab_allocator_free_chunk (chunk_size, chunk); - } - g_mutex_unlock (allocator->slab_mutex); - } - } - } - g_free (tmem); -} - -static void -thread_memory_magazine1_reload (ThreadMemory *tmem, - guint ix) -{ - Magazine *mag = &tmem->magazine1[ix]; - mem_assert (mag->chunks == NULL); /* ensure that we may reset mag->count */ - mag->count = 0; - mag->chunks = magazine_cache_pop_magazine (ix, &mag->count); -} - -static void -thread_memory_magazine2_unload (ThreadMemory *tmem, - guint ix) -{ - Magazine *mag = &tmem->magazine2[ix]; - magazine_cache_push_magazine (ix, mag->chunks, mag->count); - mag->chunks = NULL; - mag->count = 0; -} - -static inline void -thread_memory_swap_magazines (ThreadMemory *tmem, - guint ix) -{ - Magazine xmag = tmem->magazine1[ix]; - tmem->magazine1[ix] = tmem->magazine2[ix]; - tmem->magazine2[ix] = xmag; -} - -static inline gboolean -thread_memory_magazine1_is_empty (ThreadMemory *tmem, - guint ix) -{ - return tmem->magazine1[ix].chunks == NULL; -} - -static inline gboolean -thread_memory_magazine2_is_full (ThreadMemory *tmem, - guint ix) -{ - return tmem->magazine2[ix].count >= allocator_get_magazine_threshold (allocator, ix); -} - -static inline gpointer -thread_memory_magazine1_alloc (ThreadMemory *tmem, - guint ix) -{ - Magazine *mag = &tmem->magazine1[ix]; - ChunkLink *chunk = magazine_chain_pop_head (&mag->chunks); - if (G_LIKELY (mag->count > 0)) - mag->count--; - return chunk; -} - -static inline void -thread_memory_magazine2_free (ThreadMemory *tmem, - guint ix, - gpointer mem) -{ - Magazine *mag = &tmem->magazine2[ix]; - ChunkLink *chunk = mem; - chunk->data = NULL; - chunk->next = mag->chunks; - mag->chunks = chunk; - mag->count++; -} - -/* --- API functions --- */ -gpointer -g_slice_alloc (gsize mem_size) -{ - gsize chunk_size; - gpointer mem; - guint acat; - chunk_size = P2ALIGN (mem_size); - acat = allocator_categorize (chunk_size); - if (G_LIKELY (acat == 1)) /* allocate through magazine layer */ - { - ThreadMemory *tmem = thread_memory_from_self(); - guint ix = SLAB_INDEX (allocator, chunk_size); - if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix))) - { - thread_memory_swap_magazines (tmem, ix); - if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix))) - thread_memory_magazine1_reload (tmem, ix); - } - mem = thread_memory_magazine1_alloc (tmem, ix); - } - else if (acat == 2) /* allocate through slab allocator */ - { - g_mutex_lock (allocator->slab_mutex); - mem = slab_allocator_alloc_chunk (chunk_size); - g_mutex_unlock (allocator->slab_mutex); - } - else /* delegate to system malloc */ - mem = g_malloc (mem_size); - if (G_UNLIKELY (allocator->config.debug_blocks)) - smc_notify_alloc (mem, mem_size); - - TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size)); - - return mem; -} - -gpointer -g_slice_alloc0 (gsize mem_size) -{ - gpointer mem = g_slice_alloc (mem_size); - if (mem) - memset (mem, 0, mem_size); - return mem; -} - -gpointer -g_slice_copy (gsize mem_size, - gconstpointer mem_block) -{ - gpointer mem = g_slice_alloc (mem_size); - if (mem) - memcpy (mem, mem_block, mem_size); - return mem; -} - -void -g_slice_free1 (gsize mem_size, - gpointer mem_block) -{ - gsize chunk_size = P2ALIGN (mem_size); - guint acat = allocator_categorize (chunk_size); - if (G_UNLIKELY (!mem_block)) - return; - if (G_UNLIKELY (allocator->config.debug_blocks) && - !smc_notify_free (mem_block, mem_size)) - abort(); - if (G_LIKELY (acat == 1)) /* allocate through magazine layer */ - { - ThreadMemory *tmem = thread_memory_from_self(); - guint ix = SLAB_INDEX (allocator, chunk_size); - if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) - { - thread_memory_swap_magazines (tmem, ix); - if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) - thread_memory_magazine2_unload (tmem, ix); - } - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (mem_block, 0, chunk_size); - thread_memory_magazine2_free (tmem, ix, mem_block); - } - else if (acat == 2) /* allocate through slab allocator */ - { - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (mem_block, 0, chunk_size); - g_mutex_lock (allocator->slab_mutex); - slab_allocator_free_chunk (chunk_size, mem_block); - g_mutex_unlock (allocator->slab_mutex); - } - else /* delegate to system malloc */ - { - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (mem_block, 0, mem_size); - g_free (mem_block); - } - TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size)); -} - -void -g_slice_free_chain_with_offset (gsize mem_size, - gpointer mem_chain, - gsize next_offset) -{ - gpointer slice = mem_chain; - /* while the thread magazines and the magazine cache are implemented so that - * they can easily be extended to allow for free lists containing more free - * lists for the first level nodes, which would allow O(1) freeing in this - * function, the benefit of such an extension is questionable, because: - * - the magazine size counts will become mere lower bounds which confuses - * the code adapting to lock contention; - * - freeing a single node to the thread magazines is very fast, so this - * O(list_length) operation is multiplied by a fairly small factor; - * - memory usage histograms on larger applications seem to indicate that - * the amount of released multi node lists is negligible in comparison - * to single node releases. - * - the major performance bottle neck, namely g_private_get() or - * g_mutex_lock()/g_mutex_unlock() has already been moved out of the - * inner loop for freeing chained slices. - */ - gsize chunk_size = P2ALIGN (mem_size); - guint acat = allocator_categorize (chunk_size); - if (G_LIKELY (acat == 1)) /* allocate through magazine layer */ - { - ThreadMemory *tmem = thread_memory_from_self(); - guint ix = SLAB_INDEX (allocator, chunk_size); - while (slice) - { - guint8 *current = slice; - slice = *(gpointer*) (current + next_offset); - if (G_UNLIKELY (allocator->config.debug_blocks) && - !smc_notify_free (current, mem_size)) - abort(); - if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) - { - thread_memory_swap_magazines (tmem, ix); - if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) - thread_memory_magazine2_unload (tmem, ix); - } - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (current, 0, chunk_size); - thread_memory_magazine2_free (tmem, ix, current); - } - } - else if (acat == 2) /* allocate through slab allocator */ - { - g_mutex_lock (allocator->slab_mutex); - while (slice) - { - guint8 *current = slice; - slice = *(gpointer*) (current + next_offset); - if (G_UNLIKELY (allocator->config.debug_blocks) && - !smc_notify_free (current, mem_size)) - abort(); - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (current, 0, chunk_size); - slab_allocator_free_chunk (chunk_size, current); - } - g_mutex_unlock (allocator->slab_mutex); - } - else /* delegate to system malloc */ - while (slice) - { - guint8 *current = slice; - slice = *(gpointer*) (current + next_offset); - if (G_UNLIKELY (allocator->config.debug_blocks) && - !smc_notify_free (current, mem_size)) - abort(); - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (current, 0, mem_size); - g_free (current); - } -} - -/* --- single page allocator --- */ -static void -allocator_slab_stack_push (Allocator *allocator, - guint ix, - SlabInfo *sinfo) -{ - /* insert slab at slab ring head */ - if (!allocator->slab_stack[ix]) - { - sinfo->next = sinfo; - sinfo->prev = sinfo; - } - else - { - SlabInfo *next = allocator->slab_stack[ix], *prev = next->prev; - next->prev = sinfo; - prev->next = sinfo; - sinfo->next = next; - sinfo->prev = prev; - } - allocator->slab_stack[ix] = sinfo; -} - -static gsize -allocator_aligned_page_size (Allocator *allocator, - gsize n_bytes) -{ - gsize val = 1 << g_bit_storage (n_bytes - 1); - val = MAX (val, allocator->min_page_size); - return val; -} - -static void -allocator_add_slab (Allocator *allocator, - guint ix, - gsize chunk_size) -{ - ChunkLink *chunk; - SlabInfo *sinfo; - gsize addr, padding, n_chunks, color = 0; - gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size)); - /* allocate 1 page for the chunks and the slab */ - gpointer aligned_memory = allocator_memalign (page_size, page_size - NATIVE_MALLOC_PADDING); - guint8 *mem = aligned_memory; - guint i; - if (!mem) - { - const gchar *syserr = "unknown error"; -#if HAVE_STRERROR - syserr = strerror (errno); -#endif - mem_error ("failed to allocate %u bytes (alignment: %u): %s\n", - (guint) (page_size - NATIVE_MALLOC_PADDING), (guint) page_size, syserr); - } - /* mask page address */ - addr = ((gsize) mem / page_size) * page_size; - /* assert alignment */ - mem_assert (aligned_memory == (gpointer) addr); - /* basic slab info setup */ - sinfo = (SlabInfo*) (mem + page_size - SLAB_INFO_SIZE); - sinfo->n_allocated = 0; - sinfo->chunks = NULL; - /* figure cache colorization */ - n_chunks = ((guint8*) sinfo - mem) / chunk_size; - padding = ((guint8*) sinfo - mem) - n_chunks * chunk_size; - if (padding) - { - color = (allocator->color_accu * P2ALIGNMENT) % padding; - allocator->color_accu += allocator->config.color_increment; - } - /* add chunks to free list */ - chunk = (ChunkLink*) (mem + color); - sinfo->chunks = chunk; - for (i = 0; i < n_chunks - 1; i++) - { - chunk->next = (ChunkLink*) ((guint8*) chunk + chunk_size); - chunk = chunk->next; - } - chunk->next = NULL; /* last chunk */ - /* add slab to slab ring */ - allocator_slab_stack_push (allocator, ix, sinfo); -} - -static gpointer -slab_allocator_alloc_chunk (gsize chunk_size) -{ - ChunkLink *chunk; - guint ix = SLAB_INDEX (allocator, chunk_size); - /* ensure non-empty slab */ - if (!allocator->slab_stack[ix] || !allocator->slab_stack[ix]->chunks) - allocator_add_slab (allocator, ix, chunk_size); - /* allocate chunk */ - chunk = allocator->slab_stack[ix]->chunks; - allocator->slab_stack[ix]->chunks = chunk->next; - allocator->slab_stack[ix]->n_allocated++; - /* rotate empty slabs */ - if (!allocator->slab_stack[ix]->chunks) - allocator->slab_stack[ix] = allocator->slab_stack[ix]->next; - return chunk; -} - -static void -slab_allocator_free_chunk (gsize chunk_size, - gpointer mem) -{ - ChunkLink *chunk; - gboolean was_empty; - guint ix = SLAB_INDEX (allocator, chunk_size); - gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size)); - gsize addr = ((gsize) mem / page_size) * page_size; - /* mask page address */ - guint8 *page = (guint8*) addr; - SlabInfo *sinfo = (SlabInfo*) (page + page_size - SLAB_INFO_SIZE); - /* assert valid chunk count */ - mem_assert (sinfo->n_allocated > 0); - /* add chunk to free list */ - was_empty = sinfo->chunks == NULL; - chunk = (ChunkLink*) mem; - chunk->next = sinfo->chunks; - sinfo->chunks = chunk; - sinfo->n_allocated--; - /* keep slab ring partially sorted, empty slabs at end */ - if (was_empty) - { - /* unlink slab */ - SlabInfo *next = sinfo->next, *prev = sinfo->prev; - next->prev = prev; - prev->next = next; - if (allocator->slab_stack[ix] == sinfo) - allocator->slab_stack[ix] = next == sinfo ? NULL : next; - /* insert slab at head */ - allocator_slab_stack_push (allocator, ix, sinfo); - } - /* eagerly free complete unused slabs */ - if (!sinfo->n_allocated) - { - /* unlink slab */ - SlabInfo *next = sinfo->next, *prev = sinfo->prev; - next->prev = prev; - prev->next = next; - if (allocator->slab_stack[ix] == sinfo) - allocator->slab_stack[ix] = next == sinfo ? NULL : next; - /* free slab */ - allocator_memfree (page_size, page); - } -} - -/* --- memalign implementation --- */ -#ifdef HAVE_MALLOC_H -#include <malloc.h> /* memalign() */ -#endif - -/* from config.h: - * define HAVE_POSIX_MEMALIGN 1 // if free(posix_memalign(3)) works, <stdlib.h> - * define HAVE_COMPLIANT_POSIX_MEMALIGN 1 // if free(posix_memalign(3)) works for sizes != 2^n, <stdlib.h> - * define HAVE_MEMALIGN 1 // if free(memalign(3)) works, <malloc.h> - * define HAVE_VALLOC 1 // if free(valloc(3)) works, <stdlib.h> or <malloc.h> - * if none is provided, we implement malloc(3)-based alloc-only page alignment - */ - -#if !(HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC) -static GTrashStack *compat_valloc_trash = NULL; -#endif - -static gpointer -allocator_memalign (gsize alignment, - gsize memsize) -{ - gpointer aligned_memory = NULL; - gint err = ENOMEM; -#if HAVE_COMPLIANT_POSIX_MEMALIGN - err = posix_memalign (&aligned_memory, alignment, memsize); -#elif HAVE_MEMALIGN - errno = 0; - aligned_memory = memalign (alignment, memsize); - err = errno; -#elif HAVE_VALLOC - errno = 0; - aligned_memory = valloc (memsize); - err = errno; -#else - /* simplistic non-freeing page allocator */ - mem_assert (alignment == sys_page_size); - mem_assert (memsize <= sys_page_size); - if (!compat_valloc_trash) - { - const guint n_pages = 16; - guint8 *mem = malloc (n_pages * sys_page_size); - err = errno; - if (mem) - { - gint i = n_pages; - guint8 *amem = (guint8*) ALIGN ((gsize) mem, sys_page_size); - if (amem != mem) - i--; /* mem wasn't page aligned */ - while (--i >= 0) - g_trash_stack_push (&compat_valloc_trash, amem + i * sys_page_size); - } - } - aligned_memory = g_trash_stack_pop (&compat_valloc_trash); -#endif - if (!aligned_memory) - errno = err; - return aligned_memory; -} - -static void -allocator_memfree (gsize memsize, - gpointer mem) -{ -#if HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC - free (mem); -#else - mem_assert (memsize <= sys_page_size); - g_trash_stack_push (&compat_valloc_trash, mem); -#endif -} - -static void -mem_error (const char *format, - ...) -{ - const char *pname; - va_list args; - /* at least, put out "MEMORY-ERROR", in case we segfault during the rest of the function */ - fputs ("\n***MEMORY-ERROR***: ", stderr); - pname = g_get_prgname(); - fprintf (stderr, "%s[%ld]: GSlice: ", pname ? pname : "", (long)getpid()); - va_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - fputs ("\n", stderr); - abort(); - _exit (1); -} - -/* --- g-slice memory checker tree --- */ -typedef size_t SmcKType; /* key type */ -typedef size_t SmcVType; /* value type */ -typedef struct { - SmcKType key; - SmcVType value; -} SmcEntry; -static void smc_tree_insert (SmcKType key, - SmcVType value); -static gboolean smc_tree_lookup (SmcKType key, - SmcVType *value_p); -static gboolean smc_tree_remove (SmcKType key); - - -/* --- g-slice memory checker implementation --- */ -static void -smc_notify_alloc (void *pointer, - size_t size) -{ - size_t adress = (size_t) pointer; - if (pointer) - smc_tree_insert (adress, size); -} - -#if 0 -static void -smc_notify_ignore (void *pointer) -{ - size_t adress = (size_t) pointer; - if (pointer) - smc_tree_remove (adress); -} -#endif - -static int -smc_notify_free (void *pointer, - size_t size) -{ - size_t adress = (size_t) pointer; - SmcVType real_size; - gboolean found_one; - - if (!pointer) - return 1; /* ignore */ - found_one = smc_tree_lookup (adress, &real_size); - if (!found_one) - { - fprintf (stderr, "GSlice: MemChecker: attempt to release non-allocated block: %p size=%" G_GSIZE_FORMAT "\n", pointer, size); - return 0; - } - if (real_size != size && (real_size || size)) - { - fprintf (stderr, "GSlice: MemChecker: attempt to release block with invalid size: %p size=%" G_GSIZE_FORMAT " invalid-size=%" G_GSIZE_FORMAT "\n", pointer, real_size, size); - return 0; - } - if (!smc_tree_remove (adress)) - { - fprintf (stderr, "GSlice: MemChecker: attempt to release non-allocated block: %p size=%" G_GSIZE_FORMAT "\n", pointer, size); - return 0; - } - return 1; /* all fine */ -} - -/* --- g-slice memory checker tree implementation --- */ -#define SMC_TRUNK_COUNT (4093 /* 16381 */) /* prime, to distribute trunk collisions (big, allocated just once) */ -#define SMC_BRANCH_COUNT (511) /* prime, to distribute branch collisions */ -#define SMC_TRUNK_EXTENT (SMC_BRANCH_COUNT * 2039) /* key adress space per trunk, should distribute uniformly across BRANCH_COUNT */ -#define SMC_TRUNK_HASH(k) ((k / SMC_TRUNK_EXTENT) % SMC_TRUNK_COUNT) /* generate new trunk hash per megabyte (roughly) */ -#define SMC_BRANCH_HASH(k) (k % SMC_BRANCH_COUNT) - -typedef struct { - SmcEntry *entries; - unsigned int n_entries; -} SmcBranch; - -static SmcBranch **smc_tree_root = NULL; - -static void -smc_tree_abort (int errval) -{ - const char *syserr = "unknown error"; -#if HAVE_STRERROR - syserr = strerror (errval); -#endif - mem_error ("MemChecker: failure in debugging tree: %s", syserr); -} - -static inline SmcEntry* -smc_tree_branch_grow_L (SmcBranch *branch, - unsigned int index) -{ - unsigned int old_size = branch->n_entries * sizeof (branch->entries[0]); - unsigned int new_size = old_size + sizeof (branch->entries[0]); - SmcEntry *entry; - mem_assert (index <= branch->n_entries); - branch->entries = (SmcEntry*) realloc (branch->entries, new_size); - if (!branch->entries) - smc_tree_abort (errno); - entry = branch->entries + index; - g_memmove (entry + 1, entry, (branch->n_entries - index) * sizeof (entry[0])); - branch->n_entries += 1; - return entry; -} - -static inline SmcEntry* -smc_tree_branch_lookup_nearest_L (SmcBranch *branch, - SmcKType key) -{ - unsigned int n_nodes = branch->n_entries, offs = 0; - SmcEntry *check = branch->entries; - int cmp = 0; - while (offs < n_nodes) - { - unsigned int i = (offs + n_nodes) >> 1; - check = branch->entries + i; - cmp = key < check->key ? -1 : key != check->key; - if (cmp == 0) - return check; /* return exact match */ - else if (cmp < 0) - n_nodes = i; - else /* (cmp > 0) */ - offs = i + 1; - } - /* check points at last mismatch, cmp > 0 indicates greater key */ - return cmp > 0 ? check + 1 : check; /* return insertion position for inexact match */ -} - -static void -smc_tree_insert (SmcKType key, - SmcVType value) -{ - unsigned int ix0, ix1; - SmcEntry *entry; - - g_mutex_lock (smc_tree_mutex); - ix0 = SMC_TRUNK_HASH (key); - ix1 = SMC_BRANCH_HASH (key); - if (!smc_tree_root) - { - smc_tree_root = calloc (SMC_TRUNK_COUNT, sizeof (smc_tree_root[0])); - if (!smc_tree_root) - smc_tree_abort (errno); - } - if (!smc_tree_root[ix0]) - { - smc_tree_root[ix0] = calloc (SMC_BRANCH_COUNT, sizeof (smc_tree_root[0][0])); - if (!smc_tree_root[ix0]) - smc_tree_abort (errno); - } - entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key); - if (!entry || /* need create */ - entry >= smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries || /* need append */ - entry->key != key) /* need insert */ - entry = smc_tree_branch_grow_L (&smc_tree_root[ix0][ix1], entry - smc_tree_root[ix0][ix1].entries); - entry->key = key; - entry->value = value; - g_mutex_unlock (smc_tree_mutex); -} - -static gboolean -smc_tree_lookup (SmcKType key, - SmcVType *value_p) -{ - SmcEntry *entry = NULL; - unsigned int ix0 = SMC_TRUNK_HASH (key), ix1 = SMC_BRANCH_HASH (key); - gboolean found_one = FALSE; - *value_p = 0; - g_mutex_lock (smc_tree_mutex); - if (smc_tree_root && smc_tree_root[ix0]) - { - entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key); - if (entry && - entry < smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries && - entry->key == key) - { - found_one = TRUE; - *value_p = entry->value; - } - } - g_mutex_unlock (smc_tree_mutex); - return found_one; -} - -static gboolean -smc_tree_remove (SmcKType key) -{ - unsigned int ix0 = SMC_TRUNK_HASH (key), ix1 = SMC_BRANCH_HASH (key); - gboolean found_one = FALSE; - g_mutex_lock (smc_tree_mutex); - if (smc_tree_root && smc_tree_root[ix0]) - { - SmcEntry *entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key); - if (entry && - entry < smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries && - entry->key == key) - { - unsigned int i = entry - smc_tree_root[ix0][ix1].entries; - smc_tree_root[ix0][ix1].n_entries -= 1; - g_memmove (entry, entry + 1, (smc_tree_root[ix0][ix1].n_entries - i) * sizeof (entry[0])); - if (!smc_tree_root[ix0][ix1].n_entries) - { - /* avoid useless pressure on the memory system */ - free (smc_tree_root[ix0][ix1].entries); - smc_tree_root[ix0][ix1].entries = NULL; - } - found_one = TRUE; - } - } - g_mutex_unlock (smc_tree_mutex); - return found_one; -} - -#ifdef G_ENABLE_DEBUG -void -g_slice_debug_tree_statistics (void) -{ - g_mutex_lock (smc_tree_mutex); - if (smc_tree_root) - { - unsigned int i, j, t = 0, o = 0, b = 0, su = 0, ex = 0, en = 4294967295u; - double tf, bf; - for (i = 0; i < SMC_TRUNK_COUNT; i++) - if (smc_tree_root[i]) - { - t++; - for (j = 0; j < SMC_BRANCH_COUNT; j++) - if (smc_tree_root[i][j].n_entries) - { - b++; - su += smc_tree_root[i][j].n_entries; - en = MIN (en, smc_tree_root[i][j].n_entries); - ex = MAX (ex, smc_tree_root[i][j].n_entries); - } - else if (smc_tree_root[i][j].entries) - o++; /* formerly used, now empty */ - } - en = b ? en : 0; - tf = MAX (t, 1.0); /* max(1) to be a valid divisor */ - bf = MAX (b, 1.0); /* max(1) to be a valid divisor */ - fprintf (stderr, "GSlice: MemChecker: %u trunks, %u branches, %u old branches\n", t, b, o); - fprintf (stderr, "GSlice: MemChecker: %f branches per trunk, %.2f%% utilization\n", - b / tf, - 100.0 - (SMC_BRANCH_COUNT - b / tf) / (0.01 * SMC_BRANCH_COUNT)); - fprintf (stderr, "GSlice: MemChecker: %f entries per branch, %u minimum, %u maximum\n", - su / bf, en, ex); - } - else - fprintf (stderr, "GSlice: MemChecker: root=NULL\n"); - g_mutex_unlock (smc_tree_mutex); - - /* sample statistics (beast + GSLice + 24h scripted core & GUI activity): - * PID %CPU %MEM VSZ RSS COMMAND - * 8887 30.3 45.8 456068 414856 beast-0.7.1 empty.bse - * $ cat /proc/8887/statm # total-program-size resident-set-size shared-pages text/code data/stack library dirty-pages - * 114017 103714 2354 344 0 108676 0 - * $ cat /proc/8887/status - * Name: beast-0.7.1 - * VmSize: 456068 kB - * VmLck: 0 kB - * VmRSS: 414856 kB - * VmData: 434620 kB - * VmStk: 84 kB - * VmExe: 1376 kB - * VmLib: 13036 kB - * VmPTE: 456 kB - * Threads: 3 - * (gdb) print g_slice_debug_tree_statistics () - * GSlice: MemChecker: 422 trunks, 213068 branches, 0 old branches - * GSlice: MemChecker: 504.900474 branches per trunk, 98.81% utilization - * GSlice: MemChecker: 4.965039 entries per branch, 1 minimum, 37 maximum - */ -} -#endif /* G_ENABLE_DEBUG */ diff --git a/deps/glib/gslice.h b/deps/glib/gslice.h deleted file mode 100644 index 30dfbe0a..00000000 --- a/deps/glib/gslice.h +++ /dev/null @@ -1,84 +0,0 @@ -/* GLIB sliced memory - fast threaded memory chunk allocator - * Copyright (C) 2005 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_SLICE_H__ -#define __G_SLICE_H__ - -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -/* slices - fast allocation/release of small memory blocks - */ -gpointer g_slice_alloc (gsize block_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -gpointer g_slice_alloc0 (gsize block_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -gpointer g_slice_copy (gsize block_size, - gconstpointer mem_block) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); -void g_slice_free1 (gsize block_size, - gpointer mem_block); -void g_slice_free_chain_with_offset (gsize block_size, - gpointer mem_chain, - gsize next_offset); -#define g_slice_new(type) ((type*) g_slice_alloc (sizeof (type))) -#define g_slice_new0(type) ((type*) g_slice_alloc0 (sizeof (type))) -/* MemoryBlockType * - * g_slice_dup (MemoryBlockType, - * MemoryBlockType *mem_block); - * g_slice_free (MemoryBlockType, - * MemoryBlockType *mem_block); - * g_slice_free_chain (MemoryBlockType, - * MemoryBlockType *first_chain_block, - * memory_block_next_field); - * pseudo prototypes for the macro - * definitions following below. - */ - -/* we go through extra hoops to ensure type safety */ -#define g_slice_dup(type, mem) \ - (1 ? (type*) g_slice_copy (sizeof (type), (mem)) \ - : ((void) ((type*) 0 == (mem)), (type*) 0)) -#define g_slice_free(type, mem) do { \ - if (1) g_slice_free1 (sizeof (type), (mem)); \ - else (void) ((type*) 0 == (mem)); \ -} while (0) -#define g_slice_free_chain(type, mem_chain, next) do { \ - if (1) g_slice_free_chain_with_offset (sizeof (type), \ - (mem_chain), G_STRUCT_OFFSET (type, next)); \ - else (void) ((type*) 0 == (mem_chain)); \ -} while (0) - - -/* --- internal debugging API --- */ -typedef enum { - G_SLICE_CONFIG_ALWAYS_MALLOC = 1, - G_SLICE_CONFIG_BYPASS_MAGAZINES, - G_SLICE_CONFIG_WORKING_SET_MSECS, - G_SLICE_CONFIG_COLOR_INCREMENT, - G_SLICE_CONFIG_CHUNK_SIZES, - G_SLICE_CONFIG_CONTENTION_COUNTER -} GSliceConfig; -void g_slice_set_config (GSliceConfig ckey, gint64 value); -gint64 g_slice_get_config (GSliceConfig ckey); -gint64* g_slice_get_config_state (GSliceConfig ckey, gint64 address, guint *n_values); - -G_END_DECLS - -#endif /* __G_SLICE_H__ */ diff --git a/deps/glib/gslist.c b/deps/glib/gslist.c deleted file mode 100644 index eeea72d2..00000000 --- a/deps/glib/gslist.c +++ /dev/null @@ -1,1080 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include "gslist.h" -#include "gtestutils.h" - -/** - * SECTION:linked_lists_single - * @title: Singly-Linked Lists - * @short_description: linked lists containing integer values or - * pointers to data, limited to iterating over the - * list in one direction - * - * The #GSList structure and its associated functions provide a - * standard singly-linked list data structure. - * - * Each element in the list contains a piece of data, together with a - * pointer which links to the next element in the list. Using this - * pointer it is possible to move through the list in one direction - * only (unlike the <link - * linkend="glib-Doubly-Linked-Lists">Doubly-Linked Lists</link> which - * allow movement in both directions). - * - * The data contained in each element can be either integer values, by - * using one of the <link linkend="glib-Type-Conversion-Macros">Type - * Conversion Macros</link>, or simply pointers to any type of data. - * - * List elements are allocated from the <link - * linkend="glib-Memory-Slices">slice allocator</link>, which is more - * efficient than allocating elements individually. - * - * Note that most of the #GSList functions expect to be passed a - * pointer to the first element in the list. The functions which insert - * elements return the new start of the list, which may have changed. - * - * There is no function to create a #GSList. %NULL is considered to be - * the empty list so you simply set a #GSList* to %NULL. - * - * To add elements, use g_slist_append(), g_slist_prepend(), - * g_slist_insert() and g_slist_insert_sorted(). - * - * To remove elements, use g_slist_remove(). - * - * To find elements in the list use g_slist_last(), g_slist_next(), - * g_slist_nth(), g_slist_nth_data(), g_slist_find() and - * g_slist_find_custom(). - * - * To find the index of an element use g_slist_position() and - * g_slist_index(). - * - * To call a function for each element in the list use - * g_slist_foreach(). - * - * To free the entire list, use g_slist_free(). - **/ - -/** - * GSList: - * @data: holds the element's data, which can be a pointer to any kind - * of data, or any integer value using the <link - * linkend="glib-Type-Conversion-Macros">Type Conversion - * Macros</link>. - * @next: contains the link to the next element in the list. - * - * The #GSList struct is used for each element in the singly-linked - * list. - **/ - -/** - * g_slist_next: - * @slist: an element in a #GSList. - * @Returns: the next element, or %NULL if there are no more elements. - * - * A convenience macro to get the next element in a #GSList. - **/ - - -/** - * g_slist_push_allocator: - * @dummy: the #GAllocator to use when allocating #GSList elements. - * - * Sets the allocator to use to allocate #GSList elements. Use - * g_slist_pop_allocator() to restore the previous allocator. - * - * Note that this function is not available if GLib has been compiled - * with <option>--disable-mem-pools</option> - * - * Deprecated: 2.10: It does nothing, since #GSList has been converted - * to the <link linkend="glib-Memory-Slices">slice - * allocator</link> - **/ -void g_slist_push_allocator (gpointer dummy) { /* present for binary compat only */ } - -/** - * g_slist_pop_allocator: - * - * Restores the previous #GAllocator, used when allocating #GSList - * elements. - * - * Note that this function is not available if GLib has been compiled - * with <option>--disable-mem-pools</option> - * - * Deprecated: 2.10: It does nothing, since #GSList has been converted - * to the <link linkend="glib-Memory-Slices">slice - * allocator</link> - **/ -void g_slist_pop_allocator (void) { /* present for binary compat only */ } - -#define _g_slist_alloc0() g_slice_new0 (GSList) -#define _g_slist_alloc() g_slice_new (GSList) -#define _g_slist_free1(slist) g_slice_free (GSList, slist) - -/** - * g_slist_alloc: - * @Returns: a pointer to the newly-allocated #GSList element. - * - * Allocates space for one #GSList element. It is called by the - * g_slist_append(), g_slist_prepend(), g_slist_insert() and - * g_slist_insert_sorted() functions and so is rarely used on its own. - **/ -GSList* -g_slist_alloc (void) -{ - return _g_slist_alloc0 (); -} - -/** - * g_slist_free: - * @list: a #GSList - * - * Frees all of the memory used by a #GSList. - * The freed elements are returned to the slice allocator. - * - * <note><para> - * If list elements contain dynamically-allocated memory, - * you should either use g_slist_free_full() or free them manually - * first. - * </para></note> - */ -void -g_slist_free (GSList *list) -{ - g_slice_free_chain (GSList, list, next); -} - -/** - * g_slist_free_1: - * @list: a #GSList element - * - * Frees one #GSList element. - * It is usually used after g_slist_remove_link(). - */ -/** - * g_slist_free1: - * - * A macro which does the same as g_slist_free_1(). - * - * Since: 2.10 - **/ -void -g_slist_free_1 (GSList *list) -{ - _g_slist_free1 (list); -} - -/** - * g_slist_free_full: - * @list: a pointer to a #GSList - * @free_func: the function to be called to free each element's data - * - * Convenience method, which frees all the memory used by a #GSList, and - * calls the specified destroy function on every element's data. - * - * Since: 2.28 - **/ -void -g_slist_free_full (GSList *list, - GDestroyNotify free_func) -{ - g_slist_foreach (list, (GFunc) free_func, NULL); - g_slist_free (list); -} - -/** - * g_slist_append: - * @list: a #GSList - * @data: the data for the new element - * - * Adds a new element on to the end of the list. - * - * <note><para> - * The return value is the new start of the list, which may - * have changed, so make sure you store the new value. - * </para></note> - * - * <note><para> - * Note that g_slist_append() has to traverse the entire list - * to find the end, which is inefficient when adding multiple - * elements. A common idiom to avoid the inefficiency is to prepend - * the elements and reverse the list when all elements have been added. - * </para></note> - * - * |[ - * /* Notice that these are initialized to the empty list. */ - * GSList *list = NULL, *number_list = NULL; - * - * /* This is a list of strings. */ - * list = g_slist_append (list, "first"); - * list = g_slist_append (list, "second"); - * - * /* This is a list of integers. */ - * number_list = g_slist_append (number_list, GINT_TO_POINTER (27)); - * number_list = g_slist_append (number_list, GINT_TO_POINTER (14)); - * ]| - * - * Returns: the new start of the #GSList - */ -GSList* -g_slist_append (GSList *list, - gpointer data) -{ - GSList *new_list; - GSList *last; - - new_list = _g_slist_alloc (); - new_list->data = data; - new_list->next = NULL; - - if (list) - { - last = g_slist_last (list); - /* g_assert (last != NULL); */ - last->next = new_list; - - return list; - } - else - return new_list; -} - -/** - * g_slist_prepend: - * @list: a #GSList - * @data: the data for the new element - * - * Adds a new element on to the start of the list. - * - * <note><para> - * The return value is the new start of the list, which - * may have changed, so make sure you store the new value. - * </para></note> - * - * |[ - * /* Notice that it is initialized to the empty list. */ - * GSList *list = NULL; - * list = g_slist_prepend (list, "last"); - * list = g_slist_prepend (list, "first"); - * ]| - * - * Returns: the new start of the #GSList - */ -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; -} - -/** - * g_slist_insert: - * @list: a #GSList - * @data: the data for the new element - * @position: the position to insert the element. - * If this is negative, or is larger than the number - * of elements in the list, the new element is added on - * to the end of the list. - * - * Inserts a new element into the list at the given position. - * - * Returns: the new start of the #GSList - */ -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) - { - new_list->next = NULL; - 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; -} - -/** - * g_slist_insert_before: - * @slist: a #GSList - * @sibling: node to insert @data before - * @data: data to put in the newly-inserted node - * - * Inserts a node before @sibling containing @data. - * - * Returns: the new head of the list. - */ -GSList* -g_slist_insert_before (GSList *slist, - GSList *sibling, - gpointer data) -{ - if (!slist) - { - slist = _g_slist_alloc (); - slist->data = data; - slist->next = NULL; - g_return_val_if_fail (sibling == NULL, slist); - return slist; - } - else - { - GSList *node, *last = NULL; - - for (node = slist; node; last = node, node = last->next) - if (node == sibling) - break; - if (!last) - { - node = _g_slist_alloc (); - node->data = data; - node->next = slist; - - return node; - } - else - { - node = _g_slist_alloc (); - node->data = data; - node->next = last->next; - last->next = node; - - return slist; - } - } -} - -/** - * g_slist_concat: - * @list1: a #GSList - * @list2: the #GSList to add to the end of the first #GSList - * - * Adds the second #GSList onto the end of the first #GSList. - * Note that the elements of the second #GSList are not copied. - * They are used directly. - * - * Returns: the start of the new #GSList - */ -GSList * -g_slist_concat (GSList *list1, GSList *list2) -{ - if (list2) - { - if (list1) - g_slist_last (list1)->next = list2; - else - list1 = list2; - } - - return list1; -} - -/** - * g_slist_remove: - * @list: a #GSList - * @data: the data of the element to remove - * - * Removes an element from a #GSList. - * If two elements contain the same data, only the first is removed. - * If none of the elements contain the data, the #GSList is unchanged. - * - * Returns: the new start of the #GSList - */ -GSList* -g_slist_remove (GSList *list, - gconstpointer data) -{ - GSList *tmp, *prev = NULL; - - tmp = list; - while (tmp) - { - if (tmp->data == data) - { - if (prev) - prev->next = tmp->next; - else - list = tmp->next; - - g_slist_free_1 (tmp); - break; - } - prev = tmp; - tmp = prev->next; - } - - return list; -} - -/** - * g_slist_remove_all: - * @list: a #GSList - * @data: data to remove - * - * Removes all list nodes with data equal to @data. - * Returns the new head of the list. Contrast with - * g_slist_remove() which removes only the first node - * matching the given data. - * - * Returns: new head of @list - */ -GSList* -g_slist_remove_all (GSList *list, - gconstpointer data) -{ - GSList *tmp, *prev = NULL; - - tmp = list; - while (tmp) - { - if (tmp->data == data) - { - GSList *next = tmp->next; - - if (prev) - prev->next = next; - else - list = next; - - g_slist_free_1 (tmp); - tmp = next; - } - else - { - prev = tmp; - tmp = prev->next; - } - } - - return list; -} - -static inline 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; -} - -/** - * g_slist_remove_link: - * @list: a #GSList - * @link_: an element in the #GSList - * - * Removes an element from a #GSList, without - * freeing the element. The removed element's next - * link is set to %NULL, so that it becomes a - * self-contained list with one element. - * - * Returns: the new start of the #GSList, without the element - */ -GSList* -g_slist_remove_link (GSList *list, - GSList *link_) -{ - return _g_slist_remove_link (list, link_); -} - -/** - * g_slist_delete_link: - * @list: a #GSList - * @link_: node to delete - * - * Removes the node link_ from the list and frees it. - * Compare this to g_slist_remove_link() which removes the node - * without freeing it. - * - * Returns: the new head of @list - */ -GSList* -g_slist_delete_link (GSList *list, - GSList *link_) -{ - list = _g_slist_remove_link (list, link_); - _g_slist_free1 (link_); - - return list; -} - -/** - * g_slist_copy: - * @list: a #GSList - * - * Copies a #GSList. - * - * <note><para> - * Note that this is a "shallow" copy. If the list elements - * consist of pointers to data, the pointers are copied but - * the actual data isn't. - * </para></note> - * - * Returns: a copy of @list - */ -GSList* -g_slist_copy (GSList *list) -{ - GSList *new_list = NULL; - - if (list) - { - GSList *last; - - new_list = _g_slist_alloc (); - new_list->data = list->data; - last = new_list; - list = list->next; - while (list) - { - last->next = _g_slist_alloc (); - last = last->next; - last->data = list->data; - list = list->next; - } - last->next = NULL; - } - - return new_list; -} - -/** - * g_slist_reverse: - * @list: a #GSList - * - * Reverses a #GSList. - * - * Returns: the start of the reversed #GSList - */ -GSList* -g_slist_reverse (GSList *list) -{ - GSList *prev = NULL; - - while (list) - { - GSList *next = list->next; - - list->next = prev; - - prev = list; - list = next; - } - - return prev; -} - -/** - * g_slist_nth: - * @list: a #GSList - * @n: the position of the element, counting from 0 - * - * Gets the element at the given position in a #GSList. - * - * Returns: the element, or %NULL if the position is off - * the end of the #GSList - */ -GSList* -g_slist_nth (GSList *list, - guint n) -{ - while (n-- > 0 && list) - list = list->next; - - return list; -} - -/** - * g_slist_nth_data: - * @list: a #GSList - * @n: the position of the element - * - * Gets the data of the element at the given position. - * - * Returns: the element's data, or %NULL if the position - * is off the end of the #GSList - */ -gpointer -g_slist_nth_data (GSList *list, - guint n) -{ - while (n-- > 0 && list) - list = list->next; - - return list ? list->data : NULL; -} - -/** - * g_slist_find: - * @list: a #GSList - * @data: the element data to find - * - * Finds the element in a #GSList which - * contains the given data. - * - * Returns: the found #GSList element, - * or %NULL if it is not found - */ -GSList* -g_slist_find (GSList *list, - gconstpointer data) -{ - while (list) - { - if (list->data == data) - break; - list = list->next; - } - - return list; -} - - -/** - * g_slist_find_custom: - * @list: a #GSList - * @data: user data passed to the function - * @func: the function to call for each element. - * It should return 0 when the desired element is found - * - * Finds an element in a #GSList, using a supplied function to - * find the desired element. It iterates over the list, calling - * the given function which should return 0 when the desired - * element is found. The function takes two #gconstpointer arguments, - * the #GSList element's data as the first argument and the - * given user data. - * - * Returns: the found #GSList element, or %NULL if it is not found - */ -GSList* -g_slist_find_custom (GSList *list, - gconstpointer data, - GCompareFunc func) -{ - g_return_val_if_fail (func != NULL, list); - - while (list) - { - if (! func (list->data, data)) - return list; - list = list->next; - } - - return NULL; -} - -/** - * g_slist_position: - * @list: a #GSList - * @llink: an element in the #GSList - * - * Gets the position of the given element - * in the #GSList (starting from 0). - * - * Returns: the position of the element in the #GSList, - * or -1 if the element is not found - */ -gint -g_slist_position (GSList *list, - GSList *llink) -{ - gint i; - - i = 0; - while (list) - { - if (list == llink) - return i; - i++; - list = list->next; - } - - return -1; -} - -/** - * g_slist_index: - * @list: a #GSList - * @data: the data to find - * - * Gets the position of the element containing - * the given data (starting from 0). - * - * Returns: the index of the element containing the data, - * or -1 if the data is not found - */ -gint -g_slist_index (GSList *list, - gconstpointer data) -{ - gint i; - - i = 0; - while (list) - { - if (list->data == data) - return i; - i++; - list = list->next; - } - - return -1; -} - -/** - * g_slist_last: - * @list: a #GSList - * - * Gets the last element in a #GSList. - * - * <note><para> - * This function iterates over the whole list. - * </para></note> - * - * Returns: the last element in the #GSList, - * or %NULL if the #GSList has no elements - */ -GSList* -g_slist_last (GSList *list) -{ - if (list) - { - while (list->next) - list = list->next; - } - - return list; -} - -/** - * g_slist_length: - * @list: a #GSList - * - * Gets the number of elements in a #GSList. - * - * <note><para> - * This function iterates over the whole list to - * count its elements. - * </para></note> - * - * Returns: the number of elements in the #GSList - */ -guint -g_slist_length (GSList *list) -{ - guint length; - - length = 0; - while (list) - { - length++; - list = list->next; - } - - return length; -} - -/** - * g_slist_foreach: - * @list: a #GSList - * @func: the function to call with each element's data - * @user_data: user data to pass to the function - * - * Calls a function for each element of a #GSList. - */ -void -g_slist_foreach (GSList *list, - GFunc func, - gpointer user_data) -{ - while (list) - { - GSList *next = list->next; - (*func) (list->data, user_data); - list = next; - } -} - -static GSList* -g_slist_insert_sorted_real (GSList *list, - gpointer data, - GFunc func, - gpointer user_data) -{ - 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; - new_list->next = NULL; - return new_list; - } - - cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); - - while ((tmp_list->next) && (cmp > 0)) - { - prev_list = tmp_list; - tmp_list = tmp_list->next; - - cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); - } - - new_list = _g_slist_alloc (); - new_list->data = data; - - if ((!tmp_list->next) && (cmp > 0)) - { - tmp_list->next = new_list; - new_list->next = NULL; - 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; - } -} - -/** - * g_slist_insert_sorted: - * @list: a #GSList - * @data: the data for the new element - * @func: the function to compare elements in the list. - * It should return a number > 0 if the first parameter - * comes after the second parameter in the sort order. - * - * Inserts a new element into the list, using the given - * comparison function to determine its position. - * - * Returns: the new start of the #GSList - */ -GSList* -g_slist_insert_sorted (GSList *list, - gpointer data, - GCompareFunc func) -{ - return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL); -} - -/** - * g_slist_insert_sorted_with_data: - * @list: a #GSList - * @data: the data for the new element - * @func: the function to compare elements in the list. - * It should return a number > 0 if the first parameter - * comes after the second parameter in the sort order. - * @user_data: data to pass to comparison function - * - * Inserts a new element into the list, using the given - * comparison function to determine its position. - * - * Returns: the new start of the #GSList - * - * Since: 2.10 - */ -GSList* -g_slist_insert_sorted_with_data (GSList *list, - gpointer data, - GCompareDataFunc func, - gpointer user_data) -{ - return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data); -} - -static GSList * -g_slist_sort_merge (GSList *l1, - GSList *l2, - GFunc compare_func, - gpointer user_data) -{ - GSList list, *l; - gint cmp; - - l=&list; - - while (l1 && l2) - { - cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); - - if (cmp <= 0) - { - l=l->next=l1; - l1=l1->next; - } - else - { - l=l->next=l2; - l2=l2->next; - } - } - l->next= l1 ? l1 : l2; - - return list.next; -} - -static GSList * -g_slist_sort_real (GSList *list, - GFunc compare_func, - gpointer user_data) -{ - GSList *l1, *l2; - - if (!list) - return NULL; - if (!list->next) - return list; - - l1 = list; - l2 = list->next; - - while ((l2 = l2->next) != NULL) - { - if ((l2 = l2->next) == NULL) - break; - l1=l1->next; - } - l2 = l1->next; - l1->next = NULL; - - return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data), - g_slist_sort_real (l2, compare_func, user_data), - compare_func, - user_data); -} - -/** - * g_slist_sort: - * @list: a #GSList - * @compare_func: the comparison function used to sort the #GSList. - * This function is passed the data from 2 elements of the #GSList - * and should return 0 if they are equal, a negative value if the - * first element comes before the second, or a positive value if - * the first element comes after the second. - * - * Sorts a #GSList using the given comparison function. - * - * Returns: the start of the sorted #GSList - */ -GSList * -g_slist_sort (GSList *list, - GCompareFunc compare_func) -{ - return g_slist_sort_real (list, (GFunc) compare_func, NULL); -} - -/** - * g_slist_sort_with_data: - * @list: a #GSList - * @compare_func: comparison function - * @user_data: data to pass to comparison function - * - * Like g_slist_sort(), but the sort function accepts a user data argument. - * - * Returns: new head of the list - */ -GSList * -g_slist_sort_with_data (GSList *list, - GCompareDataFunc compare_func, - gpointer user_data) -{ - return g_slist_sort_real (list, (GFunc) compare_func, user_data); -} diff --git a/deps/glib/gslist.h b/deps/glib/gslist.h deleted file mode 100644 index 5e65d6db..00000000 --- a/deps/glib/gslist.h +++ /dev/null @@ -1,114 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_SLIST_H__ -#define __G_SLIST_H__ - -#include <glib/gmem.h> - -G_BEGIN_DECLS - -typedef struct _GSList GSList; - -struct _GSList -{ - gpointer data; - GSList *next; -}; - -/* Singly linked lists - */ -GSList* g_slist_alloc (void) G_GNUC_WARN_UNUSED_RESULT; -void g_slist_free (GSList *list); -void g_slist_free_1 (GSList *list); -#define g_slist_free1 g_slist_free_1 -void g_slist_free_full (GSList *list, - GDestroyNotify free_func); -GSList* g_slist_append (GSList *list, - gpointer data) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_prepend (GSList *list, - gpointer data) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_insert (GSList *list, - gpointer data, - gint position) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_insert_sorted (GSList *list, - gpointer data, - GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_insert_sorted_with_data (GSList *list, - gpointer data, - GCompareDataFunc func, - gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_insert_before (GSList *slist, - GSList *sibling, - gpointer data) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_concat (GSList *list1, - GSList *list2) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_remove (GSList *list, - gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_remove_all (GSList *list, - gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_remove_link (GSList *list, - GSList *link_) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_delete_link (GSList *list, - GSList *link_) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_reverse (GSList *list) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_copy (GSList *list) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_nth (GSList *list, - guint n); -GSList* g_slist_find (GSList *list, - gconstpointer data); -GSList* g_slist_find_custom (GSList *list, - gconstpointer data, - GCompareFunc func); -gint g_slist_position (GSList *list, - GSList *llink); -gint g_slist_index (GSList *list, - gconstpointer data); -GSList* g_slist_last (GSList *list); -guint g_slist_length (GSList *list); -void g_slist_foreach (GSList *list, - GFunc func, - gpointer user_data); -GSList* g_slist_sort (GSList *list, - GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT; -GSList* g_slist_sort_with_data (GSList *list, - GCompareDataFunc compare_func, - gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; -gpointer g_slist_nth_data (GSList *list, - guint n); - -#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL) - -#ifndef G_DISABLE_DEPRECATED -void g_slist_push_allocator (gpointer dummy); -void g_slist_pop_allocator (void); -#endif - -G_END_DECLS - -#endif /* __G_SLIST_H__ */ diff --git a/deps/glib/gstdio.c b/deps/glib/gstdio.c deleted file mode 100644 index 425d3aa8..00000000 --- a/deps/glib/gstdio.c +++ /dev/null @@ -1,831 +0,0 @@ -/* gstdio.c - wrappers for C library functions - * - * Copyright 2004 Tor Lillqvist - * - * GLib is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * GLib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with GLib; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" -#include "glibconfig.h" - -#define G_STDIO_NO_WRAP_ON_UNIX - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifdef G_OS_WIN32 -#include <windows.h> -#include <errno.h> -#include <wchar.h> -#include <direct.h> -#include <io.h> -#include <sys/utime.h> -#else -#include <utime.h> -#endif - -#include "gstdio.h" - - -#if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS) -#error Please port this to your operating system -#endif - -#if defined (_MSC_VER) && !defined(_WIN64) -#undef _wstat -#define _wstat _wstat32 -#endif - -/** - * g_access: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: as in access() - * - * A wrapper for the POSIX access() function. This function is used to - * test a pathname for one or several of read, write or execute - * permissions, or just existence. - * - * On Windows, the file protection mechanism is not at all POSIX-like, - * and the underlying function in the C library only checks the - * FAT-style READONLY attribute, and does not look at the ACL of a - * file at all. This function is this in practise almost useless on - * Windows. Software that needs to handle file permissions on Windows - * more exactly should use the Win32 API. - * - * See your C library manual for more details about access(). - * - * Returns: zero if the pathname refers to an existing file system - * object that has all the tested permissions, or -1 otherwise or on - * error. - * - * Since: 2.8 - */ -int -g_access (const gchar *filename, - int mode) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - -#ifndef X_OK -#define X_OK 1 -#endif - - retval = _waccess (wfilename, mode & ~X_OK); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return access (filename, mode); -#endif -} - -/** - * g_chmod: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: as in chmod() - * - * A wrapper for the POSIX chmod() function. The chmod() function is - * used to set the permissions of a file system object. - * - * On Windows the file protection mechanism is not at all POSIX-like, - * and the underlying chmod() function in the C library just sets or - * clears the FAT-style READONLY attribute. It does not touch any - * ACL. Software that needs to manage file permissions on Windows - * exactly should use the Win32 API. - * - * See your C library manual for more details about chmod(). - * - * Returns: zero if the operation succeeded, -1 on error. - * - * Since: 2.8 - */ -int -g_chmod (const gchar *filename, - int mode) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wchmod (wfilename, mode); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return chmod (filename, mode); -#endif -} -/** - * g_open: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @flags: as in open() - * @mode: as in open() - * - * A wrapper for the POSIX open() function. The open() function is - * used to convert a pathname into a file descriptor. - * - * On POSIX systems file descriptors are implemented by the operating - * system. On Windows, it's the C library that implements open() and - * file descriptors. The actual Win32 API for opening files is quite - * different, see MSDN documentation for CreateFile(). The Win32 API - * uses file handles, which are more randomish integers, not small - * integers like file descriptors. - * - * Because file descriptors are specific to the C library on Windows, - * the file descriptor returned by this function makes sense only to - * functions in the same C library. Thus if the GLib-using code uses a - * different C library than GLib does, the file descriptor returned by - * this function cannot be passed to C library functions like write() - * or read(). - * - * See your C library manual for more details about open(). - * - * Returns: a new file descriptor, or -1 if an error occurred. The - * return value can be used exactly like the return value from open(). - * - * Since: 2.6 - */ -int -g_open (const gchar *filename, - int flags, - int mode) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wopen (wfilename, flags, mode); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return open (filename, flags, mode); -#endif -} - -/** - * g_creat: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: as in creat() - * - * A wrapper for the POSIX creat() function. The creat() function is - * used to convert a pathname into a file descriptor, creating a file - * if necessary. - - * On POSIX systems file descriptors are implemented by the operating - * system. On Windows, it's the C library that implements creat() and - * file descriptors. The actual Windows API for opening files is - * different, see MSDN documentation for CreateFile(). The Win32 API - * uses file handles, which are more randomish integers, not small - * integers like file descriptors. - * - * Because file descriptors are specific to the C library on Windows, - * the file descriptor returned by this function makes sense only to - * functions in the same C library. Thus if the GLib-using code uses a - * different C library than GLib does, the file descriptor returned by - * this function cannot be passed to C library functions like write() - * or read(). - * - * See your C library manual for more details about creat(). - * - * Returns: a new file descriptor, or -1 if an error occurred. The - * return value can be used exactly like the return value from creat(). - * - * Since: 2.8 - */ -int -g_creat (const gchar *filename, - int mode) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wcreat (wfilename, mode); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return creat (filename, mode); -#endif -} - -/** - * g_rename: - * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @newfilename: a pathname in the GLib file name encoding - * - * A wrapper for the POSIX rename() function. The rename() function - * renames a file, moving it between directories if required. - * - * See your C library manual for more details about how rename() works - * on your system. It is not possible in general on Windows to rename - * a file that is open to some process. - * - * Returns: 0 if the renaming succeeded, -1 if an error occurred - * - * Since: 2.6 - */ -int -g_rename (const gchar *oldfilename, - const gchar *newfilename) -{ -#ifdef G_OS_WIN32 - wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL); - wchar_t *wnewfilename; - int retval; - int save_errno = 0; - - if (woldfilename == NULL) - { - errno = EINVAL; - return -1; - } - - wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL); - - if (wnewfilename == NULL) - { - g_free (woldfilename); - errno = EINVAL; - return -1; - } - - if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING)) - retval = 0; - else - { - retval = -1; - switch (GetLastError ()) - { -#define CASE(a,b) case ERROR_##a: save_errno = b; break - CASE (FILE_NOT_FOUND, ENOENT); - CASE (PATH_NOT_FOUND, ENOENT); - CASE (ACCESS_DENIED, EACCES); - CASE (NOT_SAME_DEVICE, EXDEV); - CASE (LOCK_VIOLATION, EACCES); - CASE (SHARING_VIOLATION, EACCES); - CASE (FILE_EXISTS, EEXIST); - CASE (ALREADY_EXISTS, EEXIST); -#undef CASE - default: save_errno = EIO; - } - } - - g_free (woldfilename); - g_free (wnewfilename); - - errno = save_errno; - return retval; -#else - return rename (oldfilename, newfilename); -#endif -} - -/** - * g_mkdir: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: permissions to use for the newly created directory - * - * A wrapper for the POSIX mkdir() function. The mkdir() function - * attempts to create a directory with the given name and permissions. - * The mode argument is ignored on Windows. - * - * See your C library manual for more details about mkdir(). - * - * Returns: 0 if the directory was successfully created, -1 if an error - * occurred - * - * Since: 2.6 - */ -int -g_mkdir (const gchar *filename, - int mode) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wmkdir (wfilename); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return mkdir (filename, mode); -#endif -} - -/** - * g_chdir: - * @path: a pathname in the GLib file name encoding (UTF-8 on Windows) - * - * A wrapper for the POSIX chdir() function. The function changes the - * current directory of the process to @path. - * - * See your C library manual for more details about chdir(). - * - * Returns: 0 on success, -1 if an error occurred. - * - * Since: 2.8 - */ -int -g_chdir (const gchar *path) -{ -#ifdef G_OS_WIN32 - wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wpath == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wchdir (wpath); - save_errno = errno; - - g_free (wpath); - - errno = save_errno; - return retval; -#else - return chdir (path); -#endif -} - -/** - * GStatBuf: - * - * A type corresponding to the appropriate struct type for the stat - * system call, depending on the platform and/or compiler being used. - * - * See g_stat() for more information. - **/ -/** - * g_stat: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @buf: a pointer to a <structname>stat</structname> struct, which - * will be filled with the file information - * - * A wrapper for the POSIX stat() function. The stat() function - * returns information about a file. On Windows the stat() function in - * the C library checks only the FAT-style READONLY attribute and does - * not look at the ACL at all. Thus on Windows the protection bits in - * the st_mode field are a fabrication of little use. - * - * On Windows the Microsoft C libraries have several variants of the - * <structname>stat</structname> struct and stat() function with names - * like "_stat", "_stat32", "_stat32i64" and "_stat64i32". The one - * used here is for 32-bit code the one with 32-bit size and time - * fields, specifically called "_stat32". - * - * In Microsoft's compiler, by default "struct stat" means one with - * 64-bit time fields while in MinGW "struct stat" is the legacy one - * with 32-bit fields. To hopefully clear up this messs, the gstdio.h - * header defines a type GStatBuf which is the appropriate struct type - * depending on the platform and/or compiler being used. On POSIX it - * is just "struct stat", but note that even on POSIX platforms, - * "stat" might be a macro. - * - * See your C library manual for more details about stat(). - * - * Returns: 0 if the information was successfully retrieved, -1 if an error - * occurred - * - * Since: 2.6 - */ -int -g_stat (const gchar *filename, - GStatBuf *buf) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - int len; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - len = wcslen (wfilename); - while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1])) - len--; - if (len > 0 && - (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename)) - wfilename[len] = '\0'; - - retval = _wstat (wfilename, buf); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return stat (filename, buf); -#endif -} - -/** - * g_lstat: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @buf: a pointer to a <structname>stat</structname> struct, which - * will be filled with the file information - * - * A wrapper for the POSIX lstat() function. The lstat() function is - * like stat() except that in the case of symbolic links, it returns - * information about the symbolic link itself and not the file that it - * refers to. If the system does not support symbolic links g_lstat() - * is identical to g_stat(). - * - * See your C library manual for more details about lstat(). - * - * Returns: 0 if the information was successfully retrieved, -1 if an error - * occurred - * - * Since: 2.6 - */ -int -g_lstat (const gchar *filename, - GStatBuf *buf) -{ -#ifdef HAVE_LSTAT - /* This can't be Win32, so don't do the widechar dance. */ - return lstat (filename, buf); -#else - return g_stat (filename, buf); -#endif -} - -/** - * g_unlink: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * - * A wrapper for the POSIX unlink() function. The unlink() function - * deletes a name from the filesystem. If this was the last link to the - * file and no processes have it opened, the diskspace occupied by the - * file is freed. - * - * See your C library manual for more details about unlink(). Note - * that on Windows, it is in general not possible to delete files that - * are open to some process, or mapped into memory. - * - * Returns: 0 if the name was successfully deleted, -1 if an error - * occurred - * - * Since: 2.6 - */ -int -g_unlink (const gchar *filename) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wunlink (wfilename); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return unlink (filename); -#endif -} - -/** - * g_remove: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * - * A wrapper for the POSIX remove() function. The remove() function - * deletes a name from the filesystem. - * - * See your C library manual for more details about how remove() works - * on your system. On Unix, remove() removes also directories, as it - * calls unlink() for files and rmdir() for directories. On Windows, - * although remove() in the C library only works for files, this - * function tries first remove() and then if that fails rmdir(), and - * thus works for both files and directories. Note however, that on - * Windows, it is in general not possible to remove a file that is - * open to some process, or mapped into memory. - * - * If this function fails on Windows you can't infer too much from the - * errno value. rmdir() is tried regardless of what caused remove() to - * fail. Any errno value set by remove() will be overwritten by that - * set by rmdir(). - * - * Returns: 0 if the file was successfully removed, -1 if an error - * occurred - * - * Since: 2.6 - */ -int -g_remove (const gchar *filename) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wremove (wfilename); - if (retval == -1) - retval = _wrmdir (wfilename); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return remove (filename); -#endif -} - -/** - * g_rmdir: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * - * A wrapper for the POSIX rmdir() function. The rmdir() function - * deletes a directory from the filesystem. - * - * See your C library manual for more details about how rmdir() works - * on your system. - * - * Returns: 0 if the directory was successfully removed, -1 if an error - * occurred - * - * Since: 2.6 - */ -int -g_rmdir (const gchar *filename) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wrmdir (wfilename); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return rmdir (filename); -#endif -} - -/** - * g_fopen: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: a string describing the mode in which the file should be - * opened - * - * A wrapper for the stdio fopen() function. The fopen() function - * opens a file and associates a new stream with it. - * - * Because file descriptors are specific to the C library on Windows, - * and a file descriptor is partof the <type>FILE</type> struct, the - * <type>FILE</type> pointer returned by this function makes sense - * only to functions in the same C library. Thus if the GLib-using - * code uses a different C library than GLib does, the - * <type>FILE</type> pointer returned by this function cannot be - * passed to C library functions like fprintf() or fread(). - * - * See your C library manual for more details about fopen(). - * - * Returns: A <type>FILE</type> pointer if the file was successfully - * opened, or %NULL if an error occurred - * - * Since: 2.6 - */ -FILE * -g_fopen (const gchar *filename, - const gchar *mode) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - wchar_t *wmode; - FILE *retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return NULL; - } - - wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); - - if (wmode == NULL) - { - g_free (wfilename); - errno = EINVAL; - return NULL; - } - - retval = _wfopen (wfilename, wmode); - save_errno = errno; - - g_free (wfilename); - g_free (wmode); - - errno = save_errno; - return retval; -#else - return fopen (filename, mode); -#endif -} - -/** - * g_freopen: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @mode: a string describing the mode in which the file should be - * opened - * @stream: an existing stream which will be reused, or %NULL - * - * A wrapper for the POSIX freopen() function. The freopen() function - * opens a file and associates it with an existing stream. - * - * See your C library manual for more details about freopen(). - * - * Returns: A <type>FILE</type> pointer if the file was successfully - * opened, or %NULL if an error occurred. - * - * Since: 2.6 - */ -FILE * -g_freopen (const gchar *filename, - const gchar *mode, - FILE *stream) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - wchar_t *wmode; - FILE *retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return NULL; - } - - wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); - - if (wmode == NULL) - { - g_free (wfilename); - errno = EINVAL; - return NULL; - } - - retval = _wfreopen (wfilename, wmode, stream); - save_errno = errno; - - g_free (wfilename); - g_free (wmode); - - errno = save_errno; - return retval; -#else - return freopen (filename, mode, stream); -#endif -} - -/** - * g_utime: - * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) - * @utb: a pointer to a struct utimbuf. - * - * A wrapper for the POSIX utime() function. The utime() function - * sets the access and modification timestamps of a file. - * - * See your C library manual for more details about how utime() works - * on your system. - * - * Returns: 0 if the operation was successful, -1 if an error - * occurred - * - * Since: 2.18 - */ -int -g_utime (const gchar *filename, - struct utimbuf *utb) -{ -#ifdef G_OS_WIN32 - wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); - int retval; - int save_errno; - - if (wfilename == NULL) - { - errno = EINVAL; - return -1; - } - - retval = _wutime (wfilename, (struct _utimbuf*) utb); - save_errno = errno; - - g_free (wfilename); - - errno = save_errno; - return retval; -#else - return utime (filename, utb); -#endif -} diff --git a/deps/glib/gstdio.h b/deps/glib/gstdio.h deleted file mode 100644 index a89f18bb..00000000 --- a/deps/glib/gstdio.h +++ /dev/null @@ -1,148 +0,0 @@ -/* gstdio.h - GFilename wrappers for C library functions - * - * Copyright 2004 Tor Lillqvist - * - * GLib is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * GLib is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with GLib; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#ifndef __G_STDIO_H__ -#define __G_STDIO_H__ - -#include <glib/gprintf.h> - -#include <sys/stat.h> - -G_BEGIN_DECLS - -#if defined (_MSC_VER) && !defined(_WIN64) - -/* Make it clear that we mean the struct with 32-bit st_size and - * 32-bit st_*time fields as that is how the 32-bit GLib DLL normally - * has been compiled. If you get a compiler warning when calling - * g_stat(), do take it seriously and make sure that the type of - * struct stat the code in GLib fills in matches the struct the type - * of struct stat you pass to g_stat(). To avoid hassle, to get file - * attributes just use the GIO API instead which doesn't use struct - * stat. - * - * Sure, it would be nicer to use a struct with 64-bit st_size and - * 64-bit st_*time fields, but changing that now would break ABI. And - * in MinGW, a plain "struct stat" is the one with 32-bit st_size and - * st_*time fields. - */ - -typedef struct _stat32 GStatBuf; - -#else - -typedef struct stat GStatBuf; - -#endif - -#if defined(G_OS_UNIX) && !defined(G_STDIO_NO_WRAP_ON_UNIX) - -/* Just pass on to the system functions, so there's no potential for data - * format mismatches, especially with large file interfaces. - * A few functions can't be handled in this way, since they are not defined - * in a portable system header that we could include here. - */ - -#ifndef __GTK_DOC_IGNORE__ -#define g_chmod chmod -#define g_open open -#define g_creat creat -#define g_rename rename -#define g_mkdir mkdir -#define g_stat stat -#define g_lstat lstat -#define g_remove remove -#define g_fopen fopen -#define g_freopen freopen -#define g_utime utime -#endif - -int g_access (const gchar *filename, - int mode); - -int g_chdir (const gchar *path); - -int g_unlink (const gchar *filename); - -int g_rmdir (const gchar *filename); - -#else /* ! G_OS_UNIX */ - -/* Wrappers for C library functions that take pathname arguments. On - * Unix, the pathname is a file name as it literally is in the file - * system. On well-maintained systems with consistent users who know - * what they are doing and no exchange of files with others this would - * be a well-defined encoding, preferably UTF-8. On Windows, the - * pathname is always in UTF-8, even if that is not the on-disk - * encoding, and not the encoding accepted by the C library or Win32 - * API. - */ - -int g_access (const gchar *filename, - int mode); - -int g_chmod (const gchar *filename, - int mode); - -int g_open (const gchar *filename, - int flags, - int mode); - -int g_creat (const gchar *filename, - int mode); - -int g_rename (const gchar *oldfilename, - const gchar *newfilename); - -int g_mkdir (const gchar *filename, - int mode); - -int g_chdir (const gchar *path); - -int g_stat (const gchar *filename, - GStatBuf *buf); - -int g_lstat (const gchar *filename, - GStatBuf *buf); - -int g_unlink (const gchar *filename); - -int g_remove (const gchar *filename); - -int g_rmdir (const gchar *filename); - -FILE *g_fopen (const gchar *filename, - const gchar *mode); - -FILE *g_freopen (const gchar *filename, - const gchar *mode, - FILE *stream); - -struct utimbuf; /* Don't need the real definition of struct utimbuf when just - * including this header. - */ - -int g_utime (const gchar *filename, - struct utimbuf *utb); - -#endif /* G_OS_UNIX */ - -G_END_DECLS - -#endif /* __G_STDIO_H__ */ diff --git a/deps/glib/gstrfuncs.c b/deps/glib/gstrfuncs.c deleted file mode 100644 index cb04b500..00000000 --- a/deps/glib/gstrfuncs.c +++ /dev/null @@ -1,3249 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <locale.h> -#include <errno.h> -#include <ctype.h> /* For tolower() */ -#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL) -#include <signal.h> -#endif - -#include "gstrfuncs.h" - -#include "gprintf.h" -#include "gprintfint.h" -#include "glibintl.h" -#include "gconvert.h" - -#ifdef G_OS_WIN32 -#include <windows.h> -#endif - -/* do not include <unistd.h> in this place since it - * interferes with g_strsignal() on some OSes - */ - -static const guint16 ascii_table_data[256] = { - 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, - 0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004, - 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, - 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, - 0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, - 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, - 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, - 0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, - 0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253, - 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, - 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, - 0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, - 0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073, - 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, - 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, - 0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004 - /* the upper 128 are all zeroes */ -}; - -const guint16 * const g_ascii_table = ascii_table_data; - -/** - * g_strdup: - * @str: the string to duplicate - * - * Duplicates a string. If @str is %NULL it returns %NULL. - * The returned string should be freed with g_free() - * when no longer needed. - * - * Returns: a newly-allocated copy of @str - */ -gchar* -g_strdup (const gchar *str) -{ - gchar *new_str; - gsize length; - - if (str) - { - length = strlen (str) + 1; - new_str = g_new (char, length); - memcpy (new_str, str, length); - } - else - new_str = NULL; - - return new_str; -} - -/** - * g_memdup: - * @mem: the memory to copy. - * @byte_size: the number of bytes to copy. - * - * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it - * from @mem. If @mem is %NULL it returns %NULL. - * - * Returns: a pointer to the newly-allocated copy of the memory, or %NULL if @mem - * is %NULL. - */ -gpointer -g_memdup (gconstpointer mem, - guint byte_size) -{ - gpointer new_mem; - - if (mem) - { - new_mem = g_malloc (byte_size); - memcpy (new_mem, mem, byte_size); - } - else - new_mem = NULL; - - return new_mem; -} - -/** - * g_strndup: - * @str: the string to duplicate - * @n: the maximum number of bytes to copy from @str - * - * Duplicates the first @n bytes of a string, returning a newly-allocated - * buffer @n + 1 bytes long which will always be nul-terminated. - * If @str is less than @n bytes long the buffer is padded with nuls. - * If @str is %NULL it returns %NULL. - * The returned value should be freed when no longer needed. - * - * <note><para> - * To copy a number of characters from a UTF-8 encoded string, use - * g_utf8_strncpy() instead. - * </para></note> - * - * Returns: a newly-allocated buffer containing the first @n bytes - * of @str, nul-terminated - */ -gchar* -g_strndup (const gchar *str, - gsize n) -{ - gchar *new_str; - - if (str) - { - new_str = g_new (gchar, n + 1); - strncpy (new_str, str, n); - new_str[n] = '\0'; - } - else - new_str = NULL; - - return new_str; -} - -/** - * g_strnfill: - * @length: the length of the new string - * @fill_char: the byte to fill the string with - * - * Creates a new string @length bytes long filled with @fill_char. - * The returned string should be freed when no longer needed. - * - * Returns: a newly-allocated string filled the @fill_char - */ -gchar* -g_strnfill (gsize length, - gchar fill_char) -{ - gchar *str; - - str = g_new (gchar, length + 1); - memset (str, (guchar)fill_char, length); - str[length] = '\0'; - - return str; -} - -/** - * g_stpcpy: - * @dest: destination buffer. - * @src: source string. - * - * Copies a nul-terminated string into the dest buffer, include the - * trailing nul, and return a pointer to the trailing nul byte. - * This is useful for concatenating multiple strings together - * without having to repeatedly scan for the end. - * - * Return value: a pointer to trailing nul byte. - **/ -gchar * -g_stpcpy (gchar *dest, - const gchar *src) -{ -#ifdef HAVE_STPCPY - g_return_val_if_fail (dest != NULL, NULL); - g_return_val_if_fail (src != NULL, NULL); - return stpcpy (dest, src); -#else - register gchar *d = dest; - register const gchar *s = src; - - g_return_val_if_fail (dest != NULL, NULL); - g_return_val_if_fail (src != NULL, NULL); - do - *d++ = *s; - while (*s++ != '\0'); - - return d - 1; -#endif -} - -/** - * g_strdup_vprintf: - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link> - * @args: the list of parameters to insert into the format string - * - * Similar to the standard C vsprintf() function but safer, since it - * calculates the maximum space required and allocates memory to hold - * the result. The returned string should be freed with g_free() when - * no longer needed. - * - * See also g_vasprintf(), which offers the same functionality, but - * additionally returns the length of the allocated string. - * - * Returns: a newly-allocated string holding the result - */ -gchar* -g_strdup_vprintf (const gchar *format, - va_list args) -{ - gchar *string = NULL; - - g_vasprintf (&string, format, args); - - return string; -} - -/** - * g_strdup_printf: - * @format: a standard printf() format string, but notice - * <link linkend="string-precision">string precision pitfalls</link> - * @...: the parameters to insert into the format string - * - * Similar to the standard C sprintf() function but safer, since it - * calculates the maximum space required and allocates memory to hold - * the result. The returned string should be freed with g_free() when no - * longer needed. - * - * Returns: a newly-allocated string holding the result - */ -gchar* -g_strdup_printf (const gchar *format, - ...) -{ - gchar *buffer; - va_list args; - - va_start (args, format); - buffer = g_strdup_vprintf (format, args); - va_end (args); - - return buffer; -} - -/** - * g_strconcat: - * @string1: the first string to add, which must not be %NULL - * @...: a %NULL-terminated list of strings to append to the string - * - * Concatenates all of the given strings into one long string. - * The returned string should be freed with g_free() when no longer needed. - * - * Note that this function is usually not the right function to use to - * assemble a translated message from pieces, since proper translation - * often requires the pieces to be reordered. - * - * <warning><para>The variable argument list <emphasis>must</emphasis> end - * with %NULL. If you forget the %NULL, g_strconcat() will start appending - * random memory junk to your string.</para></warning> - * - * Returns: a newly-allocated string containing all the string arguments - */ -gchar* -g_strconcat (const gchar *string1, ...) -{ - gsize l; - va_list args; - gchar *s; - gchar *concat; - gchar *ptr; - - if (!string1) - return 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); - ptr = concat; - - ptr = g_stpcpy (ptr, string1); - va_start (args, string1); - s = va_arg (args, gchar*); - while (s) - { - ptr = g_stpcpy (ptr, s); - s = va_arg (args, gchar*); - } - va_end (args); - - return concat; -} - -/** - * g_strtod: - * @nptr: the string to convert to a numeric value. - * @endptr: if non-%NULL, it returns the character after - * the last character used in the conversion. - * - * Converts a string to a #gdouble value. - * It calls the standard strtod() function to handle the conversion, but - * if the string is not completely converted it attempts the conversion - * again with g_ascii_strtod(), and returns the best match. - * - * This function should seldom be used. The normal situation when reading - * numbers not for human consumption is to use g_ascii_strtod(). Only when - * you know that you must expect both locale formatted and C formatted numbers - * should you use this. Make sure that you don't pass strings such as comma - * separated lists of values, since the commas may be interpreted as a decimal - * point in some locales, causing unexpected results. - * - * Return value: the #gdouble value. - **/ -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) - val_2 = g_ascii_strtod (nptr, &fail_pos_2); - - 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; - } -} - -/** - * g_ascii_strtod: - * @nptr: the string to convert to a numeric value. - * @endptr: if non-%NULL, it returns the character after - * the last character used in the conversion. - * - * Converts a string to a #gdouble value. - * - * This function behaves like the standard strtod() function - * does in the C locale. It does this without actually changing - * the current locale, since that would not be thread-safe. - * A limitation of the implementation is that this function - * will still accept localized versions of infinities and NANs. - * - * This function is typically used when reading configuration - * files or other non-user input that should be locale independent. - * To handle input from the user you should normally use the - * locale-sensitive system strtod() function. - * - * To convert from a #gdouble to a string in a locale-insensitive - * way, use g_ascii_dtostr(). - * - * If the correct value would cause overflow, plus or minus %HUGE_VAL - * is returned (according to the sign of the value), and %ERANGE is - * stored in %errno. If the correct value would cause underflow, - * zero is returned and %ERANGE is stored in %errno. - * - * This function resets %errno before calling strtod() so that - * you can reliably detect overflow and underflow. - * - * Return value: the #gdouble value. - **/ -gdouble -g_ascii_strtod (const gchar *nptr, - gchar **endptr) -{ - gchar *fail_pos; - gdouble val; - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - const char *p, *decimal_point_pos; - const char *end = NULL; /* Silence gcc */ - int strtod_errno; - - g_return_val_if_fail (nptr != NULL, 0); - - fail_pos = NULL; - - locale_data = localeconv (); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen (decimal_point); - - g_assert (decimal_point_len != 0); - - decimal_point_pos = NULL; - end = NULL; - - if (decimal_point[0] != '.' || - decimal_point[1] != 0) - { - p = nptr; - /* Skip leading space */ - while (g_ascii_isspace (*p)) - p++; - - /* Skip leading optional sign */ - if (*p == '+' || *p == '-') - p++; - - if (p[0] == '0' && - (p[1] == 'x' || p[1] == 'X')) - { - p += 2; - /* HEX - find the (optional) decimal point */ - - while (g_ascii_isxdigit (*p)) - p++; - - if (*p == '.') - decimal_point_pos = p++; - - while (g_ascii_isxdigit (*p)) - p++; - - if (*p == 'p' || *p == 'P') - p++; - if (*p == '+' || *p == '-') - p++; - while (g_ascii_isdigit (*p)) - p++; - - end = p; - } - else if (g_ascii_isdigit (*p) || *p == '.') - { - while (g_ascii_isdigit (*p)) - p++; - - if (*p == '.') - decimal_point_pos = p++; - - while (g_ascii_isdigit (*p)) - p++; - - if (*p == 'e' || *p == 'E') - p++; - if (*p == '+' || *p == '-') - p++; - while (g_ascii_isdigit (*p)) - p++; - - end = p; - } - /* For the other cases, we need not convert the decimal point */ - } - - if (decimal_point_pos) - { - char *copy, *c; - - /* We need to convert the '.' to the locale specific decimal point */ - copy = g_malloc (end - nptr + 1 + decimal_point_len); - - c = copy; - memcpy (c, nptr, decimal_point_pos - nptr); - c += decimal_point_pos - nptr; - memcpy (c, decimal_point, decimal_point_len); - c += decimal_point_len; - memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); - c += end - (decimal_point_pos + 1); - *c = 0; - - errno = 0; - val = strtod (copy, &fail_pos); - strtod_errno = errno; - - if (fail_pos) - { - if (fail_pos - copy > decimal_point_pos - nptr) - fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); - else - fail_pos = (char *)nptr + (fail_pos - copy); - } - - g_free (copy); - - } - else if (end) - { - char *copy; - - copy = g_malloc (end - (char *)nptr + 1); - memcpy (copy, nptr, end - nptr); - *(copy + (end - (char *)nptr)) = 0; - - errno = 0; - val = strtod (copy, &fail_pos); - strtod_errno = errno; - - if (fail_pos) - { - fail_pos = (char *)nptr + (fail_pos - copy); - } - - g_free (copy); - } - else - { - errno = 0; - val = strtod (nptr, &fail_pos); - strtod_errno = errno; - } - - if (endptr) - *endptr = fail_pos; - - errno = strtod_errno; - - return val; -} - - -/** - * g_ascii_dtostr: - * @buffer: A buffer to place the resulting string in - * @buf_len: The length of the buffer. - * @d: The #gdouble to convert - * - * Converts a #gdouble to a string, using the '.' as - * decimal point. - * - * This functions generates enough precision that converting - * the string back using g_ascii_strtod() gives the same machine-number - * (on machines with IEEE compatible 64bit doubles). It is - * guaranteed that the size of the resulting string will never - * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes. - * - * Return value: The pointer to the buffer with the converted string. - **/ -gchar * -g_ascii_dtostr (gchar *buffer, - gint buf_len, - gdouble d) -{ - return g_ascii_formatd (buffer, buf_len, "%.17g", d); -} - -/** - * g_ascii_formatd: - * @buffer: A buffer to place the resulting string in - * @buf_len: The length of the buffer. - * @format: The printf()-style format to use for the - * code to use for converting. - * @d: The #gdouble to convert - * - * Converts a #gdouble to a string, using the '.' as - * decimal point. To format the number you pass in - * a printf()-style format string. Allowed conversion - * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'. - * - * If you just want to want to serialize the value into a - * string, use g_ascii_dtostr(). - * - * Return value: The pointer to the buffer with the converted string. - */ -gchar * -g_ascii_formatd (gchar *buffer, - gint buf_len, - const gchar *format, - gdouble d) -{ - struct lconv *locale_data; - const char *decimal_point; - int decimal_point_len; - gchar *p; - int rest_len; - gchar format_char; - - g_return_val_if_fail (buffer != NULL, NULL); - g_return_val_if_fail (format[0] == '%', NULL); - g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); - - format_char = format[strlen (format) - 1]; - - g_return_val_if_fail (format_char == 'e' || format_char == 'E' || - format_char == 'f' || format_char == 'F' || - format_char == 'g' || format_char == 'G', - NULL); - - if (format[0] != '%') - return NULL; - - if (strpbrk (format + 1, "'l%")) - return NULL; - - if (!(format_char == 'e' || format_char == 'E' || - format_char == 'f' || format_char == 'F' || - format_char == 'g' || format_char == 'G')) - return NULL; - - _g_snprintf (buffer, buf_len, format, d); - - locale_data = localeconv (); - decimal_point = locale_data->decimal_point; - decimal_point_len = strlen (decimal_point); - - g_assert (decimal_point_len != 0); - - if (decimal_point[0] != '.' || - decimal_point[1] != 0) - { - p = buffer; - - while (g_ascii_isspace (*p)) - p++; - - if (*p == '+' || *p == '-') - p++; - - while (isdigit ((guchar)*p)) - p++; - - if (strncmp (p, decimal_point, decimal_point_len) == 0) - { - *p = '.'; - p++; - if (decimal_point_len > 1) - { - rest_len = strlen (p + (decimal_point_len-1)); - memmove (p, p + (decimal_point_len-1), rest_len); - p[rest_len] = 0; - } - } - } - - return buffer; -} - -static guint64 -g_parse_long_long (const gchar *nptr, - const gchar **endptr, - guint base, - gboolean *negative) -{ - /* this code is based on on the strtol(3) code from GNU libc released under - * the GNU Lesser General Public License. - * - * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02 - * Free Software Foundation, Inc. - */ -#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ - (c) == '\r' || (c) == '\t' || (c) == '\v') -#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') -#define ISLOWER(c) ((c) >= 'a' && (c) <= 'z') -#define ISALPHA(c) (ISUPPER (c) || ISLOWER (c)) -#define TOUPPER(c) (ISLOWER (c) ? (c) - 'a' + 'A' : (c)) -#define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c)) - gboolean overflow; - guint64 cutoff; - guint64 cutlim; - guint64 ui64; - const gchar *s, *save; - guchar c; - - g_return_val_if_fail (nptr != NULL, 0); - - *negative = FALSE; - if (base == 1 || base > 36) - { - errno = EINVAL; - if (endptr) - *endptr = nptr; - return 0; - } - - save = s = nptr; - - /* Skip white space. */ - while (ISSPACE (*s)) - ++s; - - if (G_UNLIKELY (!*s)) - goto noconv; - - /* Check for a sign. */ - if (*s == '-') - { - *negative = TRUE; - ++s; - } - else if (*s == '+') - ++s; - - /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ - if (*s == '0') - { - if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X') - { - s += 2; - base = 16; - } - else if (base == 0) - base = 8; - } - else if (base == 0) - base = 10; - - /* Save the pointer so we can check later if anything happened. */ - save = s; - cutoff = G_MAXUINT64 / base; - cutlim = G_MAXUINT64 % base; - - overflow = FALSE; - ui64 = 0; - c = *s; - for (; c; c = *++s) - { - if (c >= '0' && c <= '9') - c -= '0'; - else if (ISALPHA (c)) - c = TOUPPER (c) - 'A' + 10; - else - break; - if (c >= base) - break; - /* Check for overflow. */ - if (ui64 > cutoff || (ui64 == cutoff && c > cutlim)) - overflow = TRUE; - else - { - ui64 *= base; - ui64 += c; - } - } - - /* Check if anything actually happened. */ - if (s == save) - goto noconv; - - /* Store in ENDPTR the address of one character - past the last character we converted. */ - if (endptr) - *endptr = s; - - if (G_UNLIKELY (overflow)) - { - errno = ERANGE; - return G_MAXUINT64; - } - - return ui64; - - noconv: - /* We must handle a special case here: the base is 0 or 16 and the - first two characters are '0' and 'x', but the rest are no - hexadecimal digits. This is no error case. We return 0 and - ENDPTR points to the `x`. */ - if (endptr) - { - if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X' - && save[-2] == '0') - *endptr = &save[-1]; - else - /* There was no number to convert. */ - *endptr = nptr; - } - return 0; -} - -/** - * g_ascii_strtoull: - * @nptr: the string to convert to a numeric value. - * @endptr: if non-%NULL, it returns the character after - * the last character used in the conversion. - * @base: to be used for the conversion, 2..36 or 0 - * - * Converts a string to a #guint64 value. - * This function behaves like the standard strtoull() function - * does in the C locale. It does this without actually - * changing the current locale, since that would not be - * thread-safe. - * - * This function is typically used when reading configuration - * files or other non-user input that should be locale independent. - * To handle input from the user you should normally use the - * locale-sensitive system strtoull() function. - * - * If the correct value would cause overflow, %G_MAXUINT64 - * is returned, and %ERANGE is stored in %errno. If the base is - * outside the valid range, zero is returned, and %EINVAL is stored - * in %errno. If the string conversion fails, zero is returned, and - * @endptr returns @nptr (if @endptr is non-%NULL). - * - * Return value: the #guint64 value or zero on error. - * - * Since: 2.2 - */ -guint64 -g_ascii_strtoull (const gchar *nptr, - gchar **endptr, - guint base) -{ - gboolean negative; - guint64 result; - - result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative); - - /* Return the result of the appropriate sign. */ - return negative ? -result : result; -} - -/** - * g_ascii_strtoll: - * @nptr: the string to convert to a numeric value. - * @endptr: if non-%NULL, it returns the character after - * the last character used in the conversion. - * @base: to be used for the conversion, 2..36 or 0 - * - * Converts a string to a #gint64 value. - * This function behaves like the standard strtoll() function - * does in the C locale. It does this without actually - * changing the current locale, since that would not be - * thread-safe. - * - * This function is typically used when reading configuration - * files or other non-user input that should be locale independent. - * To handle input from the user you should normally use the - * locale-sensitive system strtoll() function. - * - * If the correct value would cause overflow, %G_MAXINT64 or %G_MININT64 - * is returned, and %ERANGE is stored in %errno. If the base is - * outside the valid range, zero is returned, and %EINVAL is stored - * in %errno. If the string conversion fails, zero is returned, and - * @endptr returns @nptr (if @endptr is non-%NULL). - * - * Return value: the #gint64 value or zero on error. - * - * Since: 2.12 - */ -gint64 -g_ascii_strtoll (const gchar *nptr, - gchar **endptr, - guint base) -{ - gboolean negative; - guint64 result; - - result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative); - - if (negative && result > (guint64) G_MININT64) - { - errno = ERANGE; - return G_MININT64; - } - else if (!negative && result > (guint64) G_MAXINT64) - { - errno = ERANGE; - return G_MAXINT64; - } - else if (negative) - return - (gint64) result; - else - return (gint64) result; -} - -/** - * g_strerror: - * @errnum: the system error number. See the standard C %errno - * documentation - * - * Returns a string corresponding to the given error code, e.g. - * "no such process". You should use this function in preference to - * strerror(), because it returns a string in UTF-8 encoding, and since - * not all platforms support the strerror() function. - * - * Returns: a UTF-8 string describing the error code. If the error code - * is unknown, it returns "unknown error (<code>)". The string - * can only be used until the next call to g_strerror() - */ -const gchar * -g_strerror (gint errnum) -{ - static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; - char *msg; - int saved_errno = errno; - -#ifdef HAVE_STRERROR - const char *msg_locale; - - msg_locale = strerror (errnum); - errno = saved_errno; - return msg_locale; -#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 -#if defined(EDEADLOCK) && (!defined(EDEADLK) || (EDEADLOCK != EDEADLK)) - 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 "is 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 */ - - msg = g_static_private_get (&msg_private); - if (!msg) - { - msg = g_new (gchar, 64); - g_static_private_set (&msg_private, msg, g_free); - } - - _g_sprintf (msg, "unknown error (%d)", errnum); - - errno = saved_errno; - return msg; -} - -/** - * g_strsignal: - * @signum: the signal number. See the <literal>signal</literal> - * documentation - * - * Returns a string describing the given signal, e.g. "Segmentation fault". - * You should use this function in preference to strsignal(), because it - * returns a string in UTF-8 encoding, and since not all platforms support - * the strsignal() function. - * - * Returns: a UTF-8 string describing the signal. If the signal is unknown, - * it returns "unknown signal (<signum>)". The string can only be - * used until the next call to g_strsignal() - */ -const gchar * -g_strsignal (gint signum) -{ - static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT; - char *msg; - -#ifdef HAVE_STRSIGNAL - const char *msg_locale; - -#if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN) -extern const char *strsignal(int); -#else - /* this is declared differently (const) in string.h on BeOS */ - extern char *strsignal (int sig); -#endif /* !G_OS_BEOS && !G_WITH_CYGWIN */ - msg_locale = strsignal (signum); - return msg_locale; -#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 */ - -#ifdef NO_SYS_SIGLIST_DECL - extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/ -#endif - - return (char*) /* this function should return const --josh */ sys_siglist [signum]; -#endif /* NO_SYS_SIGLIST */ - - msg = g_static_private_get (&msg_private); - if (!msg) - { - msg = g_new (gchar, 64); - g_static_private_set (&msg_private, msg, g_free); - } - - _g_sprintf (msg, "unknown signal (%d)", signum); - - return msg; -} - -/* Functions g_strlcpy and g_strlcat were originally developed by - * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code. - * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3 - * for more information. - */ - -#ifdef HAVE_STRLCPY -/* Use the native ones, if available; they might be implemented in assembly */ -gsize -g_strlcpy (gchar *dest, - const gchar *src, - gsize dest_size) -{ - g_return_val_if_fail (dest != NULL, 0); - g_return_val_if_fail (src != NULL, 0); - - return strlcpy (dest, src, dest_size); -} - -gsize -g_strlcat (gchar *dest, - const gchar *src, - gsize dest_size) -{ - g_return_val_if_fail (dest != NULL, 0); - g_return_val_if_fail (src != NULL, 0); - - return strlcat (dest, src, dest_size); -} - -#else /* ! HAVE_STRLCPY */ -/** - * g_strlcpy: - * @dest: destination buffer - * @src: source buffer - * @dest_size: length of @dest in bytes - * - * Portability wrapper that calls strlcpy() on systems which have it, - * and emulates strlcpy() otherwise. Copies @src to @dest; @dest is - * guaranteed to be nul-terminated; @src must be nul-terminated; - * @dest_size is the buffer size, not the number of chars to copy. - * - * At most dest_size - 1 characters will be copied. Always nul-terminates - * (unless dest_size == 0). This function does <emphasis>not</emphasis> - * allocate memory. Unlike strncpy(), this function doesn't pad dest (so - * it's often faster). It returns the size of the attempted result, - * strlen (src), so if @retval >= @dest_size, truncation occurred. - * - * <note><para>Caveat: strlcpy() is supposedly more secure than - * strcpy() or strncpy(), but if you really want to avoid screwups, - * g_strdup() is an even better idea.</para></note> - * - * Returns: length of @src - */ -gsize -g_strlcpy (gchar *dest, - const gchar *src, - gsize dest_size) -{ - register gchar *d = dest; - register const gchar *s = src; - register gsize n = dest_size; - - g_return_val_if_fail (dest != NULL, 0); - g_return_val_if_fail (src != NULL, 0); - - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) - do - { - register gchar c = *s++; - - *d++ = c; - if (c == 0) - break; - } - while (--n != 0); - - /* If not enough room in dest, add NUL and traverse rest of src */ - if (n == 0) - { - if (dest_size != 0) - *d = 0; - while (*s++) - ; - } - - return s - src - 1; /* count does not include NUL */ -} - -/** - * g_strlcat: - * @dest: destination buffer, already containing one nul-terminated string - * @src: source buffer - * @dest_size: length of @dest buffer in bytes (not length of existing string - * inside @dest) - * - * Portability wrapper that calls strlcat() on systems which have it, - * and emulates it otherwise. Appends nul-terminated @src string to @dest, - * guaranteeing nul-termination for @dest. The total size of @dest won't - * exceed @dest_size. - * - * At most dest_size - 1 characters will be copied. - * Unlike strncat, dest_size is the full size of dest, not the space left over. - * This function does NOT allocate memory. - * This always NUL terminates (unless siz == 0 or there were no NUL characters - * in the dest_size characters of dest to start with). - * - * <note><para>Caveat: this is supposedly a more secure alternative to - * strcat() or strncat(), but for real security g_strconcat() is harder - * to mess up.</para></note> - * - * Returns: size of attempted result, which is MIN (dest_size, strlen - * (original dest)) + strlen (src), so if retval >= dest_size, - * truncation occurred. - **/ -gsize -g_strlcat (gchar *dest, - const gchar *src, - gsize dest_size) -{ - register gchar *d = dest; - register const gchar *s = src; - register gsize bytes_left = dest_size; - gsize dlength; /* Logically, MIN (strlen (d), dest_size) */ - - g_return_val_if_fail (dest != NULL, 0); - g_return_val_if_fail (src != NULL, 0); - - /* Find the end of dst and adjust bytes left but don't go past end */ - while (*d != 0 && bytes_left-- != 0) - d++; - dlength = d - dest; - bytes_left = dest_size - dlength; - - if (bytes_left == 0) - return dlength + strlen (s); - - while (*s != 0) - { - if (bytes_left != 1) - { - *d++ = *s; - bytes_left--; - } - s++; - } - *d = 0; - - return dlength + (s - src); /* count does not include NUL */ -} -#endif /* ! HAVE_STRLCPY */ - -/** - * g_ascii_strdown: - * @str: a string. - * @len: length of @str in bytes, or -1 if @str is nul-terminated. - * - * Converts all upper case ASCII letters to lower case ASCII letters. - * - * Return value: a newly-allocated string, with all the upper case - * characters in @str converted to lower case, with - * semantics that exactly match g_ascii_tolower(). (Note - * that this is unlike the old g_strdown(), which modified - * the string in place.) - **/ -gchar* -g_ascii_strdown (const gchar *str, - gssize len) -{ - gchar *result, *s; - - g_return_val_if_fail (str != NULL, NULL); - - if (len < 0) - len = strlen (str); - - result = g_strndup (str, len); - for (s = result; *s; s++) - *s = g_ascii_tolower (*s); - - return result; -} - -/** - * g_ascii_strup: - * @str: a string. - * @len: length of @str in bytes, or -1 if @str is nul-terminated. - * - * Converts all lower case ASCII letters to upper case ASCII letters. - * - * Return value: a newly allocated string, with all the lower case - * characters in @str converted to upper case, with - * semantics that exactly match g_ascii_toupper(). (Note - * that this is unlike the old g_strup(), which modified - * the string in place.) - **/ -gchar* -g_ascii_strup (const gchar *str, - gssize len) -{ - gchar *result, *s; - - g_return_val_if_fail (str != NULL, NULL); - - if (len < 0) - len = strlen (str); - - result = g_strndup (str, len); - for (s = result; *s; s++) - *s = g_ascii_toupper (*s); - - return result; -} - -/** - * g_strdown: - * @string: the string to convert. - * - * Converts a string to lower case. - * - * Return value: the string - * - * Deprecated:2.2: This function is totally broken for the reasons discussed - * in the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown() - * instead. - **/ -gchar* -g_strdown (gchar *string) -{ - register guchar *s; - - g_return_val_if_fail (string != NULL, NULL); - - s = (guchar *) string; - - while (*s) - { - if (isupper (*s)) - *s = tolower (*s); - s++; - } - - return (gchar *) string; -} - -/** - * g_strup: - * @string: the string to convert. - * - * Converts a string to upper case. - * - * Return value: the string - * - * Deprecated:2.2: This function is totally broken for the reasons discussed - * in the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead. - **/ -gchar* -g_strup (gchar *string) -{ - register guchar *s; - - g_return_val_if_fail (string != NULL, NULL); - - s = (guchar *) string; - - while (*s) - { - if (islower (*s)) - *s = toupper (*s); - s++; - } - - return (gchar *) string; -} - -/** - * g_strreverse: - * @string: the string to reverse - * - * Reverses all of the bytes in a string. For example, - * <literal>g_strreverse ("abcdef")</literal> will result - * in "fedcba". - * - * Note that g_strreverse() doesn't work on UTF-8 strings - * containing multibyte characters. For that purpose, use - * g_utf8_strreverse(). - * - * Returns: the same pointer passed in as @string - */ -gchar* -g_strreverse (gchar *string) -{ - g_return_val_if_fail (string != NULL, 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--; - } - } - - return string; -} - -/** - * g_ascii_tolower: - * @c: any character. - * - * Convert a character to ASCII lower case. - * - * Unlike the standard C library tolower() function, this only - * recognizes standard ASCII letters and ignores the locale, returning - * all non-ASCII characters unchanged, even if they are lower case - * letters in a particular character set. Also unlike the standard - * library function, this takes and returns a char, not an int, so - * don't call it on %EOF but no need to worry about casting to #guchar - * before passing a possibly non-ASCII character in. - * - * Return value: the result of converting @c to lower case. - * If @c is not an ASCII upper case letter, - * @c is returned unchanged. - **/ -gchar -g_ascii_tolower (gchar c) -{ - return g_ascii_isupper (c) ? c - 'A' + 'a' : c; -} - -/** - * g_ascii_toupper: - * @c: any character. - * - * Convert a character to ASCII upper case. - * - * Unlike the standard C library toupper() function, this only - * recognizes standard ASCII letters and ignores the locale, returning - * all non-ASCII characters unchanged, even if they are upper case - * letters in a particular character set. Also unlike the standard - * library function, this takes and returns a char, not an int, so - * don't call it on %EOF but no need to worry about casting to #guchar - * before passing a possibly non-ASCII character in. - * - * Return value: the result of converting @c to upper case. - * If @c is not an ASCII lower case letter, - * @c is returned unchanged. - **/ -gchar -g_ascii_toupper (gchar c) -{ - return g_ascii_islower (c) ? c - 'a' + 'A' : c; -} - -/** - * g_ascii_digit_value: - * @c: an ASCII character. - * - * Determines the numeric value of a character as a decimal - * digit. Differs from g_unichar_digit_value() because it takes - * a char, so there's no worry about sign extension if characters - * are signed. - * - * Return value: If @c is a decimal digit (according to - * g_ascii_isdigit()), its numeric value. Otherwise, -1. - **/ -int -g_ascii_digit_value (gchar c) -{ - if (g_ascii_isdigit (c)) - return c - '0'; - return -1; -} - -/** - * g_ascii_xdigit_value: - * @c: an ASCII character. - * - * Determines the numeric value of a character as a hexidecimal - * digit. Differs from g_unichar_xdigit_value() because it takes - * a char, so there's no worry about sign extension if characters - * are signed. - * - * Return value: If @c is a hex digit (according to - * g_ascii_isxdigit()), its numeric value. Otherwise, -1. - **/ -int -g_ascii_xdigit_value (gchar c) -{ - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return g_ascii_digit_value (c); -} - -/** - * g_ascii_strcasecmp: - * @s1: string to compare with @s2. - * @s2: string to compare with @s1. - * - * Compare two strings, ignoring the case of ASCII characters. - * - * Unlike the BSD strcasecmp() function, this only recognizes standard - * ASCII letters and ignores the locale, treating all non-ASCII - * bytes as if they are not letters. - * - * This function should be used only on strings that are known to be - * in encodings where the bytes corresponding to ASCII letters always - * represent themselves. This includes UTF-8 and the ISO-8859-* - * charsets, but not for instance double-byte encodings like the - * Windows Codepage 932, where the trailing bytes of double-byte - * characters include all ASCII letters. If you compare two CP932 - * strings using this function, you will get false matches. - * - * Return value: 0 if the strings match, a negative value if @s1 < @s2, - * or a positive value if @s1 > @s2. - **/ -gint -g_ascii_strcasecmp (const gchar *s1, - const gchar *s2) -{ - gint c1, c2; - - g_return_val_if_fail (s1 != NULL, 0); - g_return_val_if_fail (s2 != NULL, 0); - - while (*s1 && *s2) - { - c1 = (gint)(guchar) TOLOWER (*s1); - c2 = (gint)(guchar) TOLOWER (*s2); - if (c1 != c2) - return (c1 - c2); - s1++; s2++; - } - - return (((gint)(guchar) *s1) - ((gint)(guchar) *s2)); -} - -/** - * g_ascii_strncasecmp: - * @s1: string to compare with @s2. - * @s2: string to compare with @s1. - * @n: number of characters to compare. - * - * Compare @s1 and @s2, ignoring the case of ASCII characters and any - * characters after the first @n in each string. - * - * Unlike the BSD strcasecmp() function, this only recognizes standard - * ASCII letters and ignores the locale, treating all non-ASCII - * characters as if they are not letters. - * - * The same warning as in g_ascii_strcasecmp() applies: Use this - * function only on strings known to be in encodings where bytes - * corresponding to ASCII letters always represent themselves. - * - * Return value: 0 if the strings match, a negative value if @s1 < @s2, - * or a positive value if @s1 > @s2. - **/ -gint -g_ascii_strncasecmp (const gchar *s1, - const gchar *s2, - gsize n) -{ - gint c1, c2; - - g_return_val_if_fail (s1 != NULL, 0); - g_return_val_if_fail (s2 != NULL, 0); - - while (n && *s1 && *s2) - { - n -= 1; - c1 = (gint)(guchar) TOLOWER (*s1); - c2 = (gint)(guchar) TOLOWER (*s2); - if (c1 != c2) - return (c1 - c2); - s1++; s2++; - } - - if (n) - return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); - else - return 0; -} - -/** - * g_strcasecmp: - * @s1: a string. - * @s2: a string to compare with @s1. - * - * A case-insensitive string comparison, corresponding to the standard - * strcasecmp() function on platforms which support it. - * - * Return value: 0 if the strings match, a negative value if @s1 < @s2, - * or a positive value if @s1 > @s2. - * - * Deprecated:2.2: See g_strncasecmp() for a discussion of why this function - * is deprecated and how to replace it. - **/ -gint -g_strcasecmp (const gchar *s1, - const gchar *s2) -{ -#ifdef HAVE_STRCASECMP - g_return_val_if_fail (s1 != NULL, 0); - g_return_val_if_fail (s2 != NULL, 0); - - return strcasecmp (s1, s2); -#else - gint c1, c2; - - g_return_val_if_fail (s1 != NULL, 0); - g_return_val_if_fail (s2 != NULL, 0); - - 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 -} - -/** - * g_strncasecmp: - * @s1: a string. - * @s2: a string to compare with @s1. - * @n: the maximum number of characters to compare. - * - * A case-insensitive string comparison, corresponding to the standard - * strncasecmp() function on platforms which support it. - * It is similar to g_strcasecmp() except it only compares the first @n - * characters of the strings. - * - * Return value: 0 if the strings match, a negative value if @s1 < @s2, - * or a positive value if @s1 > @s2. - * - * Deprecated:2.2: The problem with g_strncasecmp() is that it does the - * comparison by calling toupper()/tolower(). These functions are - * locale-specific and operate on single bytes. However, it is impossible - * to handle things correctly from an I18N standpoint by operating on - * bytes, since characters may be multibyte. Thus g_strncasecmp() is - * broken if your string is guaranteed to be ASCII, since it's - * locale-sensitive, and it's broken if your string is localized, since - * it doesn't work on many encodings at all, including UTF-8, EUC-JP, - * etc. - * - * There are therefore two replacement functions: g_ascii_strncasecmp(), - * which only works on ASCII and is not locale-sensitive, and - * g_utf8_casefold(), which is good for case-insensitive sorting of UTF-8. - **/ -gint -g_strncasecmp (const gchar *s1, - const gchar *s2, - guint n) -{ -#ifdef HAVE_STRNCASECMP - return strncasecmp (s1, s2, n); -#else - gint c1, c2; - - g_return_val_if_fail (s1 != NULL, 0); - g_return_val_if_fail (s2 != NULL, 0); - - while (n && *s1 && *s2) - { - n -= 1; - /* 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++; - } - - if (n) - return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); - else - return 0; -#endif -} - -gchar* -g_strdelimit (gchar *string, - const gchar *delimiters, - gchar new_delim) -{ - register gchar *c; - - g_return_val_if_fail (string != NULL, NULL); - - if (!delimiters) - delimiters = G_STR_DELIMITERS; - - for (c = string; *c; c++) - { - if (strchr (delimiters, *c)) - *c = new_delim; - } - - return string; -} - -gchar* -g_strcanon (gchar *string, - const gchar *valid_chars, - gchar substitutor) -{ - register gchar *c; - - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (valid_chars != NULL, NULL); - - for (c = string; *c; c++) - { - if (!strchr (valid_chars, *c)) - *c = substitutor; - } - - return string; -} - -gchar* -g_strcompress (const gchar *source) -{ - const gchar *p = source, *octal; - gchar *dest = g_malloc (strlen (source) + 1); - gchar *q = dest; - - while (*p) - { - if (*p == '\\') - { - p++; - switch (*p) - { - case '\0': - g_warning ("g_strcompress: trailing \\"); - goto out; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - *q = 0; - octal = p; - while ((p < octal + 3) && (*p >= '0') && (*p <= '7')) - { - *q = (*q * 8) + (*p - '0'); - p++; - } - q++; - p--; - break; - case 'b': - *q++ = '\b'; - break; - case 'f': - *q++ = '\f'; - break; - case 'n': - *q++ = '\n'; - break; - case 'r': - *q++ = '\r'; - break; - case 't': - *q++ = '\t'; - break; - default: /* Also handles \" and \\ */ - *q++ = *p; - break; - } - } - else - *q++ = *p; - p++; - } -out: - *q = 0; - - return dest; -} - -gchar * -g_strescape (const gchar *source, - const gchar *exceptions) -{ - const guchar *p; - gchar *dest; - gchar *q; - guchar excmap[256]; - - g_return_val_if_fail (source != NULL, NULL); - - p = (guchar *) source; - /* Each source byte needs maximally four destination chars (\777) */ - q = dest = g_malloc (strlen (source) * 4 + 1); - - memset (excmap, 0, 256); - if (exceptions) - { - guchar *e = (guchar *) exceptions; - - while (*e) - { - excmap[*e] = 1; - e++; - } - } - - while (*p) - { - if (excmap[*p]) - *q++ = *p; - else - { - switch (*p) - { - case '\b': - *q++ = '\\'; - *q++ = 'b'; - break; - case '\f': - *q++ = '\\'; - *q++ = 'f'; - break; - case '\n': - *q++ = '\\'; - *q++ = 'n'; - break; - case '\r': - *q++ = '\\'; - *q++ = 'r'; - break; - case '\t': - *q++ = '\\'; - *q++ = 't'; - break; - case '\\': - *q++ = '\\'; - *q++ = '\\'; - break; - case '"': - *q++ = '\\'; - *q++ = '"'; - break; - default: - if ((*p < ' ') || (*p >= 0177)) - { - *q++ = '\\'; - *q++ = '0' + (((*p) >> 6) & 07); - *q++ = '0' + (((*p) >> 3) & 07); - *q++ = '0' + ((*p) & 07); - } - else - *q++ = *p; - break; - } - } - p++; - } - *q = 0; - return dest; -} - -gchar* -g_strchug (gchar *string) -{ - guchar *start; - - g_return_val_if_fail (string != NULL, NULL); - - for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++) - ; - - g_memmove (string, start, strlen ((gchar *) start) + 1); - - return string; -} - -gchar* -g_strchomp (gchar *string) -{ - gsize len; - - g_return_val_if_fail (string != NULL, NULL); - - len = strlen (string); - while (len--) - { - if (g_ascii_isspace ((guchar) string[len])) - string[len] = '\0'; - else - break; - } - - return string; -} - -/** - * g_strsplit: - * @string: a string to split. - * @delimiter: a string which specifies the places at which to split the string. - * The delimiter is not included in any of the resulting strings, unless - * @max_tokens is reached. - * @max_tokens: the maximum number of pieces to split @string into. If this is - * less than 1, the string is split completely. - * - * Splits a string into a maximum of @max_tokens pieces, using the given - * @delimiter. If @max_tokens is reached, the remainder of @string is appended - * to the last token. - * - * As a special case, the result of splitting the empty string "" is an empty - * vector, not a vector containing a single string. The reason for this - * special case is that being able to represent a empty vector is typically - * more useful than consistent handling of empty elements. If you do need - * to represent empty elements, you'll need to check for the empty string - * before calling g_strsplit(). - * - * Return value: a newly-allocated %NULL-terminated array of strings. Use - * g_strfreev() to free it. - **/ -gchar** -g_strsplit (const gchar *string, - const gchar *delimiter, - gint max_tokens) -{ - GSList *string_list = NULL, *slist; - gchar **str_array, *s; - guint n = 0; - const gchar *remainder; - - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (delimiter != NULL, NULL); - g_return_val_if_fail (delimiter[0] != '\0', NULL); - - if (max_tokens < 1) - max_tokens = G_MAXINT; - - remainder = string; - s = strstr (remainder, delimiter); - if (s) - { - gsize delimiter_len = strlen (delimiter); - - while (--max_tokens && s) - { - gsize len; - - len = s - remainder; - string_list = g_slist_prepend (string_list, - g_strndup (remainder, len)); - n++; - remainder = s + delimiter_len; - s = strstr (remainder, delimiter); - } - } - if (*string) - { - n++; - string_list = g_slist_prepend (string_list, g_strdup (remainder)); - } - - str_array = g_new (gchar*, n + 1); - - str_array[n--] = NULL; - for (slist = string_list; slist; slist = slist->next) - str_array[n--] = slist->data; - - g_slist_free (string_list); - - return str_array; -} - -/** - * g_strsplit_set: - * @string: The string to be tokenized - * @delimiters: A nul-terminated string containing bytes that are used - * to split the string. - * @max_tokens: The maximum number of tokens to split @string into. - * If this is less than 1, the string is split completely - * - * Splits @string into a number of tokens not containing any of the characters - * in @delimiter. A token is the (possibly empty) longest string that does not - * contain any of the characters in @delimiters. If @max_tokens is reached, the - * remainder is appended to the last token. - * - * For example the result of g_strsplit_set ("abc:def/ghi", ":/", -1) is a - * %NULL-terminated vector containing the three strings "abc", "def", - * and "ghi". - * - * The result if g_strsplit_set (":def/ghi:", ":/", -1) is a %NULL-terminated - * vector containing the four strings "", "def", "ghi", and "". - * - * As a special case, the result of splitting the empty string "" is an empty - * vector, not a vector containing a single string. The reason for this - * special case is that being able to represent a empty vector is typically - * more useful than consistent handling of empty elements. If you do need - * to represent empty elements, you'll need to check for the empty string - * before calling g_strsplit_set(). - * - * Note that this function works on bytes not characters, so it can't be used - * to delimit UTF-8 strings for anything but ASCII characters. - * - * Return value: a newly-allocated %NULL-terminated array of strings. Use - * g_strfreev() to free it. - * - * Since: 2.4 - **/ -gchar ** -g_strsplit_set (const gchar *string, - const gchar *delimiters, - gint max_tokens) -{ - gboolean delim_table[256]; - GSList *tokens, *list; - gint n_tokens; - const gchar *s; - const gchar *current; - gchar *token; - gchar **result; - - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (delimiters != NULL, NULL); - - if (max_tokens < 1) - max_tokens = G_MAXINT; - - if (*string == '\0') - { - result = g_new (char *, 1); - result[0] = NULL; - return result; - } - - memset (delim_table, FALSE, sizeof (delim_table)); - for (s = delimiters; *s != '\0'; ++s) - delim_table[*(guchar *)s] = TRUE; - - tokens = NULL; - n_tokens = 0; - - s = current = string; - while (*s != '\0') - { - if (delim_table[*(guchar *)s] && n_tokens + 1 < max_tokens) - { - token = g_strndup (current, s - current); - tokens = g_slist_prepend (tokens, token); - ++n_tokens; - - current = s + 1; - } - - ++s; - } - - token = g_strndup (current, s - current); - tokens = g_slist_prepend (tokens, token); - ++n_tokens; - - result = g_new (gchar *, n_tokens + 1); - - result[n_tokens] = NULL; - for (list = tokens; list != NULL; list = list->next) - result[--n_tokens] = list->data; - - g_slist_free (tokens); - - return result; -} - -/** - * g_strfreev: - * @str_array: a %NULL-terminated array of strings to free. - - * Frees a %NULL-terminated array of strings, and the array itself. - * If called on a %NULL value, g_strfreev() simply returns. - **/ -void -g_strfreev (gchar **str_array) -{ - if (str_array) - { - int i; - - for (i = 0; str_array[i] != NULL; i++) - g_free (str_array[i]); - - g_free (str_array); - } -} - -/** - * g_strdupv: - * @str_array: %NULL-terminated array of strings. - * - * Copies %NULL-terminated array of strings. The copy is a deep copy; - * the new array should be freed by first freeing each string, then - * the array itself. g_strfreev() does this for you. If called - * on a %NULL value, g_strdupv() simply returns %NULL. - * - * Return value: a new %NULL-terminated array of strings. - **/ -gchar** -g_strdupv (gchar **str_array) -{ - if (str_array) - { - gint i; - gchar **retval; - - i = 0; - while (str_array[i]) - ++i; - - retval = g_new (gchar*, i + 1); - - i = 0; - while (str_array[i]) - { - retval[i] = g_strdup (str_array[i]); - ++i; - } - retval[i] = NULL; - - return retval; - } - else - return NULL; -} - -/** - * g_strjoinv: - * @separator: a string to insert between each of the strings, or %NULL - * @str_array: a %NULL-terminated array of strings to join - * - * Joins a number of strings together to form one long string, with the - * optional @separator inserted between each of them. The returned string - * should be freed with g_free(). - * - * Returns: a newly-allocated string containing all of the strings joined - * together, with @separator between them - */ -gchar* -g_strjoinv (const gchar *separator, - gchar **str_array) -{ - gchar *string; - gchar *ptr; - - g_return_val_if_fail (str_array != NULL, NULL); - - if (separator == NULL) - separator = ""; - - if (*str_array) - { - gint i; - gsize len; - gsize separator_len; - - separator_len = strlen (separator); - /* First part, getting length */ - len = 1 + strlen (str_array[0]); - for (i = 1; str_array[i] != NULL; i++) - len += strlen (str_array[i]); - len += separator_len * (i - 1); - - /* Second part, building string */ - string = g_new (gchar, len); - ptr = g_stpcpy (string, *str_array); - for (i = 1; str_array[i] != NULL; i++) - { - ptr = g_stpcpy (ptr, separator); - ptr = g_stpcpy (ptr, str_array[i]); - } - } - else - string = g_strdup (""); - - return string; -} - -/** - * g_strjoin: - * @separator: a string to insert between each of the strings, or %NULL - * @...: a %NULL-terminated list of strings to join - * - * Joins a number of strings together to form one long string, with the - * optional @separator inserted between each of them. The returned string - * should be freed with g_free(). - * - * Returns: a newly-allocated string containing all of the strings joined - * together, with @separator between them - */ -gchar* -g_strjoin (const gchar *separator, - ...) -{ - gchar *string, *s; - va_list args; - gsize len; - gsize separator_len; - gchar *ptr; - - if (separator == NULL) - separator = ""; - - separator_len = strlen (separator); - - va_start (args, separator); - - s = va_arg (args, gchar*); - - if (s) - { - /* First part, getting length */ - len = 1 + strlen (s); - - s = va_arg (args, gchar*); - while (s) - { - len += separator_len + strlen (s); - s = va_arg (args, gchar*); - } - va_end (args); - - /* Second part, building string */ - string = g_new (gchar, len); - - va_start (args, separator); - - s = va_arg (args, gchar*); - ptr = g_stpcpy (string, s); - - s = va_arg (args, gchar*); - while (s) - { - ptr = g_stpcpy (ptr, separator); - ptr = g_stpcpy (ptr, s); - s = va_arg (args, gchar*); - } - } - else - string = g_strdup (""); - - va_end (args); - - return string; -} - - -/** - * g_strstr_len: - * @haystack: a string. - * @haystack_len: the maximum length of @haystack. Note that -1 is - * a valid length, if @haystack is nul-terminated, meaning it will - * search through the whole string. - * @needle: the string to search for. - * - * Searches the string @haystack for the first occurrence - * of the string @needle, limiting the length of the search - * to @haystack_len. - * - * Return value: a pointer to the found occurrence, or - * %NULL if not found. - **/ -gchar * -g_strstr_len (const gchar *haystack, - gssize haystack_len, - const gchar *needle) -{ - g_return_val_if_fail (haystack != NULL, NULL); - g_return_val_if_fail (needle != NULL, NULL); - - if (haystack_len < 0) - return strstr (haystack, needle); - else - { - const gchar *p = haystack; - gsize needle_len = strlen (needle); - const gchar *end; - gsize i; - - if (needle_len == 0) - return (gchar *)haystack; - - if (haystack_len < needle_len) - return NULL; - - end = haystack + haystack_len - needle_len; - - while (p <= end && *p) - { - for (i = 0; i < needle_len; i++) - if (p[i] != needle[i]) - goto next; - - return (gchar *)p; - - next: - p++; - } - - return NULL; - } -} - -/** - * g_strrstr: - * @haystack: a nul-terminated string. - * @needle: the nul-terminated string to search for. - * - * Searches the string @haystack for the last occurrence - * of the string @needle. - * - * Return value: a pointer to the found occurrence, or - * %NULL if not found. - **/ -gchar * -g_strrstr (const gchar *haystack, - const gchar *needle) -{ - gsize i; - gsize needle_len; - gsize haystack_len; - const gchar *p; - - g_return_val_if_fail (haystack != NULL, NULL); - g_return_val_if_fail (needle != NULL, NULL); - - needle_len = strlen (needle); - haystack_len = strlen (haystack); - - if (needle_len == 0) - return (gchar *)haystack; - - if (haystack_len < needle_len) - return NULL; - - p = haystack + haystack_len - needle_len; - - while (p >= haystack) - { - for (i = 0; i < needle_len; i++) - if (p[i] != needle[i]) - goto next; - - return (gchar *)p; - - next: - p--; - } - - return NULL; -} - -/** - * g_strrstr_len: - * @haystack: a nul-terminated string. - * @haystack_len: the maximum length of @haystack. - * @needle: the nul-terminated string to search for. - * - * Searches the string @haystack for the last occurrence - * of the string @needle, limiting the length of the search - * to @haystack_len. - * - * Return value: a pointer to the found occurrence, or - * %NULL if not found. - **/ -gchar * -g_strrstr_len (const gchar *haystack, - gssize haystack_len, - const gchar *needle) -{ - g_return_val_if_fail (haystack != NULL, NULL); - g_return_val_if_fail (needle != NULL, NULL); - - if (haystack_len < 0) - return g_strrstr (haystack, needle); - else - { - gsize needle_len = strlen (needle); - const gchar *haystack_max = haystack + haystack_len; - const gchar *p = haystack; - gsize i; - - while (p < haystack_max && *p) - p++; - - if (p < haystack + needle_len) - return NULL; - - p -= needle_len; - - while (p >= haystack) - { - for (i = 0; i < needle_len; i++) - if (p[i] != needle[i]) - goto next; - - return (gchar *)p; - - next: - p--; - } - - return NULL; - } -} - - -/** - * g_str_has_suffix: - * @str: a nul-terminated string. - * @suffix: the nul-terminated suffix to look for. - * - * Looks whether the string @str ends with @suffix. - * - * Return value: %TRUE if @str end with @suffix, %FALSE otherwise. - * - * Since: 2.2 - **/ -gboolean -g_str_has_suffix (const gchar *str, - const gchar *suffix) -{ - int str_len; - int suffix_len; - - g_return_val_if_fail (str != NULL, FALSE); - g_return_val_if_fail (suffix != NULL, FALSE); - - str_len = strlen (str); - suffix_len = strlen (suffix); - - if (str_len < suffix_len) - return FALSE; - - return strcmp (str + str_len - suffix_len, suffix) == 0; -} - -/** - * g_str_has_prefix: - * @str: a nul-terminated string. - * @prefix: the nul-terminated prefix to look for. - * - * Looks whether the string @str begins with @prefix. - * - * Return value: %TRUE if @str begins with @prefix, %FALSE otherwise. - * - * Since: 2.2 - **/ -gboolean -g_str_has_prefix (const gchar *str, - const gchar *prefix) -{ - int str_len; - int prefix_len; - - g_return_val_if_fail (str != NULL, FALSE); - g_return_val_if_fail (prefix != NULL, FALSE); - - str_len = strlen (str); - prefix_len = strlen (prefix); - - if (str_len < prefix_len) - return FALSE; - - return strncmp (str, prefix, prefix_len) == 0; -} - - -/** - * g_strip_context: - * @msgid: a string - * @msgval: another string - * - * An auxiliary function for gettext() support (see Q_()). - * - * Return value: @msgval, unless @msgval is identical to @msgid and contains - * a '|' character, in which case a pointer to the substring of msgid after - * the first '|' character is returned. - * - * Since: 2.4 - **/ -const gchar * -g_strip_context (const gchar *msgid, - const gchar *msgval) -{ - if (msgval == msgid) - { - const char *c = strchr (msgid, '|'); - if (c != NULL) - return c + 1; - } - - return msgval; -} - - -/** - * g_strv_length: - * @str_array: a %NULL-terminated array of strings. - * - * Returns the length of the given %NULL-terminated - * string array @str_array. - * - * Return value: length of @str_array. - * - * Since: 2.6 - **/ -guint -g_strv_length (gchar **str_array) -{ - guint i = 0; - - g_return_val_if_fail (str_array != NULL, 0); - - while (str_array[i]) - ++i; - - return i; -} - - -/** - * g_dpgettext: - * @domain: the translation domain to use, or %NULL to use - * the domain set with textdomain() - * @msgctxtid: a combined message context and message id, separated - * by a \004 character - * @msgidoffset: the offset of the message id in @msgctxid - * - * This function is a variant of g_dgettext() which supports - * a disambiguating message context. GNU gettext uses the - * '\004' character to separate the message context and - * message id in @msgctxtid. - * If 0 is passed as @msgidoffset, this function will fall back to - * trying to use the deprecated convention of using "|" as a separation - * character. - * - * This uses g_dgettext() internally. See that functions for differences - * with dgettext() proper. - * - * Applications should normally not use this function directly, - * but use the C_() macro for translations with context. - * - * Returns: The translated string - * - * Since: 2.16 - */ -const gchar * -g_dpgettext (const gchar *domain, - const gchar *msgctxtid, - gsize msgidoffset) -{ - const gchar *translation; - gchar *sep; - - translation = g_dgettext (domain, msgctxtid); - - if (translation == msgctxtid) - { - if (msgidoffset > 0) - return msgctxtid + msgidoffset; - - sep = strchr (msgctxtid, '|'); - - if (sep) - { - /* try with '\004' instead of '|', in case - * xgettext -kQ_:1g was used - */ - gchar *tmp = g_alloca (strlen (msgctxtid) + 1); - strcpy (tmp, msgctxtid); - tmp[sep - msgctxtid] = '\004'; - - translation = g_dgettext (domain, tmp); - - if (translation == tmp) - return sep + 1; - } - } - - return translation; -} - -/* This function is taken from gettext.h - * GNU gettext uses '\004' to separate context and msgid in .mo files. - */ -/** - * g_dpgettext2: - * @domain: the translation domain to use, or %NULL to use - * the domain set with textdomain() - * @context: the message context - * @msgid: the message - * - * This function is a variant of g_dgettext() which supports - * a disambiguating message context. GNU gettext uses the - * '\004' character to separate the message context and - * message id in @msgctxtid. - * - * This uses g_dgettext() internally. See that functions for differences - * with dgettext() proper. - * - * This function differs from C_() in that it is not a macro and - * thus you may use non-string-literals as context and msgid arguments. - * - * Returns: The translated string - * - * Since: 2.18 - */ -const char * -g_dpgettext2 (const char *domain, - const char *msgctxt, - const char *msgid) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; - char* msg_ctxt_id; - - msg_ctxt_id = g_alloca (msgctxt_len + msgid_len); - - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - - translation = g_dgettext (domain, msg_ctxt_id); - - if (translation == msg_ctxt_id) - { - /* try the old way of doing message contexts, too */ - msg_ctxt_id[msgctxt_len - 1] = '|'; - translation = g_dgettext (domain, msg_ctxt_id); - - if (translation == msg_ctxt_id) - return msgid; - } - - return translation; -} - -static gboolean -_g_dgettext_should_translate (void) -{ - static gsize translate = 0; - enum { - SHOULD_TRANSLATE = 1, - SHOULD_NOT_TRANSLATE = 2 - }; - - if (G_UNLIKELY (g_once_init_enter (&translate))) - { - gboolean should_translate = TRUE; - - const char *default_domain = textdomain (NULL); - const char *translator_comment = gettext (""); -#ifndef G_OS_WIN32 - const char *translate_locale = setlocale (LC_MESSAGES, NULL); -#else - const char *translate_locale = g_win32_getlocale (); -#endif - /* We should NOT translate only if all the following hold: - * - user has called textdomain() and set textdomain to non-default - * - default domain has no translations - * - locale does not start with "en_" and is not "C" - * - * Rationale: - * - If text domain is still the default domain, maybe user calls - * it later. Continue with old behavior of translating. - * - If locale starts with "en_", we can continue using the - * translations even if the app doesn't have translations for - * this locale. That is, en_UK and en_CA for example. - * - If locale is "C", maybe user calls setlocale(LC_ALL,"") later. - * Continue with old behavior of translating. - */ - if (0 != strcmp (default_domain, "messages") && - '\0' == *translator_comment && - 0 != strncmp (translate_locale, "en_", 3) && - 0 != strcmp (translate_locale, "C")) - should_translate = FALSE; - - g_once_init_leave (&translate, - should_translate ? - SHOULD_TRANSLATE : - SHOULD_NOT_TRANSLATE); - } - - return translate == SHOULD_TRANSLATE; -} - -/** - * g_dgettext: - * @domain: the translation domain to use, or %NULL to use - * the domain set with textdomain() - * @msgid: message to translate - * - * This function is a wrapper of dgettext() which does not translate - * the message if the default domain as set with textdomain() has no - * translations for the current locale. - * - * The advantage of using this function over dgettext() proper is that - * libraries using this function (like GTK+) will not use translations - * if the application using the library does not have translations for - * the current locale. This results in a consistent English-only - * interface instead of one having partial translations. For this - * feature to work, the call to textdomain() and setlocale() should - * precede any g_dgettext() invocations. For GTK+, it means calling - * textdomain() before gtk_init or its variants. - * - * This function disables translations if and only if upon its first - * call all the following conditions hold: - * <itemizedlist> - * <listitem>@domain is not %NULL</listitem> - * <listitem>textdomain() has been called to set a default text domain</listitem> - * <listitem>there is no translations available for the default text domain - * and the current locale</listitem> - * <listitem>current locale is not "C" or any English locales (those - * starting with "en_")</listitem> - * </itemizedlist> - * - * Note that this behavior may not be desired for example if an application - * has its untranslated messages in a language other than English. In those - * cases the application should call textdomain() after initializing GTK+. - * - * Applications should normally not use this function directly, - * but use the _() macro for translations. - * - * Returns: The translated string - * - * Since: 2.18 - */ -const gchar * -g_dgettext (const gchar *domain, - const gchar *msgid) -{ - if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) - return msgid; - - return dgettext (domain, msgid); -} - -/** - * g_dcgettext: - * @domain: (allow-none): the translation domain to use, or %NULL to use - * the domain set with textdomain() - * @msgid: message to translate - * @category: a locale category - * - * This is a variant of g_dgettext() that allows specifying a locale - * category instead of always using %LC_MESSAGES. See g_dgettext() for - * more information about how this functions differs from calling - * dcgettext() directly. - * - * Returns: the translated string for the given locale category - * - * Since: 2.26 - */ -const gchar * -g_dcgettext (const gchar *domain, - const gchar *msgid, - int category) -{ - if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) - return msgid; - - return dcgettext (domain, msgid, category); -} - -/** - * g_dngettext: - * @domain: the translation domain to use, or %NULL to use - * the domain set with textdomain() - * @msgid: message to translate - * @msgid_plural: plural form of the message - * @n: the quantity for which translation is needed - * - * This function is a wrapper of dngettext() which does not translate - * the message if the default domain as set with textdomain() has no - * translations for the current locale. - * - * See g_dgettext() for details of how this differs from dngettext() - * proper. - * - * Returns: The translated string - * - * Since: 2.18 - */ -const gchar * -g_dngettext (const gchar *domain, - const gchar *msgid, - const gchar *msgid_plural, - gulong n) -{ - if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) - return n == 1 ? msgid : msgid_plural; - - return dngettext (domain, msgid, msgid_plural, n); -} diff --git a/deps/glib/gstrfuncs.h b/deps/glib/gstrfuncs.h deleted file mode 100644 index 3b429f6d..00000000 --- a/deps/glib/gstrfuncs.h +++ /dev/null @@ -1,267 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_STRFUNCS_H__ -#define __G_STRFUNCS_H__ - -#include <stdarg.h> -#include <glib/gmacros.h> -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -/* Functions like the ones in <ctype.h> that are not affected by locale. */ -typedef enum { - G_ASCII_ALNUM = 1 << 0, - G_ASCII_ALPHA = 1 << 1, - G_ASCII_CNTRL = 1 << 2, - G_ASCII_DIGIT = 1 << 3, - G_ASCII_GRAPH = 1 << 4, - G_ASCII_LOWER = 1 << 5, - G_ASCII_PRINT = 1 << 6, - G_ASCII_PUNCT = 1 << 7, - G_ASCII_SPACE = 1 << 8, - G_ASCII_UPPER = 1 << 9, - G_ASCII_XDIGIT = 1 << 10 -} GAsciiType; - -GLIB_VAR const guint16 * const g_ascii_table; - -#define g_ascii_isalnum(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_ALNUM) != 0) - -#define g_ascii_isalpha(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_ALPHA) != 0) - -#define g_ascii_iscntrl(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_CNTRL) != 0) - -#define g_ascii_isdigit(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_DIGIT) != 0) - -#define g_ascii_isgraph(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_GRAPH) != 0) - -#define g_ascii_islower(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_LOWER) != 0) - -#define g_ascii_isprint(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0) - -#define g_ascii_ispunct(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_PUNCT) != 0) - -#define g_ascii_isspace(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_SPACE) != 0) - -#define g_ascii_isupper(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_UPPER) != 0) - -#define g_ascii_isxdigit(c) \ - ((g_ascii_table[(guchar) (c)] & G_ASCII_XDIGIT) != 0) - -gchar g_ascii_tolower (gchar c) G_GNUC_CONST; -gchar g_ascii_toupper (gchar c) G_GNUC_CONST; - -gint g_ascii_digit_value (gchar c) G_GNUC_CONST; -gint g_ascii_xdigit_value (gchar c) G_GNUC_CONST; - -/* String utility functions that modify a string argument or - * return a constant string that must not be freed. - */ -#define G_STR_DELIMITERS "_-|> <." -gchar* g_strdelimit (gchar *string, - const gchar *delimiters, - gchar new_delimiter); -gchar* g_strcanon (gchar *string, - const gchar *valid_chars, - gchar substitutor); -const gchar * g_strerror (gint errnum) G_GNUC_CONST; -const gchar * g_strsignal (gint signum) G_GNUC_CONST; -gchar * g_strreverse (gchar *string); -gsize g_strlcpy (gchar *dest, - const gchar *src, - gsize dest_size); -gsize g_strlcat (gchar *dest, - const gchar *src, - gsize dest_size); -gchar * g_strstr_len (const gchar *haystack, - gssize haystack_len, - const gchar *needle); -gchar * g_strrstr (const gchar *haystack, - const gchar *needle); -gchar * g_strrstr_len (const gchar *haystack, - gssize haystack_len, - const gchar *needle); - -gboolean g_str_has_suffix (const gchar *str, - const gchar *suffix); -gboolean g_str_has_prefix (const gchar *str, - const gchar *prefix); - -/* String to/from double conversion functions */ - -gdouble g_strtod (const gchar *nptr, - gchar **endptr); -gdouble g_ascii_strtod (const gchar *nptr, - gchar **endptr); -guint64 g_ascii_strtoull (const gchar *nptr, - gchar **endptr, - guint base); -gint64 g_ascii_strtoll (const gchar *nptr, - gchar **endptr, - guint base); -/* 29 bytes should enough for all possible values that - * g_ascii_dtostr can produce. - * Then add 10 for good measure */ -#define G_ASCII_DTOSTR_BUF_SIZE (29 + 10) -gchar * g_ascii_dtostr (gchar *buffer, - gint buf_len, - gdouble d); -gchar * g_ascii_formatd (gchar *buffer, - gint buf_len, - const gchar *format, - gdouble d); - -/* removes leading spaces */ -gchar* g_strchug (gchar *string); -/* removes trailing spaces */ -gchar* g_strchomp (gchar *string); -/* removes leading & trailing spaces */ -#define g_strstrip( string ) g_strchomp (g_strchug (string)) - -gint g_ascii_strcasecmp (const gchar *s1, - const gchar *s2); -gint g_ascii_strncasecmp (const gchar *s1, - const gchar *s2, - gsize n); -gchar* g_ascii_strdown (const gchar *str, - gssize len) G_GNUC_MALLOC; -gchar* g_ascii_strup (const gchar *str, - gssize len) G_GNUC_MALLOC; - -#ifndef G_DISABLE_DEPRECATED - -/* The following four functions are deprecated and will be removed in - * the next major release. They use the locale-specific tolower and - * toupper, which is almost never the right thing. - */ - -gint g_strcasecmp (const gchar *s1, - const gchar *s2); -gint g_strncasecmp (const gchar *s1, - const gchar *s2, - guint n); -gchar* g_strdown (gchar *string); -gchar* g_strup (gchar *string); - -#endif /* G_DISABLE_DEPRECATED */ - -/* String utility functions that return a newly allocated string which - * ought to be freed with g_free from the caller at some point. - */ -gchar* g_strdup (const gchar *str) G_GNUC_MALLOC; -gchar* g_strdup_printf (const gchar *format, - ...) G_GNUC_PRINTF (1, 2) G_GNUC_MALLOC; -gchar* g_strdup_vprintf (const gchar *format, - va_list args) G_GNUC_MALLOC; -gchar* g_strndup (const gchar *str, - gsize n) G_GNUC_MALLOC; -gchar* g_strnfill (gsize length, - gchar fill_char) G_GNUC_MALLOC; -gchar* g_strconcat (const gchar *string1, - ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; -gchar* g_strjoin (const gchar *separator, - ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; - -/* Make a copy of a string interpreting C string -style escape - * sequences. Inverse of g_strescape. The recognized sequences are \b - * \f \n \r \t \\ \" and the octal format. - */ -gchar* g_strcompress (const gchar *source) G_GNUC_MALLOC; - -/* Copy a string escaping nonprintable characters like in C strings. - * Inverse of g_strcompress. The exceptions parameter, if non-NULL, points - * to a string containing characters that are not to be escaped. - * - * Deprecated API: gchar* g_strescape (const gchar *source); - * Luckily this function wasn't used much, using NULL as second parameter - * provides mostly identical semantics. - */ -gchar* g_strescape (const gchar *source, - const gchar *exceptions) G_GNUC_MALLOC; - -gpointer g_memdup (gconstpointer mem, - guint byte_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(2); - -/* NULL terminated string arrays. - * g_strsplit(), g_strsplit_set() split up string into max_tokens tokens - * at delim and return a newly allocated string array. - * g_strjoinv() concatenates all of str_array's strings, sliding in an - * optional separator, the returned string is newly allocated. - * g_strfreev() frees the array itself and all of its strings. - * g_strdupv() copies a NULL-terminated array of strings - * g_strv_length() returns the length of a NULL-terminated array of strings - */ -gchar** g_strsplit (const gchar *string, - const gchar *delimiter, - gint max_tokens) G_GNUC_MALLOC; -gchar ** g_strsplit_set (const gchar *string, - const gchar *delimiters, - gint max_tokens) G_GNUC_MALLOC; -gchar* g_strjoinv (const gchar *separator, - gchar **str_array) G_GNUC_MALLOC; -void g_strfreev (gchar **str_array); -gchar** g_strdupv (gchar **str_array) G_GNUC_MALLOC; -guint g_strv_length (gchar **str_array); - -gchar* g_stpcpy (gchar *dest, - const char *src); - -const gchar * g_strip_context (const gchar *msgid, - const gchar *msgval) G_GNUC_FORMAT(1); - -const gchar * g_dgettext (const gchar *domain, - const gchar *msgid) G_GNUC_FORMAT(2); -const gchar * g_dcgettext (const gchar *domain, - const gchar *msgid, - int category) G_GNUC_FORMAT(2); -const gchar * g_dngettext (const gchar *domain, - const gchar *msgid, - const gchar *msgid_plural, - gulong n) G_GNUC_FORMAT(3); -const gchar * g_dpgettext (const gchar *domain, - const gchar *msgctxtid, - gsize msgidoffset) G_GNUC_FORMAT(2); -const gchar * g_dpgettext2 (const gchar *domain, - const gchar *context, - const gchar *msgid) G_GNUC_FORMAT(3); - -G_END_DECLS - -#endif /* __G_STRFUNCS_H__ */ diff --git a/deps/glib/gstring.c b/deps/glib/gstring.c deleted file mode 100644 index 5a65e46d..00000000 --- a/deps/glib/gstring.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <ctype.h> - -#include "gstring.h" - -#include "gprintf.h" - - -/** - * SECTION:string_chunks - * @title: String Chunks - * @short_description: efficient storage of groups of strings - * - * String chunks are used to store groups of strings. Memory is - * allocated in blocks, and as strings are added to the #GStringChunk - * they are copied into the next free position in a block. When a block - * is full a new block is allocated. - * - * When storing a large number of strings, string chunks are more - * efficient than using g_strdup() since fewer calls to malloc() are - * needed, and less memory is wasted in memory allocation overheads. - * - * By adding strings with g_string_chunk_insert_const() it is also - * possible to remove duplicates. - * - * To create a new #GStringChunk use g_string_chunk_new(). - * - * To add strings to a #GStringChunk use g_string_chunk_insert(). - * - * To add strings to a #GStringChunk, but without duplicating strings - * which are already in the #GStringChunk, use - * g_string_chunk_insert_const(). - * - * To free the entire #GStringChunk use g_string_chunk_free(). It is - * not possible to free individual strings. - **/ - -/** - * GStringChunk: - * - * An opaque data structure representing String Chunks. It should only - * be accessed by using the following functions. - **/ -struct _GStringChunk -{ - GHashTable *const_table; - GSList *storage_list; - gsize storage_next; - gsize this_size; - gsize default_size; -}; - -/* Hash Functions. - */ - -/** - * g_str_equal: - * @v1: a key - * @v2: a key to compare with @v1 - * - * Compares two strings for byte-by-byte equality and returns %TRUE - * if they are equal. It can be passed to g_hash_table_new() as the - * @key_equal_func parameter, when using strings as keys in a #GHashTable. - * - * Note that this function is primarily meant as a hash table comparison - * function. For a general-purpose, %NULL-safe string comparison function, - * see g_strcmp0(). - * - * Returns: %TRUE if the two keys match - */ -gboolean -g_str_equal (gconstpointer v1, - gconstpointer v2) -{ - const gchar *string1 = v1; - const gchar *string2 = v2; - - return strcmp (string1, string2) == 0; -} - -/** - * g_str_hash: - * @v: a string key - * - * Converts a string to a hash value. - * - * This function implements the widely used "djb" hash apparently posted - * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit - * unsigned hash value starts at 5381 and for each byte 'c' in the - * string, is updated: <literal>hash = hash * 33 + c</literal>. This - * function uses the signed value of each byte. - * - * It can be passed to g_hash_table_new() as the @hash_func parameter, - * when using strings as keys in a #GHashTable. - * - * Returns: a hash value corresponding to the key - **/ -guint -g_str_hash (gconstpointer v) -{ - const signed char *p; - guint32 h = 5381; - - for (p = v; *p != '\0'; p++) - h = (h << 5) + h + *p; - - return h; -} - -#define MY_MAXSIZE ((gsize)-1) - -static inline gsize -nearest_power (gsize base, gsize num) -{ - if (num > MY_MAXSIZE / 2) - { - return MY_MAXSIZE; - } - else - { - gsize n = base; - - while (n < num) - n <<= 1; - - return n; - } -} - -/* String Chunks. - */ - -/** - * g_string_chunk_new: - * @size: the default size of the blocks of memory which are - * allocated to store the strings. If a particular string - * is larger than this default size, a larger block of - * memory will be allocated for it. - * - * Creates a new #GStringChunk. - * - * Returns: a new #GStringChunk - */ -GStringChunk* -g_string_chunk_new (gsize size) -{ - GStringChunk *new_chunk = g_new (GStringChunk, 1); - gsize actual_size = 1; - - actual_size = nearest_power (1, size); - - new_chunk->const_table = NULL; - new_chunk->storage_list = NULL; - new_chunk->storage_next = actual_size; - new_chunk->default_size = actual_size; - new_chunk->this_size = actual_size; - - return new_chunk; -} - -/** - * g_string_chunk_free: - * @chunk: a #GStringChunk - * - * Frees all memory allocated by the #GStringChunk. - * After calling g_string_chunk_free() it is not safe to - * access any of the strings which were contained within it. - */ -void -g_string_chunk_free (GStringChunk *chunk) -{ - GSList *tmp_list; - - g_return_if_fail (chunk != NULL); - - if (chunk->storage_list) - { - for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) - g_free (tmp_list->data); - - g_slist_free (chunk->storage_list); - } - - if (chunk->const_table) - g_hash_table_destroy (chunk->const_table); - - g_free (chunk); -} - -/** - * g_string_chunk_clear: - * @chunk: a #GStringChunk - * - * Frees all strings contained within the #GStringChunk. - * After calling g_string_chunk_clear() it is not safe to - * access any of the strings which were contained within it. - * - * Since: 2.14 - */ -void -g_string_chunk_clear (GStringChunk *chunk) -{ - GSList *tmp_list; - - g_return_if_fail (chunk != NULL); - - if (chunk->storage_list) - { - for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) - g_free (tmp_list->data); - - g_slist_free (chunk->storage_list); - - chunk->storage_list = NULL; - chunk->storage_next = chunk->default_size; - chunk->this_size = chunk->default_size; - } - - if (chunk->const_table) - g_hash_table_remove_all (chunk->const_table); -} - -/** - * g_string_chunk_insert: - * @chunk: a #GStringChunk - * @string: the string to add - * - * Adds a copy of @string to the #GStringChunk. - * It returns a pointer to the new copy of the string - * in the #GStringChunk. The characters in the string - * can be changed, if necessary, though you should not - * change anything after the end of the string. - * - * Unlike g_string_chunk_insert_const(), this function - * does not check for duplicates. Also strings added - * with g_string_chunk_insert() will not be searched - * by g_string_chunk_insert_const() when looking for - * duplicates. - * - * Returns: a pointer to the copy of @string within - * the #GStringChunk - */ -gchar* -g_string_chunk_insert (GStringChunk *chunk, - const gchar *string) -{ - g_return_val_if_fail (chunk != NULL, NULL); - - return g_string_chunk_insert_len (chunk, string, -1); -} - -/** - * g_string_chunk_insert_const: - * @chunk: a #GStringChunk - * @string: the string to add - * - * Adds a copy of @string to the #GStringChunk, unless the same - * string has already been added to the #GStringChunk with - * g_string_chunk_insert_const(). - * - * This function is useful if you need to copy a large number - * of strings but do not want to waste space storing duplicates. - * But you must remember that there may be several pointers to - * the same string, and so any changes made to the strings - * should be done very carefully. - * - * Note that g_string_chunk_insert_const() will not return a - * pointer to a string added with g_string_chunk_insert(), even - * if they do match. - * - * Returns: a pointer to the new or existing copy of @string - * within the #GStringChunk - */ -gchar* -g_string_chunk_insert_const (GStringChunk *chunk, - const gchar *string) -{ - 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 (chunk, string); - g_hash_table_insert (chunk->const_table, lookup, lookup); - } - - return lookup; -} - -/** - * g_string_chunk_insert_len: - * @chunk: a #GStringChunk - * @string: bytes to insert - * @len: number of bytes of @string to insert, or -1 to insert a - * nul-terminated string - * - * Adds a copy of the first @len bytes of @string to the #GStringChunk. - * The copy is nul-terminated. - * - * Since this function does not stop at nul bytes, it is the caller's - * responsibility to ensure that @string has at least @len addressable - * bytes. - * - * The characters in the returned string can be changed, if necessary, - * though you should not change anything after the end of the string. - * - * Return value: a pointer to the copy of @string within the #GStringChunk - * - * Since: 2.4 - */ -gchar* -g_string_chunk_insert_len (GStringChunk *chunk, - const gchar *string, - gssize len) -{ - gssize size; - gchar* pos; - - g_return_val_if_fail (chunk != NULL, NULL); - - if (len < 0) - size = strlen (string); - else - size = len; - - if ((chunk->storage_next + size + 1) > chunk->this_size) - { - gsize new_size = nearest_power (chunk->default_size, size + 1); - - chunk->storage_list = g_slist_prepend (chunk->storage_list, - g_new (gchar, new_size)); - - chunk->this_size = new_size; - chunk->storage_next = 0; - } - - pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next; - - *(pos + size) = '\0'; - - memcpy (pos, string, size); - - chunk->storage_next += size + 1; - - return pos; -} - -/* Strings. - */ -static void -g_string_maybe_expand (GString* string, - gsize len) -{ - if (string->len + len >= string->allocated_len) - { - string->allocated_len = nearest_power (1, string->len + len + 1); - string->str = g_realloc (string->str, string->allocated_len); - } -} - -/** - * g_string_sized_new: - * @dfl_size: the default size of the space allocated to - * hold the string - * - * Creates a new #GString, with enough space for @dfl_size - * bytes. This is useful if you are going to add a lot of - * text to the string and don't want it to be reallocated - * too often. - * - * Returns: the new #GString - */ -GString* -g_string_sized_new (gsize dfl_size) -{ - GString *string = g_slice_new (GString); - - string->allocated_len = 0; - string->len = 0; - string->str = NULL; - - g_string_maybe_expand (string, MAX (dfl_size, 2)); - string->str[0] = 0; - - return string; -} - -/** - * g_string_new: - * @init: the initial text to copy into the string - * - * Creates a new #GString, initialized with the given string. - * - * Returns: the new #GString - */ -GString* -g_string_new (const gchar *init) -{ - GString *string; - - if (init == NULL || *init == '\0') - string = g_string_sized_new (2); - else - { - gint len; - - len = strlen (init); - string = g_string_sized_new (len + 2); - - g_string_append_len (string, init, len); - } - - return string; -} - -/** - * g_string_new_len: - * @init: initial contents of the string - * @len: length of @init to use - * - * Creates a new #GString with @len bytes of the @init buffer. - * Because a length is provided, @init need not be nul-terminated, - * and can contain embedded nul bytes. - * - * Since this function does not stop at nul bytes, it is the caller's - * responsibility to ensure that @init has at least @len addressable - * bytes. - * - * Returns: a new #GString - */ -GString* -g_string_new_len (const gchar *init, - gssize len) -{ - GString *string; - - if (len < 0) - return g_string_new (init); - else - { - string = g_string_sized_new (len); - - if (init) - g_string_append_len (string, init, len); - - return string; - } -} - -/** - * g_string_free: - * @string: a #GString - * @free_segment: if %TRUE the actual character data is freed as well - * - * Frees the memory allocated for the #GString. - * If @free_segment is %TRUE it also frees the character data. If - * it's %FALSE, the caller gains ownership of the buffer and must - * free it after use with g_free(). - * - * Returns: the character data of @string - * (i.e. %NULL if @free_segment is %TRUE) - */ -gchar* -g_string_free (GString *string, - gboolean free_segment) -{ - gchar *segment; - - g_return_val_if_fail (string != NULL, NULL); - - if (free_segment) - { - g_free (string->str); - segment = NULL; - } - else - segment = string->str; - - g_slice_free (GString, string); - - return segment; -} - -/** - * g_string_equal: - * @v: a #GString - * @v2: another #GString - * - * Compares two strings for equality, returning %TRUE if they are equal. - * For use with #GHashTable. - * - * Returns: %TRUE if they strings are the same length and contain the - * same bytes - */ -gboolean -g_string_equal (const GString *v, - const GString *v2) -{ - gchar *p, *q; - GString *string1 = (GString *) v; - GString *string2 = (GString *) v2; - gsize i = string1->len; - - if (i != string2->len) - return FALSE; - - p = string1->str; - q = string2->str; - while (i) - { - if (*p != *q) - return FALSE; - p++; - q++; - i--; - } - return TRUE; -} - -/** - * g_string_hash: - * @str: a string to hash - * - * Creates a hash code for @str; for use with #GHashTable. - * - * Returns: hash code for @str - */ -/* 31 bit hash function */ -guint -g_string_hash (const GString *str) -{ - const gchar *p = str->str; - gsize n = str->len; - guint h = 0; - - while (n--) - { - h = (h << 5) - h + *p; - p++; - } - - return h; -} - -/** - * g_string_assign: - * @string: the destination #GString. Its current contents - * are destroyed. - * @rval: the string to copy into @string - * - * Copies the bytes from a string into a #GString, - * destroying any previous contents. It is rather like - * the standard strcpy() function, except that you do not - * have to worry about having enough space to copy the string. - * - * Returns: @string - */ -GString* -g_string_assign (GString *string, - const gchar *rval) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (rval != NULL, string); - - /* Make sure assigning to itself doesn't corrupt the string. */ - if (string->str != rval) - { - /* Assigning from substring should be ok since g_string_truncate - does not realloc. */ - g_string_truncate (string, 0); - g_string_append (string, rval); - } - - return string; -} - -/** - * g_string_truncate: - * @string: a #GString - * @len: the new size of @string - * - * Cuts off the end of the GString, leaving the first @len bytes. - * - * Returns: @string - */ -GString* -g_string_truncate (GString *string, - gsize len) -{ - g_return_val_if_fail (string != NULL, NULL); - - string->len = MIN (len, string->len); - string->str[string->len] = 0; - - return string; -} - -/** - * g_string_set_size: - * @string: a #GString - * @len: the new length - * - * Sets the length of a #GString. If the length is less than - * the current length, the string will be truncated. If the - * length is greater than the current length, the contents - * of the newly added area are undefined. (However, as - * always, string->str[string->len] will be a nul byte.) - * - * Return value: @string - **/ -GString* -g_string_set_size (GString *string, - gsize len) -{ - g_return_val_if_fail (string != NULL, NULL); - - if (len >= string->allocated_len) - g_string_maybe_expand (string, len - string->len); - - string->len = len; - string->str[len] = 0; - - return string; -} - -/** - * g_string_insert_len: - * @string: a #GString - * @pos: position in @string where insertion should - * happen, or -1 for at the end - * @val: bytes to insert - * @len: number of bytes of @val to insert - * - * Inserts @len bytes of @val into @string at @pos. - * Because @len is provided, @val may contain embedded - * nuls and need not be nul-terminated. If @pos is -1, - * bytes are inserted at the end of the string. - * - * Since this function does not stop at nul bytes, it is - * the caller's responsibility to ensure that @val has at - * least @len addressable bytes. - * - * Returns: @string - */ -GString* -g_string_insert_len (GString *string, - gssize pos, - const gchar *val, - gssize len) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (len == 0 || val != NULL, string); - - if (len == 0) - return string; - - if (len < 0) - len = strlen (val); - - if (pos < 0) - pos = string->len; - else - g_return_val_if_fail (pos <= string->len, string); - - /* Check whether val represents a substring of string. This test - probably violates chapter and verse of the C standards, since - ">=" and "<=" are only valid when val really is a substring. - In practice, it will work on modern archs. */ - if (val >= string->str && val <= string->str + string->len) - { - gsize offset = val - string->str; - gsize precount = 0; - - g_string_maybe_expand (string, len); - val = string->str + offset; - /* At this point, val is valid again. */ - - /* Open up space where we are going to insert. */ - if (pos < string->len) - g_memmove (string->str + pos + len, string->str + pos, string->len - pos); - - /* Move the source part before the gap, if any. */ - if (offset < pos) - { - precount = MIN (len, pos - offset); - memcpy (string->str + pos, val, precount); - } - - /* Move the source part after the gap, if any. */ - if (len > precount) - memcpy (string->str + pos + precount, - val + /* Already moved: */ precount + /* Space opened up: */ len, - len - precount); - } - else - { - g_string_maybe_expand (string, len); - - /* If we aren't appending at the end, move a hunk - * of the old string to the end, opening up space - */ - if (pos < string->len) - g_memmove (string->str + pos + len, string->str + pos, string->len - pos); - - /* insert the new string */ - if (len == 1) - string->str[pos] = *val; - else - memcpy (string->str + pos, val, len); - } - - string->len += len; - - string->str[string->len] = 0; - - return string; -} - -#define SUB_DELIM_CHARS "!$&'()*+,;=" - -/** - * g_string_append: - * @string: a #GString - * @val: the string to append onto the end of @string - * - * Adds a string onto the end of a #GString, expanding - * it if necessary. - * - * Returns: @string - */ -GString* -g_string_append (GString *string, - const gchar *val) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (val != NULL, string); - - return g_string_insert_len (string, -1, val, -1); -} - -/** - * g_string_append_len: - * @string: a #GString - * @val: bytes to append - * @len: number of bytes of @val to use - * - * Appends @len bytes of @val to @string. Because @len is - * provided, @val may contain embedded nuls and need not - * be nul-terminated. - * - * Since this function does not stop at nul bytes, it is - * the caller's responsibility to ensure that @val has at - * least @len addressable bytes. - * - * Returns: @string - */ -GString* -g_string_append_len (GString *string, - const gchar *val, - gssize len) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (len == 0 || val != NULL, string); - - return g_string_insert_len (string, -1, val, len); -} - -/** - * g_string_append_c: - * @string: a #GString - * @c: the byte to append onto the end of @string - * - * Adds a byte onto the end of a #GString, expanding - * it if necessary. - * - * Returns: @string - */ -#undef g_string_append_c -GString* -g_string_append_c (GString *string, - gchar c) -{ - g_return_val_if_fail (string != NULL, NULL); - - return g_string_insert_c (string, -1, c); -} - -/** - * g_string_append_unichar: - * @string: a #GString - * @wc: a Unicode character - * - * Converts a Unicode character into UTF-8, and appends it - * to the string. - * - * Return value: @string - **/ -GString* -g_string_append_unichar (GString *string, - gunichar wc) -{ - g_return_val_if_fail (string != NULL, NULL); - - return g_string_insert_unichar (string, -1, wc); -} - -/** - * g_string_prepend: - * @string: a #GString - * @val: the string to prepend on the start of @string - * - * Adds a string on to the start of a #GString, - * expanding it if necessary. - * - * Returns: @string - */ -GString* -g_string_prepend (GString *string, - const gchar *val) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (val != NULL, string); - - return g_string_insert_len (string, 0, val, -1); -} - -/** - * g_string_prepend_len: - * @string: a #GString - * @val: bytes to prepend - * @len: number of bytes in @val to prepend - * - * Prepends @len bytes of @val to @string. - * Because @len is provided, @val may contain - * embedded nuls and need not be nul-terminated. - * - * Since this function does not stop at nul bytes, - * it is the caller's responsibility to ensure that - * @val has at least @len addressable bytes. - * - * Returns: @string - */ -GString* -g_string_prepend_len (GString *string, - const gchar *val, - gssize len) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (val != NULL, string); - - return g_string_insert_len (string, 0, val, len); -} - -/** - * g_string_prepend_c: - * @string: a #GString - * @c: the byte to prepend on the start of the #GString - * - * Adds a byte onto the start of a #GString, - * expanding it if necessary. - * - * Returns: @string - */ -GString* -g_string_prepend_c (GString *string, - gchar c) -{ - g_return_val_if_fail (string != NULL, NULL); - - return g_string_insert_c (string, 0, c); -} - -/** - * g_string_prepend_unichar: - * @string: a #GString - * @wc: a Unicode character - * - * Converts a Unicode character into UTF-8, and prepends it - * to the string. - * - * Return value: @string - **/ -GString* -g_string_prepend_unichar (GString *string, - gunichar wc) -{ - g_return_val_if_fail (string != NULL, NULL); - - return g_string_insert_unichar (string, 0, wc); -} - -/** - * g_string_insert: - * @string: a #GString - * @pos: the position to insert the copy of the string - * @val: the string to insert - * - * Inserts a copy of a string into a #GString, - * expanding it if necessary. - * - * Returns: @string - */ -GString* -g_string_insert (GString *string, - gssize pos, - const gchar *val) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (val != NULL, string); - if (pos >= 0) - g_return_val_if_fail (pos <= string->len, string); - - return g_string_insert_len (string, pos, val, -1); -} - -/** - * g_string_insert_c: - * @string: a #GString - * @pos: the position to insert the byte - * @c: the byte to insert - * - * Inserts a byte into a #GString, expanding it if necessary. - * - * Returns: @string - */ -GString* -g_string_insert_c (GString *string, - gssize pos, - gchar c) -{ - g_return_val_if_fail (string != NULL, NULL); - - g_string_maybe_expand (string, 1); - - if (pos < 0) - pos = string->len; - else - g_return_val_if_fail (pos <= string->len, string); - - /* If not just an append, move the old stuff */ - if (pos < string->len) - 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 string; -} - -/** - * g_string_insert_unichar: - * @string: a #GString - * @pos: the position at which to insert character, or -1 to - * append at the end of the string - * @wc: a Unicode character - * - * Converts a Unicode character into UTF-8, and insert it - * into the string at the given position. - * - * Return value: @string - **/ -GString* -g_string_insert_unichar (GString *string, - gssize pos, - gunichar wc) -{ - gint charlen, first, i; - gchar *dest; - - g_return_val_if_fail (string != NULL, NULL); - - /* Code copied from g_unichar_to_utf() */ - if (wc < 0x80) - { - first = 0; - charlen = 1; - } - else if (wc < 0x800) - { - first = 0xc0; - charlen = 2; - } - else if (wc < 0x10000) - { - first = 0xe0; - charlen = 3; - } - else if (wc < 0x200000) - { - first = 0xf0; - charlen = 4; - } - else if (wc < 0x4000000) - { - first = 0xf8; - charlen = 5; - } - else - { - first = 0xfc; - charlen = 6; - } - /* End of copied code */ - - g_string_maybe_expand (string, charlen); - - if (pos < 0) - pos = string->len; - else - g_return_val_if_fail (pos <= string->len, string); - - /* If not just an append, move the old stuff */ - if (pos < string->len) - g_memmove (string->str + pos + charlen, string->str + pos, string->len - pos); - - dest = string->str + pos; - /* Code copied from g_unichar_to_utf() */ - for (i = charlen - 1; i > 0; --i) - { - dest[i] = (wc & 0x3f) | 0x80; - wc >>= 6; - } - dest[0] = wc | first; - /* End of copied code */ - - string->len += charlen; - - string->str[string->len] = 0; - - return string; -} - -/** - * g_string_overwrite: - * @string: a #GString - * @pos: the position at which to start overwriting - * @val: the string that will overwrite the @string starting at @pos - * - * Overwrites part of a string, lengthening it if necessary. - * - * Return value: @string - * - * Since: 2.14 - **/ -GString * -g_string_overwrite (GString *string, - gsize pos, - const gchar *val) -{ - g_return_val_if_fail (val != NULL, string); - return g_string_overwrite_len (string, pos, val, strlen (val)); -} - -/** - * g_string_overwrite_len: - * @string: a #GString - * @pos: the position at which to start overwriting - * @val: the string that will overwrite the @string starting at @pos - * @len: the number of bytes to write from @val - * - * Overwrites part of a string, lengthening it if necessary. - * This function will work with embedded nuls. - * - * Return value: @string - * - * Since: 2.14 - **/ -GString * -g_string_overwrite_len (GString *string, - gsize pos, - const gchar *val, - gssize len) -{ - gsize end; - - g_return_val_if_fail (string != NULL, NULL); - - if (!len) - return string; - - g_return_val_if_fail (val != NULL, string); - g_return_val_if_fail (pos <= string->len, string); - - if (len < 0) - len = strlen (val); - - end = pos + len; - - if (end > string->len) - g_string_maybe_expand (string, end - string->len); - - memcpy (string->str + pos, val, len); - - if (end > string->len) - { - string->str[end] = '\0'; - string->len = end; - } - - return string; -} - -/** - * g_string_erase: - * @string: a #GString - * @pos: the position of the content to remove - * @len: the number of bytes to remove, or -1 to remove all - * following bytes - * - * Removes @len bytes from a #GString, starting at position @pos. - * The rest of the #GString is shifted down to fill the gap. - * - * Returns: @string - */ -GString* -g_string_erase (GString *string, - gssize pos, - gssize len) -{ - g_return_val_if_fail (string != NULL, NULL); - g_return_val_if_fail (pos >= 0, string); - g_return_val_if_fail (pos <= string->len, string); - - if (len < 0) - len = string->len - pos; - else - { - g_return_val_if_fail (pos + len <= string->len, string); - - 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 string; -} - -/** - * g_string_ascii_down: - * @string: a GString - * - * Converts all upper case ASCII letters to lower case ASCII letters. - * - * Return value: passed-in @string pointer, with all the upper case - * characters converted to lower case in place, with - * semantics that exactly match g_ascii_tolower(). - **/ -GString* -g_string_ascii_down (GString *string) -{ - gchar *s; - gint n; - - g_return_val_if_fail (string != NULL, NULL); - - n = string->len; - s = string->str; - - while (n) - { - *s = g_ascii_tolower (*s); - s++; - n--; - } - - return string; -} - -/** - * g_string_ascii_up: - * @string: a GString - * - * Converts all lower case ASCII letters to upper case ASCII letters. - * - * Return value: passed-in @string pointer, with all the lower case - * characters converted to upper case in place, with - * semantics that exactly match g_ascii_toupper(). - **/ -GString* -g_string_ascii_up (GString *string) -{ - gchar *s; - gint n; - - g_return_val_if_fail (string != NULL, NULL); - - n = string->len; - s = string->str; - - while (n) - { - *s = g_ascii_toupper (*s); - s++; - n--; - } - - return string; -} - -/** - * g_string_down: - * @string: a #GString - * - * Converts a #GString to lowercase. - * - * Returns: the #GString. - * - * Deprecated:2.2: This function uses the locale-specific - * tolower() function, which is almost never the right thing. - * Use g_string_ascii_down() or g_utf8_strdown() instead. - */ -GString* -g_string_down (GString *string) -{ - guchar *s; - glong n; - - g_return_val_if_fail (string != NULL, NULL); - - n = string->len; - s = (guchar *) string->str; - - while (n) - { - if (isupper (*s)) - *s = tolower (*s); - s++; - n--; - } - - return string; -} - -/** - * g_string_up: - * @string: a #GString - * - * Converts a #GString to uppercase. - * - * Return value: @string - * - * Deprecated:2.2: This function uses the locale-specific - * toupper() function, which is almost never the right thing. - * Use g_string_ascii_up() or g_utf8_strup() instead. - **/ -GString* -g_string_up (GString *string) -{ - guchar *s; - glong n; - - g_return_val_if_fail (string != NULL, NULL); - - n = string->len; - s = (guchar *) string->str; - - while (n) - { - if (islower (*s)) - *s = toupper (*s); - s++; - n--; - } - - return string; -} - -/** - * g_string_append_vprintf: - * @string: a #GString - * @format: the string format. See the printf() documentation - * @args: the list of arguments to insert in the output - * - * Appends a formatted string onto the end of a #GString. - * This function is similar to g_string_append_printf() - * except that the arguments to the format string are passed - * as a va_list. - * - * Since: 2.14 - */ -void -g_string_append_vprintf (GString *string, - const gchar *format, - va_list args) -{ - gchar *buf; - gint len; - - g_return_if_fail (string != NULL); - g_return_if_fail (format != NULL); - - len = g_vasprintf (&buf, format, args); - - if (len >= 0) - { - g_string_maybe_expand (string, len); - memcpy (string->str + string->len, buf, len + 1); - string->len += len; - g_free (buf); - } -} - -/** - * g_string_vprintf: - * @string: a #GString - * @format: the string format. See the printf() documentation - * @args: the parameters to insert into the format string - * - * Writes a formatted string into a #GString. - * This function is similar to g_string_printf() except that - * the arguments to the format string are passed as a va_list. - * - * Since: 2.14 - */ -void -g_string_vprintf (GString *string, - const gchar *format, - va_list args) -{ - g_string_truncate (string, 0); - g_string_append_vprintf (string, format, args); -} - -/** - * g_string_sprintf: - * @string: a #GString - * @format: the string format. See the sprintf() documentation - * @...: the parameters to insert into the format string - * - * Writes a formatted string into a #GString. - * This is similar to the standard sprintf() function, - * except that the #GString buffer automatically expands - * to contain the results. The previous contents of the - * #GString are destroyed. - * - * Deprecated: This function has been renamed to g_string_printf(). - */ - -/** - * g_string_printf: - * @string: a #GString - * @format: the string format. See the printf() documentation - * @...: the parameters to insert into the format string - * - * Writes a formatted string into a #GString. - * This is similar to the standard sprintf() function, - * except that the #GString buffer automatically expands - * to contain the results. The previous contents of the - * #GString are destroyed. - */ -void -g_string_printf (GString *string, - const gchar *format, - ...) -{ - va_list args; - - g_string_truncate (string, 0); - - va_start (args, format); - g_string_append_vprintf (string, format, args); - va_end (args); -} - -/** - * g_string_sprintfa: - * @string: a #GString - * @format: the string format. See the sprintf() documentation - * @...: the parameters to insert into the format string - * - * Appends a formatted string onto the end of a #GString. - * This function is similar to g_string_sprintf() except that - * the text is appended to the #GString. - * - * Deprecated: This function has been renamed to g_string_append_printf() - */ - -/** - * g_string_append_printf: - * @string: a #GString - * @format: the string format. See the printf() documentation - * @...: the parameters to insert into the format string - * - * Appends a formatted string onto the end of a #GString. - * This function is similar to g_string_printf() except - * that the text is appended to the #GString. - */ -void -g_string_append_printf (GString *string, - const gchar *format, - ...) -{ - va_list args; - - va_start (args, format); - g_string_append_vprintf (string, format, args); - va_end (args); -} diff --git a/deps/glib/gstring.h b/deps/glib/gstring.h deleted file mode 100644 index b7a1eacb..00000000 --- a/deps/glib/gstring.h +++ /dev/null @@ -1,184 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_STRING_H__ -#define __G_STRING_H__ - -#include <glib/gtypes.h> -#include <glib/gunicode.h> -#include <glib/gutils.h> /* for G_CAN_INLINE */ - -G_BEGIN_DECLS - -typedef struct _GString GString; -typedef struct _GStringChunk GStringChunk; - -/** - * GString: - * @str: points to the character data. It may move as text is added. - * The @str field is null-terminated and so - * can be used as an ordinary C string. - * @len: contains the length of the string, not including the - * terminating nul byte. - * @allocated_len: the number of bytes that can be stored in the - * string before it needs to be reallocated. May be larger than @len. - * - * The #GString struct contains the public fields of a #GString. - */ -struct _GString -{ - gchar *str; - gsize len; - gsize allocated_len; -}; - -/* String Chunks - */ -GStringChunk* g_string_chunk_new (gsize size); -void g_string_chunk_free (GStringChunk *chunk); -void g_string_chunk_clear (GStringChunk *chunk); -gchar* g_string_chunk_insert (GStringChunk *chunk, - const gchar *string); -gchar* g_string_chunk_insert_len (GStringChunk *chunk, - const gchar *string, - gssize len); -gchar* g_string_chunk_insert_const (GStringChunk *chunk, - const gchar *string); - - -/* Strings - */ -GString* g_string_new (const gchar *init); -GString* g_string_new_len (const gchar *init, - gssize len); -GString* g_string_sized_new (gsize dfl_size); -gchar* g_string_free (GString *string, - gboolean free_segment); -gboolean g_string_equal (const GString *v, - const GString *v2); -guint g_string_hash (const GString *str); -GString* g_string_assign (GString *string, - const gchar *rval); -GString* g_string_truncate (GString *string, - gsize len); -GString* g_string_set_size (GString *string, - gsize len); -GString* g_string_insert_len (GString *string, - gssize pos, - const gchar *val, - gssize len); -GString* g_string_append (GString *string, - const gchar *val); -GString* g_string_append_len (GString *string, - const gchar *val, - gssize len); -GString* g_string_append_c (GString *string, - gchar c); -GString* g_string_append_unichar (GString *string, - gunichar wc); -GString* g_string_prepend (GString *string, - const gchar *val); -GString* g_string_prepend_c (GString *string, - gchar c); -GString* g_string_prepend_unichar (GString *string, - gunichar wc); -GString* g_string_prepend_len (GString *string, - const gchar *val, - gssize len); -GString* g_string_insert (GString *string, - gssize pos, - const gchar *val); -GString* g_string_insert_c (GString *string, - gssize pos, - gchar c); -GString* g_string_insert_unichar (GString *string, - gssize pos, - gunichar wc); -GString* g_string_overwrite (GString *string, - gsize pos, - const gchar *val); -GString* g_string_overwrite_len (GString *string, - gsize pos, - const gchar *val, - gssize len); -GString* g_string_erase (GString *string, - gssize pos, - gssize len); -GString* g_string_ascii_down (GString *string); -GString* g_string_ascii_up (GString *string); -void g_string_vprintf (GString *string, - const gchar *format, - va_list args); -void g_string_printf (GString *string, - const gchar *format, - ...) G_GNUC_PRINTF (2, 3); -void g_string_append_vprintf (GString *string, - const gchar *format, - va_list args); -void g_string_append_printf (GString *string, - const gchar *format, - ...) G_GNUC_PRINTF (2, 3); - -/* -- optimize g_strig_append_c --- */ -#ifdef G_CAN_INLINE -static inline GString* -g_string_append_c_inline (GString *gstring, - gchar c) -{ - if (gstring->len + 1 < gstring->allocated_len) - { - gstring->str[gstring->len++] = c; - gstring->str[gstring->len] = 0; - } - else - g_string_insert_c (gstring, -1, c); - return gstring; -} -#define g_string_append_c(gstr,c) g_string_append_c_inline (gstr, c) -#endif /* G_CAN_INLINE */ - - -#ifndef G_DISABLE_DEPRECATED - -/* The following two functions are deprecated and will be removed in - * the next major release. They use the locale-specific tolower and - * toupper, which is almost never the right thing. - */ - -GString* g_string_down (GString *string); -GString* g_string_up (GString *string); - -/* These aliases are included for compatibility. */ -#define g_string_sprintf g_string_printf -#define g_string_sprintfa g_string_append_printf - -#endif /* G_DISABLE_DEPRECATED */ - -G_END_DECLS - -#endif /* __G_STRING_H__ */ diff --git a/deps/glib/gtestutils.c b/deps/glib/gtestutils.c deleted file mode 100644 index a1a13e2d..00000000 --- a/deps/glib/gtestutils.c +++ /dev/null @@ -1,514 +0,0 @@ -/* GLib testing utilities - * Copyright (C) 2007 Imendio AB - * Authors: Tim Janik, Sven Herzberg - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "config.h" - -#include "gtestutils.h" - -#include <sys/types.h> -#ifdef G_OS_UNIX -#include <sys/wait.h> -#include <sys/time.h> -#include <fcntl.h> -#endif -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef G_OS_WIN32 -#include <io.h> -#endif -#include <errno.h> -#include <signal.h> -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif /* HAVE_SYS_SELECT_H */ - -#include "gmain.h" -#include "gstrfuncs.h" - - -/* Global variable for storing assertion messages; this is the counterpart to - * glibc's (private) __abort_msg variable, and allows developers and crash - * analysis systems like Apport and ABRT to fish out assertion messages from - * core dumps, instead of having to catch them on screen output. */ -char *__glib_assert_msg = NULL; - -static guint8* g_test_log_dump (GTestLogMsg *msg, - guint *len); - -/* --- variables --- */ -static int test_log_fd = -1; -static int test_trap_last_pid = 0; -static gboolean test_debug_log = FALSE; - -/* --- functions --- */ -const char* -g_test_log_type_name (GTestLogType log_type) -{ - switch (log_type) - { - case G_TEST_LOG_NONE: return "none"; - case G_TEST_LOG_ERROR: return "error"; - } - return "???"; -} - -static void -g_test_log_send (guint n_bytes, - const guint8 *buffer) -{ - if (test_log_fd >= 0) - { - int r; - do - r = write (test_log_fd, buffer, n_bytes); - while (r < 0 && errno == EINTR); - } - if (test_debug_log) - { - GTestLogBuffer *lbuffer = g_test_log_buffer_new (); - GTestLogMsg *msg; - guint ui; - g_test_log_buffer_push (lbuffer, n_bytes, buffer); - msg = g_test_log_buffer_pop (lbuffer); - g_warn_if_fail (msg != NULL); - g_warn_if_fail (lbuffer->data->len == 0); - g_test_log_buffer_free (lbuffer); - /* print message */ - g_printerr ("{*LOG(%s)", g_test_log_type_name (msg->log_type)); - for (ui = 0; ui < msg->n_strings; ui++) - g_printerr (":{%s}", msg->strings[ui]); - if (msg->n_nums) - { - g_printerr (":("); - for (ui = 0; ui < msg->n_nums; ui++) - g_printerr ("%s%.16Lg", ui ? ";" : "", msg->nums[ui]); - g_printerr (")"); - } - g_printerr (":LOG*}\n"); - g_test_log_msg_free (msg); - } -} - -static void -g_test_log (GTestLogType lbit, - const gchar *string1, - const gchar *string2, - guint n_args, - long double *largs) -{ - GTestLogMsg msg; - gchar *astrings[3] = { NULL, NULL, NULL }; - guint8 *dbuffer; - guint32 dbufferlen; - - msg.log_type = lbit; - msg.n_strings = (string1 != NULL) + (string1 && string2); - msg.strings = astrings; - astrings[0] = (gchar*) string1; - astrings[1] = astrings[0] ? (gchar*) string2 : NULL; - msg.n_nums = n_args; - msg.nums = largs; - dbuffer = g_test_log_dump (&msg, &dbufferlen); - g_test_log_send (dbufferlen, dbuffer); - g_free (dbuffer); -} - -void -g_assertion_message (const char *domain, - const char *file, - int line, - const char *func, - const char *message) -{ - char lstr[32]; - char *s; - - if (!message) - message = "code should not be reached"; - g_snprintf (lstr, 32, "%d", line); - s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "", - "ERROR:", file, ":", lstr, ":", - func, func[0] ? ":" : "", - " ", message, NULL); - g_printerr ("**\n%s\n", s); - - /* store assertion message in global variable, so that it can be found in a - * core dump */ - if (__glib_assert_msg != NULL) - /* free the old one */ - free (__glib_assert_msg); - __glib_assert_msg = (char*) malloc (strlen (s) + 1); - strcpy (__glib_assert_msg, s); - - g_test_log (G_TEST_LOG_ERROR, s, NULL, 0, NULL); - g_free (s); - abort(); -} - -void -g_assertion_message_expr (const char *domain, - const char *file, - int line, - const char *func, - const char *expr) -{ - char *s = g_strconcat ("assertion failed: (", expr, ")", NULL); - g_assertion_message (domain, file, line, func, s); - g_free (s); -} - -void -g_assertion_message_cmpnum (const char *domain, - const char *file, - int line, - const char *func, - const char *expr, - long double arg1, - const char *cmp, - long double arg2, - char numtype) -{ - char *s = NULL; - switch (numtype) - { - case 'i': s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break; - case 'x': s = g_strdup_printf ("assertion failed (%s): (0x%08" G_GINT64_MODIFIER "x %s 0x%08" G_GINT64_MODIFIER "x)", expr, (guint64) arg1, cmp, (guint64) arg2); break; - case 'f': s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break; - /* ideally use: floats=%.7g double=%.17g */ - } - g_assertion_message (domain, file, line, func, s); - g_free (s); -} - -void -g_assertion_message_cmpstr (const char *domain, - const char *file, - int line, - const char *func, - const char *expr, - const char *arg1, - const char *cmp, - const char *arg2) -{ - char *a1, *a2, *s, *t1 = NULL, *t2 = NULL; - a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL"); - a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL"); - g_free (t1); - g_free (t2); - s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2); - g_free (a1); - g_free (a2); - g_assertion_message (domain, file, line, func, s); - g_free (s); -} - -void -g_assertion_message_error (const char *domain, - const char *file, - int line, - const char *func, - const char *expr, - const GError *error, - GQuark error_domain, - int error_code) -{ - GString *gstring; - - /* This is used by both g_assert_error() and g_assert_no_error(), so there - * are three cases: expected an error but got the wrong error, expected - * an error but got no error, and expected no error but got an error. - */ - - gstring = g_string_new ("assertion failed "); - if (error_domain) - g_string_append_printf (gstring, "(%s == (%s, %d)): ", expr, - g_quark_to_string (error_domain), error_code); - else - g_string_append_printf (gstring, "(%s == NULL): ", expr); - - if (error) - g_string_append_printf (gstring, "%s (%s, %d)", error->message, - g_quark_to_string (error->domain), error->code); - else - g_string_append_printf (gstring, "%s is NULL", expr); - - g_assertion_message (domain, file, line, func, gstring->str); - g_string_free (gstring, TRUE); -} - -/** - * g_strcmp0: - * @str1: a C string or %NULL - * @str2: another C string or %NULL - * - * Compares @str1 and @str2 like strcmp(). Handles %NULL - * gracefully by sorting it before non-%NULL strings. - * Comparing two %NULL pointers returns 0. - * - * Returns: -1, 0 or 1, if @str1 is <, == or > than @str2. - * - * Since: 2.16 - */ -int -g_strcmp0 (const char *str1, - const char *str2) -{ - if (!str1) - return -(str1 != str2); - if (!str2) - return str1 != str2; - return strcmp (str1, str2); -} - -static inline int -g_string_must_read (GString *gstring, - int fd) -{ -#define STRING_BUFFER_SIZE 4096 - char buf[STRING_BUFFER_SIZE]; - gssize bytes; - again: - bytes = read (fd, buf, sizeof (buf)); - if (bytes == 0) - return 0; /* EOF, calling this function assumes data is available */ - else if (bytes > 0) - { - g_string_append_len (gstring, buf, bytes); - return 1; - } - else if (bytes < 0 && errno == EINTR) - goto again; - else /* bytes < 0 */ - { - g_warning ("failed to read() from child process (%d): %s", test_trap_last_pid, g_strerror (errno)); - return 1; /* ignore error after warning */ - } -} - -static inline void -g_string_write_out (GString *gstring, - int outfd, - int *stringpos) -{ - if (*stringpos < gstring->len) - { - int r; - do - r = write (outfd, gstring->str + *stringpos, gstring->len - *stringpos); - while (r < 0 && errno == EINTR); - *stringpos += MAX (r, 0); - } -} - -static void -gstring_overwrite_int (GString *gstring, - guint pos, - guint32 vuint) -{ - vuint = g_htonl (vuint); - g_string_overwrite_len (gstring, pos, (const gchar*) &vuint, 4); -} - -static void -gstring_append_int (GString *gstring, - guint32 vuint) -{ - vuint = g_htonl (vuint); - g_string_append_len (gstring, (const gchar*) &vuint, 4); -} - -static void -gstring_append_double (GString *gstring, - double vdouble) -{ - union { double vdouble; guint64 vuint64; } u; - u.vdouble = vdouble; - u.vuint64 = GUINT64_TO_BE (u.vuint64); - g_string_append_len (gstring, (const gchar*) &u.vuint64, 8); -} - -static guint8* -g_test_log_dump (GTestLogMsg *msg, - guint *len) -{ - GString *gstring = g_string_sized_new (1024); - guint ui; - gstring_append_int (gstring, 0); /* message length */ - gstring_append_int (gstring, msg->log_type); - gstring_append_int (gstring, msg->n_strings); - gstring_append_int (gstring, msg->n_nums); - gstring_append_int (gstring, 0); /* reserved */ - for (ui = 0; ui < msg->n_strings; ui++) - { - guint l = strlen (msg->strings[ui]); - gstring_append_int (gstring, l); - g_string_append_len (gstring, msg->strings[ui], l); - } - for (ui = 0; ui < msg->n_nums; ui++) - gstring_append_double (gstring, msg->nums[ui]); - *len = gstring->len; - gstring_overwrite_int (gstring, 0, *len); /* message length */ - return (guint8*) g_string_free (gstring, FALSE); -} - -static inline long double -net_double (const gchar **ipointer) -{ - union { guint64 vuint64; double vdouble; } u; - guint64 aligned_int64; - memcpy (&aligned_int64, *ipointer, 8); - *ipointer += 8; - u.vuint64 = GUINT64_FROM_BE (aligned_int64); - return u.vdouble; -} - -static inline guint32 -net_int (const gchar **ipointer) -{ - guint32 aligned_int; - memcpy (&aligned_int, *ipointer, 4); - *ipointer += 4; - return g_ntohl (aligned_int); -} - -static gboolean -g_test_log_extract (GTestLogBuffer *tbuffer) -{ - const gchar *p = tbuffer->data->str; - GTestLogMsg msg; - guint mlength; - if (tbuffer->data->len < 4 * 5) - return FALSE; - mlength = net_int (&p); - if (tbuffer->data->len < mlength) - return FALSE; - msg.log_type = net_int (&p); - msg.n_strings = net_int (&p); - msg.n_nums = net_int (&p); - if (net_int (&p) == 0) - { - guint ui; - msg.strings = g_new0 (gchar*, msg.n_strings + 1); - msg.nums = g_new0 (long double, msg.n_nums); - for (ui = 0; ui < msg.n_strings; ui++) - { - guint sl = net_int (&p); - msg.strings[ui] = g_strndup (p, sl); - p += sl; - } - for (ui = 0; ui < msg.n_nums; ui++) - msg.nums[ui] = net_double (&p); - if (p <= tbuffer->data->str + mlength) - { - g_string_erase (tbuffer->data, 0, mlength); - tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg))); - return TRUE; - } - } - g_free (msg.nums); - g_strfreev (msg.strings); - g_error ("corrupt log stream from test program"); - return FALSE; -} - -/** - * g_test_log_buffer_new: - * - * Internal function for gtester to decode test log messages, no ABI guarantees provided. - */ -GTestLogBuffer* -g_test_log_buffer_new (void) -{ - GTestLogBuffer *tb = g_new0 (GTestLogBuffer, 1); - tb->data = g_string_sized_new (1024); - return tb; -} - -/** - * g_test_log_buffer_free - * - * Internal function for gtester to free test log messages, no ABI guarantees provided. - */ -void -g_test_log_buffer_free (GTestLogBuffer *tbuffer) -{ - g_return_if_fail (tbuffer != NULL); - while (tbuffer->msgs) - g_test_log_msg_free (g_test_log_buffer_pop (tbuffer)); - g_string_free (tbuffer->data, TRUE); - g_free (tbuffer); -} - -/** - * g_test_log_buffer_push - * - * Internal function for gtester to decode test log messages, no ABI guarantees provided. - */ -void -g_test_log_buffer_push (GTestLogBuffer *tbuffer, - guint n_bytes, - const guint8 *bytes) -{ - g_return_if_fail (tbuffer != NULL); - if (n_bytes) - { - gboolean more_messages; - g_return_if_fail (bytes != NULL); - g_string_append_len (tbuffer->data, (const gchar*) bytes, n_bytes); - do - more_messages = g_test_log_extract (tbuffer); - while (more_messages); - } -} - -/** - * g_test_log_buffer_pop: - * - * Internal function for gtester to retrieve test log messages, no ABI guarantees provided. - */ -GTestLogMsg* -g_test_log_buffer_pop (GTestLogBuffer *tbuffer) -{ - GTestLogMsg *msg = NULL; - g_return_val_if_fail (tbuffer != NULL, NULL); - if (tbuffer->msgs) - { - GSList *slist = g_slist_last (tbuffer->msgs); - msg = slist->data; - tbuffer->msgs = g_slist_delete_link (tbuffer->msgs, slist); - } - return msg; -} - -/** - * g_test_log_msg_free: - * - * Internal function for gtester to free test log messages, no ABI guarantees provided. - */ -void -g_test_log_msg_free (GTestLogMsg *tmsg) -{ - g_return_if_fail (tmsg != NULL); - g_strfreev (tmsg->strings); - g_free (tmsg->nums); - g_free (tmsg); -} diff --git a/deps/glib/gtestutils.h b/deps/glib/gtestutils.h deleted file mode 100644 index d67569ee..00000000 --- a/deps/glib/gtestutils.h +++ /dev/null @@ -1,159 +0,0 @@ -/* GLib testing utilities - * Copyright (C) 2007 Imendio AB - * Authors: Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_TEST_UTILS_H__ -#define __G_TEST_UTILS_H__ - -#include <glib/gmessages.h> -#include <glib/gstring.h> -#include <glib/gerror.h> -#include <glib/gslist.h> - -G_BEGIN_DECLS - -/* assertion API */ -#define g_assert_cmpstr(s1, cmp, s2) do { const char *__s1 = (s1), *__s2 = (s2); \ - if (g_strcmp0 (__s1, __s2) cmp 0) ; else \ - g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #s1 " " #cmp " " #s2, __s1, #cmp, __s2); } while (0) -#define g_assert_cmpint(n1, cmp, n2) do { gint64 __n1 = (n1), __n2 = (n2); \ - if (__n1 cmp __n2) ; else \ - g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0) -#define g_assert_cmpuint(n1, cmp, n2) do { guint64 __n1 = (n1), __n2 = (n2); \ - if (__n1 cmp __n2) ; else \ - g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0) -#define g_assert_cmphex(n1, cmp, n2) do { guint64 __n1 = (n1), __n2 = (n2); \ - if (__n1 cmp __n2) ; else \ - g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'x'); } while (0) -#define g_assert_cmpfloat(n1,cmp,n2) do { long double __n1 = (n1), __n2 = (n2); \ - if (__n1 cmp __n2) ; else \ - g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'f'); } while (0) -#define g_assert_no_error(err) do { if (err) \ - g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #err, err, 0, 0); } while (0) -#define g_assert_error(err, dom, c) do { if (!err || (err)->domain != dom || (err)->code != c) \ - g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #err, err, dom, c); } while (0) -#ifdef G_DISABLE_ASSERT -#define g_assert_not_reached() do { (void) 0; } while (0) -#define g_assert(expr) do { (void) 0; } while (0) -#else /* !G_DISABLE_ASSERT */ -#define g_assert_not_reached() do { g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, NULL); } while (0) -#define g_assert(expr) do { if G_LIKELY (expr) ; else \ - g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ - #expr); } while (0) -#endif /* !G_DISABLE_ASSERT */ - -int g_strcmp0 (const char *str1, - const char *str2); - -void g_assertion_message (const char *domain, - const char *file, - int line, - const char *func, - const char *message) G_GNUC_NORETURN; -void g_assertion_message_expr (const char *domain, - const char *file, - int line, - const char *func, - const char *expr) G_GNUC_NORETURN; -void g_assertion_message_cmpstr (const char *domain, - const char *file, - int line, - const char *func, - const char *expr, - const char *arg1, - const char *cmp, - const char *arg2) G_GNUC_NORETURN; -void g_assertion_message_cmpnum (const char *domain, - const char *file, - int line, - const char *func, - const char *expr, - long double arg1, - const char *cmp, - long double arg2, - char numtype) G_GNUC_NORETURN; -void g_assertion_message_error (const char *domain, - const char *file, - int line, - const char *func, - const char *expr, - const GError *error, - GQuark error_domain, - int error_code) G_GNUC_NORETURN; -/* internal logging API */ -typedef enum { - G_TEST_LOG_NONE, - G_TEST_LOG_ERROR, /* s:msg */ -} GTestLogType; - -typedef struct { - GTestLogType log_type; - guint n_strings; - gchar **strings; /* NULL terminated */ - guint n_nums; - long double *nums; -} GTestLogMsg; -typedef struct { - /*< private >*/ - GString *data; - GSList *msgs; -} GTestLogBuffer; - -const char* g_test_log_type_name (GTestLogType log_type); -GTestLogBuffer* g_test_log_buffer_new (void); -void g_test_log_buffer_free (GTestLogBuffer *tbuffer); -void g_test_log_buffer_push (GTestLogBuffer *tbuffer, - guint n_bytes, - const guint8 *bytes); -GTestLogMsg* g_test_log_buffer_pop (GTestLogBuffer *tbuffer); -void g_test_log_msg_free (GTestLogMsg *tmsg); - -/** - * GTestLogFatalFunc: - * @log_domain: the log domain of the message - * @log_level: the log level of the message (including the fatal and recursion flags) - * @message: the message to process - * @user_data: user data, set in g_test_log_set_fatal_handler() - * - * Specifies the prototype of fatal log handler functions. - * - * Return value: %TRUE if the program should abort, %FALSE otherwise - * - * Since: 2.22 - */ -typedef gboolean (*GTestLogFatalFunc) (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer user_data); -void -g_test_log_set_fatal_handler (GTestLogFatalFunc log_func, - gpointer user_data); - -G_END_DECLS - -#endif /* __G_TEST_UTILS_H__ */ diff --git a/deps/glib/gthread.c b/deps/glib/gthread.c deleted file mode 100644 index 5c77f3e9..00000000 --- a/deps/glib/gthread.c +++ /dev/null @@ -1,2599 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * gthread.c: MT safety related functions - * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe - * Owen Taylor - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* Prelude {{{1 ----------------------------------------------------------- */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -/* implement gthread.h's inline functions */ -#define G_IMPLEMENT_INLINES 1 -#define __G_THREAD_C__ - -#include "config.h" - -#include "gthread.h" -#include "gthreadprivate.h" - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#ifndef G_OS_WIN32 -#include <sys/time.h> -#include <time.h> -#else -#include <windows.h> -#endif /* G_OS_WIN32 */ - -#include <string.h> - -#include "garray.h" -#include "gbitlock.h" -#include "gslist.h" -#include "gtestutils.h" -//#include "gtimer.h" - -/** - * SECTION:threads - * @title: Threads - * @short_description: thread abstraction; including threads, different - * mutexes, conditions and thread private data - * @see_also: #GThreadPool, #GAsyncQueue - * - * Threads act almost like processes, but unlike processes all threads - * of one process share the same memory. This is good, as it provides - * easy communication between the involved threads via this shared - * memory, and it is bad, because strange things (so called - * "Heisenbugs") might happen if the program is not carefully designed. - * In particular, due to the concurrent nature of threads, no - * assumptions on the order of execution of code running in different - * threads can be made, unless order is explicitly forced by the - * programmer through synchronization primitives. - * - * The aim of the thread related functions in GLib is to provide a - * portable means for writing multi-threaded software. There are - * primitives for mutexes to protect the access to portions of memory - * (#GMutex, #GStaticMutex, #G_LOCK_DEFINE, #GStaticRecMutex and - * #GStaticRWLock). There is a facility to use individual bits for - * locks (g_bit_lock()). There are primitives for condition variables to - * allow synchronization of threads (#GCond). There are primitives for - * thread-private data - data that every thread has a private instance - * of (#GPrivate, #GStaticPrivate). There are facilities for one-time - * initialization (#GOnce, g_once_init_enter()). Last but definitely - * not least there are primitives to portably create and manage - * threads (#GThread). - * - * The threading system is initialized with g_thread_init(), which - * takes an optional custom thread implementation or %NULL for the - * default implementation. If you want to call g_thread_init() with a - * non-%NULL argument this must be done before executing any other GLib - * functions (except g_mem_set_vtable()). This is a requirement even if - * no threads are in fact ever created by the process. - * - * Calling g_thread_init() with a %NULL argument is somewhat more - * relaxed. You may call any other glib functions in the main thread - * before g_thread_init() as long as g_thread_init() is not called from - * a glib callback, or with any locks held. However, many libraries - * above glib does not support late initialization of threads, so doing - * this should be avoided if possible. - * - * Please note that since version 2.24 the GObject initialization - * function g_type_init() initializes threads (with a %NULL argument), - * so most applications, including those using Gtk+ will run with - * threads enabled. If you want a special thread implementation, make - * sure you call g_thread_init() before g_type_init() is called. - * - * After calling g_thread_init(), GLib is completely thread safe (all - * global data is automatically locked), but individual data structure - * instances are not automatically locked for performance reasons. So, - * for example you must coordinate accesses to the same #GHashTable - * from multiple threads. The two notable exceptions from this rule - * are #GMainLoop and #GAsyncQueue, which <emphasis>are</emphasis> - * threadsafe and need no further application-level locking to be - * accessed from multiple threads. - * - * To help debugging problems in multithreaded applications, GLib - * supports error-checking mutexes that will give you helpful error - * messages on common problems. To use error-checking mutexes, define - * the symbol #G_ERRORCHECK_MUTEXES when compiling the application. - **/ - -/** - * G_THREADS_IMPL_POSIX: - * - * This macro is defined if POSIX style threads are used. - **/ - -/** - * G_THREADS_ENABLED: - * - * This macro is defined if GLib was compiled with thread support. This - * does not necessarily mean that there is a thread implementation - * available, but it does mean that the infrastructure is in place and - * that once you provide a thread implementation to g_thread_init(), - * GLib will be multi-thread safe. If #G_THREADS_ENABLED is not - * defined, then Glib is not, and cannot be, multi-thread safe. - **/ - -/** - * G_THREADS_IMPL_NONE: - * - * This macro is defined if no thread implementation is used. You can, - * however, provide one to g_thread_init() to make GLib multi-thread - * safe. - **/ - -/* G_LOCK Documentation {{{1 ---------------------------------------------- */ - -/* IMPLEMENTATION NOTE: - * - * G_LOCK_DEFINE and friends are convenience macros defined in - * gthread.h. Their documentation lives here. - */ - -/** - * G_LOCK_DEFINE: - * @name: the name of the lock. - * - * The %G_LOCK_* macros provide a convenient interface to #GStaticMutex - * with the advantage that they will expand to nothing in programs - * compiled against a thread-disabled GLib, saving code and memory - * there. #G_LOCK_DEFINE defines a lock. It can appear anywhere - * variable definitions may appear in programs, i.e. in the first block - * of a function or outside of functions. The @name parameter will be - * mangled to get the name of the #GStaticMutex. This means that you - * can use names of existing variables as the parameter - e.g. the name - * of the variable you intent to protect with the lock. Look at our - * <function>give_me_next_number()</function> example using the - * %G_LOCK_* macros: - * - * <example> - * <title>Using the %G_LOCK_* convenience macros</title> - * <programlisting> - * G_LOCK_DEFINE (current_number); - * - * int - * give_me_next_number (void) - * { - * static int current_number = 0; - * int ret_val; - * - * G_LOCK (current_number); - * ret_val = current_number = calc_next_number (current_number); - * G_UNLOCK (current_number); - * - * return ret_val; - * } - * </programlisting> - * </example> - **/ - -/** - * G_LOCK_DEFINE_STATIC: - * @name: the name of the lock. - * - * This works like #G_LOCK_DEFINE, but it creates a static object. - **/ - -/** - * G_LOCK_EXTERN: - * @name: the name of the lock. - * - * This declares a lock, that is defined with #G_LOCK_DEFINE in another - * module. - **/ - -/** - * G_LOCK: - * @name: the name of the lock. - * - * Works like g_mutex_lock(), but for a lock defined with - * #G_LOCK_DEFINE. - **/ - -/** - * G_TRYLOCK: - * @name: the name of the lock. - * @Returns: %TRUE, if the lock could be locked. - * - * Works like g_mutex_trylock(), but for a lock defined with - * #G_LOCK_DEFINE. - **/ - -/** - * G_UNLOCK: - * @name: the name of the lock. - * - * Works like g_mutex_unlock(), but for a lock defined with - * #G_LOCK_DEFINE. - **/ - -/* GThreadError {{{1 ------------------------------------------------------- */ -/** - * GThreadError: - * @G_THREAD_ERROR_AGAIN: a thread couldn't be created due to resource - * shortage. Try again later. - * - * Possible errors of thread related functions. - **/ - -/** - * G_THREAD_ERROR: - * - * The error domain of the GLib thread subsystem. - **/ -GQuark -g_thread_error_quark (void) -{ - return g_quark_from_static_string ("g_thread_error"); -} - -/* Miscellaneous Structures {{{1 ------------------------------------------ */ -typedef struct _GRealThread GRealThread; -struct _GRealThread -{ - GThread thread; - /* Bit 0 protects private_data. To avoid deadlocks, do not block while - * holding this (particularly on the g_thread lock). */ - volatile gint private_data_lock; - GArray *private_data; - GRealThread *next; - gpointer retval; - GSystemThread system_thread; -}; - -#define LOCK_PRIVATE_DATA(self) g_bit_lock (&(self)->private_data_lock, 0) -#define UNLOCK_PRIVATE_DATA(self) g_bit_unlock (&(self)->private_data_lock, 0) - -typedef struct _GStaticPrivateNode GStaticPrivateNode; -struct _GStaticPrivateNode -{ - gpointer data; - GDestroyNotify destroy; -}; - -static void g_thread_cleanup (gpointer data); -static void g_thread_fail (void); -static guint64 gettime (void); - -guint64 (*g_thread_gettime) (void) = gettime; - -/* Global Variables {{{1 -------------------------------------------------- */ - -static GSystemThread zero_thread; /* This is initialized to all zero */ -gboolean g_thread_use_default_impl = TRUE; - -/** - * g_thread_supported: - * @Returns: %TRUE, if the thread system is initialized. - * - * This function returns %TRUE if the thread system is initialized, and - * %FALSE if it is not. - * - * <note><para>This function is actually a macro. Apart from taking the - * address of it you can however use it as if it was a - * function.</para></note> - **/ - -/* IMPLEMENTATION NOTE: - * - * g_thread_supported() is just returns g_threads_got_initialized - */ -gboolean g_threads_got_initialized = FALSE; - - -/* Thread Implementation Virtual Function Table {{{1 ---------------------- */ -/* Virtual Function Table Documentation {{{2 ------------------------------ */ -/** - * GThreadFunctions: - * @mutex_new: virtual function pointer for g_mutex_new() - * @mutex_lock: virtual function pointer for g_mutex_lock() - * @mutex_trylock: virtual function pointer for g_mutex_trylock() - * @mutex_unlock: virtual function pointer for g_mutex_unlock() - * @mutex_free: virtual function pointer for g_mutex_free() - * @cond_new: virtual function pointer for g_cond_new() - * @cond_signal: virtual function pointer for g_cond_signal() - * @cond_broadcast: virtual function pointer for g_cond_broadcast() - * @cond_wait: virtual function pointer for g_cond_wait() - * @cond_timed_wait: virtual function pointer for g_cond_timed_wait() - * @cond_free: virtual function pointer for g_cond_free() - * @private_new: virtual function pointer for g_private_new() - * @private_get: virtual function pointer for g_private_get() - * @private_set: virtual function pointer for g_private_set() - * @thread_create: virtual function pointer for g_thread_create() - * @thread_yield: virtual function pointer for g_thread_yield() - * @thread_join: virtual function pointer for g_thread_join() - * @thread_exit: virtual function pointer for g_thread_exit() - * @thread_set_priority: virtual function pointer for - * g_thread_set_priority() - * @thread_self: virtual function pointer for g_thread_self() - * @thread_equal: used internally by recursive mutex locks and by some - * assertion checks - * - * This function table is used by g_thread_init() to initialize the - * thread system. The functions in the table are directly used by their - * g_* prepended counterparts (described in this document). For - * example, if you call g_mutex_new() then mutex_new() from the table - * provided to g_thread_init() will be called. - * - * <note><para>Do not use this struct unless you know what you are - * doing.</para></note> - **/ - -/* IMPLEMENTATION NOTE: - * - * g_thread_functions_for_glib_use is a global symbol that gets used by - * most of the "primitive" threading calls. g_mutex_lock(), for - * example, is just a macro that calls the appropriate virtual function - * out of this table. - * - * For that reason, all of those macros are documented here. - */ -GThreadFunctions g_thread_functions_for_glib_use = { -/* GMutex Virtual Functions {{{2 ------------------------------------------ */ - -/** - * GMutex: - * - * The #GMutex struct is an opaque data structure to represent a mutex - * (mutual exclusion). It can be used to protect data against shared - * access. Take for example the following function: - * - * <example> - * <title>A function which will not work in a threaded environment</title> - * <programlisting> - * int - * give_me_next_number (void) - * { - * static int current_number = 0; - * - * /<!-- -->* now do a very complicated calculation to calculate the new - * * number, this might for example be a random number generator - * *<!-- -->/ - * current_number = calc_next_number (current_number); - * - * return current_number; - * } - * </programlisting> - * </example> - * - * It is easy to see that this won't work in a multi-threaded - * application. There current_number must be protected against shared - * access. A first naive implementation would be: - * - * <example> - * <title>The wrong way to write a thread-safe function</title> - * <programlisting> - * int - * give_me_next_number (void) - * { - * static int current_number = 0; - * int ret_val; - * static GMutex * mutex = NULL; - * - * if (!mutex) mutex = g_mutex_new (<!-- -->); - * - * g_mutex_lock (mutex); - * ret_val = current_number = calc_next_number (current_number); - * g_mutex_unlock (mutex); - * - * return ret_val; - * } - * </programlisting> - * </example> - * - * This looks like it would work, but there is a race condition while - * constructing the mutex and this code cannot work reliable. Please do - * not use such constructs in your own programs! One working solution - * is: - * - * <example> - * <title>A correct thread-safe function</title> - * <programlisting> - * static GMutex *give_me_next_number_mutex = NULL; - * - * /<!-- -->* this function must be called before any call to - * * give_me_next_number(<!-- -->) - * * - * * it must be called exactly once. - * *<!-- -->/ - * void - * init_give_me_next_number (void) - * { - * g_assert (give_me_next_number_mutex == NULL); - * give_me_next_number_mutex = g_mutex_new (<!-- -->); - * } - * - * int - * give_me_next_number (void) - * { - * static int current_number = 0; - * int ret_val; - * - * g_mutex_lock (give_me_next_number_mutex); - * ret_val = current_number = calc_next_number (current_number); - * g_mutex_unlock (give_me_next_number_mutex); - * - * return ret_val; - * } - * </programlisting> - * </example> - * - * #GStaticMutex provides a simpler and safer way of doing this. - * - * If you want to use a mutex, and your code should also work without - * calling g_thread_init() first, then you cannot use a #GMutex, as - * g_mutex_new() requires that the thread system be initialized. Use a - * #GStaticMutex instead. - * - * A #GMutex should only be accessed via the following functions. - * - * <note><para>All of the <function>g_mutex_*</function> functions are - * actually macros. Apart from taking their addresses, you can however - * use them as if they were functions.</para></note> - **/ - -/** - * g_mutex_new: - * @Returns: a new #GMutex. - * - * Creates a new #GMutex. - * - * <note><para>This function will abort if g_thread_init() has not been - * called yet.</para></note> - **/ - (GMutex*(*)())g_thread_fail, - -/** - * g_mutex_lock: - * @mutex: a #GMutex. - * - * Locks @mutex. If @mutex is already locked by another thread, the - * current thread will block until @mutex is unlocked by the other - * thread. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will do nothing. - * - * <note><para>#GMutex is neither guaranteed to be recursive nor to be - * non-recursive, i.e. a thread could deadlock while calling - * g_mutex_lock(), if it already has locked @mutex. Use - * #GStaticRecMutex, if you need recursive mutexes.</para></note> - **/ - NULL, - -/** - * g_mutex_trylock: - * @mutex: a #GMutex. - * @Returns: %TRUE, if @mutex could be locked. - * - * Tries to lock @mutex. If @mutex is already locked by another thread, - * it immediately returns %FALSE. Otherwise it locks @mutex and returns - * %TRUE. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will immediately return %TRUE. - * - * <note><para>#GMutex is neither guaranteed to be recursive nor to be - * non-recursive, i.e. the return value of g_mutex_trylock() could be - * both %FALSE or %TRUE, if the current thread already has locked - * @mutex. Use #GStaticRecMutex, if you need recursive - * mutexes.</para></note> - **/ - NULL, - -/** - * g_mutex_unlock: - * @mutex: a #GMutex. - * - * Unlocks @mutex. If another thread is blocked in a g_mutex_lock() - * call for @mutex, it will be woken and can lock @mutex itself. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will do nothing. - **/ - NULL, - -/** - * g_mutex_free: - * @mutex: a #GMutex. - * - * Destroys @mutex. - * - * <note><para>Calling g_mutex_free() on a locked mutex may result in - * undefined behaviour.</para></note> - **/ - NULL, - -/* GCond Virtual Functions {{{2 ------------------------------------------ */ - -/** - * GCond: - * - * The #GCond struct is an opaque data structure that represents a - * condition. Threads can block on a #GCond if they find a certain - * condition to be false. If other threads change the state of this - * condition they signal the #GCond, and that causes the waiting - * threads to be woken up. - * - * <example> - * <title> - * Using GCond to block a thread until a condition is satisfied - * </title> - * <programlisting> - * GCond* data_cond = NULL; /<!-- -->* Must be initialized somewhere *<!-- -->/ - * GMutex* data_mutex = NULL; /<!-- -->* Must be initialized somewhere *<!-- -->/ - * gpointer current_data = NULL; - * - * void - * push_data (gpointer data) - * { - * g_mutex_lock (data_mutex); - * current_data = data; - * g_cond_signal (data_cond); - * g_mutex_unlock (data_mutex); - * } - * - * gpointer - * pop_data (void) - * { - * gpointer data; - * - * g_mutex_lock (data_mutex); - * while (!current_data) - * g_cond_wait (data_cond, data_mutex); - * data = current_data; - * current_data = NULL; - * g_mutex_unlock (data_mutex); - * - * return data; - * } - * </programlisting> - * </example> - * - * Whenever a thread calls <function>pop_data()</function> now, it will - * wait until current_data is non-%NULL, i.e. until some other thread - * has called <function>push_data()</function>. - * - * <note><para>It is important to use the g_cond_wait() and - * g_cond_timed_wait() functions only inside a loop which checks for the - * condition to be true. It is not guaranteed that the waiting thread - * will find the condition fulfilled after it wakes up, even if the - * signaling thread left the condition in that state: another thread may - * have altered the condition before the waiting thread got the chance - * to be woken up, even if the condition itself is protected by a - * #GMutex, like above.</para></note> - * - * A #GCond should only be accessed via the following functions. - * - * <note><para>All of the <function>g_cond_*</function> functions are - * actually macros. Apart from taking their addresses, you can however - * use them as if they were functions.</para></note> - **/ - -/** - * g_cond_new: - * @Returns: a new #GCond. - * - * Creates a new #GCond. This function will abort, if g_thread_init() - * has not been called yet. - **/ - (GCond*(*)())g_thread_fail, - -/** - * g_cond_signal: - * @cond: a #GCond. - * - * If threads are waiting for @cond, exactly one of them is woken up. - * It is good practice to hold the same lock as the waiting thread - * while calling this function, though not required. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will do nothing. - **/ - NULL, - -/** - * g_cond_broadcast: - * @cond: a #GCond. - * - * If threads are waiting for @cond, all of them are woken up. It is - * good practice to lock the same mutex as the waiting threads, while - * calling this function, though not required. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will do nothing. - **/ - NULL, - -/** - * g_cond_wait: - * @cond: a #GCond. - * @mutex: a #GMutex, that is currently locked. - * - * Waits until this thread is woken up on @cond. The @mutex is unlocked - * before falling asleep and locked again before resuming. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will immediately return. - **/ - NULL, - -/** - * g_cond_timed_wait: - * @cond: a #GCond. - * @mutex: a #GMutex that is currently locked. - * @abs_time: a #GTimeVal, determining the final time. - * @Returns: %TRUE if @cond was signalled, or %FALSE on timeout. - * - * Waits until this thread is woken up on @cond, but not longer than - * until the time specified by @abs_time. The @mutex is unlocked before - * falling asleep and locked again before resuming. - * - * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait(). - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will immediately return %TRUE. - * - * To easily calculate @abs_time a combination of g_get_current_time() - * and g_time_val_add() can be used. - **/ - NULL, - -/** - * g_cond_free: - * @cond: a #GCond. - * - * Destroys the #GCond. - **/ - NULL, - -/* GPrivate Virtual Functions {{{2 --------------------------------------- */ - -/** - * GPrivate: - * - * <note><para> - * #GStaticPrivate is a better choice for most uses. - * </para></note> - * - * The #GPrivate struct is an opaque data structure to represent a - * thread private data key. Threads can thereby obtain and set a - * pointer which is private to the current thread. Take our - * <function>give_me_next_number(<!-- -->)</function> example from - * above. Suppose we don't want <literal>current_number</literal> to be - * shared between the threads, but instead to be private to each thread. - * This can be done as follows: - * - * <example> - * <title>Using GPrivate for per-thread data</title> - * <programlisting> - * GPrivate* current_number_key = NULL; /<!-- -->* Must be initialized somewhere - * with g_private_new (g_free); *<!-- -->/ - * - * int - * give_me_next_number (void) - * { - * int *current_number = g_private_get (current_number_key); - * - * if (!current_number) - * { - * current_number = g_new (int, 1); - * *current_number = 0; - * g_private_set (current_number_key, current_number); - * } - * - * *current_number = calc_next_number (*current_number); - * - * return *current_number; - * } - * </programlisting> - * </example> - * - * Here the pointer belonging to the key - * <literal>current_number_key</literal> is read. If it is %NULL, it has - * not been set yet. Then get memory for an integer value, assign this - * memory to the pointer and write the pointer back. Now we have an - * integer value that is private to the current thread. - * - * The #GPrivate struct should only be accessed via the following - * functions. - * - * <note><para>All of the <function>g_private_*</function> functions are - * actually macros. Apart from taking their addresses, you can however - * use them as if they were functions.</para></note> - **/ - -/** - * g_private_new: - * @destructor: a function to destroy the data keyed to #GPrivate when - * a thread ends. - * @Returns: a new #GPrivate. - * - * Creates a new #GPrivate. If @destructor is non-%NULL, it is a - * pointer to a destructor function. Whenever a thread ends and the - * corresponding pointer keyed to this instance of #GPrivate is - * non-%NULL, the destructor is called with this pointer as the - * argument. - * - * <note><para> - * #GStaticPrivate is a better choice for most uses. - * </para></note> - * - * <note><para>@destructor is used quite differently from @notify in - * g_static_private_set().</para></note> - * - * <note><para>A #GPrivate cannot be freed. Reuse it instead, if you - * can, to avoid shortage, or use #GStaticPrivate.</para></note> - * - * <note><para>This function will abort if g_thread_init() has not been - * called yet.</para></note> - **/ - (GPrivate*(*)(GDestroyNotify))g_thread_fail, - -/** - * g_private_get: - * @private_key: a #GPrivate. - * @Returns: the corresponding pointer. - * - * Returns the pointer keyed to @private_key for the current thread. If - * g_private_set() hasn't been called for the current @private_key and - * thread yet, this pointer will be %NULL. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will return the value of @private_key - * casted to #gpointer. Note however, that private data set - * <emphasis>before</emphasis> g_thread_init() will - * <emphasis>not</emphasis> be retained <emphasis>after</emphasis> the - * call. Instead, %NULL will be returned in all threads directly after - * g_thread_init(), regardless of any g_private_set() calls issued - * before threading system intialization. - **/ - NULL, - -/** - * g_private_set: - * @private_key: a #GPrivate. - * @data: the new pointer. - * - * Sets the pointer keyed to @private_key for the current thread. - * - * This function can be used even if g_thread_init() has not yet been - * called, and, in that case, will set @private_key to @data casted to - * #GPrivate*. See g_private_get() for resulting caveats. - **/ - NULL, - -/* GThread Virtual Functions {{{2 ---------------------------------------- */ -/** - * GThread: - * - * The #GThread struct represents a running thread. It has three public - * read-only members, but the underlying struct is bigger, so you must - * not copy this struct. - * - * <note><para>Resources for a joinable thread are not fully released - * until g_thread_join() is called for that thread.</para></note> - **/ - -/** - * GThreadFunc: - * @data: data passed to the thread. - * @Returns: the return value of the thread, which will be returned by - * g_thread_join(). - * - * Specifies the type of the @func functions passed to - * g_thread_create() or g_thread_create_full(). - **/ - -/** - * GThreadPriority: - * @G_THREAD_PRIORITY_LOW: a priority lower than normal - * @G_THREAD_PRIORITY_NORMAL: the default priority - * @G_THREAD_PRIORITY_HIGH: a priority higher than normal - * @G_THREAD_PRIORITY_URGENT: the highest priority - * - * Specifies the priority of a thread. - * - * <note><para>It is not guaranteed that threads with different priorities - * really behave accordingly. On some systems (e.g. Linux) there are no - * thread priorities. On other systems (e.g. Solaris) there doesn't - * seem to be different scheduling for different priorities. All in all - * try to avoid being dependent on priorities.</para></note> - **/ - -/** - * g_thread_create: - * @func: a function to execute in the new thread. - * @data: an argument to supply to the new thread. - * @joinable: should this thread be joinable? - * @error: return location for error. - * @Returns: the new #GThread on success. - * - * This function creates a new thread with the default priority. - * - * If @joinable is %TRUE, you can wait for this threads termination - * calling g_thread_join(). Otherwise the thread will just disappear - * when it terminates. - * - * The new thread executes the function @func with the argument @data. - * If the thread was created successfully, it is returned. - * - * @error can be %NULL to ignore errors, or non-%NULL to report errors. - * The error is set, if and only if the function returns %NULL. - **/ - (void(*)(GThreadFunc, gpointer, gulong, - gboolean, gboolean, GThreadPriority, - gpointer, GError**))g_thread_fail, - -/** - * g_thread_yield: - * - * Gives way to other threads waiting to be scheduled. - * - * This function is often used as a method to make busy wait less evil. - * But in most cases you will encounter, there are better methods to do - * that. So in general you shouldn't use this function. - **/ - NULL, - - NULL, /* thread_join */ - NULL, /* thread_exit */ - NULL, /* thread_set_priority */ - NULL, /* thread_self */ - NULL /* thread_equal */ -}; - -/* Local Data {{{1 -------------------------------------------------------- */ - -static GMutex *g_once_mutex = NULL; -static GCond *g_once_cond = NULL; -static GPrivate *g_thread_specific_private = NULL; -static GRealThread *g_thread_all_threads = NULL; -static GSList *g_thread_free_indices = NULL; -static GSList* g_once_init_list = NULL; - -G_LOCK_DEFINE_STATIC (g_thread); - -/* Initialisation {{{1 ---------------------------------------------------- */ - -#ifdef G_THREADS_ENABLED -/** - * g_thread_init: - * @vtable: a function table of type #GThreadFunctions, that provides - * the entry points to the thread system to be used. - * - * If you use GLib from more than one thread, you must initialize the - * thread system by calling g_thread_init(). Most of the time you will - * only have to call <literal>g_thread_init (NULL)</literal>. - * - * <note><para>Do not call g_thread_init() with a non-%NULL parameter unless - * you really know what you are doing.</para></note> - * - * <note><para>g_thread_init() must not be called directly or indirectly as a - * callback from GLib. Also no mutexes may be currently locked while - * calling g_thread_init().</para></note> - * - * <note><para>g_thread_init() changes the way in which #GTimer measures - * elapsed time. As a consequence, timers that are running while - * g_thread_init() is called may report unreliable times.</para></note> - * - * Calling g_thread_init() multiple times is allowed (since version - * 2.24), but nothing happens except for the first call. If the - * argument is non-%NULL on such a call a warning will be printed, but - * otherwise the argument is ignored. - * - * If no thread system is available and @vtable is %NULL or if not all - * elements of @vtable are non-%NULL, then g_thread_init() will abort. - * - * <note><para>To use g_thread_init() in your program, you have to link with - * the libraries that the command <command>pkg-config --libs - * gthread-2.0</command> outputs. This is not the case for all the - * other thread related functions of GLib. Those can be used without - * having to link with the thread libraries.</para></note> - **/ - -/* This must be called only once, before any threads are created. - * It will only be called from g_thread_init() in -lgthread. - */ -void -g_thread_init_glib (void) -{ - /* We let the main thread (the one that calls g_thread_init) inherit - * the static_private data set before calling g_thread_init - */ - GRealThread* main_thread = (GRealThread*) g_thread_self (); - - /* mutex and cond creation works without g_threads_got_initialized */ - g_once_mutex = g_mutex_new (); - g_once_cond = g_cond_new (); - - /* we may only create mutex and cond in here */ - _g_mem_thread_init_noprivate_nomessage (); - - /* setup the basic threading system */ - g_threads_got_initialized = TRUE; - g_thread_specific_private = g_private_new (g_thread_cleanup); - g_private_set (g_thread_specific_private, main_thread); - G_THREAD_UF (thread_self, (&main_thread->system_thread)); - - /* complete memory system initialization, g_private_*() works now */ - _g_slice_thread_init_nomessage (); - - /* accomplish log system initialization to enable messaging */ - _g_messages_thread_init_nomessage (); - - /* we may run full-fledged initializers from here */ - _g_utils_thread_init (); - _g_futex_thread_init (); -#ifdef G_OS_WIN32 - _g_win32_thread_init (); -#endif -} -#endif /* G_THREADS_ENABLED */ - -/* The following sections implement: GOnce, GStaticMutex, GStaticRecMutex, - * GStaticPrivate, - **/ - -/* GOnce {{{1 ------------------------------------------------------------- */ - -/** - * GOnce: - * @status: the status of the #GOnce - * @retval: the value returned by the call to the function, if @status - * is %G_ONCE_STATUS_READY - * - * A #GOnce struct controls a one-time initialization function. Any - * one-time initialization function must have its own unique #GOnce - * struct. - * - * Since: 2.4 - **/ - -/** - * G_ONCE_INIT: - * - * A #GOnce must be initialized with this macro before it can be used. - * - * <informalexample> - * <programlisting> - * GOnce my_once = G_ONCE_INIT; - * </programlisting> - * </informalexample> - * - * Since: 2.4 - **/ - -/** - * GOnceStatus: - * @G_ONCE_STATUS_NOTCALLED: the function has not been called yet. - * @G_ONCE_STATUS_PROGRESS: the function call is currently in progress. - * @G_ONCE_STATUS_READY: the function has been called. - * - * The possible statuses of a one-time initialization function - * controlled by a #GOnce struct. - * - * Since: 2.4 - **/ - -/** - * g_once: - * @once: a #GOnce structure - * @func: the #GThreadFunc function associated to @once. This function - * is called only once, regardless of the number of times it and - * its associated #GOnce struct are passed to g_once(). - * @arg: data to be passed to @func - * - * The first call to this routine by a process with a given #GOnce - * struct calls @func with the given argument. Thereafter, subsequent - * calls to g_once() with the same #GOnce struct do not call @func - * again, but return the stored result of the first call. On return - * from g_once(), the status of @once will be %G_ONCE_STATUS_READY. - * - * For example, a mutex or a thread-specific data key must be created - * exactly once. In a threaded environment, calling g_once() ensures - * that the initialization is serialized across multiple threads. - * - * <note><para>Calling g_once() recursively on the same #GOnce struct in - * @func will lead to a deadlock.</para></note> - * - * <informalexample> - * <programlisting> - * gpointer - * get_debug_flags (void) - * { - * static GOnce my_once = G_ONCE_INIT; - * - * g_once (&my_once, parse_debug_flags, NULL); - * - * return my_once.retval; - * } - * </programlisting> - * </informalexample> - * - * Since: 2.4 - **/ -gpointer -g_once_impl (GOnce *once, - GThreadFunc func, - gpointer arg) -{ - g_mutex_lock (g_once_mutex); - - while (once->status == G_ONCE_STATUS_PROGRESS) - g_cond_wait (g_once_cond, g_once_mutex); - - if (once->status != G_ONCE_STATUS_READY) - { - once->status = G_ONCE_STATUS_PROGRESS; - g_mutex_unlock (g_once_mutex); - - once->retval = func (arg); - - g_mutex_lock (g_once_mutex); - once->status = G_ONCE_STATUS_READY; - g_cond_broadcast (g_once_cond); - } - - g_mutex_unlock (g_once_mutex); - - return once->retval; -} - -/** - * g_once_init_enter: - * @value_location: location of a static initializable variable - * containing 0. - * @Returns: %TRUE if the initialization section should be entered, - * %FALSE and blocks otherwise - * - * Function to be called when starting a critical initialization - * section. The argument @value_location must point to a static - * 0-initialized variable that will be set to a value other than 0 at - * the end of the initialization section. In combination with - * g_once_init_leave() and the unique address @value_location, it can - * be ensured that an initialization section will be executed only once - * during a program's life time, and that concurrent threads are - * blocked until initialization completed. To be used in constructs - * like this: - * - * <informalexample> - * <programlisting> - * static gsize initialization_value = 0; - * - * if (g_once_init_enter (&initialization_value)) - * { - * gsize setup_value = 42; /<!-- -->* initialization code here *<!-- -->/ - * - * g_once_init_leave (&initialization_value, setup_value); - * } - * - * /<!-- -->* use initialization_value here *<!-- -->/ - * </programlisting> - * </informalexample> - * - * Since: 2.14 - **/ -gboolean -g_once_init_enter_impl (volatile gsize *value_location) -{ - gboolean need_init = FALSE; - g_mutex_lock (g_once_mutex); - if (g_atomic_pointer_get (value_location) == NULL) - { - if (!g_slist_find (g_once_init_list, (void*) value_location)) - { - need_init = TRUE; - g_once_init_list = g_slist_prepend (g_once_init_list, (void*) value_location); - } - else - do - g_cond_wait (g_once_cond, g_once_mutex); - while (g_slist_find (g_once_init_list, (void*) value_location)); - } - g_mutex_unlock (g_once_mutex); - return need_init; -} - -/** - * g_once_init_leave: - * @value_location: location of a static initializable variable - * containing 0. - * @initialization_value: new non-0 value for *@value_location. - * - * Counterpart to g_once_init_enter(). Expects a location of a static - * 0-initialized initialization variable, and an initialization value - * other than 0. Sets the variable to the initialization value, and - * releases concurrent threads blocking in g_once_init_enter() on this - * initialization variable. - * - * Since: 2.14 - **/ -void -g_once_init_leave (volatile gsize *value_location, - gsize initialization_value) -{ - g_return_if_fail (g_atomic_pointer_get (value_location) == NULL); - g_return_if_fail (initialization_value != 0); - g_return_if_fail (g_once_init_list != NULL); - - g_atomic_pointer_set (value_location, initialization_value); - g_mutex_lock (g_once_mutex); - g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location); - g_cond_broadcast (g_once_cond); - g_mutex_unlock (g_once_mutex); -} - -/* GStaticMutex {{{1 ------------------------------------------------------ */ - -/** - * GStaticMutex: - * - * A #GStaticMutex works like a #GMutex, but it has one significant - * advantage. It doesn't need to be created at run-time like a #GMutex, - * but can be defined at compile-time. Here is a shorter, easier and - * safer version of our <function>give_me_next_number()</function> - * example: - * - * <example> - * <title> - * Using <structname>GStaticMutex</structname> - * to simplify thread-safe programming - * </title> - * <programlisting> - * int - * give_me_next_number (void) - * { - * static int current_number = 0; - * int ret_val; - * static GStaticMutex mutex = G_STATIC_MUTEX_INIT; - * - * g_static_mutex_lock (&mutex); - * ret_val = current_number = calc_next_number (current_number); - * g_static_mutex_unlock (&mutex); - * - * return ret_val; - * } - * </programlisting> - * </example> - * - * Sometimes you would like to dynamically create a mutex. If you don't - * want to require prior calling to g_thread_init(), because your code - * should also be usable in non-threaded programs, you are not able to - * use g_mutex_new() and thus #GMutex, as that requires a prior call to - * g_thread_init(). In theses cases you can also use a #GStaticMutex. - * It must be initialized with g_static_mutex_init() before using it - * and freed with with g_static_mutex_free() when not needed anymore to - * free up any allocated resources. - * - * Even though #GStaticMutex is not opaque, it should only be used with - * the following functions, as it is defined differently on different - * platforms. - * - * All of the <function>g_static_mutex_*</function> functions apart - * from <function>g_static_mutex_get_mutex</function> can also be used - * even if g_thread_init() has not yet been called. Then they do - * nothing, apart from <function>g_static_mutex_trylock</function>, - * which does nothing but returning %TRUE. - * - * <note><para>All of the <function>g_static_mutex_*</function> - * functions are actually macros. Apart from taking their addresses, you - * can however use them as if they were functions.</para></note> - **/ - -/** - * G_STATIC_MUTEX_INIT: - * - * A #GStaticMutex must be initialized with this macro, before it can - * be used. This macro can used be to initialize a variable, but it - * cannot be assigned to a variable. In that case you have to use - * g_static_mutex_init(). - * - * <informalexample> - * <programlisting> - * GStaticMutex my_mutex = G_STATIC_MUTEX_INIT; - * </programlisting> - * </informalexample> - **/ - -/** - * g_static_mutex_init: - * @mutex: a #GStaticMutex to be initialized. - * - * Initializes @mutex. Alternatively you can initialize it with - * #G_STATIC_MUTEX_INIT. - **/ -void -g_static_mutex_init (GStaticMutex *mutex) -{ - static const GStaticMutex init_mutex = G_STATIC_MUTEX_INIT; - - g_return_if_fail (mutex); - - *mutex = init_mutex; -} - -/* IMPLEMENTATION NOTE: - * - * On some platforms a GStaticMutex is actually a normal GMutex stored - * inside of a structure instead of being allocated dynamically. We can - * only do this for platforms on which we know, in advance, how to - * allocate (size) and initialise (value) that memory. - * - * On other platforms, a GStaticMutex is nothing more than a pointer to - * a GMutex. In that case, the first access we make to the static mutex - * must first allocate the normal GMutex and store it into the pointer. - * - * configure.ac writes macros into glibconfig.h to determine if - * g_static_mutex_get_mutex() accesses the structure in memory directly - * (on platforms where we are able to do that) or if it ends up here, - * where we may have to allocate the GMutex before returning it. - */ - -/** - * g_static_mutex_get_mutex: - * @mutex: a #GStaticMutex. - * @Returns: the #GMutex corresponding to @mutex. - * - * For some operations (like g_cond_wait()) you must have a #GMutex - * instead of a #GStaticMutex. This function will return the - * corresponding #GMutex for @mutex. - **/ -GMutex * -g_static_mutex_get_mutex_impl (GMutex** mutex) -{ - GMutex *result; - - if (!g_thread_supported ()) - return NULL; - - result = g_atomic_pointer_get (mutex); - - if (!result) - { - g_assert (g_once_mutex); - - g_mutex_lock (g_once_mutex); - - result = *mutex; - if (!result) - { - result = g_mutex_new (); - g_atomic_pointer_set (mutex, result); - } - - g_mutex_unlock (g_once_mutex); - } - - return result; -} - -/* IMPLEMENTATION NOTE: - * - * g_static_mutex_lock(), g_static_mutex_trylock() and - * g_static_mutex_unlock() are all preprocessor macros that wrap the - * corresponding g_mutex_*() function around a call to - * g_static_mutex_get_mutex(). - */ - -/** - * g_static_mutex_lock: - * @mutex: a #GStaticMutex. - * - * Works like g_mutex_lock(), but for a #GStaticMutex. - **/ - -/** - * g_static_mutex_trylock: - * @mutex: a #GStaticMutex. - * @Returns: %TRUE, if the #GStaticMutex could be locked. - * - * Works like g_mutex_trylock(), but for a #GStaticMutex. - **/ - -/** - * g_static_mutex_unlock: - * @mutex: a #GStaticMutex. - * - * Works like g_mutex_unlock(), but for a #GStaticMutex. - **/ - -/** - * g_static_mutex_free: - * @mutex: a #GStaticMutex to be freed. - * - * Releases all resources allocated to @mutex. - * - * You don't have to call this functions for a #GStaticMutex with an - * unbounded lifetime, i.e. objects declared 'static', but if you have - * a #GStaticMutex as a member of a structure and the structure is - * freed, you should also free the #GStaticMutex. - * - * <note><para>Calling g_static_mutex_free() on a locked mutex may - * result in undefined behaviour.</para></note> - **/ -void -g_static_mutex_free (GStaticMutex* mutex) -{ - GMutex **runtime_mutex; - - g_return_if_fail (mutex); - - /* The runtime_mutex is the first (or only) member of GStaticMutex, - * see both versions (of glibconfig.h) in configure.ac. Note, that - * this variable is NULL, if g_thread_init() hasn't been called or - * if we're using the default thread implementation and it provides - * static mutexes. */ - runtime_mutex = ((GMutex**)mutex); - - if (*runtime_mutex) - g_mutex_free (*runtime_mutex); - - *runtime_mutex = NULL; -} - -/* ------------------------------------------------------------------------ */ - -/** - * GStaticRecMutex: - * - * A #GStaticRecMutex works like a #GStaticMutex, but it can be locked - * multiple times by one thread. If you enter it n times, you have to - * unlock it n times again to let other threads lock it. An exception - * is the function g_static_rec_mutex_unlock_full(): that allows you to - * unlock a #GStaticRecMutex completely returning the depth, (i.e. the - * number of times this mutex was locked). The depth can later be used - * to restore the state of the #GStaticRecMutex by calling - * g_static_rec_mutex_lock_full(). - * - * Even though #GStaticRecMutex is not opaque, it should only be used - * with the following functions. - * - * All of the <function>g_static_rec_mutex_*</function> functions can - * be used even if g_thread_init() has not been called. Then they do - * nothing, apart from <function>g_static_rec_mutex_trylock</function>, - * which does nothing but returning %TRUE. - **/ - -/** - * G_STATIC_REC_MUTEX_INIT: - * - * A #GStaticRecMutex must be initialized with this macro before it can - * be used. This macro can used be to initialize a variable, but it - * cannot be assigned to a variable. In that case you have to use - * g_static_rec_mutex_init(). - * - * <informalexample> - * <programlisting> - * GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT; - * </programlisting> - </informalexample> - **/ - -/** - * g_static_rec_mutex_init: - * @mutex: a #GStaticRecMutex to be initialized. - * - * A #GStaticRecMutex must be initialized with this function before it - * can be used. Alternatively you can initialize it with - * #G_STATIC_REC_MUTEX_INIT. - **/ -void -g_static_rec_mutex_init (GStaticRecMutex *mutex) -{ - static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT; - - g_return_if_fail (mutex); - - *mutex = init_mutex; -} - -/** - * g_static_rec_mutex_lock: - * @mutex: a #GStaticRecMutex to lock. - * - * Locks @mutex. If @mutex is already locked by another thread, the - * current thread will block until @mutex is unlocked by the other - * thread. If @mutex is already locked by the calling thread, this - * functions increases the depth of @mutex and returns immediately. - **/ -void -g_static_rec_mutex_lock (GStaticRecMutex* mutex) -{ - GSystemThread self; - - g_return_if_fail (mutex); - - if (!g_thread_supported ()) - return; - - G_THREAD_UF (thread_self, (&self)); - - if (g_system_thread_equal (self, mutex->owner)) - { - mutex->depth++; - return; - } - g_static_mutex_lock (&mutex->mutex); - g_system_thread_assign (mutex->owner, self); - mutex->depth = 1; -} - -/** - * g_static_rec_mutex_trylock: - * @mutex: a #GStaticRecMutex to lock. - * @Returns: %TRUE, if @mutex could be locked. - * - * Tries to lock @mutex. If @mutex is already locked by another thread, - * it immediately returns %FALSE. Otherwise it locks @mutex and returns - * %TRUE. If @mutex is already locked by the calling thread, this - * functions increases the depth of @mutex and immediately returns - * %TRUE. - **/ -gboolean -g_static_rec_mutex_trylock (GStaticRecMutex* mutex) -{ - GSystemThread self; - - g_return_val_if_fail (mutex, FALSE); - - if (!g_thread_supported ()) - return TRUE; - - G_THREAD_UF (thread_self, (&self)); - - if (g_system_thread_equal (self, mutex->owner)) - { - mutex->depth++; - return TRUE; - } - - if (!g_static_mutex_trylock (&mutex->mutex)) - return FALSE; - - g_system_thread_assign (mutex->owner, self); - mutex->depth = 1; - return TRUE; -} - -/** - * g_static_rec_mutex_unlock: - * @mutex: a #GStaticRecMutex to unlock. - * - * Unlocks @mutex. Another thread will be allowed to lock @mutex only - * when it has been unlocked as many times as it had been locked - * before. If @mutex is completely unlocked and another thread is - * blocked in a g_static_rec_mutex_lock() call for @mutex, it will be - * woken and can lock @mutex itself. - **/ -void -g_static_rec_mutex_unlock (GStaticRecMutex* mutex) -{ - g_return_if_fail (mutex); - - if (!g_thread_supported ()) - return; - - if (mutex->depth > 1) - { - mutex->depth--; - return; - } - g_system_thread_assign (mutex->owner, zero_thread); - g_static_mutex_unlock (&mutex->mutex); -} - -/** - * g_static_rec_mutex_lock_full: - * @mutex: a #GStaticRecMutex to lock. - * @depth: number of times this mutex has to be unlocked to be - * completely unlocked. - * - * Works like calling g_static_rec_mutex_lock() for @mutex @depth times. - **/ -void -g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, - guint depth) -{ - GSystemThread self; - g_return_if_fail (mutex); - - if (!g_thread_supported ()) - return; - - if (depth == 0) - return; - - G_THREAD_UF (thread_self, (&self)); - - if (g_system_thread_equal (self, mutex->owner)) - { - mutex->depth += depth; - return; - } - g_static_mutex_lock (&mutex->mutex); - g_system_thread_assign (mutex->owner, self); - mutex->depth = depth; -} - -/** - * g_static_rec_mutex_unlock_full: - * @mutex: a #GStaticRecMutex to completely unlock. - * @Returns: number of times @mutex has been locked by the current - * thread. - * - * Completely unlocks @mutex. If another thread is blocked in a - * g_static_rec_mutex_lock() call for @mutex, it will be woken and can - * lock @mutex itself. This function returns the number of times that - * @mutex has been locked by the current thread. To restore the state - * before the call to g_static_rec_mutex_unlock_full() you can call - * g_static_rec_mutex_lock_full() with the depth returned by this - * function. - **/ -guint -g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex) -{ - guint depth; - - g_return_val_if_fail (mutex, 0); - - if (!g_thread_supported ()) - return 1; - - depth = mutex->depth; - - g_system_thread_assign (mutex->owner, zero_thread); - mutex->depth = 0; - g_static_mutex_unlock (&mutex->mutex); - - return depth; -} - -/** - * g_static_rec_mutex_free: - * @mutex: a #GStaticRecMutex to be freed. - * - * Releases all resources allocated to a #GStaticRecMutex. - * - * You don't have to call this functions for a #GStaticRecMutex with an - * unbounded lifetime, i.e. objects declared 'static', but if you have - * a #GStaticRecMutex as a member of a structure and the structure is - * freed, you should also free the #GStaticRecMutex. - **/ -void -g_static_rec_mutex_free (GStaticRecMutex *mutex) -{ - g_return_if_fail (mutex); - - g_static_mutex_free (&mutex->mutex); -} - -/* GStaticPrivate {{{1 ---------------------------------------------------- */ - -/** - * GStaticPrivate: - * - * A #GStaticPrivate works almost like a #GPrivate, but it has one - * significant advantage. It doesn't need to be created at run-time - * like a #GPrivate, but can be defined at compile-time. This is - * similar to the difference between #GMutex and #GStaticMutex. Now - * look at our <function>give_me_next_number()</function> example with - * #GStaticPrivate: - * - * <example> - * <title>Using GStaticPrivate for per-thread data</title> - * <programlisting> - * int - * give_me_next_number (<!-- -->) - * { - * static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT; - * int *current_number = g_static_private_get (&current_number_key); - * - * if (!current_number) - * { - * current_number = g_new (int,1); - * *current_number = 0; - * g_static_private_set (&current_number_key, current_number, g_free); - * } - * - * *current_number = calc_next_number (*current_number); - * - * return *current_number; - * } - * </programlisting> - * </example> - **/ - -/** - * G_STATIC_PRIVATE_INIT: - * - * Every #GStaticPrivate must be initialized with this macro, before it - * can be used. - * - * <informalexample> - * <programlisting> - * GStaticPrivate my_private = G_STATIC_PRIVATE_INIT; - * </programlisting> - * </informalexample> - **/ - -/** - * g_static_private_init: - * @private_key: a #GStaticPrivate to be initialized. - * - * Initializes @private_key. Alternatively you can initialize it with - * #G_STATIC_PRIVATE_INIT. - **/ -void -g_static_private_init (GStaticPrivate *private_key) -{ - private_key->index = 0; -} - -/** - * g_static_private_get: - * @private_key: a #GStaticPrivate. - * @Returns: the corresponding pointer. - * - * Works like g_private_get() only for a #GStaticPrivate. - * - * This function works even if g_thread_init() has not yet been called. - **/ -gpointer -g_static_private_get (GStaticPrivate *private_key) -{ - GRealThread *self = (GRealThread*) g_thread_self (); - GArray *array; - gpointer ret = NULL; - - LOCK_PRIVATE_DATA (self); - - array = self->private_data; - - if (array && private_key->index != 0 && private_key->index <= array->len) - ret = g_array_index (array, GStaticPrivateNode, - private_key->index - 1).data; - - UNLOCK_PRIVATE_DATA (self); - return ret; -} - -/** - * g_static_private_set: - * @private_key: a #GStaticPrivate. - * @data: the new pointer. - * @notify: a function to be called with the pointer whenever the - * current thread ends or sets this pointer again. - * - * Sets the pointer keyed to @private_key for the current thread and - * the function @notify to be called with that pointer (%NULL or - * non-%NULL), whenever the pointer is set again or whenever the - * current thread ends. - * - * This function works even if g_thread_init() has not yet been called. - * If g_thread_init() is called later, the @data keyed to @private_key - * will be inherited only by the main thread, i.e. the one that called - * g_thread_init(). - * - * <note><para>@notify is used quite differently from @destructor in - * g_private_new().</para></note> - **/ -void -g_static_private_set (GStaticPrivate *private_key, - gpointer data, - GDestroyNotify notify) -{ - GRealThread *self = (GRealThread*) g_thread_self (); - GArray *array; - static guint next_index = 0; - GStaticPrivateNode *node; - gpointer ddata = NULL; - GDestroyNotify ddestroy = NULL; - - if (!private_key->index) - { - G_LOCK (g_thread); - - if (!private_key->index) - { - if (g_thread_free_indices) - { - private_key->index = - GPOINTER_TO_UINT (g_thread_free_indices->data); - g_thread_free_indices = - g_slist_delete_link (g_thread_free_indices, - g_thread_free_indices); - } - else - private_key->index = ++next_index; - } - - G_UNLOCK (g_thread); - } - - LOCK_PRIVATE_DATA (self); - - array = self->private_data; - if (!array) - { - array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode)); - self->private_data = array; - } - - if (private_key->index > array->len) - g_array_set_size (array, private_key->index); - - node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1); - - ddata = node->data; - ddestroy = node->destroy; - - node->data = data; - node->destroy = notify; - - UNLOCK_PRIVATE_DATA (self); - - if (ddestroy) - ddestroy (ddata); -} - -/** - * g_static_private_free: - * @private_key: a #GStaticPrivate to be freed. - * - * Releases all resources allocated to @private_key. - * - * You don't have to call this functions for a #GStaticPrivate with an - * unbounded lifetime, i.e. objects declared 'static', but if you have - * a #GStaticPrivate as a member of a structure and the structure is - * freed, you should also free the #GStaticPrivate. - **/ -void -g_static_private_free (GStaticPrivate *private_key) -{ - guint idx = private_key->index; - GRealThread *thread, *next; - GArray *garbage = NULL; - - if (!idx) - return; - - private_key->index = 0; - - G_LOCK (g_thread); - - thread = g_thread_all_threads; - - for (thread = g_thread_all_threads; thread; thread = next) - { - GArray *array; - - next = thread->next; - - LOCK_PRIVATE_DATA (thread); - - array = thread->private_data; - - if (array && idx <= array->len) - { - GStaticPrivateNode *node = &g_array_index (array, - GStaticPrivateNode, - idx - 1); - gpointer ddata = node->data; - GDestroyNotify ddestroy = node->destroy; - - node->data = NULL; - node->destroy = NULL; - - if (ddestroy) - { - /* defer non-trivial destruction til after we've finished - * iterating, since we must continue to hold the lock */ - if (garbage == NULL) - garbage = g_array_new (FALSE, TRUE, - sizeof (GStaticPrivateNode)); - - g_array_set_size (garbage, garbage->len + 1); - - node = &g_array_index (garbage, GStaticPrivateNode, - garbage->len - 1); - node->data = ddata; - node->destroy = ddestroy; - } - } - - UNLOCK_PRIVATE_DATA (thread); - } - g_thread_free_indices = g_slist_prepend (g_thread_free_indices, - GUINT_TO_POINTER (idx)); - G_UNLOCK (g_thread); - - if (garbage) - { - guint i; - - for (i = 0; i < garbage->len; i++) - { - GStaticPrivateNode *node; - - node = &g_array_index (garbage, GStaticPrivateNode, i); - node->destroy (node->data); - } - - g_array_free (garbage, TRUE); - } -} - -/* GThread Extra Functions {{{1 ------------------------------------------- */ -static void -g_thread_cleanup (gpointer data) -{ - if (data) - { - GRealThread* thread = data; - GArray *array; - - LOCK_PRIVATE_DATA (thread); - array = thread->private_data; - thread->private_data = NULL; - UNLOCK_PRIVATE_DATA (thread); - - if (array) - { - guint i; - - for (i = 0; i < array->len; i++ ) - { - GStaticPrivateNode *node = - &g_array_index (array, GStaticPrivateNode, i); - if (node->destroy) - node->destroy (node->data); - } - g_array_free (array, TRUE); - } - - /* We only free the thread structure, if it isn't joinable. If - it is, the structure is freed in g_thread_join */ - if (!thread->thread.joinable) - { - GRealThread *t, *p; - - G_LOCK (g_thread); - for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) - { - if (t == thread) - { - if (p) - p->next = t->next; - else - g_thread_all_threads = t->next; - break; - } - } - G_UNLOCK (g_thread); - - /* Just to make sure, this isn't used any more */ - g_system_thread_assign (thread->system_thread, zero_thread); - g_free (thread); - } - } -} - -static void -g_thread_fail (void) -{ - g_error ("The thread system is not yet initialized."); -} - -#define G_NSEC_PER_SEC 1000000000 -#define G_USEC_PER_SEC 1000000 - -static guint64 -gettime (void) -{ -#ifdef G_OS_WIN32 - guint64 v; - - /* Returns 100s of nanoseconds since start of 1601 */ - GetSystemTimeAsFileTime ((FILETIME *)&v); - - /* Offset to Unix epoch */ - v -= G_GINT64_CONSTANT (116444736000000000); - /* Convert to nanoseconds */ - v *= 100; - - return v; -#else - struct timeval tv; - - gettimeofday (&tv, NULL); - - return (guint64) tv.tv_sec * G_NSEC_PER_SEC + tv.tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC); -#endif -} - -static gpointer -g_thread_create_proxy (gpointer data) -{ - GRealThread* thread = data; - - g_assert (data); - - /* This has to happen before G_LOCK, as that might call g_thread_self */ - g_private_set (g_thread_specific_private, data); - - /* the lock makes sure, that thread->system_thread is written, - before thread->thread.func is called. See g_thread_create. */ - G_LOCK (g_thread); - G_UNLOCK (g_thread); - - thread->retval = thread->thread.func (thread->thread.data); - - return NULL; -} - -/** - * g_thread_create_full: - * @func: a function to execute in the new thread. - * @data: an argument to supply to the new thread. - * @stack_size: a stack size for the new thread. - * @joinable: should this thread be joinable? - * @bound: should this thread be bound to a system thread? - * @priority: a priority for the thread. - * @error: return location for error. - * @Returns: the new #GThread on success. - * - * This function creates a new thread with the priority @priority. If - * the underlying thread implementation supports it, the thread gets a - * stack size of @stack_size or the default value for the current - * platform, if @stack_size is 0. - * - * If @joinable is %TRUE, you can wait for this threads termination - * calling g_thread_join(). Otherwise the thread will just disappear - * when it terminates. If @bound is %TRUE, this thread will be - * scheduled in the system scope, otherwise the implementation is free - * to do scheduling in the process scope. The first variant is more - * expensive resource-wise, but generally faster. On some systems (e.g. - * Linux) all threads are bound. - * - * The new thread executes the function @func with the argument @data. - * If the thread was created successfully, it is returned. - * - * @error can be %NULL to ignore errors, or non-%NULL to report errors. - * The error is set, if and only if the function returns %NULL. - * - * <note><para>It is not guaranteed that threads with different priorities - * really behave accordingly. On some systems (e.g. Linux) there are no - * thread priorities. On other systems (e.g. Solaris) there doesn't - * seem to be different scheduling for different priorities. All in all - * try to avoid being dependent on priorities. Use - * %G_THREAD_PRIORITY_NORMAL here as a default.</para></note> - * - * <note><para>Only use g_thread_create_full() if you really can't use - * g_thread_create() instead. g_thread_create() does not take - * @stack_size, @bound, and @priority as arguments, as they should only - * be used in cases in which it is unavoidable.</para></note> - **/ -GThread* -g_thread_create_full (GThreadFunc func, - gpointer data, - gulong stack_size, - gboolean joinable, - gboolean bound, - GThreadPriority priority, - GError **error) -{ - GRealThread* result; - GError *local_error = NULL; - g_return_val_if_fail (func, NULL); - g_return_val_if_fail (priority >= G_THREAD_PRIORITY_LOW, NULL); - g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL); - - result = g_new0 (GRealThread, 1); - - result->thread.joinable = joinable; - result->thread.priority = priority; - result->thread.func = func; - result->thread.data = data; - result->private_data = NULL; - G_LOCK (g_thread); - G_THREAD_UF (thread_create, (g_thread_create_proxy, result, - stack_size, joinable, bound, priority, - &result->system_thread, &local_error)); - if (!local_error) - { - result->next = g_thread_all_threads; - g_thread_all_threads = result; - } - G_UNLOCK (g_thread); - - if (local_error) - { - g_propagate_error (error, local_error); - g_free (result); - return NULL; - } - - return (GThread*) result; -} - -/** - * g_thread_exit: - * @retval: the return value of this thread. - * - * Exits the current thread. If another thread is waiting for that - * thread using g_thread_join() and the current thread is joinable, the - * waiting thread will be woken up and get @retval as the return value - * of g_thread_join(). If the current thread is not joinable, @retval - * is ignored. Calling - * - * <informalexample> - * <programlisting> - * g_thread_exit (retval); - * </programlisting> - * </informalexample> - * - * is equivalent to returning @retval from the function @func, as given - * to g_thread_create(). - * - * <note><para>Never call g_thread_exit() from within a thread of a - * #GThreadPool, as that will mess up the bookkeeping and lead to funny - * and unwanted results.</para></note> - **/ -void -g_thread_exit (gpointer retval) -{ - GRealThread* real = (GRealThread*) g_thread_self (); - real->retval = retval; - G_THREAD_CF (thread_exit, (void)0, ()); -} - -/** - * g_thread_join: - * @thread: a #GThread to be waited for. - * @Returns: the return value of the thread. - * - * Waits until @thread finishes, i.e. the function @func, as given to - * g_thread_create(), returns or g_thread_exit() is called by @thread. - * All resources of @thread including the #GThread struct are released. - * @thread must have been created with @joinable=%TRUE in - * g_thread_create(). The value returned by @func or given to - * g_thread_exit() by @thread is returned by this function. - **/ -gpointer -g_thread_join (GThread* thread) -{ - GRealThread* real = (GRealThread*) thread; - GRealThread *p, *t; - gpointer retval; - - g_return_val_if_fail (thread, NULL); - g_return_val_if_fail (thread->joinable, NULL); - g_return_val_if_fail (!g_system_thread_equal (real->system_thread, - zero_thread), NULL); - - G_THREAD_UF (thread_join, (&real->system_thread)); - - retval = real->retval; - - G_LOCK (g_thread); - for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next) - { - if (t == (GRealThread*) thread) - { - if (p) - p->next = t->next; - else - g_thread_all_threads = t->next; - break; - } - } - G_UNLOCK (g_thread); - - /* Just to make sure, this isn't used any more */ - thread->joinable = 0; - g_system_thread_assign (real->system_thread, zero_thread); - - /* the thread structure for non-joinable threads is freed upon - thread end. We free the memory here. This will leave a loose end, - if a joinable thread is not joined. */ - - g_free (thread); - - return retval; -} - -/** - * g_thread_set_priority: - * @thread: a #GThread. - * @priority: a new priority for @thread. - * - * Changes the priority of @thread to @priority. - * - * <note><para>It is not guaranteed that threads with different - * priorities really behave accordingly. On some systems (e.g. Linux) - * there are no thread priorities. On other systems (e.g. Solaris) there - * doesn't seem to be different scheduling for different priorities. All - * in all try to avoid being dependent on priorities.</para></note> - **/ -void -g_thread_set_priority (GThread* thread, - GThreadPriority priority) -{ - GRealThread* real = (GRealThread*) thread; - - g_return_if_fail (thread); - g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread)); - g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW); - g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT); - - thread->priority = priority; - - G_THREAD_CF (thread_set_priority, (void)0, - (&real->system_thread, priority)); -} - -/** - * g_thread_self: - * @Returns: the current thread. - * - * This functions returns the #GThread corresponding to the calling - * thread. - **/ -GThread* -g_thread_self (void) -{ - GRealThread* thread = g_private_get (g_thread_specific_private); - - if (!thread) - { - /* If no thread data is available, provide and set one. This - can happen for the main thread and for threads, that are not - created by GLib. */ - thread = g_new0 (GRealThread, 1); - thread->thread.joinable = FALSE; /* This is a save guess */ - thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is - just a guess */ - thread->thread.func = NULL; - thread->thread.data = NULL; - thread->private_data = NULL; - - if (g_thread_supported ()) - G_THREAD_UF (thread_self, (&thread->system_thread)); - - g_private_set (g_thread_specific_private, thread); - - G_LOCK (g_thread); - thread->next = g_thread_all_threads; - g_thread_all_threads = thread; - G_UNLOCK (g_thread); - } - - return (GThread*)thread; -} - -/* GStaticRWLock {{{1 ----------------------------------------------------- */ - -/** - * GStaticRWLock: - * - * The #GStaticRWLock struct represents a read-write lock. A read-write - * lock can be used for protecting data that some portions of code only - * read from, while others also write. In such situations it is - * desirable that several readers can read at once, whereas of course - * only one writer may write at a time. Take a look at the following - * example: - * - * <example> - * <title>An array with access functions</title> - * <programlisting> - * GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT; - * GPtrArray *array; - * - * gpointer - * my_array_get (guint index) - * { - * gpointer retval = NULL; - * - * if (!array) - * return NULL; - * - * g_static_rw_lock_reader_lock (&rwlock); - * if (index < array->len) - * retval = g_ptr_array_index (array, index); - * g_static_rw_lock_reader_unlock (&rwlock); - * - * return retval; - * } - * - * void - * my_array_set (guint index, gpointer data) - * { - * g_static_rw_lock_writer_lock (&rwlock); - * - * if (!array) - * array = g_ptr_array_new (<!-- -->); - * - * if (index >= array->len) - * g_ptr_array_set_size (array, index+1); - * g_ptr_array_index (array, index) = data; - * - * g_static_rw_lock_writer_unlock (&rwlock); - * } - * </programlisting> - * </example> - * - * This example shows an array which can be accessed by many readers - * (the <function>my_array_get()</function> function) simultaneously, - * whereas the writers (the <function>my_array_set()</function> - * function) will only be allowed once at a time and only if no readers - * currently access the array. This is because of the potentially - * dangerous resizing of the array. Using these functions is fully - * multi-thread safe now. - * - * Most of the time, writers should have precedence over readers. That - * means, for this implementation, that as soon as a writer wants to - * lock the data, no other reader is allowed to lock the data, whereas, - * of course, the readers that already have locked the data are allowed - * to finish their operation. As soon as the last reader unlocks the - * data, the writer will lock it. - * - * Even though #GStaticRWLock is not opaque, it should only be used - * with the following functions. - * - * All of the <function>g_static_rw_lock_*</function> functions can be - * used even if g_thread_init() has not been called. Then they do - * nothing, apart from <function>g_static_rw_lock_*_trylock</function>, - * which does nothing but returning %TRUE. - * - * <note><para>A read-write lock has a higher overhead than a mutex. For - * example, both g_static_rw_lock_reader_lock() and - * g_static_rw_lock_reader_unlock() have to lock and unlock a - * #GStaticMutex, so it takes at least twice the time to lock and unlock - * a #GStaticRWLock that it does to lock and unlock a #GStaticMutex. So - * only data structures that are accessed by multiple readers, and which - * keep the lock for a considerable time justify a #GStaticRWLock. The - * above example most probably would fare better with a - * #GStaticMutex.</para></note> - **/ - -/** - * G_STATIC_RW_LOCK_INIT: - * - * A #GStaticRWLock must be initialized with this macro before it can - * be used. This macro can used be to initialize a variable, but it - * cannot be assigned to a variable. In that case you have to use - * g_static_rw_lock_init(). - * - * <informalexample> - * <programlisting> - * GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT; - * </programlisting> - * </informalexample> - **/ - -/** - * g_static_rw_lock_init: - * @lock: a #GStaticRWLock to be initialized. - * - * A #GStaticRWLock must be initialized with this function before it - * can be used. Alternatively you can initialize it with - * #G_STATIC_RW_LOCK_INIT. - **/ -void -g_static_rw_lock_init (GStaticRWLock* lock) -{ - static const GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT; - - g_return_if_fail (lock); - - *lock = init_lock; -} - -inline static void -g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex) -{ - if (!*cond) - *cond = g_cond_new (); - g_cond_wait (*cond, g_static_mutex_get_mutex (mutex)); -} - -inline static void -g_static_rw_lock_signal (GStaticRWLock* lock) -{ - if (lock->want_to_write && lock->write_cond) - g_cond_signal (lock->write_cond); - else if (lock->want_to_read && lock->read_cond) - g_cond_broadcast (lock->read_cond); -} - -/** - * g_static_rw_lock_reader_lock: - * @lock: a #GStaticRWLock to lock for reading. - * - * Locks @lock for reading. There may be unlimited concurrent locks for - * reading of a #GStaticRWLock at the same time. If @lock is already - * locked for writing by another thread or if another thread is already - * waiting to lock @lock for writing, this function will block until - * @lock is unlocked by the other writing thread and no other writing - * threads want to lock @lock. This lock has to be unlocked by - * g_static_rw_lock_reader_unlock(). - * - * #GStaticRWLock is not recursive. It might seem to be possible to - * recursively lock for reading, but that can result in a deadlock, due - * to writer preference. - **/ -void -g_static_rw_lock_reader_lock (GStaticRWLock* lock) -{ - g_return_if_fail (lock); - - if (!g_threads_got_initialized) - return; - - g_static_mutex_lock (&lock->mutex); - lock->want_to_read++; - while (lock->have_writer || lock->want_to_write) - g_static_rw_lock_wait (&lock->read_cond, &lock->mutex); - lock->want_to_read--; - lock->read_counter++; - g_static_mutex_unlock (&lock->mutex); -} - -/** - * g_static_rw_lock_reader_trylock: - * @lock: a #GStaticRWLock to lock for reading. - * @Returns: %TRUE, if @lock could be locked for reading. - * - * Tries to lock @lock for reading. If @lock is already locked for - * writing by another thread or if another thread is already waiting to - * lock @lock for writing, immediately returns %FALSE. Otherwise locks - * @lock for reading and returns %TRUE. This lock has to be unlocked by - * g_static_rw_lock_reader_unlock(). - **/ -gboolean -g_static_rw_lock_reader_trylock (GStaticRWLock* lock) -{ - gboolean ret_val = FALSE; - - g_return_val_if_fail (lock, FALSE); - - if (!g_threads_got_initialized) - return TRUE; - - g_static_mutex_lock (&lock->mutex); - if (!lock->have_writer && !lock->want_to_write) - { - lock->read_counter++; - ret_val = TRUE; - } - g_static_mutex_unlock (&lock->mutex); - return ret_val; -} - -/** - * g_static_rw_lock_reader_unlock: - * @lock: a #GStaticRWLock to unlock after reading. - * - * Unlocks @lock. If a thread waits to lock @lock for writing and all - * locks for reading have been unlocked, the waiting thread is woken up - * and can lock @lock for writing. - **/ -void -g_static_rw_lock_reader_unlock (GStaticRWLock* lock) -{ - g_return_if_fail (lock); - - if (!g_threads_got_initialized) - return; - - g_static_mutex_lock (&lock->mutex); - lock->read_counter--; - if (lock->read_counter == 0) - g_static_rw_lock_signal (lock); - g_static_mutex_unlock (&lock->mutex); -} - -/** - * g_static_rw_lock_writer_lock: - * @lock: a #GStaticRWLock to lock for writing. - * - * Locks @lock for writing. If @lock is already locked for writing or - * reading by other threads, this function will block until @lock is - * completely unlocked and then lock @lock for writing. While this - * functions waits to lock @lock, no other thread can lock @lock for - * reading. When @lock is locked for writing, no other thread can lock - * @lock (neither for reading nor writing). This lock has to be - * unlocked by g_static_rw_lock_writer_unlock(). - **/ -void -g_static_rw_lock_writer_lock (GStaticRWLock* lock) -{ - g_return_if_fail (lock); - - if (!g_threads_got_initialized) - return; - - g_static_mutex_lock (&lock->mutex); - lock->want_to_write++; - while (lock->have_writer || lock->read_counter) - g_static_rw_lock_wait (&lock->write_cond, &lock->mutex); - lock->want_to_write--; - lock->have_writer = TRUE; - g_static_mutex_unlock (&lock->mutex); -} - -/** - * g_static_rw_lock_writer_trylock: - * @lock: a #GStaticRWLock to lock for writing. - * @Returns: %TRUE, if @lock could be locked for writing. - * - * Tries to lock @lock for writing. If @lock is already locked (for - * either reading or writing) by another thread, it immediately returns - * %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This - * lock has to be unlocked by g_static_rw_lock_writer_unlock(). - **/ -gboolean -g_static_rw_lock_writer_trylock (GStaticRWLock* lock) -{ - gboolean ret_val = FALSE; - - g_return_val_if_fail (lock, FALSE); - - if (!g_threads_got_initialized) - return TRUE; - - g_static_mutex_lock (&lock->mutex); - if (!lock->have_writer && !lock->read_counter) - { - lock->have_writer = TRUE; - ret_val = TRUE; - } - g_static_mutex_unlock (&lock->mutex); - return ret_val; -} - -/** - * g_static_rw_lock_writer_unlock: - * @lock: a #GStaticRWLock to unlock after writing. - * - * Unlocks @lock. If a thread is waiting to lock @lock for writing and - * all locks for reading have been unlocked, the waiting thread is - * woken up and can lock @lock for writing. If no thread is waiting to - * lock @lock for writing, and some thread or threads are waiting to - * lock @lock for reading, the waiting threads are woken up and can - * lock @lock for reading. - **/ -void -g_static_rw_lock_writer_unlock (GStaticRWLock* lock) -{ - g_return_if_fail (lock); - - if (!g_threads_got_initialized) - return; - - g_static_mutex_lock (&lock->mutex); - lock->have_writer = FALSE; - g_static_rw_lock_signal (lock); - g_static_mutex_unlock (&lock->mutex); -} - -/** - * g_static_rw_lock_free: - * @lock: a #GStaticRWLock to be freed. - * - * Releases all resources allocated to @lock. - * - * You don't have to call this functions for a #GStaticRWLock with an - * unbounded lifetime, i.e. objects declared 'static', but if you have - * a #GStaticRWLock as a member of a structure, and the structure is - * freed, you should also free the #GStaticRWLock. - **/ -void -g_static_rw_lock_free (GStaticRWLock* lock) -{ - g_return_if_fail (lock); - - if (lock->read_cond) - { - g_cond_free (lock->read_cond); - lock->read_cond = NULL; - } - if (lock->write_cond) - { - g_cond_free (lock->write_cond); - lock->write_cond = NULL; - } - g_static_mutex_free (&lock->mutex); -} - -/* Unsorted {{{1 ---------------------------------------------------------- */ - -/** - * g_thread_foreach - * @thread_func: function to call for all GThread structures - * @user_data: second argument to @thread_func - * - * Call @thread_func on all existing #GThread structures. Note that - * threads may decide to exit while @thread_func is running, so - * without intimate knowledge about the lifetime of foreign threads, - * @thread_func shouldn't access the GThread* pointer passed in as - * first argument. However, @thread_func will not be called for threads - * which are known to have exited already. - * - * Due to thread lifetime checks, this function has an execution complexity - * which is quadratic in the number of existing threads. - * - * Since: 2.10 - */ -void -g_thread_foreach (GFunc thread_func, - gpointer user_data) -{ - GSList *slist = NULL; - GRealThread *thread; - g_return_if_fail (thread_func != NULL); - /* snapshot the list of threads for iteration */ - G_LOCK (g_thread); - for (thread = g_thread_all_threads; thread; thread = thread->next) - slist = g_slist_prepend (slist, thread); - G_UNLOCK (g_thread); - /* walk the list, skipping non-existent threads */ - while (slist) - { - GSList *node = slist; - slist = node->next; - /* check whether the current thread still exists */ - G_LOCK (g_thread); - for (thread = g_thread_all_threads; thread; thread = thread->next) - if (thread == node->data) - break; - G_UNLOCK (g_thread); - if (thread) - thread_func (thread, user_data); - g_slist_free_1 (node); - } -} - -/** - * g_thread_get_initialized - * - * Indicates if g_thread_init() has been called. - * - * Returns: %TRUE if threads have been initialized. - * - * Since: 2.20 - */ -gboolean -g_thread_get_initialized () -{ - return g_thread_supported (); -} diff --git a/deps/glib/gthread.h b/deps/glib/gthread.h deleted file mode 100644 index 4d3999b1..00000000 --- a/deps/glib/gthread.h +++ /dev/null @@ -1,405 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_THREAD_H__ -#define __G_THREAD_H__ - -#include <glib/gerror.h> -#include <glib/gutils.h> /* for G_INLINE_FUNC */ -#include <glib/gatomic.h> /* for g_atomic_pointer_get */ - -G_BEGIN_DECLS - -/* GLib Thread support - */ - -extern GQuark g_thread_error_quark (void); -#define G_THREAD_ERROR g_thread_error_quark () - -typedef enum -{ - G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */ -} GThreadError; - -typedef gpointer (*GThreadFunc) (gpointer data); - -typedef enum -{ - G_THREAD_PRIORITY_LOW, - G_THREAD_PRIORITY_NORMAL, - G_THREAD_PRIORITY_HIGH, - G_THREAD_PRIORITY_URGENT -} GThreadPriority; - -typedef struct _GThread GThread; -struct _GThread -{ - /*< private >*/ - GThreadFunc func; - gpointer data; - gboolean joinable; - GThreadPriority priority; -}; - -typedef struct _GMutex GMutex; -typedef struct _GCond GCond; -typedef struct _GPrivate GPrivate; -typedef struct _GStaticPrivate GStaticPrivate; - -typedef struct _GThreadFunctions GThreadFunctions; -struct _GThreadFunctions -{ - GMutex* (*mutex_new) (void); - void (*mutex_lock) (GMutex *mutex); - gboolean (*mutex_trylock) (GMutex *mutex); - void (*mutex_unlock) (GMutex *mutex); - void (*mutex_free) (GMutex *mutex); - GCond* (*cond_new) (void); - void (*cond_signal) (GCond *cond); - void (*cond_broadcast) (GCond *cond); - void (*cond_wait) (GCond *cond, - GMutex *mutex); - gboolean (*cond_timed_wait) (GCond *cond, - GMutex *mutex, - GTimeVal *end_time); - void (*cond_free) (GCond *cond); - GPrivate* (*private_new) (GDestroyNotify destructor); - gpointer (*private_get) (GPrivate *private_key); - void (*private_set) (GPrivate *private_key, - gpointer data); - void (*thread_create) (GThreadFunc func, - gpointer data, - gulong stack_size, - gboolean joinable, - gboolean bound, - GThreadPriority priority, - gpointer thread, - GError **error); - void (*thread_yield) (void); - void (*thread_join) (gpointer thread); - void (*thread_exit) (void); - void (*thread_set_priority)(gpointer thread, - GThreadPriority priority); - void (*thread_self) (gpointer thread); - gboolean (*thread_equal) (gpointer thread1, - gpointer thread2); -}; - -GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use; -GLIB_VAR gboolean g_thread_use_default_impl; -GLIB_VAR gboolean g_threads_got_initialized; - -GLIB_VAR guint64 (*g_thread_gettime) (void); - -/* initializes the mutex/cond/private implementation for glib, might - * only be called once, and must not be called directly or indirectly - * from another glib-function, e.g. as a callback. - */ -void g_thread_init (GThreadFunctions *vtable); - -/* Errorcheck mutexes. If you define G_ERRORCHECK_MUTEXES, then all - * mutexes will check for re-locking and re-unlocking */ - -/* Initialize thread system with errorcheck mutexes. vtable must be - * NULL. Do not call directly. Use #define G_ERRORCHECK_MUTEXES - * instead. - */ -void g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable); - -/* Checks if thread support is initialized. Identical to the - * g_thread_supported macro but provided for language bindings. - */ -gboolean g_thread_get_initialized (void); - -/* A random number to recognize debug calls to g_mutex_... */ -#define G_MUTEX_DEBUG_MAGIC 0xf8e18ad7 - -#ifdef G_ERRORCHECK_MUTEXES -#define g_thread_init(vtable) g_thread_init_with_errorcheck_mutexes (vtable) -#endif - -/* internal function for fallback static mutex implementation */ -GMutex* g_static_mutex_get_mutex_impl (GMutex **mutex); - -#define g_static_mutex_get_mutex_impl_shortcut(mutex) \ - (g_atomic_pointer_get (mutex) ? *(mutex) : \ - g_static_mutex_get_mutex_impl (mutex)) - -/* shorthands for conditional and unconditional function calls */ - -#define G_THREAD_UF(op, arglist) \ - (*g_thread_functions_for_glib_use . op) arglist -#define G_THREAD_CF(op, fail, arg) \ - (g_thread_supported () ? G_THREAD_UF (op, arg) : (fail)) -#define G_THREAD_ECF(op, fail, mutex, type) \ - (g_thread_supported () ? \ - ((type(*)(GMutex*, const gulong, gchar const*)) \ - (*g_thread_functions_for_glib_use . op)) \ - (mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail)) - -#ifndef G_ERRORCHECK_MUTEXES -# define g_mutex_lock(mutex) \ - G_THREAD_CF (mutex_lock, (void)0, (mutex)) -# define g_mutex_trylock(mutex) \ - G_THREAD_CF (mutex_trylock, TRUE, (mutex)) -# define g_mutex_unlock(mutex) \ - G_THREAD_CF (mutex_unlock, (void)0, (mutex)) -# define g_mutex_free(mutex) \ - G_THREAD_CF (mutex_free, (void)0, (mutex)) -# define g_cond_wait(cond, mutex) \ - G_THREAD_CF (cond_wait, (void)0, (cond, mutex)) -# define g_cond_timed_wait(cond, mutex, abs_time) \ - G_THREAD_CF (cond_timed_wait, TRUE, (cond, mutex, abs_time)) -#else /* G_ERRORCHECK_MUTEXES */ -# define g_mutex_lock(mutex) \ - G_THREAD_ECF (mutex_lock, (void)0, (mutex), void) -# define g_mutex_trylock(mutex) \ - G_THREAD_ECF (mutex_trylock, TRUE, (mutex), gboolean) -# define g_mutex_unlock(mutex) \ - G_THREAD_ECF (mutex_unlock, (void)0, (mutex), void) -# define g_mutex_free(mutex) \ - G_THREAD_ECF (mutex_free, (void)0, (mutex), void) -# define g_cond_wait(cond, mutex) \ - (g_thread_supported () ? ((void(*)(GCond*, GMutex*, gulong, gchar*))\ - g_thread_functions_for_glib_use.cond_wait) \ - (cond, mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (void) 0) -# define g_cond_timed_wait(cond, mutex, abs_time) \ - (g_thread_supported () ? \ - ((gboolean(*)(GCond*, GMutex*, GTimeVal*, gulong, gchar*)) \ - g_thread_functions_for_glib_use.cond_timed_wait) \ - (cond, mutex, abs_time, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : TRUE) -#endif /* G_ERRORCHECK_MUTEXES */ - -#if defined(G_THREADS_ENABLED) && defined(G_THREADS_MANDATORY) -#define g_thread_supported() 1 -#else -#define g_thread_supported() (g_threads_got_initialized) -#endif -#define g_mutex_new() G_THREAD_UF (mutex_new, ()) -#define g_cond_new() G_THREAD_UF (cond_new, ()) -#define g_cond_signal(cond) G_THREAD_CF (cond_signal, (void)0, (cond)) -#define g_cond_broadcast(cond) G_THREAD_CF (cond_broadcast, (void)0, (cond)) -#define g_cond_free(cond) G_THREAD_CF (cond_free, (void)0, (cond)) -#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor)) -#define g_private_get(private_key) G_THREAD_CF (private_get, \ - ((gpointer)private_key), \ - (private_key)) -#define g_private_set(private_key, value) G_THREAD_CF (private_set, \ - (void) (private_key = \ - (GPrivate*) (value)), \ - (private_key, value)) -#define g_thread_yield() G_THREAD_CF (thread_yield, (void)0, ()) - -#define g_thread_create(func, data, joinable, error) \ - (g_thread_create_full (func, data, 0, joinable, FALSE, \ - G_THREAD_PRIORITY_NORMAL, error)) - -GThread* g_thread_create_full (GThreadFunc func, - gpointer data, - gulong stack_size, - gboolean joinable, - gboolean bound, - GThreadPriority priority, - GError **error); -GThread* g_thread_self (void); -void g_thread_exit (gpointer retval); -gpointer g_thread_join (GThread *thread); - -void g_thread_set_priority (GThread *thread, - GThreadPriority priority); - -/* GStaticMutexes can be statically initialized with the value - * G_STATIC_MUTEX_INIT, and then they can directly be used, that is - * much easier, than having to explicitly allocate the mutex before - * use - */ -#define g_static_mutex_lock(mutex) \ - g_mutex_lock (g_static_mutex_get_mutex (mutex)) -#define g_static_mutex_trylock(mutex) \ - g_mutex_trylock (g_static_mutex_get_mutex (mutex)) -#define g_static_mutex_unlock(mutex) \ - g_mutex_unlock (g_static_mutex_get_mutex (mutex)) -void g_static_mutex_init (GStaticMutex *mutex); -void g_static_mutex_free (GStaticMutex *mutex); - -struct _GStaticPrivate -{ - /*< private >*/ - guint index; -}; -#define G_STATIC_PRIVATE_INIT { 0 } -void g_static_private_init (GStaticPrivate *private_key); -gpointer g_static_private_get (GStaticPrivate *private_key); -void g_static_private_set (GStaticPrivate *private_key, - gpointer data, - GDestroyNotify notify); -void g_static_private_free (GStaticPrivate *private_key); - -typedef struct _GStaticRecMutex GStaticRecMutex; -struct _GStaticRecMutex -{ - /*< private >*/ - GStaticMutex mutex; - guint depth; - GSystemThread owner; -}; - -#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT, 0, {{0, 0, 0, 0}} } -void g_static_rec_mutex_init (GStaticRecMutex *mutex); -void g_static_rec_mutex_lock (GStaticRecMutex *mutex); -gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex); -void g_static_rec_mutex_unlock (GStaticRecMutex *mutex); -void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, - guint depth); -guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex); -void g_static_rec_mutex_free (GStaticRecMutex *mutex); - -typedef struct _GStaticRWLock GStaticRWLock; -struct _GStaticRWLock -{ - /*< private >*/ - GStaticMutex mutex; - GCond *read_cond; - GCond *write_cond; - guint read_counter; - gboolean have_writer; - guint want_to_read; - guint want_to_write; -}; - -#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 } - -void g_static_rw_lock_init (GStaticRWLock* lock); -void g_static_rw_lock_reader_lock (GStaticRWLock* lock); -gboolean g_static_rw_lock_reader_trylock (GStaticRWLock* lock); -void g_static_rw_lock_reader_unlock (GStaticRWLock* lock); -void g_static_rw_lock_writer_lock (GStaticRWLock* lock); -gboolean g_static_rw_lock_writer_trylock (GStaticRWLock* lock); -void g_static_rw_lock_writer_unlock (GStaticRWLock* lock); -void g_static_rw_lock_free (GStaticRWLock* lock); - -void g_thread_foreach (GFunc thread_func, - gpointer user_data); - -typedef enum -{ - G_ONCE_STATUS_NOTCALLED, - G_ONCE_STATUS_PROGRESS, - G_ONCE_STATUS_READY -} GOnceStatus; - -typedef struct _GOnce GOnce; -struct _GOnce -{ - volatile GOnceStatus status; - volatile gpointer retval; -}; - -#define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL } - -gpointer g_once_impl (GOnce *once, GThreadFunc func, gpointer arg); - -#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED -# define g_once(once, func, arg) g_once_impl ((once), (func), (arg)) -#else /* !G_ATOMIC_OP_MEMORY_BARRIER_NEEDED*/ -# define g_once(once, func, arg) \ - (((once)->status == G_ONCE_STATUS_READY) ? \ - (once)->retval : \ - g_once_impl ((once), (func), (arg))) -#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */ - -/* initialize-once guards, keyed by value_location */ -G_INLINE_FUNC gboolean g_once_init_enter (volatile gsize *value_location); -gboolean g_once_init_enter_impl (volatile gsize *value_location); -void g_once_init_leave (volatile gsize *value_location, - gsize initialization_value); -#if defined (G_CAN_INLINE) || defined (__G_THREAD_C__) -G_INLINE_FUNC gboolean -g_once_init_enter (volatile gsize *value_location) -{ - if G_LIKELY ((gpointer) g_atomic_pointer_get (value_location) != NULL) - return FALSE; - else - return g_once_init_enter_impl (value_location); -} -#endif /* G_CAN_INLINE || __G_THREAD_C__ */ - -/* these are some convenience macros that expand to nothing if GLib - * was configured with --disable-threads. for using StaticMutexes, - * you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name) - * if you need to export the mutex. With G_LOCK_EXTERN (name) you can - * declare such an globally defined lock. name is a unique identifier - * for the protected varibale or code portion. locking, testing and - * unlocking of such mutexes can be done with G_LOCK(), G_UNLOCK() and - * G_TRYLOCK() respectively. - */ -extern void glib_dummy_decl (void); -#define G_LOCK_NAME(name) g__ ## name ## _lock -#ifdef G_THREADS_ENABLED -# define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name) -# define G_LOCK_DEFINE(name) \ - GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT -# define G_LOCK_EXTERN(name) extern GStaticMutex G_LOCK_NAME (name) - -# ifdef G_DEBUG_LOCKS -# define G_LOCK(name) G_STMT_START{ \ - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \ - "file %s: line %d (%s): locking: %s ", \ - __FILE__, __LINE__, G_STRFUNC, \ - #name); \ - g_static_mutex_lock (&G_LOCK_NAME (name)); \ - }G_STMT_END -# define G_UNLOCK(name) G_STMT_START{ \ - g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \ - "file %s: line %d (%s): unlocking: %s ", \ - __FILE__, __LINE__, G_STRFUNC, \ - #name); \ - g_static_mutex_unlock (&G_LOCK_NAME (name)); \ - }G_STMT_END -# define G_TRYLOCK(name) \ - (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \ - "file %s: line %d (%s): try locking: %s ", \ - __FILE__, __LINE__, G_STRFUNC, \ - #name), g_static_mutex_trylock (&G_LOCK_NAME (name))) -# else /* !G_DEBUG_LOCKS */ -# define G_LOCK(name) g_static_mutex_lock (&G_LOCK_NAME (name)) -# define G_UNLOCK(name) g_static_mutex_unlock (&G_LOCK_NAME (name)) -# define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name)) -# endif /* !G_DEBUG_LOCKS */ -#else /* !G_THREADS_ENABLED */ -# define G_LOCK_DEFINE_STATIC(name) extern void glib_dummy_decl (void) -# define G_LOCK_DEFINE(name) extern void glib_dummy_decl (void) -# define G_LOCK_EXTERN(name) extern void glib_dummy_decl (void) -# define G_LOCK(name) -# define G_UNLOCK(name) -# define G_TRYLOCK(name) (TRUE) -#endif /* !G_THREADS_ENABLED */ - -G_END_DECLS - -#endif /* __G_THREAD_H__ */ diff --git a/deps/glib/gthreadprivate.h b/deps/glib/gthreadprivate.h deleted file mode 100644 index 7ebdadf4..00000000 --- a/deps/glib/gthreadprivate.h +++ /dev/null @@ -1,68 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * - * gthreadprivate.h - GLib internal thread system related declarations. - * - * Copyright (C) 2003 Sebastian Wilhelmi - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#ifndef __G_THREADPRIVATE_H__ -#define __G_THREADPRIVATE_H__ - -G_BEGIN_DECLS - -/* System thread identifier comparison and assignment */ -#if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P -# define g_system_thread_equal_simple(thread1, thread2) \ - ((thread1).dummy_pointer == (thread2).dummy_pointer) -# define g_system_thread_assign(dest, src) \ - ((dest).dummy_pointer = (src).dummy_pointer) -#else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */ -# define g_system_thread_equal_simple(thread1, thread2) \ - (memcmp (&(thread1), &(thread2), GLIB_SIZEOF_SYSTEM_THREAD) == 0) -# define g_system_thread_assign(dest, src) \ - (memcpy (&(dest), &(src), GLIB_SIZEOF_SYSTEM_THREAD)) -#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */ - -#define g_system_thread_equal(thread1, thread2) \ - (g_thread_functions_for_glib_use.thread_equal ? \ - g_thread_functions_for_glib_use.thread_equal (&(thread1), &(thread2)) :\ - g_system_thread_equal_simple((thread1), (thread2))) - -/* Is called from gthread/gthread-impl.c */ -void g_thread_init_glib (void); - -/* base initializers, may only use g_mutex_new(), g_cond_new() */ -G_GNUC_INTERNAL void _g_mem_thread_init_noprivate_nomessage (void); -/* initializers that may also use g_private_new() */ -G_GNUC_INTERNAL void _g_slice_thread_init_nomessage (void); -G_GNUC_INTERNAL void _g_messages_thread_init_nomessage (void); - -/* full fledged initializers */ -G_GNUC_INTERNAL void _g_convert_thread_init (void); -G_GNUC_INTERNAL void _g_rand_thread_init (void); -G_GNUC_INTERNAL void _g_main_thread_init (void); -G_GNUC_INTERNAL void _g_atomic_thread_init (void); -G_GNUC_INTERNAL void _g_utils_thread_init (void); -G_GNUC_INTERNAL void _g_futex_thread_init (void); - -#ifdef G_OS_WIN32 -G_GNUC_INTERNAL void _g_win32_thread_init (void); -#endif /* G_OS_WIN32 */ - -G_END_DECLS - -#endif /* __G_THREADPRIVATE_H__ */ diff --git a/deps/glib/gtypes.h b/deps/glib/gtypes.h deleted file mode 100644 index 0ad27297..00000000 --- a/deps/glib/gtypes.h +++ /dev/null @@ -1,459 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_TYPES_H__ -#define __G_TYPES_H__ - -#include <glibconfig.h> -#include <glib/gmacros.h> -#include <time.h> - -G_BEGIN_DECLS - -/* Provide type definitions for commonly used types. - * These are useful because a "gint8" can be adjusted - * to be 1 byte (8 bits) on all platforms. Similarly and - * more importantly, "gint32" can be adjusted to be - * 4 bytes (32 bits) on all platforms. - */ - -typedef char gchar; -typedef short gshort; -typedef long glong; -typedef int gint; -typedef gint gboolean; - -typedef unsigned char guchar; -typedef unsigned short gushort; -typedef unsigned long gulong; -typedef unsigned int guint; - -typedef float gfloat; -typedef double gdouble; - -/* Define min and max constants for the fixed size numerical types */ -#define G_MININT8 ((gint8) 0x80) -#define G_MAXINT8 ((gint8) 0x7f) -#define G_MAXUINT8 ((guint8) 0xff) - -#define G_MININT16 ((gint16) 0x8000) -#define G_MAXINT16 ((gint16) 0x7fff) -#define G_MAXUINT16 ((guint16) 0xffff) - -#define G_MININT32 ((gint32) 0x80000000) -#define G_MAXINT32 ((gint32) 0x7fffffff) -#define G_MAXUINT32 ((guint32) 0xffffffff) - -#define G_MININT64 ((gint64) G_GINT64_CONSTANT(0x8000000000000000)) -#define G_MAXINT64 G_GINT64_CONSTANT(0x7fffffffffffffff) -#define G_MAXUINT64 G_GINT64_CONSTANT(0xffffffffffffffffU) - -typedef void* gpointer; -typedef const void *gconstpointer; - -typedef gint (*GCompareFunc) (gconstpointer a, - gconstpointer b); -typedef gint (*GCompareDataFunc) (gconstpointer a, - gconstpointer b, - gpointer user_data); -typedef gboolean (*GEqualFunc) (gconstpointer a, - gconstpointer b); -typedef void (*GDestroyNotify) (gpointer data); -typedef void (*GFunc) (gpointer data, - gpointer user_data); -typedef guint (*GHashFunc) (gconstpointer key); -typedef void (*GHFunc) (gpointer key, - gpointer value, - gpointer user_data); - -/** - * GFreeFunc: - * @data: a data pointer - * - * Declares a type of function which takes an arbitrary - * data pointer argument and has no return value. It is - * not currently used in GLib or GTK+. - */ -typedef void (*GFreeFunc) (gpointer data); - -/** - * GTranslateFunc: - * @str: the untranslated string - * @data: user data specified when installing the function, e.g. - * in g_option_group_set_translate_func() - * - * The type of functions which are used to translate user-visible - * strings, for <option>--help</option> output. - * - * Returns: a translation of the string for the current locale. - * The returned string is owned by GLib and must not be freed. - */ -typedef const gchar * (*GTranslateFunc) (const gchar *str, - gpointer data); - - -/* Define some mathematical constants that aren't available - * symbolically in some strict ISO C implementations. - * - * Note that the large number of digits used in these definitions - * doesn't imply that GLib or current computers in general would be - * able to handle floating point numbers with an accuracy like this. - * It's mostly an exercise in futility and future proofing. For - * extended precision floating point support, look somewhere else - * than GLib. - */ -#define G_E 2.7182818284590452353602874713526624977572470937000 -#define G_LN2 0.69314718055994530941723212145817656807550013436026 -#define G_LN10 2.3025850929940456840179914546843642076011014886288 -#define G_PI 3.1415926535897932384626433832795028841971693993751 -#define G_PI_2 1.5707963267948966192313216916397514420985846996876 -#define G_PI_4 0.78539816339744830961566084581987572104929234984378 -#define G_SQRT2 1.4142135623730950488016887242096980785696718753769 - -/* Portable endian checks and conversions - * - * glibconfig.h defines G_BYTE_ORDER which expands to one of - * the below macros. - */ -#define G_LITTLE_ENDIAN 1234 -#define G_BIG_ENDIAN 4321 -#define G_PDP_ENDIAN 3412 /* unused, need specific PDP check */ - - -/* Basic bit swapping functions - */ -#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((guint16) ( \ - (guint16) ((guint16) (val) >> 8) | \ - (guint16) ((guint16) (val) << 8))) - -#define GUINT32_SWAP_LE_BE_CONSTANT(val) ((guint32) ( \ - (((guint32) (val) & (guint32) 0x000000ffU) << 24) | \ - (((guint32) (val) & (guint32) 0x0000ff00U) << 8) | \ - (((guint32) (val) & (guint32) 0x00ff0000U) >> 8) | \ - (((guint32) (val) & (guint32) 0xff000000U) >> 24))) - -#define GUINT64_SWAP_LE_BE_CONSTANT(val) ((guint64) ( \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x00000000000000ffU)) << 56) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x000000000000ff00U)) << 40) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x0000000000ff0000U)) << 24) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x00000000ff000000U)) << 8) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x000000ff00000000U)) >> 8) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x0000ff0000000000U)) >> 24) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0x00ff000000000000U)) >> 40) | \ - (((guint64) (val) & \ - (guint64) G_GINT64_CONSTANT (0xff00000000000000U)) >> 56))) - -/* Arch specific stuff for speed - */ -#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__) -# if defined (__i386__) -# define GUINT16_SWAP_LE_BE_IA32(val) \ - (G_GNUC_EXTENSION \ - ({ register guint16 __v, __x = ((guint16) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT16_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ ("rorw $8, %w0" \ - : "=r" (__v) \ - : "0" (__x) \ - : "cc"); \ - __v; })) -# if !defined (__i486__) && !defined (__i586__) \ - && !defined (__pentium__) && !defined (__i686__) \ - && !defined (__pentiumpro__) && !defined (__pentium4__) -# define GUINT32_SWAP_LE_BE_IA32(val) \ - (G_GNUC_EXTENSION \ - ({ register guint32 __v, __x = ((guint32) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ ("rorw $8, %w0\n\t" \ - "rorl $16, %0\n\t" \ - "rorw $8, %w0" \ - : "=r" (__v) \ - : "0" (__x) \ - : "cc"); \ - __v; })) -# else /* 486 and higher has bswap */ -# define GUINT32_SWAP_LE_BE_IA32(val) \ - (G_GNUC_EXTENSION \ - ({ register guint32 __v, __x = ((guint32) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ ("bswap %0" \ - : "=r" (__v) \ - : "0" (__x)); \ - __v; })) -# endif /* processor specific 32-bit stuff */ -# define GUINT64_SWAP_LE_BE_IA32(val) \ - (G_GNUC_EXTENSION \ - ({ union { guint64 __ll; \ - guint32 __l[2]; } __w, __r; \ - __w.__ll = ((guint64) (val)); \ - if (__builtin_constant_p (__w.__ll)) \ - __r.__ll = GUINT64_SWAP_LE_BE_CONSTANT (__w.__ll); \ - else \ - { \ - __r.__l[0] = GUINT32_SWAP_LE_BE (__w.__l[1]); \ - __r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]); \ - } \ - __r.__ll; })) - /* Possibly just use the constant version and let gcc figure it out? */ -# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA32 (val)) -# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA32 (val)) -# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA32 (val)) -# elif defined (__ia64__) -# define GUINT16_SWAP_LE_BE_IA64(val) \ - (G_GNUC_EXTENSION \ - ({ register guint16 __v, __x = ((guint16) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT16_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ __volatile__ ("shl %0 = %1, 48 ;;" \ - "mux1 %0 = %0, @rev ;;" \ - : "=r" (__v) \ - : "r" (__x)); \ - __v; })) -# define GUINT32_SWAP_LE_BE_IA64(val) \ - (G_GNUC_EXTENSION \ - ({ register guint32 __v, __x = ((guint32) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ __volatile__ ("shl %0 = %1, 32 ;;" \ - "mux1 %0 = %0, @rev ;;" \ - : "=r" (__v) \ - : "r" (__x)); \ - __v; })) -# define GUINT64_SWAP_LE_BE_IA64(val) \ - (G_GNUC_EXTENSION \ - ({ register guint64 __v, __x = ((guint64) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT64_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ __volatile__ ("mux1 %0 = %1, @rev ;;" \ - : "=r" (__v) \ - : "r" (__x)); \ - __v; })) -# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA64 (val)) -# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA64 (val)) -# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA64 (val)) -# elif defined (__x86_64__) -# define GUINT32_SWAP_LE_BE_X86_64(val) \ - (G_GNUC_EXTENSION \ - ({ register guint32 __v, __x = ((guint32) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ ("bswapl %0" \ - : "=r" (__v) \ - : "0" (__x)); \ - __v; })) -# define GUINT64_SWAP_LE_BE_X86_64(val) \ - (G_GNUC_EXTENSION \ - ({ register guint64 __v, __x = ((guint64) (val)); \ - if (__builtin_constant_p (__x)) \ - __v = GUINT64_SWAP_LE_BE_CONSTANT (__x); \ - else \ - __asm__ ("bswapq %0" \ - : "=r" (__v) \ - : "0" (__x)); \ - __v; })) - /* gcc seems to figure out optimal code for this on its own */ -# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) -# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86_64 (val)) -# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86_64 (val)) -# else /* generic gcc */ -# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) -# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val)) -# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val)) -# endif -#else /* generic */ -# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) -# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val)) -# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val)) -#endif /* generic */ - -#define GUINT16_SWAP_LE_PDP(val) ((guint16) (val)) -#define GUINT16_SWAP_BE_PDP(val) (GUINT16_SWAP_LE_BE (val)) -#define GUINT32_SWAP_LE_PDP(val) ((guint32) ( \ - (((guint32) (val) & (guint32) 0x0000ffffU) << 16) | \ - (((guint32) (val) & (guint32) 0xffff0000U) >> 16))) -#define GUINT32_SWAP_BE_PDP(val) ((guint32) ( \ - (((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \ - (((guint32) (val) & (guint32) 0xff00ff00U) >> 8))) - -/* The G*_TO_?E() macros are defined in glibconfig.h. - * The transformation is symmetric, so the FROM just maps to the TO. - */ -#define GINT16_FROM_LE(val) (GINT16_TO_LE (val)) -#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val)) -#define GINT16_FROM_BE(val) (GINT16_TO_BE (val)) -#define GUINT16_FROM_BE(val) (GUINT16_TO_BE (val)) -#define GINT32_FROM_LE(val) (GINT32_TO_LE (val)) -#define GUINT32_FROM_LE(val) (GUINT32_TO_LE (val)) -#define GINT32_FROM_BE(val) (GINT32_TO_BE (val)) -#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val)) - -#define GINT64_FROM_LE(val) (GINT64_TO_LE (val)) -#define GUINT64_FROM_LE(val) (GUINT64_TO_LE (val)) -#define GINT64_FROM_BE(val) (GINT64_TO_BE (val)) -#define GUINT64_FROM_BE(val) (GUINT64_TO_BE (val)) - -#define GLONG_FROM_LE(val) (GLONG_TO_LE (val)) -#define GULONG_FROM_LE(val) (GULONG_TO_LE (val)) -#define GLONG_FROM_BE(val) (GLONG_TO_BE (val)) -#define GULONG_FROM_BE(val) (GULONG_TO_BE (val)) - -#define GINT_FROM_LE(val) (GINT_TO_LE (val)) -#define GUINT_FROM_LE(val) (GUINT_TO_LE (val)) -#define GINT_FROM_BE(val) (GINT_TO_BE (val)) -#define GUINT_FROM_BE(val) (GUINT_TO_BE (val)) - -#define GSIZE_FROM_LE(val) (GSIZE_TO_LE (val)) -#define GSSIZE_FROM_LE(val) (GSSIZE_TO_LE (val)) -#define GSIZE_FROM_BE(val) (GSIZE_TO_BE (val)) -#define GSSIZE_FROM_BE(val) (GSSIZE_TO_BE (val)) - - -/* Portable versions of host-network order stuff - */ -#define g_ntohl(val) (GUINT32_FROM_BE (val)) -#define g_ntohs(val) (GUINT16_FROM_BE (val)) -#define g_htonl(val) (GUINT32_TO_BE (val)) -#define g_htons(val) (GUINT16_TO_BE (val)) - -/* IEEE Standard 754 Single Precision Storage Format (gfloat): - * - * 31 30 23 22 0 - * +--------+---------------+---------------+ - * | s 1bit | e[30:23] 8bit | f[22:0] 23bit | - * +--------+---------------+---------------+ - * B0------------------->B1------->B2-->B3--> - * - * IEEE Standard 754 Double Precision Storage Format (gdouble): - * - * 63 62 52 51 32 31 0 - * +--------+----------------+----------------+ +---------------+ - * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit | - * +--------+----------------+----------------+ +---------------+ - * B0--------------->B1---------->B2--->B3----> B4->B5->B6->B7-> - */ -/* subtract from biased_exponent to form base2 exponent (normal numbers) */ -typedef union _GDoubleIEEE754 GDoubleIEEE754; -typedef union _GFloatIEEE754 GFloatIEEE754; -#define G_IEEE754_FLOAT_BIAS (127) -#define G_IEEE754_DOUBLE_BIAS (1023) -/* multiply with base2 exponent to get base10 exponent (normal numbers) */ -#define G_LOG_2_BASE_10 (0.30102999566398119521) -#if G_BYTE_ORDER == G_LITTLE_ENDIAN -union _GFloatIEEE754 -{ - gfloat v_float; - struct { - guint mantissa : 23; - guint biased_exponent : 8; - guint sign : 1; - } mpn; -}; -union _GDoubleIEEE754 -{ - gdouble v_double; - struct { - guint mantissa_low : 32; - guint mantissa_high : 20; - guint biased_exponent : 11; - guint sign : 1; - } mpn; -}; -#elif G_BYTE_ORDER == G_BIG_ENDIAN -union _GFloatIEEE754 -{ - gfloat v_float; - struct { - guint sign : 1; - guint biased_exponent : 8; - guint mantissa : 23; - } mpn; -}; -union _GDoubleIEEE754 -{ - gdouble v_double; - struct { - guint sign : 1; - guint biased_exponent : 11; - guint mantissa_high : 20; - guint mantissa_low : 32; - } mpn; -}; -#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */ -#error unknown ENDIAN type -#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */ - -typedef struct _GTimeVal GTimeVal; - -struct _GTimeVal -{ - glong tv_sec; - glong tv_usec; -}; - -G_END_DECLS - -/* We prefix variable declarations so they can - * properly get exported in Windows DLLs. - */ -#ifndef GLIB_VAR -# ifdef G_PLATFORM_WIN32 -# ifdef GLIB_STATIC_COMPILATION -# define GLIB_VAR extern -# else /* !GLIB_STATIC_COMPILATION */ -# ifdef GLIB_COMPILATION -# ifdef DLL_EXPORT -# define GLIB_VAR __declspec(dllexport) -# else /* !DLL_EXPORT */ -# define GLIB_VAR extern -# endif /* !DLL_EXPORT */ -# else /* !GLIB_COMPILATION */ -# define GLIB_VAR extern __declspec(dllimport) -# endif /* !GLIB_COMPILATION */ -# endif /* !GLIB_STATIC_COMPILATION */ -# else /* !G_PLATFORM_WIN32 */ -# define GLIB_VAR extern -# endif /* !G_PLATFORM_WIN32 */ -#endif /* GLIB_VAR */ - -#endif /* __G_TYPES_H__ */ diff --git a/deps/glib/gunicode.h b/deps/glib/gunicode.h deleted file mode 100644 index d8c45c6c..00000000 --- a/deps/glib/gunicode.h +++ /dev/null @@ -1,728 +0,0 @@ -/* gunicode.h - Unicode manipulation functions - * - * Copyright (C) 1999, 2000 Tom Tromey - * Copyright 2000, 2005 Red Hat, Inc. - * - * The Gnome Library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * The Gnome Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the Gnome Library; see the file COPYING.LIB. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_UNICODE_H__ -#define __G_UNICODE_H__ - -#include <glib/gerror.h> -#include <glib/gtypes.h> - -G_BEGIN_DECLS - -/** - * gunichar: - * - * A type which can hold any UTF-32 or UCS-4 character code, - * also known as a Unicode code point. - * - * If you want to produce the UTF-8 representation of a #gunichar, - * use g_ucs4_to_utf8(). See also g_utf8_to_ucs4() for the reverse - * process. - * - * To print/scan values of this type as integer, use - * %G_GINT32_MODIFIER and/or %G_GUINT32_FORMAT. - * - * The notation to express a Unicode code point in running text is - * as a hexadecimal number with four to six digits and uppercase - * letters, prefixed by the string "U+". Leading zeros are omitted, - * unless the code point would have fewer than four hexadecimal digits. - * For example, "U+0041 LATIN CAPITAL LETTER A". To print a code point - * in the U+-notation, use the format string "U+\%04"G_GINT32_FORMAT"X". - * To scan, use the format string "U+\%06"G_GINT32_FORMAT"X". - * - * |[ - * gunichar c; - * sscanf ("U+0041", "U+%06"G_GINT32_FORMAT"X", &c) - * g_print ("Read U+%04"G_GINT32_FORMAT"X", c); - * ]| - */ -typedef guint32 gunichar; - -/** - * gunichar2: - * - * A type which can hold any UTF-16 code - * point<footnote id="utf16_surrogate_pairs">UTF-16 also has so called - * <firstterm>surrogate pairs</firstterm> to encode characters beyond - * the BMP as pairs of 16bit numbers. Surrogate pairs cannot be stored - * in a single gunichar2 field, but all GLib functions accepting gunichar2 - * arrays will correctly interpret surrogate pairs.</footnote>. - * - * To print/scan values of this type to/from text you need to convert - * to/from UTF-8, using g_utf16_to_utf8()/g_utf8_to_utf16(). - * - * To print/scan values of this type as integer, use - * %G_GINT16_MODIFIER and/or %G_GUINT16_FORMAT. - */ -typedef guint16 gunichar2; - -/** - * GUnicodeType: - * @G_UNICODE_CONTROL: General category "Other, Control" (Cc) - * @G_UNICODE_FORMAT: General category "Other, Format" (Cf) - * @G_UNICODE_UNASSIGNED: General category "Other, Not Assigned" (Cn) - * @G_UNICODE_PRIVATE_USE: General category "Other, Private Use" (Co) - * @G_UNICODE_SURROGATE: General category "Other, Surrogate" (Cs) - * @G_UNICODE_LOWERCASE_LETTER: General category "Letter, Lowercase" (Ll) - * @G_UNICODE_MODIFIER_LETTER: General category "Letter, Modifier" (Lm) - * @G_UNICODE_OTHER_LETTER: General category "Letter, Other" (Lo) - * @G_UNICODE_TITLECASE_LETTER: General category "Letter, Titlecase" (Lt) - * @G_UNICODE_UPPERCASE_LETTER: General category "Letter, Uppercase" (Lu) - * @G_UNICODE_SPACING_MARK: General category "Mark, Spacing" (Mc) - * @G_UNICODE_ENCLOSING_MARK: General category "Mark, Enclosing" (Me) - * @G_UNICODE_NON_SPACING_MARK: General category "Mark, Nonspacing" (Mn) - * @G_UNICODE_DECIMAL_NUMBER: General category "Number, Decimal Digit" (Nd) - * @G_UNICODE_LETTER_NUMBER: General category "Number, Letter" (Nl) - * @G_UNICODE_OTHER_NUMBER: General category "Number, Other" (No) - * @G_UNICODE_CONNECT_PUNCTUATION: General category "Punctuation, Connector" (Pc) - * @G_UNICODE_DASH_PUNCTUATION: General category "Punctuation, Dash" (Pd) - * @G_UNICODE_CLOSE_PUNCTUATION: General category "Punctuation, Close" (Pe) - * @G_UNICODE_FINAL_PUNCTUATION: General category "Punctuation, Final quote" (Pf) - * @G_UNICODE_INITIAL_PUNCTUATION: General category "Punctuation, Initial quote" (Pi) - * @G_UNICODE_OTHER_PUNCTUATION: General category "Punctuation, Other" (Po) - * @G_UNICODE_OPEN_PUNCTUATION: General category "Punctuation, Open" (Ps) - * @G_UNICODE_CURRENCY_SYMBOL: General category "Symbol, Currency" (Sc) - * @G_UNICODE_MODIFIER_SYMBOL: General category "Symbol, Modifier" (Sk) - * @G_UNICODE_MATH_SYMBOL: General category "Symbol, Math" (Sm) - * @G_UNICODE_OTHER_SYMBOL: General category "Symbol, Other" (So) - * @G_UNICODE_LINE_SEPARATOR: General category "Separator, Line" (Zl) - * @G_UNICODE_PARAGRAPH_SEPARATOR: General category "Separator, Paragraph" (Zp) - * @G_UNICODE_SPACE_SEPARATOR: General category "Separator, Space" (Zs) - * - * These are the possible character classifications from the - * Unicode specification. - * See <ulink url="http://www.unicode.org/Public/UNIDATA/UnicodeData.html">http://www.unicode.org/Public/UNIDATA/UnicodeData.html</ulink>. - */ -typedef enum -{ - G_UNICODE_CONTROL, - G_UNICODE_FORMAT, - G_UNICODE_UNASSIGNED, - G_UNICODE_PRIVATE_USE, - G_UNICODE_SURROGATE, - G_UNICODE_LOWERCASE_LETTER, - G_UNICODE_MODIFIER_LETTER, - G_UNICODE_OTHER_LETTER, - G_UNICODE_TITLECASE_LETTER, - G_UNICODE_UPPERCASE_LETTER, - G_UNICODE_SPACING_MARK, - G_UNICODE_ENCLOSING_MARK, - G_UNICODE_NON_SPACING_MARK, - G_UNICODE_DECIMAL_NUMBER, - G_UNICODE_LETTER_NUMBER, - G_UNICODE_OTHER_NUMBER, - G_UNICODE_CONNECT_PUNCTUATION, - G_UNICODE_DASH_PUNCTUATION, - G_UNICODE_CLOSE_PUNCTUATION, - G_UNICODE_FINAL_PUNCTUATION, - G_UNICODE_INITIAL_PUNCTUATION, - G_UNICODE_OTHER_PUNCTUATION, - G_UNICODE_OPEN_PUNCTUATION, - G_UNICODE_CURRENCY_SYMBOL, - G_UNICODE_MODIFIER_SYMBOL, - G_UNICODE_MATH_SYMBOL, - G_UNICODE_OTHER_SYMBOL, - G_UNICODE_LINE_SEPARATOR, - G_UNICODE_PARAGRAPH_SEPARATOR, - G_UNICODE_SPACE_SEPARATOR -} GUnicodeType; - -/** - * G_UNICODE_COMBINING_MARK: - * - * Older name for %G_UNICODE_SPACING_MARK. - * - * Deprecated: 2.30: Use %G_UNICODE_SPACING_MARK. - */ -#ifndef G_DISABLE_DEPRECATED -#define G_UNICODE_COMBINING_MARK G_UNICODE_SPACING_MARK -#endif - -/** - * GUnicodeBreakType: - * @G_UNICODE_BREAK_MANDATORY: Mandatory Break (BK) - * @G_UNICODE_BREAK_CARRIAGE_RETURN: Carriage Return (CR) - * @G_UNICODE_BREAK_LINE_FEED: Line Feed (LF) - * @G_UNICODE_BREAK_COMBINING_MARK: Attached Characters and Combining Marks (CM) - * @G_UNICODE_BREAK_SURROGATE: Surrogates (SG) - * @G_UNICODE_BREAK_ZERO_WIDTH_SPACE: Zero Width Space (ZW) - * @G_UNICODE_BREAK_INSEPARABLE: Inseparable (IN) - * @G_UNICODE_BREAK_NON_BREAKING_GLUE: Non-breaking ("Glue") (GL) - * @G_UNICODE_BREAK_CONTINGENT: Contingent Break Opportunity (CB) - * @G_UNICODE_BREAK_SPACE: Space (SP) - * @G_UNICODE_BREAK_AFTER: Break Opportunity After (BA) - * @G_UNICODE_BREAK_BEFORE: Break Opportunity Before (BB) - * @G_UNICODE_BREAK_BEFORE_AND_AFTER: Break Opportunity Before and After (B2) - * @G_UNICODE_BREAK_HYPHEN: Hyphen (HY) - * @G_UNICODE_BREAK_NON_STARTER: Nonstarter (NS) - * @G_UNICODE_BREAK_OPEN_PUNCTUATION: Opening Punctuation (OP) - * @G_UNICODE_BREAK_CLOSE_PUNCTUATION: Closing Punctuation (CL) - * @G_UNICODE_BREAK_QUOTATION: Ambiguous Quotation (QU) - * @G_UNICODE_BREAK_EXCLAMATION: Exclamation/Interrogation (EX) - * @G_UNICODE_BREAK_IDEOGRAPHIC: Ideographic (ID) - * @G_UNICODE_BREAK_NUMERIC: Numeric (NU) - * @G_UNICODE_BREAK_INFIX_SEPARATOR: Infix Separator (Numeric) (IS) - * @G_UNICODE_BREAK_SYMBOL: Symbols Allowing Break After (SY) - * @G_UNICODE_BREAK_ALPHABETIC: Ordinary Alphabetic and Symbol Characters (AL) - * @G_UNICODE_BREAK_PREFIX: Prefix (Numeric) (PR) - * @G_UNICODE_BREAK_POSTFIX: Postfix (Numeric) (PO) - * @G_UNICODE_BREAK_COMPLEX_CONTEXT: Complex Content Dependent (South East Asian) (SA) - * @G_UNICODE_BREAK_AMBIGUOUS: Ambiguous (Alphabetic or Ideographic) (AI) - * @G_UNICODE_BREAK_UNKNOWN: Unknown (XX) - * @G_UNICODE_BREAK_NEXT_LINE: Next Line (NL) - * @G_UNICODE_BREAK_WORD_JOINER: Word Joiner (WJ) - * @G_UNICODE_BREAK_HANGUL_L_JAMO: Hangul L Jamo (JL) - * @G_UNICODE_BREAK_HANGUL_V_JAMO: Hangul V Jamo (JV) - * @G_UNICODE_BREAK_HANGUL_T_JAMO: Hangul T Jamo (JT) - * @G_UNICODE_BREAK_HANGUL_LV_SYLLABLE: Hangul LV Syllable (H2) - * @G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE: Hangul LVT Syllable (H3) - * @G_UNICODE_BREAK_CLOSE_PARANTHESIS: Closing Parenthesis (CP). Since 2.28 - * - * These are the possible line break classifications. - * - * The five Hangul types were added in Unicode 4.1, so, has been - * introduced in GLib 2.10. Note that new types may be added in the future. - * Applications should be ready to handle unknown values. - * They may be regarded as %G_UNICODE_BREAK_UNKNOWN. - * - * See <ulink url="http://www.unicode.org/unicode/reports/tr14/">http://www.unicode.org/unicode/reports/tr14/</ulink>. - */ -typedef enum -{ - G_UNICODE_BREAK_MANDATORY, - G_UNICODE_BREAK_CARRIAGE_RETURN, - G_UNICODE_BREAK_LINE_FEED, - G_UNICODE_BREAK_COMBINING_MARK, - G_UNICODE_BREAK_SURROGATE, - G_UNICODE_BREAK_ZERO_WIDTH_SPACE, - G_UNICODE_BREAK_INSEPARABLE, - G_UNICODE_BREAK_NON_BREAKING_GLUE, - G_UNICODE_BREAK_CONTINGENT, - G_UNICODE_BREAK_SPACE, - G_UNICODE_BREAK_AFTER, - G_UNICODE_BREAK_BEFORE, - G_UNICODE_BREAK_BEFORE_AND_AFTER, - G_UNICODE_BREAK_HYPHEN, - G_UNICODE_BREAK_NON_STARTER, - G_UNICODE_BREAK_OPEN_PUNCTUATION, - G_UNICODE_BREAK_CLOSE_PUNCTUATION, - G_UNICODE_BREAK_QUOTATION, - G_UNICODE_BREAK_EXCLAMATION, - G_UNICODE_BREAK_IDEOGRAPHIC, - G_UNICODE_BREAK_NUMERIC, - G_UNICODE_BREAK_INFIX_SEPARATOR, - G_UNICODE_BREAK_SYMBOL, - G_UNICODE_BREAK_ALPHABETIC, - G_UNICODE_BREAK_PREFIX, - G_UNICODE_BREAK_POSTFIX, - G_UNICODE_BREAK_COMPLEX_CONTEXT, - G_UNICODE_BREAK_AMBIGUOUS, - G_UNICODE_BREAK_UNKNOWN, - G_UNICODE_BREAK_NEXT_LINE, - G_UNICODE_BREAK_WORD_JOINER, - G_UNICODE_BREAK_HANGUL_L_JAMO, - G_UNICODE_BREAK_HANGUL_V_JAMO, - G_UNICODE_BREAK_HANGUL_T_JAMO, - G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, - G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, - G_UNICODE_BREAK_CLOSE_PARANTHESIS -} GUnicodeBreakType; - -/** - * GUnicodeScript: - * @G_UNICODE_SCRIPT_INVALID_CODE: - * a value never returned from g_unichar_get_script() - * @G_UNICODE_SCRIPT_COMMON: a character used by multiple different scripts - * @G_UNICODE_SCRIPT_INHERITED: a mark glyph that takes its script from the - * i base glyph to which it is attached - * @G_UNICODE_SCRIPT_ARABIC: Arabic - * @G_UNICODE_SCRIPT_ARMENIAN: Armenian - * @G_UNICODE_SCRIPT_BENGALI: Bengali - * @G_UNICODE_SCRIPT_BOPOMOFO: Bopomofo - * @G_UNICODE_SCRIPT_CHEROKEE: Cherokee - * @G_UNICODE_SCRIPT_COPTIC: Coptic - * @G_UNICODE_SCRIPT_CYRILLIC: Cyrillic - * @G_UNICODE_SCRIPT_DESERET: Deseret - * @G_UNICODE_SCRIPT_DEVANAGARI: Devanagari - * @G_UNICODE_SCRIPT_ETHIOPIC: Ethiopic - * @G_UNICODE_SCRIPT_GEORGIAN: Georgian - * @G_UNICODE_SCRIPT_GOTHIC: Gothic - * @G_UNICODE_SCRIPT_GREEK: Greek - * @G_UNICODE_SCRIPT_GUJARATI: Gujarati - * @G_UNICODE_SCRIPT_GURMUKHI: Gurmukhi - * @G_UNICODE_SCRIPT_HAN: Han - * @G_UNICODE_SCRIPT_HANGUL: Hangul - * @G_UNICODE_SCRIPT_HEBREW: Hebrew - * @G_UNICODE_SCRIPT_HIRAGANA: Hiragana - * @G_UNICODE_SCRIPT_KANNADA: Kannada - * @G_UNICODE_SCRIPT_KATAKANA: Katakana - * @G_UNICODE_SCRIPT_KHMER: Khmer - * @G_UNICODE_SCRIPT_LAO: Lao - * @G_UNICODE_SCRIPT_LATIN: Latin - * @G_UNICODE_SCRIPT_MALAYALAM: Malayalam - * @G_UNICODE_SCRIPT_MONGOLIAN: Mongolian - * @G_UNICODE_SCRIPT_MYANMAR: Myanmar - * @G_UNICODE_SCRIPT_OGHAM: Ogham - * @G_UNICODE_SCRIPT_OLD_ITALIC: Old Italic - * @G_UNICODE_SCRIPT_ORIYA: Oriya - * @G_UNICODE_SCRIPT_RUNIC: Runic - * @G_UNICODE_SCRIPT_SINHALA: Sinhala - * @G_UNICODE_SCRIPT_SYRIAC: Syriac - * @G_UNICODE_SCRIPT_TAMIL: Tamil - * @G_UNICODE_SCRIPT_TELUGU: Telugu - * @G_UNICODE_SCRIPT_THAANA: Thaana - * @G_UNICODE_SCRIPT_THAI: Thai - * @G_UNICODE_SCRIPT_TIBETAN: Tibetan - * @G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL: - * Canadian Aboriginal - * @G_UNICODE_SCRIPT_YI: Yi - * @G_UNICODE_SCRIPT_TAGALOG: Tagalog - * @G_UNICODE_SCRIPT_HANUNOO: Hanunoo - * @G_UNICODE_SCRIPT_BUHID: Buhid - * @G_UNICODE_SCRIPT_TAGBANWA: Tagbanwa - * @G_UNICODE_SCRIPT_BRAILLE: Braille - * @G_UNICODE_SCRIPT_CYPRIOT: Cypriot - * @G_UNICODE_SCRIPT_LIMBU: Limbu - * @G_UNICODE_SCRIPT_OSMANYA: Osmanya - * @G_UNICODE_SCRIPT_SHAVIAN: Shavian - * @G_UNICODE_SCRIPT_LINEAR_B: Linear B - * @G_UNICODE_SCRIPT_TAI_LE: Tai Le - * @G_UNICODE_SCRIPT_UGARITIC: Ugaritic - * @G_UNICODE_SCRIPT_NEW_TAI_LUE: - * New Tai Lue - * @G_UNICODE_SCRIPT_BUGINESE: Buginese - * @G_UNICODE_SCRIPT_GLAGOLITIC: Glagolitic - * @G_UNICODE_SCRIPT_TIFINAGH: Tifinagh - * @G_UNICODE_SCRIPT_SYLOTI_NAGRI: - * Syloti Nagri - * @G_UNICODE_SCRIPT_OLD_PERSIAN: - * Old Persian - * @G_UNICODE_SCRIPT_KHAROSHTHI: Kharoshthi - * @G_UNICODE_SCRIPT_UNKNOWN: an unassigned code point - * @G_UNICODE_SCRIPT_BALINESE: Balinese - * @G_UNICODE_SCRIPT_CUNEIFORM: Cuneiform - * @G_UNICODE_SCRIPT_PHOENICIAN: Phoenician - * @G_UNICODE_SCRIPT_PHAGS_PA: Phags-pa - * @G_UNICODE_SCRIPT_NKO: N'Ko - * @G_UNICODE_SCRIPT_KAYAH_LI: Kayah Li. Since 2.16.3 - * @G_UNICODE_SCRIPT_LEPCHA: Lepcha. Since 2.16.3 - * @G_UNICODE_SCRIPT_REJANG: Rejang. Since 2.16.3 - * @G_UNICODE_SCRIPT_SUNDANESE: Sundanese. Since 2.16.3 - * @G_UNICODE_SCRIPT_SAURASHTRA: Saurashtra. Since 2.16.3 - * @G_UNICODE_SCRIPT_CHAM: Cham. Since 2.16.3 - * @G_UNICODE_SCRIPT_OL_CHIKI: Ol Chiki. Since 2.16.3 - * @G_UNICODE_SCRIPT_VAI: Vai. Since 2.16.3 - * @G_UNICODE_SCRIPT_CARIAN: Carian. Since 2.16.3 - * @G_UNICODE_SCRIPT_LYCIAN: Lycian. Since 2.16.3 - * @G_UNICODE_SCRIPT_LYDIAN: Lydian. Since 2.16.3 - * @G_UNICODE_SCRIPT_AVESTAN: Avestan. Since 2.26 - * @G_UNICODE_SCRIPT_BAMUM: Bamum. Since 2.26 - * @G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS: - * Egyptian Hieroglpyhs. Since 2.26 - * @G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC: - * Imperial Aramaic. Since 2.26 - * @G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI: - * Inscriptional Pahlavi. Since 2.26 - * @G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN: - * Inscriptional Parthian. Since 2.26 - * @G_UNICODE_SCRIPT_JAVANESE: Javanese. Since 2.26 - * @G_UNICODE_SCRIPT_KAITHI: Kaithi. Since 2.26 - * @G_UNICODE_SCRIPT_LISU: Lisu. Since 2.26 - * @G_UNICODE_SCRIPT_MEETEI_MAYEK: - * Meetei Mayek. Since 2.26 - * @G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN: - * Old South Arabian. Since 2.26 - * @G_UNICODE_SCRIPT_OLD_TURKIC: Old Turkic. Since 2.28 - * @G_UNICODE_SCRIPT_SAMARITAN: Samaritan. Since 2.26 - * @G_UNICODE_SCRIPT_TAI_THAM: Tai Tham. Since 2.26 - * @G_UNICODE_SCRIPT_TAI_VIET: Tai Viet. Since 2.26 - * @G_UNICODE_SCRIPT_BATAK: Batak. Since 2.28 - * @G_UNICODE_SCRIPT_BRAHMI: Brahmi. Since 2.28 - * @G_UNICODE_SCRIPT_MANDAIC: Mandaic. Since 2.28 - * - * The #GUnicodeScript enumeration identifies different writing - * systems. The values correspond to the names as defined in the - * Unicode standard. The enumeration has been added in GLib 2.14, - * and is interchangeable with #PangoScript. - * - * Note that new types may be added in the future. Applications - * should be ready to handle unknown values. - * See <ulink - * url="http://www.unicode.org/reports/tr24/">Unicode Standard Annex - * #24: Script names</ulink>. - */ -typedef enum -{ /* ISO 15924 code */ - G_UNICODE_SCRIPT_INVALID_CODE = -1, - G_UNICODE_SCRIPT_COMMON = 0, /* Zyyy */ - G_UNICODE_SCRIPT_INHERITED, /* Qaai */ - G_UNICODE_SCRIPT_ARABIC, /* Arab */ - G_UNICODE_SCRIPT_ARMENIAN, /* Armn */ - G_UNICODE_SCRIPT_BENGALI, /* Beng */ - G_UNICODE_SCRIPT_BOPOMOFO, /* Bopo */ - G_UNICODE_SCRIPT_CHEROKEE, /* Cher */ - G_UNICODE_SCRIPT_COPTIC, /* Qaac */ - G_UNICODE_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */ - G_UNICODE_SCRIPT_DESERET, /* Dsrt */ - G_UNICODE_SCRIPT_DEVANAGARI, /* Deva */ - G_UNICODE_SCRIPT_ETHIOPIC, /* Ethi */ - G_UNICODE_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */ - G_UNICODE_SCRIPT_GOTHIC, /* Goth */ - G_UNICODE_SCRIPT_GREEK, /* Grek */ - G_UNICODE_SCRIPT_GUJARATI, /* Gujr */ - G_UNICODE_SCRIPT_GURMUKHI, /* Guru */ - G_UNICODE_SCRIPT_HAN, /* Hani */ - G_UNICODE_SCRIPT_HANGUL, /* Hang */ - G_UNICODE_SCRIPT_HEBREW, /* Hebr */ - G_UNICODE_SCRIPT_HIRAGANA, /* Hira */ - G_UNICODE_SCRIPT_KANNADA, /* Knda */ - G_UNICODE_SCRIPT_KATAKANA, /* Kana */ - G_UNICODE_SCRIPT_KHMER, /* Khmr */ - G_UNICODE_SCRIPT_LAO, /* Laoo */ - G_UNICODE_SCRIPT_LATIN, /* Latn (Latf, Latg) */ - G_UNICODE_SCRIPT_MALAYALAM, /* Mlym */ - G_UNICODE_SCRIPT_MONGOLIAN, /* Mong */ - G_UNICODE_SCRIPT_MYANMAR, /* Mymr */ - G_UNICODE_SCRIPT_OGHAM, /* Ogam */ - G_UNICODE_SCRIPT_OLD_ITALIC, /* Ital */ - G_UNICODE_SCRIPT_ORIYA, /* Orya */ - G_UNICODE_SCRIPT_RUNIC, /* Runr */ - G_UNICODE_SCRIPT_SINHALA, /* Sinh */ - G_UNICODE_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */ - G_UNICODE_SCRIPT_TAMIL, /* Taml */ - G_UNICODE_SCRIPT_TELUGU, /* Telu */ - G_UNICODE_SCRIPT_THAANA, /* Thaa */ - G_UNICODE_SCRIPT_THAI, /* Thai */ - G_UNICODE_SCRIPT_TIBETAN, /* Tibt */ - G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */ - G_UNICODE_SCRIPT_YI, /* Yiii */ - G_UNICODE_SCRIPT_TAGALOG, /* Tglg */ - G_UNICODE_SCRIPT_HANUNOO, /* Hano */ - G_UNICODE_SCRIPT_BUHID, /* Buhd */ - G_UNICODE_SCRIPT_TAGBANWA, /* Tagb */ - - /* Unicode-4.0 additions */ - G_UNICODE_SCRIPT_BRAILLE, /* Brai */ - G_UNICODE_SCRIPT_CYPRIOT, /* Cprt */ - G_UNICODE_SCRIPT_LIMBU, /* Limb */ - G_UNICODE_SCRIPT_OSMANYA, /* Osma */ - G_UNICODE_SCRIPT_SHAVIAN, /* Shaw */ - G_UNICODE_SCRIPT_LINEAR_B, /* Linb */ - G_UNICODE_SCRIPT_TAI_LE, /* Tale */ - G_UNICODE_SCRIPT_UGARITIC, /* Ugar */ - - /* Unicode-4.1 additions */ - G_UNICODE_SCRIPT_NEW_TAI_LUE, /* Talu */ - G_UNICODE_SCRIPT_BUGINESE, /* Bugi */ - G_UNICODE_SCRIPT_GLAGOLITIC, /* Glag */ - G_UNICODE_SCRIPT_TIFINAGH, /* Tfng */ - G_UNICODE_SCRIPT_SYLOTI_NAGRI, /* Sylo */ - G_UNICODE_SCRIPT_OLD_PERSIAN, /* Xpeo */ - G_UNICODE_SCRIPT_KHAROSHTHI, /* Khar */ - - /* Unicode-5.0 additions */ - G_UNICODE_SCRIPT_UNKNOWN, /* Zzzz */ - G_UNICODE_SCRIPT_BALINESE, /* Bali */ - G_UNICODE_SCRIPT_CUNEIFORM, /* Xsux */ - G_UNICODE_SCRIPT_PHOENICIAN, /* Phnx */ - G_UNICODE_SCRIPT_PHAGS_PA, /* Phag */ - G_UNICODE_SCRIPT_NKO, /* Nkoo */ - - /* Unicode-5.1 additions */ - G_UNICODE_SCRIPT_KAYAH_LI, /* Kali */ - G_UNICODE_SCRIPT_LEPCHA, /* Lepc */ - G_UNICODE_SCRIPT_REJANG, /* Rjng */ - G_UNICODE_SCRIPT_SUNDANESE, /* Sund */ - G_UNICODE_SCRIPT_SAURASHTRA, /* Saur */ - G_UNICODE_SCRIPT_CHAM, /* Cham */ - G_UNICODE_SCRIPT_OL_CHIKI, /* Olck */ - G_UNICODE_SCRIPT_VAI, /* Vaii */ - G_UNICODE_SCRIPT_CARIAN, /* Cari */ - G_UNICODE_SCRIPT_LYCIAN, /* Lyci */ - G_UNICODE_SCRIPT_LYDIAN, /* Lydi */ - - /* Unicode-5.2 additions */ - G_UNICODE_SCRIPT_AVESTAN, /* Avst */ - G_UNICODE_SCRIPT_BAMUM, /* Bamu */ - G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, /* Egyp */ - G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, /* Armi */ - G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, /* Phli */ - G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */ - G_UNICODE_SCRIPT_JAVANESE, /* Java */ - G_UNICODE_SCRIPT_KAITHI, /* Kthi */ - G_UNICODE_SCRIPT_LISU, /* Lisu */ - G_UNICODE_SCRIPT_MEETEI_MAYEK, /* Mtei */ - G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN, /* Sarb */ - G_UNICODE_SCRIPT_OLD_TURKIC, /* Orkh */ - G_UNICODE_SCRIPT_SAMARITAN, /* Samr */ - G_UNICODE_SCRIPT_TAI_THAM, /* Lana */ - G_UNICODE_SCRIPT_TAI_VIET, /* Tavt */ - - /* Unicode-6.0 additions */ - G_UNICODE_SCRIPT_BATAK, /* Batk */ - G_UNICODE_SCRIPT_BRAHMI, /* Brah */ - G_UNICODE_SCRIPT_MANDAIC /* Mand */ -} GUnicodeScript; - -guint32 g_unicode_script_to_iso15924 (GUnicodeScript script); -GUnicodeScript g_unicode_script_from_iso15924 (guint32 iso15924); - -/* Returns TRUE if current locale uses UTF-8 charset. If CHARSET is - * not null, sets *CHARSET to the name of the current locale's - * charset. This value is statically allocated, and should be copied - * in case the locale's charset will be changed later using setlocale() - * or in some other way. - */ -gboolean g_get_charset (const char **charset); - -/* These are all analogs of the <ctype.h> functions. - */ -gboolean g_unichar_isalnum (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isalpha (gunichar c) G_GNUC_CONST; -gboolean g_unichar_iscntrl (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isdigit (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isgraph (gunichar c) G_GNUC_CONST; -gboolean g_unichar_islower (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isprint (gunichar c) G_GNUC_CONST; -gboolean g_unichar_ispunct (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isspace (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isupper (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isxdigit (gunichar c) G_GNUC_CONST; -gboolean g_unichar_istitle (gunichar c) G_GNUC_CONST; -gboolean g_unichar_isdefined (gunichar c) G_GNUC_CONST; -gboolean g_unichar_iswide (gunichar c) G_GNUC_CONST; -gboolean g_unichar_iswide_cjk(gunichar c) G_GNUC_CONST; -gboolean g_unichar_iszerowidth(gunichar c) G_GNUC_CONST; -gboolean g_unichar_ismark (gunichar c) G_GNUC_CONST; - -/* More <ctype.h> functions. These convert between the three cases. - * See the Unicode book to understand title case. */ -gunichar g_unichar_toupper (gunichar c) G_GNUC_CONST; -gunichar g_unichar_tolower (gunichar c) G_GNUC_CONST; -gunichar g_unichar_totitle (gunichar c) G_GNUC_CONST; - -/* If C is a digit (according to `g_unichar_isdigit'), then return its - numeric value. Otherwise return -1. */ -gint g_unichar_digit_value (gunichar c) G_GNUC_CONST; - -gint g_unichar_xdigit_value (gunichar c) G_GNUC_CONST; - -/* Return the Unicode character type of a given character. */ -GUnicodeType g_unichar_type (gunichar c) G_GNUC_CONST; - -/* Return the line break property for a given character */ -GUnicodeBreakType g_unichar_break_type (gunichar c) G_GNUC_CONST; - -/* Returns the combining class for a given character */ -gint g_unichar_combining_class (gunichar uc) G_GNUC_CONST; - -gboolean g_unichar_get_mirror_char (gunichar ch, - gunichar *mirrored_ch); - -GUnicodeScript g_unichar_get_script (gunichar ch) G_GNUC_CONST; - -/* Validate a Unicode character */ -gboolean g_unichar_validate (gunichar ch) G_GNUC_CONST; - -/* Pairwise canonical compose/decompose */ -gboolean g_unichar_compose (gunichar a, - gunichar b, - gunichar *ch); -gboolean g_unichar_decompose (gunichar ch, - gunichar *a, - gunichar *b); - -gsize g_unichar_fully_decompose (gunichar ch, - gboolean compat, - gunichar *result, - gsize result_len); - -/* Compute canonical ordering of a string in-place. This rearranges - decomposed characters in the string according to their combining - classes. See the Unicode manual for more information. */ -void g_unicode_canonical_ordering (gunichar *string, - gsize len); - - -#ifndef G_DISABLE_DEPRECATED -/* Deprecated. Use g_unichar_fully_decompose() */ -gunichar *g_unicode_canonical_decomposition (gunichar ch, - gsize *result_len) G_GNUC_MALLOC; -#endif - -/* Array of skip-bytes-per-initial character. - */ -GLIB_VAR const gchar * const g_utf8_skip; - -/** - * g_utf8_next_char: - * @p: Pointer to the start of a valid UTF-8 character - * - * Skips to the next character in a UTF-8 string. The string must be - * valid; this macro is as fast as possible, and has no error-checking. - * You would use this macro to iterate over a string character by - * character. The macro returns the start of the next UTF-8 character. - * Before using this macro, use g_utf8_validate() to validate strings - * that may contain invalid UTF-8. - */ -#define g_utf8_next_char(p) (char *)((p) + g_utf8_skip[*(const guchar *)(p)]) - -gunichar g_utf8_get_char (const gchar *p) G_GNUC_PURE; -gunichar g_utf8_get_char_validated (const gchar *p, - gssize max_len) G_GNUC_PURE; - -gchar* g_utf8_offset_to_pointer (const gchar *str, - glong offset) G_GNUC_PURE; -glong g_utf8_pointer_to_offset (const gchar *str, - const gchar *pos) G_GNUC_PURE; -gchar* g_utf8_prev_char (const gchar *p) G_GNUC_PURE; -gchar* g_utf8_find_next_char (const gchar *p, - const gchar *end) G_GNUC_PURE; -gchar* g_utf8_find_prev_char (const gchar *str, - const gchar *p) G_GNUC_PURE; - -glong g_utf8_strlen (const gchar *p, - gssize max) G_GNUC_PURE; - -gchar *g_utf8_substring (const gchar *str, - glong start_pos, - glong end_pos) G_GNUC_MALLOC; - -gchar *g_utf8_strncpy (gchar *dest, - const gchar *src, - gsize n); - -/* Find the UTF-8 character corresponding to ch, in string p. These - functions are equivalants to strchr and strrchr */ -gchar* g_utf8_strchr (const gchar *p, - gssize len, - gunichar c); -gchar* g_utf8_strrchr (const gchar *p, - gssize len, - gunichar c); -gchar* g_utf8_strreverse (const gchar *str, - gssize len); - -gunichar2 *g_utf8_to_utf16 (const gchar *str, - glong len, - glong *items_read, - glong *items_written, - GError **error) G_GNUC_MALLOC; -gunichar * g_utf8_to_ucs4 (const gchar *str, - glong len, - glong *items_read, - glong *items_written, - GError **error) G_GNUC_MALLOC; -gunichar * g_utf8_to_ucs4_fast (const gchar *str, - glong len, - glong *items_written) G_GNUC_MALLOC; -gunichar * g_utf16_to_ucs4 (const gunichar2 *str, - glong len, - glong *items_read, - glong *items_written, - GError **error) G_GNUC_MALLOC; -gchar* g_utf16_to_utf8 (const gunichar2 *str, - glong len, - glong *items_read, - glong *items_written, - GError **error) G_GNUC_MALLOC; -gunichar2 *g_ucs4_to_utf16 (const gunichar *str, - glong len, - glong *items_read, - glong *items_written, - GError **error) G_GNUC_MALLOC; -gchar* g_ucs4_to_utf8 (const gunichar *str, - glong len, - glong *items_read, - glong *items_written, - GError **error) G_GNUC_MALLOC; - -gint g_unichar_to_utf8 (gunichar c, - gchar *outbuf); - -gboolean g_utf8_validate (const gchar *str, - gssize max_len, - const gchar **end); - -gchar *g_utf8_strup (const gchar *str, - gssize len) G_GNUC_MALLOC; -gchar *g_utf8_strdown (const gchar *str, - gssize len) G_GNUC_MALLOC; -gchar *g_utf8_casefold (const gchar *str, - gssize len) G_GNUC_MALLOC; - -/** - * GNormalizeMode: - * @G_NORMALIZE_DEFAULT: standardize differences that do not affect the - * text content, such as the above-mentioned accent representation - * @G_NORMALIZE_NFD: another name for %G_NORMALIZE_DEFAULT - * @G_NORMALIZE_DEFAULT_COMPOSE: like %G_NORMALIZE_DEFAULT, but with - * composed forms rather than a maximally decomposed form - * @G_NORMALIZE_NFC: another name for %G_NORMALIZE_DEFAULT_COMPOSE - * @G_NORMALIZE_ALL: beyond %G_NORMALIZE_DEFAULT also standardize the - * "compatibility" characters in Unicode, such as SUPERSCRIPT THREE - * to the standard forms (in this case DIGIT THREE). Formatting - * information may be lost but for most text operations such - * characters should be considered the same - * @G_NORMALIZE_NFKD: another name for %G_NORMALIZE_ALL - * @G_NORMALIZE_ALL_COMPOSE: like %G_NORMALIZE_ALL, but with composed - * forms rather than a maximally decomposed form - * @G_NORMALIZE_NFKC: another name for %G_NORMALIZE_ALL_COMPOSE - * - * Defines how a Unicode string is transformed in a canonical - * form, standardizing such issues as whether a character with - * an accent is represented as a base character and combining - * accent or as a single precomposed character. Unicode strings - * should generally be normalized before comparing them. - */ -typedef enum { - G_NORMALIZE_DEFAULT, - G_NORMALIZE_NFD = G_NORMALIZE_DEFAULT, - G_NORMALIZE_DEFAULT_COMPOSE, - G_NORMALIZE_NFC = G_NORMALIZE_DEFAULT_COMPOSE, - G_NORMALIZE_ALL, - G_NORMALIZE_NFKD = G_NORMALIZE_ALL, - G_NORMALIZE_ALL_COMPOSE, - G_NORMALIZE_NFKC = G_NORMALIZE_ALL_COMPOSE -} GNormalizeMode; - -gchar *g_utf8_normalize (const gchar *str, - gssize len, - GNormalizeMode mode) G_GNUC_MALLOC; - -gint g_utf8_collate (const gchar *str1, - const gchar *str2) G_GNUC_PURE; -gchar *g_utf8_collate_key (const gchar *str, - gssize len) G_GNUC_MALLOC; -gchar *g_utf8_collate_key_for_filename (const gchar *str, - gssize len) G_GNUC_MALLOC; - - -/* private */ - -gchar *_g_utf8_make_valid (const gchar *name); - -G_END_DECLS - -#endif /* __G_UNICODE_H__ */ diff --git a/deps/glib/gutils.c b/deps/glib/gutils.c deleted file mode 100644 index 5be0ecbd..00000000 --- a/deps/glib/gutils.c +++ /dev/null @@ -1,3870 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe for the unix part, FIXME: make the win32 part MT safe as well. - */ - -/** - * SECTION:version - * @Title: Version Information - * @Short_description: Variables and functions to check the GLib version - * - * GLib provides version information, primarily useful in configure - * checks for builds that have a configure script. Applications will - * not typically use the features described here. - */ - -/** - * GLIB_MAJOR_VERSION: - * - * The major version number of the GLib library. - * - * Like #glib_major_version, but from the headers used at - * application compile time, rather than from the library - * linked against at application run time. - */ - -/** - * GLIB_MINOR_VERSION: - * - * The minor version number of the GLib library. - * - * Like #gtk_minor_version, but from the headers used at - * application compile time, rather than from the library - * linked against at application run time. - */ - -/** - * GLIB_MICRO_VERSION: - * - * The micro version number of the GLib library. - * - * Like #gtk_micro_version, but from the headers used at - * application compile time, rather than from the library - * linked against at application run time. - */ - -#include "config.h" - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <locale.h> -#include <string.h> -#include <ctype.h> /* For tolower() */ -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif -#include <sys/types.h> -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif -#ifdef HAVE_CRT_EXTERNS_H -#include <crt_externs.h> /* for _NSGetEnviron */ -#endif - -/* implement gutils's inline functions - */ -#define G_IMPLEMENT_INLINES 1 -#define __G_UTILS_C__ -#include "gutils.h" - -#include "gfileutils.h" -#include "ghash.h" -#include "gslist.h" -#include "gprintfint.h" -#include "gthread.h" -#include "gthreadprivate.h" -#include "gtestutils.h" -#include "gunicode.h" -#include "gstrfuncs.h" -#include "garray.h" -#include "glibintl.h" - -#ifdef G_PLATFORM_WIN32 -#include "garray.h" -#include "gconvert.h" -#include "gwin32.h" -#endif - - -/** - * SECTION:misc_utils - * @title: Miscellaneous Utility Functions - * @short_description: a selection of portable utility functions - * - * These are portable utility functions. - */ - -#ifdef MAXPATHLEN -#define G_PATH_LENGTH MAXPATHLEN -#elif defined (PATH_MAX) -#define G_PATH_LENGTH PATH_MAX -#elif defined (_PC_PATH_MAX) -#define G_PATH_LENGTH sysconf(_PC_PATH_MAX) -#else -#define G_PATH_LENGTH 2048 -#endif - -#ifdef G_PLATFORM_WIN32 -# define STRICT /* Strict typing, please */ -# include <windows.h> -# undef STRICT -# ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS -# define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2 -# define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4 -# endif -# include <lmcons.h> /* For UNLEN */ -#endif /* G_PLATFORM_WIN32 */ - -#ifdef G_OS_WIN32 -# include <direct.h> -# include <shlobj.h> - /* older SDK (e.g. msvc 5.0) does not have these*/ -# ifndef CSIDL_MYMUSIC -# define CSIDL_MYMUSIC 13 -# endif -# ifndef CSIDL_MYVIDEO -# define CSIDL_MYVIDEO 14 -# endif -# ifndef CSIDL_INTERNET_CACHE -# define CSIDL_INTERNET_CACHE 32 -# endif -# ifndef CSIDL_COMMON_APPDATA -# define CSIDL_COMMON_APPDATA 35 -# endif -# ifndef CSIDL_MYPICTURES -# define CSIDL_MYPICTURES 0x27 -# endif -# ifndef CSIDL_COMMON_DOCUMENTS -# define CSIDL_COMMON_DOCUMENTS 46 -# endif -# ifndef CSIDL_PROFILE -# define CSIDL_PROFILE 40 -# endif -# include <process.h> -#endif - -#ifdef HAVE_CARBON -#include <CoreServices/CoreServices.h> -#endif - -#ifdef HAVE_CODESET -#include <langinfo.h> -#endif - -const guint glib_major_version = GLIB_MAJOR_VERSION; -const guint glib_minor_version = GLIB_MINOR_VERSION; -const guint glib_micro_version = GLIB_MICRO_VERSION; -const guint glib_interface_age = GLIB_INTERFACE_AGE; -const guint glib_binary_age = GLIB_BINARY_AGE; - -#ifdef G_PLATFORM_WIN32 - -static HMODULE glib_dll = NULL; - -#ifdef DLL_EXPORT - -BOOL WINAPI -DllMain (HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - glib_dll = hinstDLL; - - return TRUE; -} - -#endif - -gchar * -_glib_get_dll_directory (void) -{ - gchar *retval; - gchar *p; - wchar_t wc_fn[MAX_PATH]; - -#ifdef DLL_EXPORT - if (glib_dll == NULL) - return NULL; -#endif - - /* This code is different from that in - * g_win32_get_package_installation_directory_of_module() in that - * here we return the actual folder where the GLib DLL is. We don't - * do the check for it being in a "bin" or "lib" subfolder and then - * returning the parent of that. - * - * In a statically built GLib, glib_dll will be NULL and we will - * thus look up the application's .exe file's location. - */ - if (!GetModuleFileNameW (glib_dll, wc_fn, MAX_PATH)) - return NULL; - - retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); - - p = strrchr (retval, G_DIR_SEPARATOR); - if (p == NULL) - { - /* Wtf? */ - return NULL; - } - *p = '\0'; - - return retval; -} - -#endif - -/** - * glib_check_version: - * @required_major: the required major version. - * @required_minor: the required minor version. - * @required_micro: the required micro version. - * - * Checks that the GLib library in use is compatible with the - * given version. Generally you would pass in the constants - * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION - * as the three arguments to this function; that produces - * a check that the library in use is compatible with - * the version of GLib the application or module was compiled - * against. - * - * Compatibility is defined by two things: first the version - * of the running library is newer than the version - * @required_major.required_minor.@required_micro. Second - * the running library must be binary compatible with the - * version @required_major.required_minor.@required_micro - * (same major version.) - * - * Return value: %NULL if the GLib library is compatible with the - * given version, or a string describing the version mismatch. - * The returned string is owned by GLib and must not be modified - * or freed. - * - * Since: 2.6 - **/ -const gchar * -glib_check_version (guint required_major, - guint required_minor, - guint required_micro) -{ - gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION; - gint required_effective_micro = 100 * required_minor + required_micro; - - if (required_major > GLIB_MAJOR_VERSION) - return "GLib version too old (major mismatch)"; - if (required_major < GLIB_MAJOR_VERSION) - return "GLib version too new (major mismatch)"; - if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE) - return "GLib version too new (micro mismatch)"; - if (required_effective_micro > glib_effective_micro) - return "GLib version too old (micro mismatch)"; - return NULL; -} - -#if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY) -/** - * g_memmove: - * @dest: the destination address to copy the bytes to. - * @src: the source address to copy the bytes from. - * @len: the number of bytes to copy. - * - * Copies a block of memory @len bytes long, from @src to @dest. - * The source and destination areas may overlap. - * - * In order to use this function, you must include - * <filename>string.h</filename> yourself, because this macro will - * typically simply resolve to memmove() and GLib does not include - * <filename>string.h</filename> for you. - */ -void -g_memmove (gpointer dest, - gconstpointer src, - gulong len) -{ - gchar* destptr = dest; - const gchar* srcptr = src; - if (src + len < dest || dest + len < src) - { - bcopy (src, dest, len); - return; - } - else if (dest <= src) - { - while (len--) - *(destptr++) = *(srcptr++); - } - else - { - destptr += len; - srcptr += len; - while (len--) - *(--destptr) = *(--srcptr); - } -} -#endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */ - -#ifdef G_OS_WIN32 -#undef g_atexit -#endif - -/** - * g_atexit: - * @func: (scope async): the function to call on normal program termination. - * - * Specifies a function to be called at normal program termination. - * - * Since GLib 2.8.2, on Windows g_atexit() actually is a preprocessor - * macro that maps to a call to the atexit() function in the C - * library. This means that in case the code that calls g_atexit(), - * i.e. atexit(), is in a DLL, the function will be called when the - * DLL is detached from the program. This typically makes more sense - * than that the function is called when the GLib DLL is detached, - * which happened earlier when g_atexit() was a function in the GLib - * DLL. - * - * The behaviour of atexit() in the context of dynamically loaded - * modules is not formally specified and varies wildly. - * - * On POSIX systems, calling g_atexit() (or atexit()) in a dynamically - * loaded module which is unloaded before the program terminates might - * well cause a crash at program exit. - * - * Some POSIX systems implement atexit() like Windows, and have each - * dynamically loaded module maintain an own atexit chain that is - * called when the module is unloaded. - * - * On other POSIX systems, before a dynamically loaded module is - * unloaded, the registered atexit functions (if any) residing in that - * module are called, regardless where the code that registered them - * resided. This is presumably the most robust approach. - * - * As can be seen from the above, for portability it's best to avoid - * calling g_atexit() (or atexit()) except in the main executable of a - * program. - */ -void -g_atexit (GVoidFunc func) -{ - gint result; - const gchar *error = NULL; - - /* keep this in sync with glib.h */ - -#ifdef G_NATIVE_ATEXIT - result = ATEXIT (func); - if (result) - error = g_strerror (errno); -#elif defined (HAVE_ATEXIT) -# ifdef NeXT /* @#%@! NeXTStep */ - result = !atexit ((void (*)(void)) func); - if (result) - error = g_strerror (errno); -# else - result = atexit ((void (*)(void)) func); - if (result) - error = g_strerror (errno); -# endif /* NeXT */ -#elif defined (HAVE_ON_EXIT) - result = on_exit ((void (*)(int, void *)) func, NULL); - if (result) - error = g_strerror (errno); -#else - result = 0; - error = "no implementation"; -#endif /* G_NATIVE_ATEXIT */ - - if (error) - g_error ("Could not register atexit() function: %s", error); -} - -/* Based on execvp() from GNU Libc. - * Some of this code is cut-and-pasted into gspawn.c - */ - -static gchar* -my_strchrnul (const gchar *str, - gchar c) -{ - gchar *p = (gchar*)str; - while (*p && (*p != c)) - ++p; - - return p; -} - -#ifdef G_OS_WIN32 - -static gchar *inner_find_program_in_path (const gchar *program); - -gchar* -g_find_program_in_path (const gchar *program) -{ - const gchar *last_dot = strrchr (program, '.'); - - if (last_dot == NULL || - strchr (last_dot, '\\') != NULL || - strchr (last_dot, '/') != NULL) - { - const gint program_length = strlen (program); - gchar *pathext = g_build_path (";", - ".exe;.cmd;.bat;.com", - g_getenv ("PATHEXT"), - NULL); - gchar *p; - gchar *decorated_program; - gchar *retval; - - p = pathext; - do - { - gchar *q = my_strchrnul (p, ';'); - - decorated_program = g_malloc (program_length + (q-p) + 1); - memcpy (decorated_program, program, program_length); - memcpy (decorated_program+program_length, p, q-p); - decorated_program [program_length + (q-p)] = '\0'; - - retval = inner_find_program_in_path (decorated_program); - g_free (decorated_program); - - if (retval != NULL) - { - g_free (pathext); - return retval; - } - p = q; - } while (*p++ != '\0'); - g_free (pathext); - return NULL; - } - else - return inner_find_program_in_path (program); -} - -#endif - -/** - * g_find_program_in_path: - * @program: a program name in the GLib file name encoding - * - * Locates the first executable named @program in the user's path, in the - * same way that execvp() would locate it. Returns an allocated string - * with the absolute path name, or %NULL if the program is not found in - * the path. If @program is already an absolute path, returns a copy of - * @program if @program exists and is executable, and %NULL otherwise. - * - * On Windows, if @program does not have a file type suffix, tries - * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in - * the <envar>PATHEXT</envar> environment variable. - * - * On Windows, it looks for the file in the same way as CreateProcess() - * would. This means first in the directory where the executing - * program was loaded from, then in the current directory, then in the - * Windows 32-bit system directory, then in the Windows directory, and - * finally in the directories in the <envar>PATH</envar> environment - * variable. If the program is found, the return value contains the - * full name including the type suffix. - * - * Return value: absolute path, or %NULL - **/ -#ifdef G_OS_WIN32 -static gchar * -inner_find_program_in_path (const gchar *program) -#else -gchar* -g_find_program_in_path (const gchar *program) -#endif -{ - const gchar *path, *p; - gchar *name, *freeme; -#ifdef G_OS_WIN32 - const gchar *path_copy; - gchar *filename = NULL, *appdir = NULL; - gchar *sysdir = NULL, *windir = NULL; - int n; - wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN], - wwindir[MAXPATHLEN]; -#endif - gsize len; - gsize pathlen; - - g_return_val_if_fail (program != NULL, NULL); - - /* If it is an absolute path, or a relative path including subdirectories, - * don't look in PATH. - */ - if (g_path_is_absolute (program) - || strchr (program, G_DIR_SEPARATOR) != NULL -#ifdef G_OS_WIN32 - || strchr (program, '/') != NULL -#endif - ) - { - if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) && - !g_file_test (program, G_FILE_TEST_IS_DIR)) - return g_strdup (program); - else - return NULL; - } - - path = g_getenv ("PATH"); -#if defined(G_OS_UNIX) || defined(G_OS_BEOS) - if (path == NULL) - { - /* There is no `PATH' in the environment. The default - * search path in GNU libc is the current directory followed by - * the path `confstr' returns for `_CS_PATH'. - */ - - /* In GLib we put . last, for security, and don't use the - * unportable confstr(); UNIX98 does not actually specify - * what to search if PATH is unset. POSIX may, dunno. - */ - - path = "/bin:/usr/bin:."; - } -#else - n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN); - if (n > 0 && n < MAXPATHLEN) - filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL); - - n = GetSystemDirectoryW (wsysdir, MAXPATHLEN); - if (n > 0 && n < MAXPATHLEN) - sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL); - - n = GetWindowsDirectoryW (wwindir, MAXPATHLEN); - if (n > 0 && n < MAXPATHLEN) - windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL); - - if (filename) - { - appdir = g_path_get_dirname (filename); - g_free (filename); - } - - path = g_strdup (path); - - if (windir) - { - const gchar *tem = path; - path = g_strconcat (windir, ";", path, NULL); - g_free ((gchar *) tem); - g_free (windir); - } - - if (sysdir) - { - const gchar *tem = path; - path = g_strconcat (sysdir, ";", path, NULL); - g_free ((gchar *) tem); - g_free (sysdir); - } - - { - const gchar *tem = path; - path = g_strconcat (".;", path, NULL); - g_free ((gchar *) tem); - } - - if (appdir) - { - const gchar *tem = path; - path = g_strconcat (appdir, ";", path, NULL); - g_free ((gchar *) tem); - g_free (appdir); - } - - path_copy = path; -#endif - - len = strlen (program) + 1; - pathlen = strlen (path); - freeme = name = g_malloc (pathlen + len + 1); - - /* Copy the file name at the top, including '\0' */ - memcpy (name + pathlen + 1, program, len); - name = name + pathlen; - /* And add the slash before the filename */ - *name = G_DIR_SEPARATOR; - - p = path; - do - { - char *startp; - - path = p; - p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR); - - if (p == path) - /* Two adjacent colons, or a colon at the beginning or the end - * of `PATH' means to search the current directory. - */ - startp = name + 1; - else - startp = memcpy (name - (p - path), path, p - path); - - if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) && - !g_file_test (startp, G_FILE_TEST_IS_DIR)) - { - gchar *ret; - ret = g_strdup (startp); - g_free (freeme); -#ifdef G_OS_WIN32 - g_free ((gchar *) path_copy); -#endif - return ret; - } - } - while (*p++ != '\0'); - - g_free (freeme); -#ifdef G_OS_WIN32 - g_free ((gchar *) path_copy); -#endif - - return NULL; -} - -static gboolean -debug_key_matches (const gchar *key, - const gchar *token, - guint length) -{ - for (; length; length--, key++, token++) - { - char k = (*key == '_') ? '-' : tolower (*key ); - char t = (*token == '_') ? '-' : tolower (*token); - - if (k != t) - return FALSE; - } - - return *key == '\0'; -} - -/** - * g_parse_debug_string: - * @string: (allow-none): a list of debug options separated by colons, spaces, or - * commas, or %NULL. - * @keys: (array length=nkeys): pointer to an array of #GDebugKey which associate - * strings with bit flags. - * @nkeys: the number of #GDebugKey<!-- -->s in the array. - * - * Parses a string containing debugging options - * into a %guint containing bit flags. This is used - * within GDK and GTK+ to parse the debug options passed on the - * command line or through environment variables. - * - * If @string is equal to "all", all flags are set. If @string - * is equal to "help", all the available keys in @keys are printed - * out to standard error. - * - * Returns: the combined set of bit flags. - */ -guint -g_parse_debug_string (const gchar *string, - const GDebugKey *keys, - guint nkeys) -{ - guint i; - guint result = 0; - - if (string == NULL) - return 0; - - /* this function is used by gmem.c/gslice.c initialization code, - * so introducing malloc dependencies here would require adaptions - * of those code portions. - */ - - if (!g_ascii_strcasecmp (string, "all")) - { - for (i=0; i<nkeys; i++) - result |= keys[i].value; - } - else if (!g_ascii_strcasecmp (string, "help")) - { - /* using stdio directly for the reason stated above */ - fprintf (stderr, "Supported debug values: "); - for (i=0; i<nkeys; i++) - fprintf (stderr, " %s", keys[i].key); - fprintf (stderr, "\n"); - } - else - { - const gchar *p = string; - const gchar *q; - - while (*p) - { - q = strpbrk (p, ":;, \t"); - if (!q) - q = p + strlen(p); - - for (i = 0; i < nkeys; i++) - if (debug_key_matches (keys[i].key, p, q - p)) - result |= keys[i].value; - - p = q; - if (*p) - p++; - } - } - - return result; -} - -/** - * g_basename: - * @file_name: the name of the file. - * - * Gets the name of the file without any leading directory components. - * It returns a pointer into the given file name string. - * - * Return value: the name of the file without any leading directory components. - * - * Deprecated:2.2: Use g_path_get_basename() instead, but notice that - * g_path_get_basename() allocates new memory for the returned string, unlike - * this function which returns a pointer into the argument. - **/ -const gchar * -g_basename (const gchar *file_name) -{ - register gchar *base; - - g_return_val_if_fail (file_name != NULL, NULL); - - base = strrchr (file_name, G_DIR_SEPARATOR); - -#ifdef G_OS_WIN32 - { - gchar *q = strrchr (file_name, '/'); - if (base == NULL || (q != NULL && q > base)) - base = q; - } -#endif - - if (base) - return base + 1; - -#ifdef G_OS_WIN32 - if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':') - return (gchar*) file_name + 2; -#endif /* G_OS_WIN32 */ - - return (gchar*) file_name; -} - -/** - * g_path_get_basename: - * @file_name: the name of the file. - * - * Gets the last component of the filename. If @file_name ends with a - * directory separator it gets the component before the last slash. If - * @file_name consists only of directory separators (and on Windows, - * possibly a drive letter), a single separator is returned. If - * @file_name is empty, it gets ".". - * - * Return value: a newly allocated string containing the last component of - * the filename. - */ -gchar* -g_path_get_basename (const gchar *file_name) -{ - register gssize base; - register gssize last_nonslash; - gsize len; - gchar *retval; - - g_return_val_if_fail (file_name != NULL, NULL); - - if (file_name[0] == '\0') - /* empty string */ - return g_strdup ("."); - - last_nonslash = strlen (file_name) - 1; - - while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash])) - last_nonslash--; - - if (last_nonslash == -1) - /* string only containing slashes */ - return g_strdup (G_DIR_SEPARATOR_S); - -#ifdef G_OS_WIN32 - if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':') - /* string only containing slashes and a drive */ - return g_strdup (G_DIR_SEPARATOR_S); -#endif /* G_OS_WIN32 */ - - base = last_nonslash; - - while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base])) - base--; - -#ifdef G_OS_WIN32 - if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':') - base = 1; -#endif /* G_OS_WIN32 */ - - len = last_nonslash - base; - retval = g_malloc (len + 1); - memcpy (retval, file_name + base + 1, len); - retval [len] = '\0'; - return retval; -} - -/** - * g_path_is_absolute: - * @file_name: a file name. - * - * Returns %TRUE if the given @file_name is an absolute file name. - * Note that this is a somewhat vague concept on Windows. - * - * On POSIX systems, an absolute file name is well-defined. It always - * starts from the single root directory. For example "/usr/local". - * - * On Windows, the concepts of current drive and drive-specific - * current directory introduce vagueness. This function interprets as - * an absolute file name one that either begins with a directory - * separator such as "\Users\tml" or begins with the root on a drive, - * for example "C:\Windows". The first case also includes UNC paths - * such as "\\myserver\docs\foo". In all cases, either slashes or - * backslashes are accepted. - * - * Note that a file name relative to the current drive root does not - * truly specify a file uniquely over time and across processes, as - * the current drive is a per-process value and can be changed. - * - * File names relative the current directory on some specific drive, - * such as "D:foo/bar", are not interpreted as absolute by this - * function, but they obviously are not relative to the normal current - * directory as returned by getcwd() or g_get_current_dir() - * either. Such paths should be avoided, or need to be handled using - * Windows-specific code. - * - * Returns: %TRUE if @file_name is absolute. - */ -gboolean -g_path_is_absolute (const gchar *file_name) -{ - g_return_val_if_fail (file_name != NULL, FALSE); - - if (G_IS_DIR_SEPARATOR (file_name[0])) - return TRUE; - -#ifdef G_OS_WIN32 - /* Recognize drive letter on native Windows */ - if (g_ascii_isalpha (file_name[0]) && - file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2])) - return TRUE; -#endif /* G_OS_WIN32 */ - - return FALSE; -} - -/** - * g_path_skip_root: - * @file_name: a file name. - * - * Returns a pointer into @file_name after the root component, i.e. after - * the "/" in UNIX or "C:\" under Windows. If @file_name is not an absolute - * path it returns %NULL. - * - * Returns: a pointer into @file_name after the root component. - */ -const gchar * -g_path_skip_root (const gchar *file_name) -{ - g_return_val_if_fail (file_name != NULL, NULL); - -#ifdef G_PLATFORM_WIN32 - /* Skip \\server\share or //server/share */ - if (G_IS_DIR_SEPARATOR (file_name[0]) && - G_IS_DIR_SEPARATOR (file_name[1]) && - file_name[2] && - !G_IS_DIR_SEPARATOR (file_name[2])) - { - gchar *p; - - p = strchr (file_name + 2, G_DIR_SEPARATOR); -#ifdef G_OS_WIN32 - { - gchar *q = strchr (file_name + 2, '/'); - if (p == NULL || (q != NULL && q < p)) - p = q; - } -#endif - if (p && - p > file_name + 2 && - p[1]) - { - file_name = p + 1; - - while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0])) - file_name++; - - /* Possibly skip a backslash after the share name */ - if (G_IS_DIR_SEPARATOR (file_name[0])) - file_name++; - - return (gchar *)file_name; - } - } -#endif - - /* Skip initial slashes */ - if (G_IS_DIR_SEPARATOR (file_name[0])) - { - while (G_IS_DIR_SEPARATOR (file_name[0])) - file_name++; - return (gchar *)file_name; - } - -#ifdef G_OS_WIN32 - /* Skip X:\ */ - if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2])) - return (gchar *)file_name + 3; -#endif - - return NULL; -} - -/** - * g_bit_nth_lsf: - * @mask: a #gulong containing flags - * @nth_bit: the index of the bit to start the search from - * - * Find the position of the first bit set in @mask, searching - * from (but not including) @nth_bit upwards. Bits are numbered - * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63, - * usually). To start searching from the 0th bit, set @nth_bit to -1. - * - * Returns: the index of the first bit set which is higher than @nth_bit - */ - -/** - * g_bit_nth_msf: - * @mask: a #gulong containing flags - * @nth_bit: the index of the bit to start the search from - * - * Find the position of the first bit set in @mask, searching - * from (but not including) @nth_bit downwards. Bits are numbered - * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63, - * usually). To start searching from the last bit, set @nth_bit to - * -1 or GLIB_SIZEOF_LONG * 8. - * - * Returns: the index of the first bit set which is lower than @nth_bit - */ - -/** - * g_bit_storage: - * @number: a #guint - * - * Gets the number of bits used to hold @number, - * e.g. if @number is 4, 3 bits are needed. - * - * Returns: the number of bits used to hold @number - */ - -/** - * g_dirname: - * @file_name: the name of the file - * - * Gets the directory components of a file name. - * If the file name has no directory components "." is returned. - * The returned string should be freed when no longer needed. - * - * Returns: the directory components of the file - * - * Deprecated: use g_path_get_dirname() instead - */ - -/** - * g_path_get_dirname: - * @file_name: the name of the file. - * - * Gets the directory components of a file name. If the file name has no - * directory components "." is returned. The returned string should be - * freed when no longer needed. - * - * Returns: the directory components of the file. - */ -gchar* -g_path_get_dirname (const gchar *file_name) -{ - register gchar *base; - register gsize len; - - g_return_val_if_fail (file_name != NULL, NULL); - - base = strrchr (file_name, G_DIR_SEPARATOR); -#ifdef G_OS_WIN32 - { - gchar *q = strrchr (file_name, '/'); - if (base == NULL || (q != NULL && q > base)) - base = q; - } -#endif - if (!base) - { -#ifdef G_OS_WIN32 - if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':') - { - gchar drive_colon_dot[4]; - - drive_colon_dot[0] = file_name[0]; - drive_colon_dot[1] = ':'; - drive_colon_dot[2] = '.'; - drive_colon_dot[3] = '\0'; - - return g_strdup (drive_colon_dot); - } -#endif - return g_strdup ("."); - } - - while (base > file_name && G_IS_DIR_SEPARATOR (*base)) - base--; - -#ifdef G_OS_WIN32 - /* base points to the char before the last slash. - * - * In case file_name is the root of a drive (X:\) or a child of the - * root of a drive (X:\foo), include the slash. - * - * In case file_name is the root share of an UNC path - * (\\server\share), add a slash, returning \\server\share\ . - * - * In case file_name is a direct child of a share in an UNC path - * (\\server\share\foo), include the slash after the share name, - * returning \\server\share\ . - */ - if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':') - base++; - else if (G_IS_DIR_SEPARATOR (file_name[0]) && - G_IS_DIR_SEPARATOR (file_name[1]) && - file_name[2] && - !G_IS_DIR_SEPARATOR (file_name[2]) && - base >= file_name + 2) - { - const gchar *p = file_name + 2; - while (*p && !G_IS_DIR_SEPARATOR (*p)) - p++; - if (p == base + 1) - { - len = (guint) strlen (file_name) + 1; - base = g_new (gchar, len + 1); - strcpy (base, file_name); - base[len-1] = G_DIR_SEPARATOR; - base[len] = 0; - return base; - } - if (G_IS_DIR_SEPARATOR (*p)) - { - p++; - while (*p && !G_IS_DIR_SEPARATOR (*p)) - p++; - if (p == base + 1) - base++; - } - } -#endif - - len = (guint) 1 + base - file_name; - - base = g_new (gchar, len + 1); - g_memmove (base, file_name, len); - base[len] = 0; - - return base; -} - -/** - * g_get_current_dir: - * - * Gets the current directory. - * The returned string should be freed when no longer needed. The encoding - * of the returned string is system defined. On Windows, it is always UTF-8. - * - * Returns: the current directory. - */ -gchar* -g_get_current_dir (void) -{ -#ifdef G_OS_WIN32 - - gchar *dir = NULL; - wchar_t dummy[2], *wdir; - int len; - - len = GetCurrentDirectoryW (2, dummy); - wdir = g_new (wchar_t, len); - - if (GetCurrentDirectoryW (len, wdir) == len - 1) - dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL); - - g_free (wdir); - - if (dir == NULL) - dir = g_strdup ("\\"); - - return dir; - -#else - - gchar *buffer = NULL; - gchar *dir = NULL; - static gulong max_len = 0; - - if (max_len == 0) - max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH; - - /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd") - * and, if that wasn't bad enough, hangs in doing so. - */ -#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD) - buffer = g_new (gchar, max_len + 1); - *buffer = 0; - dir = getwd (buffer); -#else /* !sun || !HAVE_GETCWD */ - while (max_len < G_MAXULONG / 2) - { - g_free (buffer); - buffer = g_new (gchar, max_len + 1); - *buffer = 0; - dir = getcwd (buffer, max_len); - - if (dir || errno != ERANGE) - break; - - max_len *= 2; - } -#endif /* !sun || !HAVE_GETCWD */ - - if (!dir || !*buffer) - { - /* hm, should we g_error() out here? - * this can happen if e.g. "./" has mode \0000 - */ - buffer[0] = G_DIR_SEPARATOR; - buffer[1] = 0; - } - - dir = g_strdup (buffer); - g_free (buffer); - - return dir; -#endif /* !Win32 */ -} - -/** - * g_getenv: - * @variable: the environment variable to get, in the GLib file name encoding. - * - * Returns the value of an environment variable. The name and value - * are in the GLib file name encoding. On UNIX, this means the actual - * bytes which might or might not be in some consistent character set - * and encoding. On Windows, it is in UTF-8. On Windows, in case the - * environment variable's value contains references to other - * environment variables, they are expanded. - * - * Return value: the value of the environment variable, or %NULL if - * the environment variable is not found. The returned string may be - * overwritten by the next call to g_getenv(), g_setenv() or - * g_unsetenv(). - **/ -const gchar * -g_getenv (const gchar *variable) -{ -#ifndef G_OS_WIN32 - - g_return_val_if_fail (variable != NULL, NULL); - - return getenv (variable); - -#else /* G_OS_WIN32 */ - - GQuark quark; - gchar *value; - wchar_t dummy[2], *wname, *wvalue; - int len; - - g_return_val_if_fail (variable != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL); - - /* On Windows NT, it is relatively typical that environment - * variables contain references to other environment variables. If - * so, use ExpandEnvironmentStrings(). (In an ideal world, such - * environment variables would be stored in the Registry as - * REG_EXPAND_SZ type values, and would then get automatically - * expanded before a program sees them. But there is broken software - * that stores environment variables as REG_SZ values even if they - * contain references to other environment variables.) - */ - - wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); - - len = GetEnvironmentVariableW (wname, dummy, 2); - - if (len == 0) - { - g_free (wname); - return NULL; - } - else if (len == 1) - len = 2; - - wvalue = g_new (wchar_t, len); - - if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1) - { - g_free (wname); - g_free (wvalue); - return NULL; - } - - if (wcschr (wvalue, L'%') != NULL) - { - wchar_t *tem = wvalue; - - len = ExpandEnvironmentStringsW (wvalue, dummy, 2); - - if (len > 0) - { - wvalue = g_new (wchar_t, len); - - if (ExpandEnvironmentStringsW (tem, wvalue, len) != len) - { - g_free (wvalue); - wvalue = tem; - } - else - g_free (tem); - } - } - - value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL); - - g_free (wname); - g_free (wvalue); - - quark = g_quark_from_string (value); - g_free (value); - - return g_quark_to_string (quark); - -#endif /* G_OS_WIN32 */ -} - -/* _g_getenv_nomalloc - * this function does a getenv() without doing any kind of allocation - * through glib. it's suitable for chars <= 127 only (both, for the - * variable name and the contents) and for contents < 1024 chars in - * length. also, it aliases "" to a NULL return value. - **/ -const gchar* -_g_getenv_nomalloc (const gchar *variable, - gchar buffer[1024]) -{ - const gchar *retval = getenv (variable); - if (retval && retval[0]) - { - gint l = strlen (retval); - if (l < 1024) - { - strncpy (buffer, retval, l); - buffer[l] = 0; - return buffer; - } - } - return NULL; -} - -/** - * g_setenv: - * @variable: the environment variable to set, must not contain '='. - * @value: the value for to set the variable to. - * @overwrite: whether to change the variable if it already exists. - * - * Sets an environment variable. Both the variable's name and value - * should be in the GLib file name encoding. On UNIX, this means that - * they can be any sequence of bytes. On Windows, they should be in - * UTF-8. - * - * Note that on some systems, when variables are overwritten, the memory - * used for the previous variables and its value isn't reclaimed. - * - * Returns: %FALSE if the environment variable couldn't be set. - * - * Since: 2.4 - */ -gboolean -g_setenv (const gchar *variable, - const gchar *value, - gboolean overwrite) -{ -#ifndef G_OS_WIN32 - - gint result; -#ifndef HAVE_SETENV - gchar *string; -#endif - - g_return_val_if_fail (variable != NULL, FALSE); - g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE); - -#ifdef HAVE_SETENV - result = setenv (variable, value, overwrite); -#else - if (!overwrite && getenv (variable) != NULL) - return TRUE; - - /* This results in a leak when you overwrite existing - * settings. It would be fairly easy to fix this by keeping - * our own parallel array or hash table. - */ - string = g_strconcat (variable, "=", value, NULL); - result = putenv (string); -#endif - return result == 0; - -#else /* G_OS_WIN32 */ - - gboolean retval; - wchar_t *wname, *wvalue, *wassignment; - gchar *tem; - - g_return_val_if_fail (variable != NULL, FALSE); - g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE); - g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE); - g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); - - if (!overwrite && g_getenv (variable) != NULL) - return TRUE; - - /* We want to (if possible) set both the environment variable copy - * kept by the C runtime and the one kept by the system. - * - * We can't use only the C runtime's putenv or _wputenv() as that - * won't work for arbitrary Unicode strings in a "non-Unicode" app - * (with main() and not wmain()). In a "main()" app the C runtime - * initializes the C runtime's environment table by converting the - * real (wide char) environment variables to system codepage, thus - * breaking those that aren't representable in the system codepage. - * - * As the C runtime's putenv() will also set the system copy, we do - * the putenv() first, then call SetEnvironmentValueW ourselves. - */ - - wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); - wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL); - tem = g_strconcat (variable, "=", value, NULL); - wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL); - - g_free (tem); - _wputenv (wassignment); - g_free (wassignment); - - retval = (SetEnvironmentVariableW (wname, wvalue) != 0); - - g_free (wname); - g_free (wvalue); - - return retval; - -#endif /* G_OS_WIN32 */ -} - -#ifdef HAVE__NSGETENVIRON -#define environ (*_NSGetEnviron()) -#elif !defined(G_OS_WIN32) - -/* According to the Single Unix Specification, environ is not in - * any system header, although unistd.h often declares it. - */ -extern char **environ; -#endif - -/** - * g_unsetenv: - * @variable: the environment variable to remove, must not contain '='. - * - * Removes an environment variable from the environment. - * - * Note that on some systems, when variables are overwritten, the memory - * used for the previous variables and its value isn't reclaimed. - * Furthermore, this function can't be guaranteed to operate in a - * threadsafe way. - * - * Since: 2.4 - **/ -void -g_unsetenv (const gchar *variable) -{ -#ifndef G_OS_WIN32 - -#ifdef HAVE_UNSETENV - g_return_if_fail (variable != NULL); - g_return_if_fail (strchr (variable, '=') == NULL); - - unsetenv (variable); -#else /* !HAVE_UNSETENV */ - int len; - gchar **e, **f; - - g_return_if_fail (variable != NULL); - g_return_if_fail (strchr (variable, '=') == NULL); - - len = strlen (variable); - - /* Mess directly with the environ array. - * This seems to be the only portable way to do this. - * - * Note that we remove *all* environment entries for - * the variable name, not just the first. - */ - e = f = environ; - while (*e != NULL) - { - if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') - { - *f = *e; - f++; - } - e++; - } - *f = NULL; -#endif /* !HAVE_UNSETENV */ - -#else /* G_OS_WIN32 */ - - wchar_t *wname, *wassignment; - gchar *tem; - - g_return_if_fail (variable != NULL); - g_return_if_fail (strchr (variable, '=') == NULL); - g_return_if_fail (g_utf8_validate (variable, -1, NULL)); - - wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); - tem = g_strconcat (variable, "=", NULL); - wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL); - - g_free (tem); - _wputenv (wassignment); - g_free (wassignment); - - SetEnvironmentVariableW (wname, NULL); - - g_free (wname); - -#endif /* G_OS_WIN32 */ -} - -/** - * g_listenv: - * - * Gets the names of all variables set in the environment. - * - * Returns: (array zero-terminated=1) (transfer full): a %NULL-terminated list of strings which must be freed - * with g_strfreev(). - * - * Programs that want to be portable to Windows should typically use - * this function and g_getenv() instead of using the environ array - * from the C library directly. On Windows, the strings in the environ - * array are in system codepage encoding, while in most of the typical - * use cases for environment variables in GLib-using programs you want - * the UTF-8 encoding that this function and g_getenv() provide. - * - * Since: 2.8 - */ -gchar ** -g_listenv (void) -{ -#ifndef G_OS_WIN32 - gchar **result, *eq; - gint len, i, j; - - len = g_strv_length (environ); - result = g_new0 (gchar *, len + 1); - - j = 0; - for (i = 0; i < len; i++) - { - eq = strchr (environ[i], '='); - if (eq) - result[j++] = g_strndup (environ[i], eq - environ[i]); - } - - result[j] = NULL; - - return result; -#else - gchar **result, *eq; - gint len = 0, j; - wchar_t *p, *q; - - p = (wchar_t *) GetEnvironmentStringsW (); - if (p != NULL) - { - q = p; - while (*q) - { - q += wcslen (q) + 1; - len++; - } - } - result = g_new0 (gchar *, len + 1); - - j = 0; - q = p; - while (*q) - { - result[j] = g_utf16_to_utf8 (q, -1, NULL, NULL, NULL); - if (result[j] != NULL) - { - eq = strchr (result[j], '='); - if (eq && eq > result[j]) - { - *eq = '\0'; - j++; - } - else - g_free (result[j]); - } - q += wcslen (q) + 1; - } - result[j] = NULL; - FreeEnvironmentStringsW (p); - - return result; -#endif -} - -/** - * g_get_environ: - * - * Gets the list of environment variables for the current process. The - * list is %NULL terminated and each item in the list is of the form - * 'NAME=VALUE'. - * - * This is equivalent to direct access to the 'environ' global variable, - * except portable. - * - * The return value is freshly allocated and it should be freed with - * g_strfreev() when it is no longer needed. - * - * Returns: (array zero-terminated=1) (transfer full): the list of environment variables - * - * Since: 2.28 - */ -gchar ** -g_get_environ (void) -{ -#ifndef G_OS_WIN32 - return g_strdupv (environ); -#else - gunichar2 *strings; - gchar **result; - gint i, n; - - strings = GetEnvironmentStringsW (); - for (n = 0; strings[n]; n += wcslen (strings + n) + 1); - result = g_new (char *, n + 1); - for (i = 0; strings[i]; i += wcslen (strings + i) + 1) - result[i] = g_utf16_to_utf8 (strings + i, -1, NULL, NULL, NULL); - FreeEnvironmentStringsW (strings); - result[i] = NULL; - - return result; -#endif -} - -G_LOCK_DEFINE_STATIC (g_utils_global); - -static gchar *g_tmp_dir = NULL; -static gchar *g_user_name = NULL; -static gchar *g_real_name = NULL; -static gchar *g_home_dir = NULL; -static gchar *g_host_name = NULL; - -#ifdef G_OS_WIN32 -/* System codepage versions of the above, kept at file level so that they, - * too, are produced only once. - */ -static gchar *g_tmp_dir_cp = NULL; -static gchar *g_user_name_cp = NULL; -static gchar *g_real_name_cp = NULL; -static gchar *g_home_dir_cp = NULL; -#endif - -static gchar *g_user_data_dir = NULL; -static gchar **g_system_data_dirs = NULL; -static gchar *g_user_cache_dir = NULL; -static gchar *g_user_config_dir = NULL; -static gchar **g_system_config_dirs = NULL; - -static gchar **g_user_special_dirs = NULL; - -/* fifteen minutes of fame for everybody */ -#define G_USER_DIRS_EXPIRE 15 * 60 - -#ifdef G_OS_WIN32 - -static gchar * -get_special_folder (int csidl) -{ - wchar_t path[MAX_PATH+1]; - HRESULT hr; - LPITEMIDLIST pidl = NULL; - BOOL b; - gchar *retval = NULL; - - hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl); - if (hr == S_OK) - { - b = SHGetPathFromIDListW (pidl, path); - if (b) - retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL); - CoTaskMemFree (pidl); - } - return retval; -} - -static char * -get_windows_directory_root (void) -{ - wchar_t wwindowsdir[MAX_PATH]; - - if (GetWindowsDirectoryW (wwindowsdir, G_N_ELEMENTS (wwindowsdir))) - { - /* Usually X:\Windows, but in terminal server environments - * might be an UNC path, AFAIK. - */ - char *windowsdir = g_utf16_to_utf8 (wwindowsdir, -1, NULL, NULL, NULL); - char *p; - - if (windowsdir == NULL) - return g_strdup ("C:\\"); - - p = (char *) g_path_skip_root (windowsdir); - if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':') - p--; - *p = '\0'; - return windowsdir; - } - else - return g_strdup ("C:\\"); -} - -#endif - -/* HOLDS: g_utils_global_lock */ -static void -g_get_any_init_do (void) -{ - gchar hostname[100]; - - g_tmp_dir = g_strdup (g_getenv ("TMPDIR")); - if (g_tmp_dir == NULL || *g_tmp_dir == '\0') - g_tmp_dir = g_strdup (g_getenv ("TMP")); - if (g_tmp_dir == NULL || *g_tmp_dir == '\0') - g_tmp_dir = g_strdup (g_getenv ("TEMP")); - -#ifdef G_OS_WIN32 - if (g_tmp_dir == NULL || *g_tmp_dir == '\0') - g_tmp_dir = get_windows_directory_root (); -#else -#ifdef P_tmpdir - if (g_tmp_dir == NULL || *g_tmp_dir == '\0') - { - gsize k; - g_tmp_dir = g_strdup (P_tmpdir); - k = strlen (g_tmp_dir); - if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1])) - g_tmp_dir[k - 1] = '\0'; - } -#endif - - if (g_tmp_dir == NULL || *g_tmp_dir == '\0') - { - g_tmp_dir = g_strdup ("/tmp"); - } -#endif /* !G_OS_WIN32 */ - -#ifdef G_OS_WIN32 - /* We check $HOME first for Win32, though it is a last resort for Unix - * where we prefer the results of getpwuid(). - */ - g_home_dir = g_strdup (g_getenv ("HOME")); - - /* Only believe HOME if it is an absolute path and exists */ - if (g_home_dir) - { - if (!(g_path_is_absolute (g_home_dir) && - g_file_test (g_home_dir, G_FILE_TEST_IS_DIR))) - { - g_free (g_home_dir); - g_home_dir = NULL; - } - } - - /* In case HOME is Unix-style (it happens), convert it to - * Windows style. - */ - if (g_home_dir) - { - gchar *p; - while ((p = strchr (g_home_dir, '/')) != NULL) - *p = '\\'; - } - - if (!g_home_dir) - { - /* USERPROFILE is probably the closest equivalent to $HOME? */ - if (g_getenv ("USERPROFILE") != NULL) - g_home_dir = g_strdup (g_getenv ("USERPROFILE")); - } - - if (!g_home_dir) - g_home_dir = get_special_folder (CSIDL_PROFILE); - - if (!g_home_dir) - g_home_dir = get_windows_directory_root (); -#endif /* G_OS_WIN32 */ - -#ifdef HAVE_PWD_H - { - struct passwd *pw = NULL; - gpointer buffer = NULL; - gint error; - gchar *logname; - -# if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R) - struct passwd pwd; -# ifdef _SC_GETPW_R_SIZE_MAX - /* This reurns the maximum length */ - glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); - - if (bufsize < 0) - bufsize = 64; -# else /* _SC_GETPW_R_SIZE_MAX */ - glong bufsize = 64; -# endif /* _SC_GETPW_R_SIZE_MAX */ - - logname = (gchar *) g_getenv ("LOGNAME"); - - do - { - g_free (buffer); - /* we allocate 6 extra bytes to work around a bug in - * Mac OS < 10.3. See #156446 - */ - buffer = g_malloc (bufsize + 6); - errno = 0; - -# ifdef HAVE_POSIX_GETPWUID_R - if (logname) { - error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw); - if (!pw || (pw->pw_uid != getuid ())) { - /* LOGNAME is lying, fall back to looking up the uid */ - error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw); - } - } else { - error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw); - } - error = error < 0 ? errno : error; -# else /* HAVE_NONPOSIX_GETPWUID_R */ - /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */ -# if defined(_AIX) || defined(__hpux) - error = getpwuid_r (getuid (), &pwd, buffer, bufsize); - pw = error == 0 ? &pwd : NULL; -# else /* !_AIX */ - if (logname) { - pw = getpwnam_r (logname, &pwd, buffer, bufsize); - if (!pw || (pw->pw_uid != getuid ())) { - /* LOGNAME is lying, fall back to looking up the uid */ - pw = getpwuid_r (getuid (), &pwd, buffer, bufsize); - } - } else { - pw = getpwuid_r (getuid (), &pwd, buffer, bufsize); - } - error = pw ? 0 : errno; -# endif /* !_AIX */ -# endif /* HAVE_NONPOSIX_GETPWUID_R */ - - if (!pw) - { - /* we bail out prematurely if the user id can't be found - * (should be pretty rare case actually), or if the buffer - * should be sufficiently big and lookups are still not - * successful. - */ - if (error == 0 || error == ENOENT) - { - g_warning ("getpwuid_r(): failed due to unknown user id (%lu)", - (gulong) getuid ()); - break; - } - if (bufsize > 32 * 1024) - { - g_warning ("getpwuid_r(): failed due to: %s.", - g_strerror (error)); - break; - } - - bufsize *= 2; - } - } - while (!pw); -# endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */ - - if (!pw) - { - setpwent (); - pw = getpwuid (getuid ()); - endpwent (); - } - if (pw) - { - g_user_name = g_strdup (pw->pw_name); - - if (pw->pw_gecos && *pw->pw_gecos != '\0') - { - gchar **gecos_fields; - gchar **name_parts; - - /* split the gecos field and substitute '&' */ - gecos_fields = g_strsplit (pw->pw_gecos, ",", 0); - name_parts = g_strsplit (gecos_fields[0], "&", 0); - pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]); - g_real_name = g_strjoinv (pw->pw_name, name_parts); - g_strfreev (gecos_fields); - g_strfreev (name_parts); - } - - if (!g_home_dir) - g_home_dir = g_strdup (pw->pw_dir); - } - g_free (buffer); - } - -#else /* !HAVE_PWD_H */ - -#ifdef G_OS_WIN32 - { - guint len = UNLEN+1; - wchar_t buffer[UNLEN+1]; - - if (GetUserNameW (buffer, (LPDWORD) &len)) - { - g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL); - g_real_name = g_strdup (g_user_name); - } - } -#endif /* G_OS_WIN32 */ - -#endif /* !HAVE_PWD_H */ - -#ifndef G_OS_WIN32 - if (!g_home_dir) - g_home_dir = g_strdup (g_getenv ("HOME")); -#endif - -#ifdef __EMX__ - /* change '\\' in %HOME% to '/' */ - g_strdelimit (g_home_dir, "\\",'/'); -#endif - if (!g_user_name) - g_user_name = g_strdup ("somebody"); - if (!g_real_name) - g_real_name = g_strdup ("Unknown"); - - { -#ifndef G_OS_WIN32 - gboolean hostname_fail = (gethostname (hostname, sizeof (hostname)) == -1); -#else - DWORD size = sizeof (hostname); - gboolean hostname_fail = (!GetComputerName (hostname, &size)); -#endif - g_host_name = g_strdup (hostname_fail ? "localhost" : hostname); - } - -#ifdef G_OS_WIN32 - g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL); - g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL); - g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL); - - if (!g_tmp_dir_cp) - g_tmp_dir_cp = g_strdup ("\\"); - if (!g_user_name_cp) - g_user_name_cp = g_strdup ("somebody"); - if (!g_real_name_cp) - g_real_name_cp = g_strdup ("Unknown"); - - /* home_dir might be NULL, unlike tmp_dir, user_name and - * real_name. - */ - if (g_home_dir) - g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL); - else - g_home_dir_cp = NULL; -#endif /* G_OS_WIN32 */ -} - -static inline void -g_get_any_init (void) -{ - if (!g_tmp_dir) - g_get_any_init_do (); -} - -static inline void -g_get_any_init_locked (void) -{ - G_LOCK (g_utils_global); - g_get_any_init (); - G_UNLOCK (g_utils_global); -} - - -/** - * g_get_user_name: - * - * Gets the user name of the current user. The encoding of the returned - * string is system-defined. On UNIX, it might be the preferred file name - * encoding, or something else, and there is no guarantee that it is even - * consistent on a machine. On Windows, it is always UTF-8. - * - * Returns: the user name of the current user. - */ -const gchar * -g_get_user_name (void) -{ - g_get_any_init_locked (); - return g_user_name; -} - -/** - * g_get_real_name: - * - * Gets the real name of the user. This usually comes from the user's entry - * in the <filename>passwd</filename> file. The encoding of the returned - * string is system-defined. (On Windows, it is, however, always UTF-8.) - * If the real user name cannot be determined, the string "Unknown" is - * returned. - * - * Returns: the user's real name. - */ -const gchar * -g_get_real_name (void) -{ - g_get_any_init_locked (); - return g_real_name; -} - -/** - * g_get_home_dir: - * - * Gets the current user's home directory as defined in the - * password database. - * - * Note that in contrast to traditional UNIX tools, this function - * prefers <filename>passwd</filename> entries over the <envar>HOME</envar> - * environment variable. - * - * One of the reasons for this decision is that applications in many - * cases need special handling to deal with the case where - * <envar>HOME</envar> is - * <simplelist> - * <member>Not owned by the user</member> - * <member>Not writeable</member> - * <member>Not even readable</member> - * </simplelist> - * Since applications are in general <emphasis>not</emphasis> written - * to deal with these situations it was considered better to make - * g_get_home_dir() not pay attention to <envar>HOME</envar> and to - * return the real home directory for the user. If applications - * want to pay attention to <envar>HOME</envar>, they can do: - * |[ - * const char *homedir = g_getenv ("HOME"); - * if (!homedir) - * homedir = g_get_home_dir (<!-- -->); - * ]| - * - * Returns: the current user's home directory - */ -const gchar * -g_get_home_dir (void) -{ - g_get_any_init_locked (); - return g_home_dir; -} - -/** - * g_get_tmp_dir: - * - * Gets the directory to use for temporary files. This is found from - * inspecting the environment variables <envar>TMPDIR</envar>, - * <envar>TMP</envar>, and <envar>TEMP</envar> in that order. If none - * of those are defined "/tmp" is returned on UNIX and "C:\" on Windows. - * The encoding of the returned string is system-defined. On Windows, - * it is always UTF-8. The return value is never %NULL or the empty string. - * - * Returns: the directory to use for temporary files. - */ -const gchar * -g_get_tmp_dir (void) -{ - g_get_any_init_locked (); - return g_tmp_dir; -} - -/** - * g_get_host_name: - * - * Return a name for the machine. - * - * The returned name is not necessarily a fully-qualified domain name, - * or even present in DNS or some other name service at all. It need - * not even be unique on your local network or site, but usually it - * is. Callers should not rely on the return value having any specific - * properties like uniqueness for security purposes. Even if the name - * of the machine is changed while an application is running, the - * return value from this function does not change. The returned - * string is owned by GLib and should not be modified or freed. If no - * name can be determined, a default fixed string "localhost" is - * returned. - * - * Returns: the host name of the machine. - * - * Since: 2.8 - */ -const gchar * -g_get_host_name (void) -{ - g_get_any_init_locked (); - return g_host_name; -} - -G_LOCK_DEFINE_STATIC (g_prgname); -static gchar *g_prgname = NULL; - -/** - * g_get_prgname: - * - * Gets the name of the program. This name should <emphasis>not</emphasis> - * be localized, contrast with g_get_application_name(). - * (If you are using GDK or GTK+ the program name is set in gdk_init(), - * which is called by gtk_init(). The program name is found by taking - * the last component of <literal>argv[0]</literal>.) - * - * Returns: the name of the program. The returned string belongs - * to GLib and must not be modified or freed. - */ -gchar* -g_get_prgname (void) -{ - gchar* retval; - - G_LOCK (g_prgname); -#ifdef G_OS_WIN32 - if (g_prgname == NULL) - { - static gboolean beenhere = FALSE; - - if (!beenhere) - { - gchar *utf8_buf = NULL; - wchar_t buf[MAX_PATH+1]; - - beenhere = TRUE; - if (GetModuleFileNameW (GetModuleHandle (NULL), - buf, G_N_ELEMENTS (buf)) > 0) - utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL); - - if (utf8_buf) - { - g_prgname = g_path_get_basename (utf8_buf); - g_free (utf8_buf); - } - } - } -#endif - retval = g_prgname; - G_UNLOCK (g_prgname); - - return retval; -} - -/** - * g_set_prgname: - * @prgname: the name of the program. - * - * Sets the name of the program. This name should <emphasis>not</emphasis> - * be localized, contrast with g_set_application_name(). Note that for - * thread-safety reasons this function can only be called once. - */ -void -g_set_prgname (const gchar *prgname) -{ - G_LOCK (g_prgname); - g_free (g_prgname); - g_prgname = g_strdup (prgname); - G_UNLOCK (g_prgname); -} - -G_LOCK_DEFINE_STATIC (g_application_name); -static gchar *g_application_name = NULL; - -/** - * g_get_application_name: - * - * Gets a human-readable name for the application, as set by - * g_set_application_name(). This name should be localized if - * possible, and is intended for display to the user. Contrast with - * g_get_prgname(), which gets a non-localized name. If - * g_set_application_name() has not been called, returns the result of - * g_get_prgname() (which may be %NULL if g_set_prgname() has also not - * been called). - * - * Return value: human-readable application name. may return %NULL - * - * Since: 2.2 - **/ -const gchar * -g_get_application_name (void) -{ - gchar* retval; - - G_LOCK (g_application_name); - retval = g_application_name; - G_UNLOCK (g_application_name); - - if (retval == NULL) - return g_get_prgname (); - - return retval; -} - -/** - * g_set_application_name: - * @application_name: localized name of the application - * - * Sets a human-readable name for the application. This name should be - * localized if possible, and is intended for display to the user. - * Contrast with g_set_prgname(), which sets a non-localized name. - * g_set_prgname() will be called automatically by gtk_init(), - * but g_set_application_name() will not. - * - * Note that for thread safety reasons, this function can only - * be called once. - * - * The application name will be used in contexts such as error messages, - * or when displaying an application's name in the task list. - * - * Since: 2.2 - **/ -void -g_set_application_name (const gchar *application_name) -{ - gboolean already_set = FALSE; - - G_LOCK (g_application_name); - if (g_application_name) - already_set = TRUE; - else - g_application_name = g_strdup (application_name); - G_UNLOCK (g_application_name); - - if (already_set) - g_warning ("g_set_application_name() called multiple times"); -} - -/** - * g_get_user_data_dir: - * - * Returns a base directory in which to access application data such - * as icons that is customized for a particular user. - * - * On UNIX platforms this is determined using the mechanisms described in - * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec"> - * XDG Base Directory Specification</ulink>. - * In this case the directory retrieved will be XDG_DATA_HOME. - * - * On Windows this is the folder to use for local (as opposed to - * roaming) application data. See documentation for - * CSIDL_LOCAL_APPDATA. Note that on Windows it thus is the same as - * what g_get_user_config_dir() returns. - * - * Return value: a string owned by GLib that must not be modified - * or freed. - * Since: 2.6 - **/ -const gchar * -g_get_user_data_dir (void) -{ - gchar *data_dir; - - G_LOCK (g_utils_global); - - if (!g_user_data_dir) - { -#ifdef G_OS_WIN32 - data_dir = get_special_folder (CSIDL_LOCAL_APPDATA); -#else - data_dir = (gchar *) g_getenv ("XDG_DATA_HOME"); - - if (data_dir && data_dir[0]) - data_dir = g_strdup (data_dir); -#endif - if (!data_dir || !data_dir[0]) - { - g_get_any_init (); - - if (g_home_dir) - data_dir = g_build_filename (g_home_dir, ".local", - "share", NULL); - else - data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local", - "share", NULL); - } - - g_user_data_dir = data_dir; - } - else - data_dir = g_user_data_dir; - - G_UNLOCK (g_utils_global); - - return data_dir; -} - -static void -g_init_user_config_dir (void) -{ - gchar *config_dir; - - if (!g_user_config_dir) - { -#ifdef G_OS_WIN32 - config_dir = get_special_folder (CSIDL_LOCAL_APPDATA); -#else - config_dir = (gchar *) g_getenv ("XDG_CONFIG_HOME"); - - if (config_dir && config_dir[0]) - config_dir = g_strdup (config_dir); -#endif - if (!config_dir || !config_dir[0]) - { - g_get_any_init (); - - if (g_home_dir) - config_dir = g_build_filename (g_home_dir, ".config", NULL); - else - config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL); - } - - g_user_config_dir = config_dir; - } -} - -/** - * g_get_user_config_dir: - * - * Returns a base directory in which to store user-specific application - * configuration information such as user preferences and settings. - * - * On UNIX platforms this is determined using the mechanisms described in - * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec"> - * XDG Base Directory Specification</ulink>. - * In this case the directory retrieved will be XDG_CONFIG_HOME. - * - * On Windows this is the folder to use for local (as opposed to - * roaming) application data. See documentation for - * CSIDL_LOCAL_APPDATA. Note that on Windows it thus is the same as - * what g_get_user_data_dir() returns. - * - * Return value: a string owned by GLib that must not be modified - * or freed. - * Since: 2.6 - **/ -const gchar * -g_get_user_config_dir (void) -{ - G_LOCK (g_utils_global); - - g_init_user_config_dir (); - - G_UNLOCK (g_utils_global); - - return g_user_config_dir; -} - -/** - * g_get_user_cache_dir: - * - * Returns a base directory in which to store non-essential, cached - * data specific to particular user. - * - * On UNIX platforms this is determined using the mechanisms described in - * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec"> - * XDG Base Directory Specification</ulink>. - * In this case the directory retrieved will be XDG_CACHE_HOME. - * - * On Windows is the directory that serves as a common repository for - * temporary Internet files. A typical path is - * C:\Documents and Settings\username\Local Settings\Temporary Internet Files. - * See documentation for CSIDL_INTERNET_CACHE. - * - * Return value: a string owned by GLib that must not be modified - * or freed. - * Since: 2.6 - **/ -const gchar * -g_get_user_cache_dir (void) -{ - gchar *cache_dir; - - G_LOCK (g_utils_global); - - if (!g_user_cache_dir) - { -#ifdef G_OS_WIN32 - cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); /* XXX correct? */ -#else - cache_dir = (gchar *) g_getenv ("XDG_CACHE_HOME"); - - if (cache_dir && cache_dir[0]) - cache_dir = g_strdup (cache_dir); -#endif - if (!cache_dir || !cache_dir[0]) - { - g_get_any_init (); - - if (g_home_dir) - cache_dir = g_build_filename (g_home_dir, ".cache", NULL); - else - cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL); - } - g_user_cache_dir = cache_dir; - } - else - cache_dir = g_user_cache_dir; - - G_UNLOCK (g_utils_global); - - return cache_dir; -} - -/** - * g_get_user_runtime_dir: - * - * Returns a directory that is unique to the current user on the local - * system. - * - * On UNIX platforms this is determined using the mechanisms described in - * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec"> - * XDG Base Directory Specification</ulink>. This is the directory - * specified in the <envar>XDG_RUNTIME_DIR</envar> environment variable. - * In the case that this variable is not set, GLib will issue a warning - * message to stderr and return the value of g_get_user_cache_dir(). - * - * On Windows this is the folder to use for local (as opposed to - * roaming) application data. See documentation for - * CSIDL_LOCAL_APPDATA. Note that on Windows it thus is the same as - * what g_get_user_config_dir() returns. - * - * Returns: a string owned by GLib that must not be modified or freed. - * - * Since: 2.28 - **/ -const gchar * -g_get_user_runtime_dir (void) -{ -#ifndef G_OS_WIN32 - static const gchar *runtime_dir; - static gsize initialised; - - if (g_once_init_enter (&initialised)) - { - runtime_dir = g_strdup (getenv ("XDG_RUNTIME_DIR")); - - g_once_init_leave (&initialised, 1); - } - - if (runtime_dir) - return runtime_dir; - - /* Both fallback for UNIX and the default - * in Windows: use the user cache directory. - */ -#endif - - return g_get_user_cache_dir (); -} - -#ifdef HAVE_CARBON - -static gchar * -find_folder (OSType type) -{ - gchar *filename = NULL; - FSRef found; - - if (FSFindFolder (kUserDomain, type, kDontCreateFolder, &found) == noErr) - { - CFURLRef url = CFURLCreateFromFSRef (kCFAllocatorSystemDefault, &found); - - if (url) - { - CFStringRef path = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle); - - if (path) - { - filename = g_strdup (CFStringGetCStringPtr (path, kCFStringEncodingUTF8)); - - if (! filename) - { - filename = g_new0 (gchar, CFStringGetLength (path) * 3 + 1); - - CFStringGetCString (path, filename, - CFStringGetLength (path) * 3 + 1, - kCFStringEncodingUTF8); - } - - CFRelease (path); - } - - CFRelease (url); - } - } - - return filename; -} - -static void -load_user_special_dirs (void) -{ - g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = find_folder (kDesktopFolderType); - g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = find_folder (kDocumentsFolderType); - g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = find_folder (kDesktopFolderType); /* XXX correct ? */ - g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = find_folder (kMusicDocumentsFolderType); - g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = find_folder (kPictureDocumentsFolderType); - g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = NULL; - g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = NULL; - g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = find_folder (kMovieDocumentsFolderType); -} - -#endif /* HAVE_CARBON */ - -#if defined(G_OS_WIN32) -static void -load_user_special_dirs (void) -{ - typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid, - DWORD dwFlags, - HANDLE hToken, - PWSTR *ppszPath); - t_SHGetKnownFolderPath p_SHGetKnownFolderPath; - - static const GUID FOLDERID_Downloads = - { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; - static const GUID FOLDERID_Public = - { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } }; - - wchar_t *wcp; - - p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandle ("shell32.dll"), - "SHGetKnownFolderPath"); - - g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY); - g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL); - - if (p_SHGetKnownFolderPath == NULL) - { - g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); - } - else - { - wcp = NULL; - (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp); - if (wcp) - { - g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL); - if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL) - g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); - CoTaskMemFree (wcp); - } - else - g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); - } - - g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC); - g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES); - - if (p_SHGetKnownFolderPath == NULL) - { - /* XXX */ - g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); - } - else - { - wcp = NULL; - (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp); - if (wcp) - { - g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL); - if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL) - g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); - CoTaskMemFree (wcp); - } - else - g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); - } - - g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES); - g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO); -} -#endif /* G_OS_WIN32 */ - -static void g_init_user_config_dir (void); - -#if defined(G_OS_UNIX) && !defined(HAVE_CARBON) - -/* adapted from xdg-user-dir-lookup.c - * - * Copyright (C) 2007 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -static void -load_user_special_dirs (void) -{ - gchar *config_file; - gchar *data; - gchar **lines; - gint n_lines, i; - - g_init_user_config_dir (); - config_file = g_build_filename (g_user_config_dir, - "user-dirs.dirs", - NULL); - - if (!g_file_get_contents (config_file, &data, NULL, NULL)) - { - g_free (config_file); - return; - } - - lines = g_strsplit (data, "\n", -1); - n_lines = g_strv_length (lines); - g_free (data); - - for (i = 0; i < n_lines; i++) - { - gchar *buffer = lines[i]; - gchar *d, *p; - gint len; - gboolean is_relative = FALSE; - GUserDirectory directory; - - /* Remove newline at end */ - len = strlen (buffer); - if (len > 0 && buffer[len - 1] == '\n') - buffer[len - 1] = 0; - - p = buffer; - while (*p == ' ' || *p == '\t') - p++; - - if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0) - { - directory = G_USER_DIRECTORY_DESKTOP; - p += strlen ("XDG_DESKTOP_DIR"); - } - else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0) - { - directory = G_USER_DIRECTORY_DOCUMENTS; - p += strlen ("XDG_DOCUMENTS_DIR"); - } - else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0) - { - directory = G_USER_DIRECTORY_DOWNLOAD; - p += strlen ("XDG_DOWNLOAD_DIR"); - } - else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0) - { - directory = G_USER_DIRECTORY_MUSIC; - p += strlen ("XDG_MUSIC_DIR"); - } - else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0) - { - directory = G_USER_DIRECTORY_PICTURES; - p += strlen ("XDG_PICTURES_DIR"); - } - else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0) - { - directory = G_USER_DIRECTORY_PUBLIC_SHARE; - p += strlen ("XDG_PUBLICSHARE_DIR"); - } - else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0) - { - directory = G_USER_DIRECTORY_TEMPLATES; - p += strlen ("XDG_TEMPLATES_DIR"); - } - else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0) - { - directory = G_USER_DIRECTORY_VIDEOS; - p += strlen ("XDG_VIDEOS_DIR"); - } - else - continue; - - while (*p == ' ' || *p == '\t') - p++; - - if (*p != '=') - continue; - p++; - - while (*p == ' ' || *p == '\t') - p++; - - if (*p != '"') - continue; - p++; - - if (strncmp (p, "$HOME", 5) == 0) - { - p += 5; - is_relative = TRUE; - } - else if (*p != '/') - continue; - - d = strrchr (p, '"'); - if (!d) - continue; - *d = 0; - - d = p; - - /* remove trailing slashes */ - len = strlen (d); - if (d[len - 1] == '/') - d[len - 1] = 0; - - if (is_relative) - { - g_get_any_init (); - g_user_special_dirs[directory] = g_build_filename (g_home_dir, d, NULL); - } - else - g_user_special_dirs[directory] = g_strdup (d); - } - - g_strfreev (lines); - g_free (config_file); -} - -#endif /* G_OS_UNIX && !HAVE_CARBON */ - - -/** - * g_reload_user_special_dirs_cache: - * - * Resets the cache used for g_get_user_special_dir(), so - * that the latest on-disk version is used. Call this only - * if you just changed the data on disk yourself. - * - * Due to threadsafety issues this may cause leaking of strings - * that were previously returned from g_get_user_special_dir() - * that can't be freed. We ensure to only leak the data for - * the directories that actually changed value though. - * - * Since: 2.22 - */ -void -g_reload_user_special_dirs_cache (void) -{ - int i; - - G_LOCK (g_utils_global); - - if (g_user_special_dirs != NULL) - { - /* save a copy of the pointer, to check if some memory can be preserved */ - char **old_g_user_special_dirs = g_user_special_dirs; - char *old_val; - - /* recreate and reload our cache */ - g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES); - load_user_special_dirs (); - - /* only leak changed directories */ - for (i = 0; i < G_USER_N_DIRECTORIES; i++) - { - old_val = old_g_user_special_dirs[i]; - if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0) - { - /* don't leak */ - g_free (g_user_special_dirs[i]); - g_user_special_dirs[i] = old_val; - } - else - g_free (old_val); - } - - /* free the old array */ - g_free (old_g_user_special_dirs); - } - - G_UNLOCK (g_utils_global); -} - -/** - * g_get_user_special_dir: - * @directory: the logical id of special directory - * - * Returns the full path of a special directory using its logical id. - * - * On Unix this is done using the XDG special user directories. - * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP - * falls back to <filename>$HOME/Desktop</filename> when XDG special - * user directories have not been set up. - * - * Depending on the platform, the user might be able to change the path - * of the special directory without requiring the session to restart; GLib - * will not reflect any change once the special directories are loaded. - * - * Return value: the path to the specified special directory, or %NULL - * if the logical id was not found. The returned string is owned by - * GLib and should not be modified or freed. - * - * Since: 2.14 - */ -const gchar * -g_get_user_special_dir (GUserDirectory directory) -{ - g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP && - directory < G_USER_N_DIRECTORIES, NULL); - - G_LOCK (g_utils_global); - - if (G_UNLIKELY (g_user_special_dirs == NULL)) - { - g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES); - - load_user_special_dirs (); - - /* Special-case desktop for historical compatibility */ - if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL) - { - g_get_any_init (); - - g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = - g_build_filename (g_home_dir, "Desktop", NULL); - } - } - - G_UNLOCK (g_utils_global); - - return g_user_special_dirs[directory]; -} - -#ifdef G_OS_WIN32 - -#undef g_get_system_data_dirs - -static HMODULE -get_module_for_address (gconstpointer address) -{ - /* Holds the g_utils_global lock */ - - static gboolean beenhere = FALSE; - typedef BOOL (WINAPI *t_GetModuleHandleExA) (DWORD, LPCTSTR, HMODULE *); - static t_GetModuleHandleExA p_GetModuleHandleExA = NULL; - HMODULE hmodule = NULL; - - if (!address) - return NULL; - - if (!beenhere) - { - p_GetModuleHandleExA = - (t_GetModuleHandleExA) GetProcAddress (GetModuleHandle ("kernel32.dll"), - "GetModuleHandleExA"); - beenhere = TRUE; - } - - if (p_GetModuleHandleExA == NULL || - !(*p_GetModuleHandleExA) (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - address, &hmodule)) - { - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery (address, &mbi, sizeof (mbi)); - hmodule = (HMODULE) mbi.AllocationBase; - } - - return hmodule; -} - -static gchar * -get_module_share_dir (gconstpointer address) -{ - HMODULE hmodule; - gchar *filename; - gchar *retval; - - hmodule = get_module_for_address (address); - if (hmodule == NULL) - return NULL; - - filename = g_win32_get_package_installation_directory_of_module (hmodule); - retval = g_build_filename (filename, "share", NULL); - g_free (filename); - - return retval; -} - -const gchar * const * -g_win32_get_system_data_dirs_for_module (void (*address_of_function)()) -{ - GArray *data_dirs; - HMODULE hmodule; - static GHashTable *per_module_data_dirs = NULL; - gchar **retval; - gchar *p; - gchar *exe_root; - - if (address_of_function) - { - G_LOCK (g_utils_global); - hmodule = get_module_for_address (address_of_function); - if (hmodule != NULL) - { - if (per_module_data_dirs == NULL) - per_module_data_dirs = g_hash_table_new (NULL, NULL); - else - { - retval = g_hash_table_lookup (per_module_data_dirs, hmodule); - - if (retval != NULL) - { - G_UNLOCK (g_utils_global); - return (const gchar * const *) retval; - } - } - } - } - - data_dirs = g_array_new (TRUE, TRUE, sizeof (char *)); - - /* Documents and Settings\All Users\Application Data */ - p = get_special_folder (CSIDL_COMMON_APPDATA); - if (p) - g_array_append_val (data_dirs, p); - - /* Documents and Settings\All Users\Documents */ - p = get_special_folder (CSIDL_COMMON_DOCUMENTS); - if (p) - g_array_append_val (data_dirs, p); - - /* Using the above subfolders of Documents and Settings perhaps - * makes sense from a Windows perspective. - * - * But looking at the actual use cases of this function in GTK+ - * and GNOME software, what we really want is the "share" - * subdirectory of the installation directory for the package - * our caller is a part of. - * - * The address_of_function parameter, if non-NULL, points to a - * function in the calling module. Use that to determine that - * module's installation folder, and use its "share" subfolder. - * - * Additionally, also use the "share" subfolder of the installation - * locations of GLib and the .exe file being run. - * - * To guard against none of the above being what is really wanted, - * callers of this function should have Win32-specific code to look - * up their installation folder themselves, and handle a subfolder - * "share" of it in the same way as the folders returned from this - * function. - */ - - p = get_module_share_dir (address_of_function); - if (p) - g_array_append_val (data_dirs, p); - - if (glib_dll != NULL) - { - gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll); - p = g_build_filename (glib_root, "share", NULL); - if (p) - g_array_append_val (data_dirs, p); - g_free (glib_root); - } - - exe_root = g_win32_get_package_installation_directory_of_module (NULL); - p = g_build_filename (exe_root, "share", NULL); - if (p) - g_array_append_val (data_dirs, p); - g_free (exe_root); - - retval = (gchar **) g_array_free (data_dirs, FALSE); - - if (address_of_function) - { - if (hmodule != NULL) - g_hash_table_insert (per_module_data_dirs, hmodule, retval); - G_UNLOCK (g_utils_global); - } - - return (const gchar * const *) retval; -} - -#endif - -/** - * g_get_system_data_dirs: - * - * Returns an ordered list of base directories in which to access - * system-wide application data. - * - * On UNIX platforms this is determined using the mechanisms described in - * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec"> - * XDG Base Directory Specification</ulink> - * In this case the list of directories retrieved will be XDG_DATA_DIRS. - * - * On Windows the first elements in the list are the Application Data - * and Documents folders for All Users. (These can be determined only - * on Windows 2000 or later and are not present in the list on other - * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and - * CSIDL_COMMON_DOCUMENTS. - * - * Then follows the "share" subfolder in the installation folder for - * the package containing the DLL that calls this function, if it can - * be determined. - * - * Finally the list contains the "share" subfolder in the installation - * folder for GLib, and in the installation folder for the package the - * application's .exe file belongs to. - * - * The installation folders above are determined by looking up the - * folder where the module (DLL or EXE) in question is located. If the - * folder's name is "bin", its parent is used, otherwise the folder - * itself. - * - * Note that on Windows the returned list can vary depending on where - * this function is called. - * - * Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib that must - * not be modified or freed. - * Since: 2.6 - **/ -const gchar * const * -g_get_system_data_dirs (void) -{ - gchar **data_dir_vector; - - G_LOCK (g_utils_global); - - if (!g_system_data_dirs) - { -#ifdef G_OS_WIN32 - data_dir_vector = (gchar **) g_win32_get_system_data_dirs_for_module (NULL); -#else - gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS"); - - if (!data_dirs || !data_dirs[0]) - data_dirs = "/usr/local/share/:/usr/share/"; - - data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0); -#endif - - g_system_data_dirs = data_dir_vector; - } - else - data_dir_vector = g_system_data_dirs; - - G_UNLOCK (g_utils_global); - - return (const gchar * const *) data_dir_vector; -} - -/** - * g_get_system_config_dirs: - * - * Returns an ordered list of base directories in which to access - * system-wide configuration information. - * - * On UNIX platforms this is determined using the mechanisms described in - * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec"> - * XDG Base Directory Specification</ulink>. - * In this case the list of directories retrieved will be XDG_CONFIG_DIRS. - * - * On Windows is the directory that contains application data for all users. - * A typical path is C:\Documents and Settings\All Users\Application Data. - * This folder is used for application data that is not user specific. - * For example, an application can store a spell-check dictionary, a database - * of clip art, or a log file in the CSIDL_COMMON_APPDATA folder. - * This information will not roam and is available to anyone using the computer. - * - * Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib that must - * not be modified or freed. - * Since: 2.6 - **/ -const gchar * const * -g_get_system_config_dirs (void) -{ - gchar *conf_dirs, **conf_dir_vector; - - G_LOCK (g_utils_global); - - if (!g_system_config_dirs) - { -#ifdef G_OS_WIN32 - conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA); - if (conf_dirs) - { - conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); - g_free (conf_dirs); - } - else - { - /* Return empty list */ - conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0); - } -#else - conf_dirs = (gchar *) g_getenv ("XDG_CONFIG_DIRS"); - - if (!conf_dirs || !conf_dirs[0]) - conf_dirs = "/etc/xdg"; - - conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); -#endif - - g_system_config_dirs = conf_dir_vector; - } - else - conf_dir_vector = g_system_config_dirs; - G_UNLOCK (g_utils_global); - - return (const gchar * const *) conf_dir_vector; -} - -#ifndef G_OS_WIN32 - -static GHashTable *alias_table = NULL; - -/* read an alias file for the locales */ -static void -read_aliases (gchar *file) -{ - FILE *fp; - char buf[256]; - - if (!alias_table) - alias_table = g_hash_table_new (g_str_hash, g_str_equal); - fp = fopen (file,"r"); - if (!fp) - return; - while (fgets (buf, 256, fp)) - { - char *p, *q; - - g_strstrip (buf); - - /* Line is a comment */ - if ((buf[0] == '#') || (buf[0] == '\0')) - continue; - - /* Reads first column */ - for (p = buf, q = NULL; *p; p++) { - if ((*p == '\t') || (*p == ' ') || (*p == ':')) { - *p = '\0'; - q = p+1; - while ((*q == '\t') || (*q == ' ')) { - q++; - } - break; - } - } - /* The line only had one column */ - if (!q || *q == '\0') - continue; - - /* Read second column */ - for (p = q; *p; p++) { - if ((*p == '\t') || (*p == ' ')) { - *p = '\0'; - break; - } - } - - /* Add to alias table if necessary */ - if (!g_hash_table_lookup (alias_table, buf)) { - g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q)); - } - } - fclose (fp); -} - -#endif - -static char * -unalias_lang (char *lang) -{ -#ifndef G_OS_WIN32 - char *p; - int i; - - if (!alias_table) - read_aliases ("/usr/share/locale/locale.alias"); - - i = 0; - while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0)) - { - lang = p; - if (i++ == 30) - { - static gboolean said_before = FALSE; - if (!said_before) - g_warning ("Too many alias levels for a locale, " - "may indicate a loop"); - said_before = TRUE; - return lang; - } - } -#endif - return lang; -} - -/* Mask for components of locale spec. The ordering here is from - * least significant to most significant - */ -enum -{ - COMPONENT_CODESET = 1 << 0, - COMPONENT_TERRITORY = 1 << 1, - COMPONENT_MODIFIER = 1 << 2 -}; - -/* Break an X/Open style locale specification into components - */ -static guint -explode_locale (const gchar *locale, - gchar **language, - gchar **territory, - gchar **codeset, - gchar **modifier) -{ - const gchar *uscore_pos; - const gchar *at_pos; - const gchar *dot_pos; - - guint mask = 0; - - uscore_pos = strchr (locale, '_'); - dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.'); - at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@'); - - if (at_pos) - { - mask |= COMPONENT_MODIFIER; - *modifier = g_strdup (at_pos); - } - else - at_pos = locale + strlen (locale); - - if (dot_pos) - { - mask |= COMPONENT_CODESET; - *codeset = g_strndup (dot_pos, at_pos - dot_pos); - } - else - dot_pos = at_pos; - - if (uscore_pos) - { - mask |= COMPONENT_TERRITORY; - *territory = g_strndup (uscore_pos, dot_pos - uscore_pos); - } - else - uscore_pos = dot_pos; - - *language = g_strndup (locale, uscore_pos - locale); - - return mask; -} - -/* - * Compute all interesting variants for a given locale name - - * by stripping off different components of the value. - * - * For simplicity, we assume that the locale is in - * X/Open format: language[_territory][.codeset][@modifier] - * - * TODO: Extend this to handle the CEN format (see the GNUlibc docs) - * as well. We could just copy the code from glibc wholesale - * but it is big, ugly, and complicated, so I'm reluctant - * to do so when this should handle 99% of the time... - */ -static void -append_locale_variants (GPtrArray *array, - const gchar *locale) -{ - gchar *language = NULL; - gchar *territory = NULL; - gchar *codeset = NULL; - gchar *modifier = NULL; - - guint mask; - guint i, j; - - g_return_if_fail (locale != NULL); - - mask = explode_locale (locale, &language, &territory, &codeset, &modifier); - - /* Iterate through all possible combinations, from least attractive - * to most attractive. - */ - for (j = 0; j <= mask; ++j) - { - i = mask - j; - - if ((i & ~mask) == 0) - { - gchar *val = g_strconcat (language, - (i & COMPONENT_TERRITORY) ? territory : "", - (i & COMPONENT_CODESET) ? codeset : "", - (i & COMPONENT_MODIFIER) ? modifier : "", - NULL); - g_ptr_array_add (array, val); - } - } - - g_free (language); - if (mask & COMPONENT_CODESET) - g_free (codeset); - if (mask & COMPONENT_TERRITORY) - g_free (territory); - if (mask & COMPONENT_MODIFIER) - g_free (modifier); -} - -/** - * g_get_locale_variants: - * @locale: a locale identifier - * - * Returns a list of derived variants of @locale, which can be used to - * e.g. construct locale-dependent filenames or search paths. The returned - * list is sorted from most desirable to least desirable. - * This function handles territory, charset and extra locale modifiers. - * - * For example, if @locale is "fr_BE", then the returned list - * is "fr_BE", "fr". - * - * If you need the list of variants for the <emphasis>current locale</emphasis>, - * use g_get_language_names(). - * - * Returns: (transfer full) (array zero-terminated=1) (element-type utf8): a newly - * allocated array of newly allocated strings with the locale variants. Free with - * g_strfreev(). - * - * Since: 2.28 - */ -gchar ** -g_get_locale_variants (const gchar *locale) -{ - GPtrArray *array; - - g_return_val_if_fail (locale != NULL, NULL); - - array = g_ptr_array_sized_new (8); - append_locale_variants (array, locale); - g_ptr_array_add (array, NULL); - - return (gchar **) g_ptr_array_free (array, FALSE); -} - -/* The following is (partly) taken from the gettext package. - Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. */ - -static const gchar * -guess_category_value (const gchar *category_name) -{ - const gchar *retval; - - /* The highest priority value is the `LANGUAGE' environment - variable. This is a GNU extension. */ - retval = g_getenv ("LANGUAGE"); - if ((retval != NULL) && (retval[0] != '\0')) - return retval; - - /* `LANGUAGE' is not set. So we have to proceed with the POSIX - methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some - systems this can be done by the `setlocale' function itself. */ - - /* Setting of LC_ALL overwrites all other. */ - retval = g_getenv ("LC_ALL"); - if ((retval != NULL) && (retval[0] != '\0')) - return retval; - - /* Next comes the name of the desired category. */ - retval = g_getenv (category_name); - if ((retval != NULL) && (retval[0] != '\0')) - return retval; - - /* Last possibility is the LANG environment variable. */ - retval = g_getenv ("LANG"); - if ((retval != NULL) && (retval[0] != '\0')) - return retval; - -#ifdef G_PLATFORM_WIN32 - /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and - * LANG, which we already did above. Oh well. The main point of - * calling g_win32_getlocale() is to get the thread's locale as used - * by Windows and the Microsoft C runtime (in the "English_United - * States" format) translated into the Unixish format. - */ - { - char *locale = g_win32_getlocale (); - retval = g_intern_string (locale); - g_free (locale); - return retval; - } -#endif - - return NULL; -} - -typedef struct _GLanguageNamesCache GLanguageNamesCache; - -struct _GLanguageNamesCache { - gchar *languages; - gchar **language_names; -}; - -static void -language_names_cache_free (gpointer data) -{ - GLanguageNamesCache *cache = data; - g_free (cache->languages); - g_strfreev (cache->language_names); - g_free (cache); -} - -/** - * g_get_language_names: - * - * Computes a list of applicable locale names, which can be used to - * e.g. construct locale-dependent filenames or search paths. The returned - * list is sorted from most desirable to least desirable and always contains - * the default locale "C". - * - * For example, if LANGUAGE=de:en_US, then the returned list is - * "de", "en_US", "en", "C". - * - * This function consults the environment variables <envar>LANGUAGE</envar>, - * <envar>LC_ALL</envar>, <envar>LC_MESSAGES</envar> and <envar>LANG</envar> - * to find the list of locales specified by the user. - * - * Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib - * that must not be modified or freed. - * - * Since: 2.6 - **/ -const gchar * const * -g_get_language_names (void) -{ - static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT; - GLanguageNamesCache *cache = g_static_private_get (&cache_private); - const gchar *value; - - if (!cache) - { - cache = g_new0 (GLanguageNamesCache, 1); - g_static_private_set (&cache_private, cache, language_names_cache_free); - } - - value = guess_category_value ("LC_MESSAGES"); - if (!value) - value = "C"; - - if (!(cache->languages && strcmp (cache->languages, value) == 0)) - { - GPtrArray *array; - gchar **alist, **a; - - g_free (cache->languages); - g_strfreev (cache->language_names); - cache->languages = g_strdup (value); - - array = g_ptr_array_sized_new (8); - - alist = g_strsplit (value, ":", 0); - for (a = alist; *a; a++) - append_locale_variants (array, unalias_lang (*a)); - g_strfreev (alist); - g_ptr_array_add (array, g_strdup ("C")); - g_ptr_array_add (array, NULL); - - cache->language_names = (gchar **) g_ptr_array_free (array, FALSE); - } - - return (const gchar * const *) cache->language_names; -} - -/** - * g_direct_hash: - * @v: a #gpointer key - * - * Converts a gpointer to a hash value. - * It can be passed to g_hash_table_new() as the @hash_func parameter, - * when using pointers as keys in a #GHashTable. - * - * Returns: a hash value corresponding to the key. - */ -guint -g_direct_hash (gconstpointer v) -{ - return GPOINTER_TO_UINT (v); -} - -/** - * g_direct_equal: - * @v1: a key. - * @v2: a key to compare with @v1. - * - * Compares two #gpointer arguments and returns %TRUE if they are equal. - * It can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using pointers as keys in a #GHashTable. - * - * Returns: %TRUE if the two keys match. - */ -gboolean -g_direct_equal (gconstpointer v1, - gconstpointer v2) -{ - return v1 == v2; -} - -/** - * g_int_equal: - * @v1: a pointer to a #gint key. - * @v2: a pointer to a #gint key to compare with @v1. - * - * Compares the two #gint values being pointed to and returns - * %TRUE if they are equal. - * It can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using pointers to integers as keys in a #GHashTable. - * - * Returns: %TRUE if the two keys match. - */ -gboolean -g_int_equal (gconstpointer v1, - gconstpointer v2) -{ - return *((const gint*) v1) == *((const gint*) v2); -} - -/** - * g_int_hash: - * @v: a pointer to a #gint key - * - * Converts a pointer to a #gint to a hash value. - * It can be passed to g_hash_table_new() as the @hash_func parameter, - * when using pointers to integers values as keys in a #GHashTable. - * - * Returns: a hash value corresponding to the key. - */ -guint -g_int_hash (gconstpointer v) -{ - return *(const gint*) v; -} - -/** - * g_int64_equal: - * @v1: a pointer to a #gint64 key. - * @v2: a pointer to a #gint64 key to compare with @v1. - * - * Compares the two #gint64 values being pointed to and returns - * %TRUE if they are equal. - * It can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using pointers to 64-bit integers as keys in a #GHashTable. - * - * Returns: %TRUE if the two keys match. - * - * Since: 2.22 - */ -gboolean -g_int64_equal (gconstpointer v1, - gconstpointer v2) -{ - return *((const gint64*) v1) == *((const gint64*) v2); -} - -/** - * g_int64_hash: - * @v: a pointer to a #gint64 key - * - * Converts a pointer to a #gint64 to a hash value. - * It can be passed to g_hash_table_new() as the @hash_func parameter, - * when using pointers to 64-bit integers values as keys in a #GHashTable. - * - * Returns: a hash value corresponding to the key. - * - * Since: 2.22 - */ -guint -g_int64_hash (gconstpointer v) -{ - return (guint) *(const gint64*) v; -} - -/** - * g_double_equal: - * @v1: a pointer to a #gdouble key. - * @v2: a pointer to a #gdouble key to compare with @v1. - * - * Compares the two #gdouble values being pointed to and returns - * %TRUE if they are equal. - * It can be passed to g_hash_table_new() as the @key_equal_func - * parameter, when using pointers to doubles as keys in a #GHashTable. - * - * Returns: %TRUE if the two keys match. - * - * Since: 2.22 - */ -gboolean -g_double_equal (gconstpointer v1, - gconstpointer v2) -{ - return *((const gdouble*) v1) == *((const gdouble*) v2); -} - -/** - * g_double_hash: - * @v: a pointer to a #gdouble key - * - * Converts a pointer to a #gdouble to a hash value. - * It can be passed to g_hash_table_new() as the @hash_func parameter, - * when using pointers to doubles as keys in a #GHashTable. - * - * Returns: a hash value corresponding to the key. - * - * Since: 2.22 - */ -guint -g_double_hash (gconstpointer v) -{ - return (guint) *(const gdouble*) v; -} - -/** - * g_nullify_pointer: - * @nullify_location: the memory address of the pointer. - * - * Set the pointer at the specified location to %NULL. - **/ -void -g_nullify_pointer (gpointer *nullify_location) -{ - g_return_if_fail (nullify_location != NULL); - - *nullify_location = NULL; -} - -/* This is called from g_thread_init(). It's used to - * initialize some static data in a threadsafe way. - */ -void -_g_utils_thread_init (void) -{ - g_get_language_names (); -} - -#ifdef G_OS_WIN32 - -/** - * _glib_get_locale_dir: - * - * Return the path to the share\locale or lib\locale subfolder of the - * GLib installation folder. The path is in the system codepage. We - * have to use system codepage as bindtextdomain() doesn't have a - * UTF-8 interface. - */ -gchar * -_glib_get_locale_dir (void) -{ - gchar *install_dir = NULL, *locale_dir; - gchar *retval = NULL; - - if (glib_dll != NULL) - install_dir = g_win32_get_package_installation_directory_of_module (glib_dll); - - if (install_dir) - { - /* - * Append "/share/locale" or "/lib/locale" depending on whether - * autoconfigury detected GNU gettext or not. - */ - const char *p = GLIB_LOCALE_DIR + strlen (GLIB_LOCALE_DIR); - while (*--p != '/') - ; - while (*--p != '/') - ; - - locale_dir = g_build_filename (install_dir, p, NULL); - - retval = g_win32_locale_filename_from_utf8 (locale_dir); - - g_free (install_dir); - g_free (locale_dir); - } - - if (retval) - return retval; - else - return g_strdup (""); -} - -#undef GLIB_LOCALE_DIR - -#endif /* G_OS_WIN32 */ - -static void -ensure_gettext_initialized(void) -{ - static gboolean _glib_gettext_initialized = FALSE; - - if (!_glib_gettext_initialized) - { -#ifdef G_OS_WIN32 - gchar *tmp = _glib_get_locale_dir (); - bindtextdomain (GETTEXT_PACKAGE, tmp); - g_free (tmp); -#else - bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); -#endif -# ifdef HAVE_BIND_TEXTDOMAIN_CODESET - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); -# endif - _glib_gettext_initialized = TRUE; - } -} - -/** - * glib_gettext: - * @str: The string to be translated - * - * Returns the translated string from the glib translations. - * This is an internal function and should only be used by - * the internals of glib (such as libgio). - * - * Returns: the transation of @str to the current locale - */ -const gchar * -glib_gettext (const gchar *str) -{ - ensure_gettext_initialized(); - - return g_dgettext (GETTEXT_PACKAGE, str); -} - -/** - * glib_pgettext: - * @msgctxtid: a combined message context and message id, separated - * by a \004 character - * @msgidoffset: the offset of the message id in @msgctxid - * - * This function is a variant of glib_gettext() which supports - * a disambiguating message context. See g_dpgettext() for full - * details. - * - * This is an internal function and should only be used by - * the internals of glib (such as libgio). - * - * Returns: the transation of @str to the current locale - */ -const gchar * -glib_pgettext(const gchar *msgctxtid, - gsize msgidoffset) -{ - ensure_gettext_initialized(); - - return g_dpgettext (GETTEXT_PACKAGE, msgctxtid, msgidoffset); -} - -#if defined (G_OS_WIN32) && !defined (_WIN64) - -/* Binary compatibility versions. Not for newly compiled code. */ - -#undef g_find_program_in_path - -gchar* -g_find_program_in_path (const gchar *program) -{ - gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL); - gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program); - gchar *retval; - - g_free (utf8_program); - if (utf8_retval == NULL) - return NULL; - retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL); - g_free (utf8_retval); - - return retval; -} - -#undef g_get_current_dir - -gchar* -g_get_current_dir (void) -{ - gchar *utf8_dir = g_get_current_dir_utf8 (); - gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL); - g_free (utf8_dir); - return dir; -} - -#undef g_getenv - -const gchar * -g_getenv (const gchar *variable) -{ - gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL); - const gchar *utf8_value = g_getenv_utf8 (utf8_variable); - gchar *value; - GQuark quark; - - g_free (utf8_variable); - if (!utf8_value) - return NULL; - value = g_locale_from_utf8 (utf8_value, -1, NULL, NULL, NULL); - quark = g_quark_from_string (value); - g_free (value); - - return g_quark_to_string (quark); -} - -#undef g_setenv - -gboolean -g_setenv (const gchar *variable, - const gchar *value, - gboolean overwrite) -{ - gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL); - gchar *utf8_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL); - gboolean retval = g_setenv_utf8 (utf8_variable, utf8_value, overwrite); - - g_free (utf8_variable); - g_free (utf8_value); - - return retval; -} - -#undef g_unsetenv - -void -g_unsetenv (const gchar *variable) -{ - gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL); - - g_unsetenv_utf8 (utf8_variable); - - g_free (utf8_variable); -} - -#undef g_get_user_name - -const gchar * -g_get_user_name (void) -{ - g_get_any_init_locked (); - return g_user_name_cp; -} - -#undef g_get_real_name - -const gchar * -g_get_real_name (void) -{ - g_get_any_init_locked (); - return g_real_name_cp; -} - -#undef g_get_home_dir - -const gchar * -g_get_home_dir (void) -{ - g_get_any_init_locked (); - return g_home_dir_cp; -} - -#undef g_get_tmp_dir - -const gchar * -g_get_tmp_dir (void) -{ - g_get_any_init_locked (); - return g_tmp_dir_cp; -} - -#endif diff --git a/deps/glib/gutils.h b/deps/glib/gutils.h deleted file mode 100644 index 93dc947e..00000000 --- a/deps/glib/gutils.h +++ /dev/null @@ -1,526 +0,0 @@ -/* GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only <glib.h> can be included directly." -#endif - -#ifndef __G_UTILS_H__ -#define __G_UTILS_H__ - -#include <glib/gtypes.h> -#include <stdarg.h> - -G_BEGIN_DECLS - -#ifdef G_OS_WIN32 - -/* On Win32, the canonical directory separator is the backslash, and - * the search path separator is the semicolon. Note that also the - * (forward) slash works as directory separator. - */ -#define G_DIR_SEPARATOR '\\' -#define G_DIR_SEPARATOR_S "\\" -#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/') -#define G_SEARCHPATH_SEPARATOR ';' -#define G_SEARCHPATH_SEPARATOR_S ";" - -#else /* !G_OS_WIN32 */ - -/* Unix */ - -#define G_DIR_SEPARATOR '/' -#define G_DIR_SEPARATOR_S "/" -#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR) -#define G_SEARCHPATH_SEPARATOR ':' -#define G_SEARCHPATH_SEPARATOR_S ":" - -#endif /* !G_OS_WIN32 */ - -/* Define G_VA_COPY() to do the right thing for copying va_list variables. - * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy. - */ -#if !defined (G_VA_COPY) -# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) -# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2)) -# elif defined (G_VA_COPY_AS_ARRAY) -# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list)) -# else /* va_list is a pointer */ -# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2)) -# endif /* va_list is a pointer */ -#endif /* !G_VA_COPY */ - -/* inlining hassle. for compilers that don't allow the `inline' keyword, - * mostly because of strict ANSI C compliance or dumbness, we try to fall - * back to either `__inline__' or `__inline'. - * G_CAN_INLINE is defined in glibconfig.h if the compiler seems to be - * actually *capable* to do function inlining, in which case inline - * function bodies do make sense. we also define G_INLINE_FUNC to properly - * export the function prototypes if no inlining can be performed. - * inline function bodies have to be special cased with G_CAN_INLINE and a - * .c file specific macro to allow one compiled instance with extern linkage - * of the functions by defining G_IMPLEMENT_INLINES and the .c file macro. - */ -#if defined (G_HAVE_INLINE) && defined (__GNUC__) && defined (__STRICT_ANSI__) -# undef inline -# define inline __inline__ -#elif !defined (G_HAVE_INLINE) -# undef inline -# if defined (G_HAVE___INLINE__) -# define inline __inline__ -# elif defined (G_HAVE___INLINE) -# define inline __inline -# else /* !inline && !__inline__ && !__inline */ -# define inline /* don't inline, then */ -# endif -#endif -#ifdef G_IMPLEMENT_INLINES -# define G_INLINE_FUNC -# undef G_CAN_INLINE -#elif defined (__GNUC__) -# define G_INLINE_FUNC static __inline __attribute__ ((unused)) -#elif defined (G_CAN_INLINE) -# define G_INLINE_FUNC static inline -#else /* can't inline */ -# define G_INLINE_FUNC -#endif /* !G_INLINE_FUNC */ - -#ifndef __GTK_DOC_IGNORE__ -#ifdef G_OS_WIN32 -#define g_get_user_name g_get_user_name_utf8 -#define g_get_real_name g_get_real_name_utf8 -#define g_get_home_dir g_get_home_dir_utf8 -#define g_get_tmp_dir g_get_tmp_dir_utf8 -#endif -#endif - -const gchar * g_get_user_name (void); -const gchar * g_get_real_name (void); -const gchar * g_get_home_dir (void); -const gchar * g_get_tmp_dir (void); -const gchar * g_get_host_name (void); -gchar * g_get_prgname (void); -void g_set_prgname (const gchar *prgname); -const gchar * g_get_application_name (void); -void g_set_application_name (const gchar *application_name); - -void g_reload_user_special_dirs_cache (void); -const gchar * g_get_user_data_dir (void); -const gchar * g_get_user_config_dir (void); -const gchar * g_get_user_cache_dir (void); -const gchar * const * g_get_system_data_dirs (void); - -#ifdef G_OS_WIN32 -/* This functions is not part of the public GLib API */ -const gchar * const * g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void)); -#endif - -#if defined (G_OS_WIN32) && defined (G_CAN_INLINE) && !defined (__cplusplus) -/* This function is not part of the public GLib API either. Just call - * g_get_system_data_dirs() in your code, never mind that that is - * actually a macro and you will in fact call this inline function. - */ -static inline const gchar * const * -_g_win32_get_system_data_dirs (void) -{ - return g_win32_get_system_data_dirs_for_module ((void (*)(void)) &_g_win32_get_system_data_dirs); -} -#define g_get_system_data_dirs _g_win32_get_system_data_dirs -#endif - -const gchar * const * g_get_system_config_dirs (void); - -const gchar * g_get_user_runtime_dir (void); - -const gchar * const * g_get_language_names (void); - -gchar **g_get_locale_variants (const gchar *locale); - -/** - * GUserDirectory: - * @G_USER_DIRECTORY_DESKTOP: the user's Desktop directory - * @G_USER_DIRECTORY_DOCUMENTS: the user's Documents directory - * @G_USER_DIRECTORY_DOWNLOAD: the user's Downloads directory - * @G_USER_DIRECTORY_MUSIC: the user's Music directory - * @G_USER_DIRECTORY_PICTURES: the user's Pictures directory - * @G_USER_DIRECTORY_PUBLIC_SHARE: the user's shared directory - * @G_USER_DIRECTORY_TEMPLATES: the user's Templates directory - * @G_USER_DIRECTORY_VIDEOS: the user's Movies directory - * @G_USER_N_DIRECTORIES: the number of enum values - * - * These are logical ids for special directories which are defined - * depending on the platform used. You should use g_get_user_special_dir() - * to retrieve the full path associated to the logical id. - * - * The #GUserDirectory enumeration can be extended at later date. Not - * every platform has a directory for every logical id in this - * enumeration. - * - * Since: 2.14 - */ -typedef enum { - G_USER_DIRECTORY_DESKTOP, - G_USER_DIRECTORY_DOCUMENTS, - G_USER_DIRECTORY_DOWNLOAD, - G_USER_DIRECTORY_MUSIC, - G_USER_DIRECTORY_PICTURES, - G_USER_DIRECTORY_PUBLIC_SHARE, - G_USER_DIRECTORY_TEMPLATES, - G_USER_DIRECTORY_VIDEOS, - - G_USER_N_DIRECTORIES -} GUserDirectory; - -const gchar * g_get_user_special_dir (GUserDirectory directory); - -/** - * GDebugKey: - * @key: the string - * @value: the flag - * - * Associates a string with a bit flag. - * Used in g_parse_debug_string(). - */ -typedef struct _GDebugKey GDebugKey; -struct _GDebugKey -{ - const gchar *key; - guint value; -}; - -/* Miscellaneous utility functions - */ -guint g_parse_debug_string (const gchar *string, - const GDebugKey *keys, - guint nkeys); - -gint g_snprintf (gchar *string, - gulong n, - gchar const *format, - ...) G_GNUC_PRINTF (3, 4); -gint g_vsnprintf (gchar *string, - gulong n, - gchar const *format, - va_list args); - -/* Check if a file name is an absolute path */ -gboolean g_path_is_absolute (const gchar *file_name); - -/* In case of absolute paths, skip the root part */ -const gchar * g_path_skip_root (const gchar *file_name); - -#ifndef G_DISABLE_DEPRECATED - -const gchar * g_basename (const gchar *file_name); -#define g_dirname g_path_get_dirname - -#endif /* G_DISABLE_DEPRECATED */ - -#ifndef __GTK_DOC_IGNORE__ -#ifdef G_OS_WIN32 -#define g_get_current_dir g_get_current_dir_utf8 -#endif -#endif - -/* The returned strings are newly allocated with g_malloc() */ -gchar* g_get_current_dir (void); -gchar* g_path_get_basename (const gchar *file_name) G_GNUC_MALLOC; -gchar* g_path_get_dirname (const gchar *file_name) G_GNUC_MALLOC; - -/* Set the pointer at the specified location to NULL */ -void g_nullify_pointer (gpointer *nullify_location); - -/* return the environment string for the variable. The returned memory - * must not be freed. */ -#ifndef __GTK_DOC_IGNORE__ -#ifdef G_OS_WIN32 -#define g_getenv g_getenv_utf8 -#define g_setenv g_setenv_utf8 -#define g_unsetenv g_unsetenv_utf8 -#define g_find_program_in_path g_find_program_in_path_utf8 -#endif -#endif - -const gchar * g_getenv (const gchar *variable); -gboolean g_setenv (const gchar *variable, - const gchar *value, - gboolean overwrite); -void g_unsetenv (const gchar *variable); -gchar** g_listenv (void); -gchar** g_get_environ (void); - -/* private */ -const gchar* _g_getenv_nomalloc (const gchar *variable, - gchar buffer[1024]); - -/** - * GVoidFunc: - * - * Declares a type of function which takes no arguments - * and has no return value. It is used to specify the type - * function passed to g_atexit(). - */ -typedef void (*GVoidFunc) (void); -#ifndef ATEXIT -# define ATEXIT(proc) g_ATEXIT(proc) -#else -# define G_NATIVE_ATEXIT -#endif /* ATEXIT */ -/* we use a GLib function as a replacement for ATEXIT, so - * the programmer is not required to check the return value - * (if there is any in the implementation) and doesn't encounter - * missing include files. - */ -void g_atexit (GVoidFunc func); - -#ifdef G_OS_WIN32 -/* It's a bad idea to wrap atexit() on Windows. If the GLib DLL calls - * atexit(), the function will be called when the GLib DLL is detached - * from the program, which is not what the caller wants. The caller - * wants the function to be called when it *itself* exits (or is - * detached, in case the caller, too, is a DLL). - */ -#if (defined(__MINGW_H) && !defined(_STDLIB_H_)) || (defined(_MSC_VER) && !defined(_INC_STDLIB)) -int atexit (void (*)(void)); -#endif -#define g_atexit(func) atexit(func) -#endif - -/* Look for an executable in PATH, following execvp() rules */ -gchar* g_find_program_in_path (const gchar *program); - -/* Bit tests - */ -G_INLINE_FUNC gint g_bit_nth_lsf (gulong mask, - gint nth_bit) G_GNUC_CONST; -G_INLINE_FUNC gint g_bit_nth_msf (gulong mask, - gint nth_bit) G_GNUC_CONST; -G_INLINE_FUNC guint g_bit_storage (gulong number) G_GNUC_CONST; - -/* Trash Stacks - * elements need to be >= sizeof (gpointer) - */ -typedef struct _GTrashStack GTrashStack; -struct _GTrashStack -{ - GTrashStack *next; -}; - -G_INLINE_FUNC void g_trash_stack_push (GTrashStack **stack_p, - gpointer data_p); -G_INLINE_FUNC gpointer g_trash_stack_pop (GTrashStack **stack_p); -G_INLINE_FUNC gpointer g_trash_stack_peek (GTrashStack **stack_p); -G_INLINE_FUNC guint g_trash_stack_height (GTrashStack **stack_p); - -/* inline function implementations - */ -#if defined (G_CAN_INLINE) || defined (__G_UTILS_C__) -G_INLINE_FUNC gint -g_bit_nth_lsf (gulong mask, - gint nth_bit) -{ - if (G_UNLIKELY (nth_bit < -1)) - nth_bit = -1; - while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1)) - { - nth_bit++; - if (mask & (1UL << nth_bit)) - return nth_bit; - } - return -1; -} -G_INLINE_FUNC gint -g_bit_nth_msf (gulong mask, - gint nth_bit) -{ - if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8)) - nth_bit = GLIB_SIZEOF_LONG * 8; - while (nth_bit > 0) - { - nth_bit--; - if (mask & (1UL << nth_bit)) - return nth_bit; - } - return -1; -} -G_INLINE_FUNC guint -g_bit_storage (gulong number) -{ -#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) - return G_LIKELY (number) ? - ((GLIB_SIZEOF_LONG * 8U - 1) ^ __builtin_clzl(number)) + 1 : 1; -#else - register guint n_bits = 0; - - do - { - n_bits++; - number >>= 1; - } - while (number); - return n_bits; -#endif -} -G_INLINE_FUNC void -g_trash_stack_push (GTrashStack **stack_p, - gpointer data_p) -{ - GTrashStack *data = (GTrashStack *) data_p; - - data->next = *stack_p; - *stack_p = data; -} -G_INLINE_FUNC gpointer -g_trash_stack_pop (GTrashStack **stack_p) -{ - GTrashStack *data; - - data = *stack_p; - if (data) - { - *stack_p = data->next; - /* NULLify private pointer here, most platforms store NULL as - * subsequent 0 bytes - */ - data->next = NULL; - } - - return data; -} -G_INLINE_FUNC gpointer -g_trash_stack_peek (GTrashStack **stack_p) -{ - GTrashStack *data; - - data = *stack_p; - - return data; -} -G_INLINE_FUNC guint -g_trash_stack_height (GTrashStack **stack_p) -{ - GTrashStack *data; - guint i = 0; - - for (data = *stack_p; data; data = data->next) - i++; - - return i; -} -#endif /* G_CAN_INLINE || __G_UTILS_C__ */ - -/* Glib version. - * we prefix variable declarations so they can - * properly get exported in windows dlls. - */ -GLIB_VAR const guint glib_major_version; -GLIB_VAR const guint glib_minor_version; -GLIB_VAR const guint glib_micro_version; -GLIB_VAR const guint glib_interface_age; -GLIB_VAR const guint glib_binary_age; - -const gchar * glib_check_version (guint required_major, - guint required_minor, - guint required_micro); - -/** - * GLIB_CHECK_VERSION: - * @major: the major version to check for - * @minor: the minor version to check for - * @micro: the micro version to check for - * - * Checks the version of the GLib library that is being compiled - * against. - * - * <example> - * <title>Checking the version of the GLib library</title> - * <programlisting> - * if (!GLIB_CHECK_VERSION (1, 2, 0)) - * g_error ("GLib version 1.2.0 or above is needed"); - * </programlisting> - * </example> - * - * See glib_check_version() for a runtime check. - * - * Returns: %TRUE if the version of the GLib header files - * is the same as or newer than the passed-in version. - */ -#define GLIB_CHECK_VERSION(major,minor,micro) \ - (GLIB_MAJOR_VERSION > (major) || \ - (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION > (minor)) || \ - (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION == (minor) && \ - GLIB_MICRO_VERSION >= (micro))) - -G_END_DECLS - -#ifndef G_DISABLE_DEPRECATED - -/* - * This macro is deprecated. This DllMain() is too complex. It is - * recommended to write an explicit minimal DLlMain() that just saves - * the handle to the DLL and then use that handle instead, for - * instance passing it to - * g_win32_get_package_installation_directory_of_module(). - * - * On Windows, this macro defines a DllMain function that stores the - * actual DLL name that the code being compiled will be included in. - * STATIC should be empty or 'static'. DLL_NAME is the name of the - * (pointer to the) char array where the DLL name will be stored. If - * this is used, you must also include <windows.h>. If you need a more complex - * DLL entry point function, you cannot use this. - * - * On non-Windows platforms, expands to nothing. - */ - -#ifndef G_PLATFORM_WIN32 -# define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name) -#else -# define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name) \ -static char *dll_name; \ - \ -BOOL WINAPI \ -DllMain (HINSTANCE hinstDLL, \ - DWORD fdwReason, \ - LPVOID lpvReserved) \ -{ \ - wchar_t wcbfr[1000]; \ - char *tem; \ - switch (fdwReason) \ - { \ - case DLL_PROCESS_ATTACH: \ - GetModuleFileNameW ((HMODULE) hinstDLL, wcbfr, G_N_ELEMENTS (wcbfr)); \ - tem = g_utf16_to_utf8 (wcbfr, -1, NULL, NULL, NULL); \ - dll_name = g_path_get_basename (tem); \ - g_free (tem); \ - break; \ - } \ - \ - return TRUE; \ -} - -#endif /* !G_DISABLE_DEPRECATED */ - -#endif /* G_PLATFORM_WIN32 */ - -#endif /* __G_UTILS_H__ */ diff --git a/deps/gmodule/Makefile.am b/deps/gmodule/Makefile.am deleted file mode 100644 index 73991a05..00000000 --- a/deps/gmodule/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ - -noinst_LTLIBRARIES = libgmodule.la - -libgmodule_la_CPPFLAGS = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/deps \ - -I$(top_srcdir)/deps/glib \ - -I$(top_builddir)/deps/glib \ - -Wall \ - $(NULL) - -EXTRA_DIST = \ - gmoduleconf.h.in \ - gmodule-dl.c \ - gmodule-dld.c \ - gmodule-dyld.c \ - gmodule-win32.c \ - gmoduleconf.h.win32 \ - $(NULL) - -BUILT_SOURCES = gmoduleconf.h -gmoduleconf.h: gmoduleconf.h.in - -libgmodule_la_SOURCES = gmodule.c -libgmodule_la_LIBADD = \ - $(G_MODULE_LIBS_EXTRA) \ - $(G_MODULE_LIBS) \ - $(top_builddir)/deps/glib/$(libglib) \ - $(NULL) -libgmodule_la_LDFLAGS = \ - $(G_MODULE_LDFLAGS) \ - $(NULL) diff --git a/deps/gmodule/README b/deps/gmodule/README deleted file mode 100644 index 74be42bf..00000000 --- a/deps/gmodule/README +++ /dev/null @@ -1,4 +0,0 @@ -gmodule is taken from the same glib version as deps/glib. - -The only modification is to drop the support for .la libtool archive, which -avoid pulling in GParser (and its dependencies). diff --git a/deps/gmodule/gmodule-dl.c b/deps/gmodule/gmodule-dl.c deleted file mode 100644 index ad4d8ce1..00000000 --- a/deps/gmodule/gmodule-dl.c +++ /dev/null @@ -1,166 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998, 2000 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ -#include "config.h" - -#include <dlfcn.h> - -/* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */ - - -/* dlerror() is not implemented on all systems - */ -#ifndef G_MODULE_HAVE_DLERROR -# ifdef __NetBSD__ -# define dlerror() g_strerror (errno) -# else /* !__NetBSD__ */ -/* could we rely on errno's state here? */ -# define dlerror() "unknown dl-error" -# endif /* !__NetBSD__ */ -#endif /* G_MODULE_HAVE_DLERROR */ - -/* some flags are missing on some systems, so we provide - * harmless defaults. - * The Perl sources say, RTLD_LAZY needs to be defined as (1), - * at least for Solaris 1. - * - * Mandatory: - * RTLD_LAZY - resolve undefined symbols as code from the dynamic library - * is executed. - * RTLD_NOW - resolve all undefined symbols before dlopen returns, and fail - * if this cannot be done. - * Optionally: - * RTLD_GLOBAL - the external symbols defined in the library will be made - * available to subsequently loaded libraries. - */ -#ifndef RTLD_LAZY -#define RTLD_LAZY 1 -#endif /* RTLD_LAZY */ -#ifndef RTLD_NOW -#define RTLD_NOW 0 -#endif /* RTLD_NOW */ -/* some systems (OSF1 V5.0) have broken RTLD_GLOBAL linkage */ -#ifdef G_MODULE_BROKEN_RTLD_GLOBAL -#undef RTLD_GLOBAL -#endif /* G_MODULE_BROKEN_RTLD_GLOBAL */ -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif /* RTLD_GLOBAL */ - - -/* --- functions --- */ -static gchar* -fetch_dlerror (gboolean replace_null) -{ - gchar *msg = dlerror (); - - /* make sure we always return an error message != NULL, if - * expected to do so. */ - - if (!msg && replace_null) - return "unknown dl-error"; - - return msg; -} - -static gpointer -_g_module_open (const gchar *file_name, - gboolean bind_lazy, - gboolean bind_local) -{ - gpointer handle; - - handle = dlopen (file_name, - (bind_local ? 0 : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); - if (!handle) - g_module_set_error (fetch_dlerror (TRUE)); - - return handle; -} - -static gpointer -_g_module_self (void) -{ - gpointer handle; - - /* to query symbols from the program itself, special link options - * are required on some systems. - */ - - handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); - if (!handle) - g_module_set_error (fetch_dlerror (TRUE)); - - return handle; -} - -static void -_g_module_close (gpointer handle, - gboolean is_unref) -{ - /* are there any systems out there that have dlopen()/dlclose() - * without a reference count implementation? - */ - is_unref |= 1; - - if (is_unref) - { - if (dlclose (handle) != 0) - g_module_set_error (fetch_dlerror (TRUE)); - } -} - -static gpointer -_g_module_symbol (gpointer handle, - const gchar *symbol_name) -{ - gpointer p; - gchar *msg; - - fetch_dlerror (FALSE); - p = dlsym (handle, symbol_name); - msg = fetch_dlerror (FALSE); - if (msg) - g_module_set_error (msg); - - return p; -} - -static gchar* -_g_module_build_path (const gchar *directory, - const gchar *module_name) -{ - if (directory && *directory) { - if (strncmp (module_name, "lib", 3) == 0) - return g_strconcat (directory, "/", module_name, NULL); - else - return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); - } else if (strncmp (module_name, "lib", 3) == 0) - return g_strdup (module_name); - else - return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); -} diff --git a/deps/gmodule/gmodule-dld.c b/deps/gmodule/gmodule-dld.c deleted file mode 100644 index 4db0f7f1..00000000 --- a/deps/gmodule/gmodule-dld.c +++ /dev/null @@ -1,161 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998, 2000 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ -#include "config.h" - -#include <dl.h> - - -/* some flags are missing on some systems, so we provide - * harmless defaults. - * - * Mandatory: - * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. - * BIND_DEFERRED - Delay code symbol resolution until actual reference. - * - * Optionally: - * BIND_FIRST - Place the library at the head of the symbol search order. - * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied - * symbols as fatal. This flag allows binding of unsatisfied code - * symbols to be deferred until use. - * [Perl: For certain libraries, like DCE, deferred binding often - * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE - * still allows unresolved references in situations like this.] - * BIND_NOSTART - Do not call the initializer for the shared library when the - * library is loaded, nor on a future call to shl_unload(). - * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols. - * - * hp9000s700/hp9000s800: - * BIND_RESTRICTED - Restrict symbols visible by the library to those present at - * library load time. - * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified - * by the path argument. - */ -#ifndef DYNAMIC_PATH -#define DYNAMIC_PATH 0 -#endif /* DYNAMIC_PATH */ -#ifndef BIND_RESTRICTED -#define BIND_RESTRICTED 0 -#endif /* BIND_RESTRICTED */ - -#define OPT_BIND_FLAGS (BIND_NONFATAL | BIND_VERBOSE) - - -/* --- functions --- */ - -/* - * shl_load() does not appear to support making symbols invisible to - * the global namespace. However, the default is to put the library - * last in the search order, which is approximately what we want, - * since it will cause symbols that conflict with existing symbols to - * be invisible. It is unclear if BIND_FIRST should be used when - * bind_local==0, since it may cause the loaded symbols to be used - * preferentially to the application's symbols, which is Almost - * Always Wrong. --ds - */ -static gpointer -_g_module_open (const gchar *file_name, - gboolean bind_lazy, - gboolean bind_local) -{ - shl_t shl_handle; - - shl_handle = shl_load (file_name, - (bind_lazy ? BIND_DEFERRED : BIND_IMMEDIATE) | OPT_BIND_FLAGS, 0); - if (!shl_handle) - { - /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ - g_module_set_error (g_strerror (errno)); - } - - return (gpointer) shl_handle; -} - -static gpointer -_g_module_self (void) -{ - shl_t shl_handle; - - shl_handle = PROG_HANDLE; - if (!shl_handle) - g_module_set_error (g_strerror (errno)); - - return shl_handle; -} - -static void -_g_module_close (gpointer handle, - gboolean is_unref) -{ - if (!is_unref) - { - if (shl_unload ((shl_t) handle) != 0) - g_module_set_error (g_strerror (errno)); - } -} - -static gpointer -_g_module_symbol (gpointer handle, - const gchar *symbol_name) -{ - gpointer p = NULL; - - /* should we restrict lookups to TYPE_PROCEDURE? - */ - if (handle == PROG_HANDLE) - { - /* PROG_HANDLE will only lookup symbols in the program itself, not honouring - * libraries. passing NULL as a handle will also try to lookup the symbol - * in currently loaded libraries. fix pointed out and supplied by: - * David Gero <dgero@nortelnetworks.com> - */ - handle = NULL; - } - if (shl_findsym ((shl_t*) &handle, symbol_name, TYPE_UNDEFINED, &p) != 0 || - handle == NULL || p == NULL) - { - /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ - g_module_set_error (g_strerror (errno)); - } - - return p; -} - -static gchar* -_g_module_build_path (const gchar *directory, - const gchar *module_name) -{ - if (directory && *directory) - if (strncmp (module_name, "lib", 3) == 0) - return g_strconcat (directory, "/", module_name, NULL); - else - return g_strconcat (directory, "/lib", module_name, ".sl", NULL); - else if (strncmp (module_name, "lib", 3) == 0) - return g_strdup (module_name); - else - return g_strconcat ("lib", module_name, ".sl", NULL); -} diff --git a/deps/gmodule/gmodule-dyld.c b/deps/gmodule/gmodule-dyld.c deleted file mode 100644 index 20bf8a3f..00000000 --- a/deps/gmodule/gmodule-dyld.c +++ /dev/null @@ -1,152 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998, 2000 Tim Janik - * - * dyld (Darwin) GMODULE implementation - * Copyright (C) 2001 Dan Winship - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ -#include "config.h" - -#include <mach-o/dyld.h> - -static gpointer self_module = GINT_TO_POINTER (1); - -static gpointer -_g_module_open (const gchar *file_name, - gboolean bind_lazy, - gboolean bind_local) -{ - NSObjectFileImage image; - NSObjectFileImageReturnCode ret; - NSModule module; - unsigned long options; - char *msg; - - ret = NSCreateObjectFileImageFromFile (file_name, &image); - if (ret != NSObjectFileImageSuccess) - { - switch (ret) - { - case NSObjectFileImageInappropriateFile: - case NSObjectFileImageFormat: - msg = g_strdup_printf ("%s is not a loadable module", file_name); - break; - - case NSObjectFileImageArch: - msg = g_strdup_printf ("%s is not built for this architecture", - file_name); - break; - - case NSObjectFileImageAccess: - if (access (file_name, F_OK) == 0) - msg = g_strdup_printf ("%s: permission denied", file_name); - else - msg = g_strdup_printf ("%s: no such file or directory", file_name); - break; - - default: - msg = g_strdup_printf ("unknown error for %s", file_name); - break; - } - - g_module_set_error (msg); - g_free (msg); - return NULL; - } - - options = NSLINKMODULE_OPTION_RETURN_ON_ERROR; - if (bind_local) - options |= NSLINKMODULE_OPTION_PRIVATE; - if (!bind_lazy) - options |= NSLINKMODULE_OPTION_BINDNOW; - module = NSLinkModule (image, file_name, options); - NSDestroyObjectFileImage (image); - if (!module) - { - NSLinkEditErrors c; - int error_number; - const char *file, *error; - - NSLinkEditError (&c, &error_number, &file, &error); - msg = g_strdup_printf ("could not link %s: %s", file_name, error); - g_module_set_error (msg); - g_free (msg); - return NULL; - } - - return module; -} - -static gpointer -_g_module_self (void) -{ - return &self_module; -} - -static void -_g_module_close (gpointer handle, - gboolean is_unref) -{ - if (handle == &self_module) - return; - - if (!NSUnLinkModule (handle, 0)) - g_module_set_error ("could not unlink module"); -} - -static gpointer -_g_module_symbol (gpointer handle, - const gchar *symbol_name) -{ - NSSymbol sym; - char *msg; - - if (handle == &self_module) - { - if (NSIsSymbolNameDefined (symbol_name)) - sym = NSLookupAndBindSymbol (symbol_name); - else - sym = NULL; - } - else - sym = NSLookupSymbolInModule (handle, symbol_name); - - if (!sym) - { - msg = g_strdup_printf ("no such symbol %s", symbol_name); - g_module_set_error (msg); - g_free (msg); - return NULL; - } - - return NSAddressOfSymbol (sym); -} - -static gchar* -_g_module_build_path (const gchar *directory, - const gchar *module_name) -{ - if (directory && *directory) - { - if (strncmp (module_name, "lib", 3) == 0) - return g_strconcat (directory, "/", module_name, NULL); - else - return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); - } - else if (strncmp (module_name, "lib", 3) == 0) - return g_strdup (module_name); - else - return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); -} diff --git a/deps/gmodule/gmodule-win32.c b/deps/gmodule/gmodule-win32.c deleted file mode 100644 index 7dfb25f9..00000000 --- a/deps/gmodule/gmodule-win32.c +++ /dev/null @@ -1,200 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998, 2000 Tim Janik - * - * Win32 GMODULE implementation - * Copyright (C) 1998 Tor Lillqvist - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ -#include "config.h" - -#include <stdio.h> -#include <windows.h> - -#include <tlhelp32.h> - -#ifdef G_WITH_CYGWIN -#include <sys/cygwin.h> -#endif - -static void -set_error (const gchar *format, - ...) -{ - gchar *error; - gchar *detail; - gchar *message; - va_list args; - - error = g_win32_error_message (GetLastError ()); - - va_start (args, format); - detail = g_strdup_vprintf (format, args); - va_end (args); - - message = g_strconcat (detail, error, NULL); - - g_module_set_error (message); - g_free (message); - g_free (detail); - g_free (error); -} - -/* --- functions --- */ -static gpointer -_g_module_open (const gchar *file_name, - gboolean bind_lazy, - gboolean bind_local) -{ - HINSTANCE handle; - wchar_t *wfilename; -#ifdef G_WITH_CYGWIN - gchar tmp[MAX_PATH]; - - cygwin_conv_to_win32_path(file_name, tmp); - file_name = tmp; -#endif - wfilename = g_utf8_to_utf16 (file_name, -1, NULL, NULL, NULL); - - handle = LoadLibraryW (wfilename); - g_free (wfilename); - - if (!handle) - set_error ("`%s': ", file_name); - - return handle; -} - -static gint dummy; -static gpointer null_module_handle = &dummy; - -static gpointer -_g_module_self (void) -{ - return null_module_handle; -} - -static void -_g_module_close (gpointer handle, - gboolean is_unref) -{ - if (handle != null_module_handle) - if (!FreeLibrary (handle)) - set_error (""); -} - -static gpointer -find_in_any_module_using_toolhelp (const gchar *symbol_name) -{ - HANDLE snapshot; - MODULEENTRY32 me32; - - gpointer p; - - if ((snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0)) == (HANDLE) -1) - return NULL; - - me32.dwSize = sizeof (me32); - p = NULL; - if (Module32First (snapshot, &me32)) - { - do { - if ((p = GetProcAddress (me32.hModule, symbol_name)) != NULL) - break; - } while (Module32Next (snapshot, &me32)); - } - - CloseHandle (snapshot); - - return p; -} - -static gpointer -find_in_any_module (const gchar *symbol_name) -{ - gpointer result; - - if ((result = find_in_any_module_using_toolhelp (symbol_name)) == NULL) - return NULL; - else - return result; -} - -static gpointer -_g_module_symbol (gpointer handle, - const gchar *symbol_name) -{ - gpointer p; - - if (handle == null_module_handle) - { - if ((p = GetProcAddress (GetModuleHandle (NULL), symbol_name)) == NULL) - p = find_in_any_module (symbol_name); - } - else - p = GetProcAddress (handle, symbol_name); - - if (!p) - set_error (""); - - return p; -} - -static gchar* -_g_module_build_path (const gchar *directory, - const gchar *module_name) -{ - gint k; - - k = strlen (module_name); - - if (directory && *directory) - if (k > 4 && g_ascii_strcasecmp (module_name + k - 4, ".dll") == 0) - return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, NULL); -#ifdef G_WITH_CYGWIN - else if (strncmp (module_name, "lib", 3) == 0 || strncmp (module_name, "cyg", 3) == 0) - return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, ".dll", NULL); - else - return g_strconcat (directory, G_DIR_SEPARATOR_S, "cyg", module_name, ".dll", NULL); -#else - else if (strncmp (module_name, "lib", 3) == 0) - return g_strconcat (directory, G_DIR_SEPARATOR_S, module_name, ".dll", NULL); - else - return g_strconcat (directory, G_DIR_SEPARATOR_S, "lib", module_name, ".dll", NULL); -#endif - else if (k > 4 && g_ascii_strcasecmp (module_name + k - 4, ".dll") == 0) - return g_strdup (module_name); -#ifdef G_WITH_CYGWIN - else if (strncmp (module_name, "lib", 3) == 0 || strncmp (module_name, "cyg", 3) == 0) - return g_strconcat (module_name, ".dll", NULL); - else - return g_strconcat ("cyg", module_name, ".dll", NULL); -#else - else if (strncmp (module_name, "lib", 3) == 0) - return g_strconcat (module_name, ".dll", NULL); - else - return g_strconcat ("lib", module_name, ".dll", NULL); -#endif -} diff --git a/deps/gmodule/gmodule.c b/deps/gmodule/gmodule.c deleted file mode 100644 index 787bde63..00000000 --- a/deps/gmodule/gmodule.c +++ /dev/null @@ -1,580 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -/* - * MT safe - */ - -#include "config.h" - -#include "glib.h" -#include "gmodule.h" - -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif -#ifdef G_OS_WIN32 -#include <io.h> /* For open() and close() prototypes. */ -#endif - -#include "gmoduleconf.h" -#include "gstdio.h" - -/* We maintain a list of modules, so we can reference count them. - * That's needed because some platforms don't support references counts on - * modules e.g. the shl_* implementation of HP-UX - * (http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html). - * Also, the module for the program itself is kept seperatedly for - * faster access and because it has special semantics. - */ - - -/* --- structures --- */ -struct _GModule -{ - gchar *file_name; -#if defined (G_OS_WIN32) && !defined(_WIN64) - gchar *cp_file_name; -#endif - gpointer handle; - guint ref_count : 31; - guint is_resident : 1; - GModuleUnload unload; - GModule *next; -}; - - -/* --- prototypes --- */ -static gpointer _g_module_open (const gchar *file_name, - gboolean bind_lazy, - gboolean bind_local); -static void _g_module_close (gpointer handle, - gboolean is_unref); -static gpointer _g_module_self (void); -static gpointer _g_module_symbol (gpointer handle, - const gchar *symbol_name); -static gchar* _g_module_build_path (const gchar *directory, - const gchar *module_name); -static inline void g_module_set_error (const gchar *error); -static inline GModule* g_module_find_by_handle (gpointer handle); -static inline GModule* g_module_find_by_name (const gchar *name); - - -/* --- variables --- */ -static GModule *modules = NULL; -static GModule *main_module = NULL; -static GStaticPrivate module_error_private = G_STATIC_PRIVATE_INIT; -static gboolean module_debug_initialized = FALSE; -static guint module_debug_flags = 0; - - -/* --- inline functions --- */ -static inline GModule* -g_module_find_by_handle (gpointer handle) -{ - GModule *module; - GModule *retval = NULL; - - if (main_module && main_module->handle == handle) - retval = main_module; - else - for (module = modules; module; module = module->next) - if (handle == module->handle) - { - retval = module; - break; - } - - return retval; -} - -static inline GModule* -g_module_find_by_name (const gchar *name) -{ - GModule *module; - GModule *retval = NULL; - - for (module = modules; module; module = module->next) - if (strcmp (name, module->file_name) == 0) - { - retval = module; - break; - } - - return retval; -} - -static inline void -g_module_set_error_unduped (gchar *error) -{ - g_static_private_set (&module_error_private, error, g_free); - errno = 0; -} - -static inline void -g_module_set_error (const gchar *error) -{ - g_module_set_error_unduped (g_strdup (error)); -} - - -/* --- include platform specifc code --- */ -#define SUPPORT_OR_RETURN(rv) { g_module_set_error (NULL); } -#if (G_MODULE_IMPL == G_MODULE_IMPL_DL) -#include "gmodule-dl.c" -#elif (G_MODULE_IMPL == G_MODULE_IMPL_DLD) -#include "gmodule-dld.c" -#elif (G_MODULE_IMPL == G_MODULE_IMPL_WIN32) -#include "gmodule-win32.c" -#elif (G_MODULE_IMPL == G_MODULE_IMPL_DYLD) -#include "gmodule-dyld.c" -#elif (G_MODULE_IMPL == G_MODULE_IMPL_AR) -#include "gmodule-ar.c" -#else -#undef SUPPORT_OR_RETURN -#define SUPPORT_OR_RETURN(rv) { g_module_set_error ("dynamic modules are " \ - "not supported by this system"); return rv; } -static gpointer -_g_module_open (const gchar *file_name, - gboolean bind_lazy, - gboolean bind_local) -{ - return NULL; -} -static void -_g_module_close (gpointer handle, - gboolean is_unref) -{ -} -static gpointer -_g_module_self (void) -{ - return NULL; -} -static gpointer -_g_module_symbol (gpointer handle, - const gchar *symbol_name) -{ - return NULL; -} -static gchar* -_g_module_build_path (const gchar *directory, - const gchar *module_name) -{ - return NULL; -} -#endif /* no implementation */ - -/* --- functions --- */ -gboolean -g_module_supported (void) -{ - SUPPORT_OR_RETURN (FALSE); - - return TRUE; -} - -static inline gboolean -str_check_suffix (const gchar* string, - const gchar* suffix) -{ - gsize string_len = strlen (string); - gsize suffix_len = strlen (suffix); - - return string_len >= suffix_len && - strcmp (string + string_len - suffix_len, suffix) == 0; -} - -enum -{ - G_MODULE_DEBUG_RESIDENT_MODULES = 1 << 0, - G_MODULE_DEBUG_BIND_NOW_MODULES = 1 << 1 -}; - -static void -_g_module_debug_init (void) -{ - const GDebugKey keys[] = { - { "resident-modules", G_MODULE_DEBUG_RESIDENT_MODULES }, - { "bind-now-modules", G_MODULE_DEBUG_BIND_NOW_MODULES } - }; - const gchar *env; - - env = g_getenv ("G_DEBUG"); - - module_debug_flags = - !env ? 0 : g_parse_debug_string (env, keys, G_N_ELEMENTS (keys)); - - module_debug_initialized = TRUE; -} - -static GStaticRecMutex g_module_global_lock = G_STATIC_REC_MUTEX_INIT; - -GModule* -g_module_open (const gchar *file_name, - GModuleFlags flags) -{ - GModule *module; - gpointer handle = NULL; - gchar *name = NULL; - - SUPPORT_OR_RETURN (NULL); - - g_static_rec_mutex_lock (&g_module_global_lock); - - if (G_UNLIKELY (!module_debug_initialized)) - _g_module_debug_init (); - - if (module_debug_flags & G_MODULE_DEBUG_BIND_NOW_MODULES) - flags &= ~G_MODULE_BIND_LAZY; - - if (!file_name) - { - if (!main_module) - { - handle = _g_module_self (); - if (handle) - { - main_module = g_new (GModule, 1); - main_module->file_name = NULL; -#if defined (G_OS_WIN32) && !defined(_WIN64) - main_module->cp_file_name = NULL; -#endif - main_module->handle = handle; - main_module->ref_count = 1; - main_module->is_resident = TRUE; - main_module->unload = NULL; - main_module->next = NULL; - } - } - else - main_module->ref_count++; - - g_static_rec_mutex_unlock (&g_module_global_lock); - return main_module; - } - - /* we first search the module list by name */ - module = g_module_find_by_name (file_name); - if (module) - { - module->ref_count++; - - g_static_rec_mutex_unlock (&g_module_global_lock); - return module; - } - - /* check whether we have a readable file right away */ - if (g_file_test (file_name, G_FILE_TEST_IS_REGULAR)) - name = g_strdup (file_name); - /* try completing file name with standard library suffix */ - if (!name) - { - name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL); - if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) - { - g_free (name); - name = NULL; - } - } - /* try completing by appending libtool suffix */ - if (!name) - { - name = g_strconcat (file_name, ".la", NULL); - if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) - { - g_free (name); - name = NULL; - } - } - /* we can't access() the file, lets hope the platform backends finds - * it via library paths - */ - if (!name) - { - gchar *dot = strrchr (file_name, '.'); - gchar *slash = strrchr (file_name, G_DIR_SEPARATOR); - - /* make sure the name has a suffix */ - if (!dot || dot < slash) - name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL); - else - name = g_strdup (file_name); - } - - /* ok, try loading the module */ - if (name) - { - handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0, - (flags & G_MODULE_BIND_LOCAL) != 0); - } - else - { - gchar *display_file_name = g_filename_display_name (file_name); - g_module_set_error_unduped (g_strdup_printf ("unable to access file \"%s\"", display_file_name)); - g_free (display_file_name); - } - g_free (name); - - if (handle) - { - gchar *saved_error; - GModuleCheckInit check_init; - const gchar *check_failed = NULL; - - /* search the module list by handle, since file names are not unique */ - module = g_module_find_by_handle (handle); - if (module) - { - _g_module_close (module->handle, TRUE); - module->ref_count++; - g_module_set_error (NULL); - - g_static_rec_mutex_unlock (&g_module_global_lock); - return module; - } - - saved_error = g_strdup (g_module_error ()); - g_module_set_error (NULL); - - module = g_new (GModule, 1); - module->file_name = g_strdup (file_name); -#if defined (G_OS_WIN32) && !defined(_WIN64) - module->cp_file_name = g_locale_from_utf8 (file_name, -1, - NULL, NULL, NULL); -#endif - module->handle = handle; - module->ref_count = 1; - module->is_resident = FALSE; - module->unload = NULL; - module->next = modules; - modules = module; - - /* check initialization */ - if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init) && check_init != NULL) - check_failed = check_init (module); - - /* we don't call unload() if the initialization check failed. */ - if (!check_failed) - g_module_symbol (module, "g_module_unload", (gpointer) &module->unload); - - if (check_failed) - { - gchar *error; - - error = g_strconcat ("GModule (", file_name, ") ", - "initialization check failed: ", - check_failed, NULL); - g_module_close (module); - module = NULL; - g_module_set_error (error); - g_free (error); - } - else - g_module_set_error (saved_error); - - g_free (saved_error); - } - - if (module != NULL && - (module_debug_flags & G_MODULE_DEBUG_RESIDENT_MODULES)) - g_module_make_resident (module); - - g_static_rec_mutex_unlock (&g_module_global_lock); - return module; -} - -#if defined (G_OS_WIN32) && !defined(_WIN64) - -#undef g_module_open - -GModule* -g_module_open (const gchar *file_name, - GModuleFlags flags) -{ - gchar *utf8_file_name = g_locale_to_utf8 (file_name, -1, NULL, NULL, NULL); - GModule *retval = g_module_open_utf8 (utf8_file_name, flags); - - g_free (utf8_file_name); - - return retval; -} - -#endif - -gboolean -g_module_close (GModule *module) -{ - SUPPORT_OR_RETURN (FALSE); - - g_return_val_if_fail (module != NULL, FALSE); - g_return_val_if_fail (module->ref_count > 0, FALSE); - - g_static_rec_mutex_lock (&g_module_global_lock); - - module->ref_count--; - - if (!module->ref_count && !module->is_resident && module->unload) - { - GModuleUnload unload; - - unload = module->unload; - module->unload = NULL; - unload (module); - } - - if (!module->ref_count && !module->is_resident) - { - GModule *last; - GModule *node; - - last = NULL; - - node = modules; - while (node) - { - if (node == module) - { - if (last) - last->next = node->next; - else - modules = node->next; - break; - } - last = node; - node = last->next; - } - module->next = NULL; - - _g_module_close (module->handle, FALSE); - g_free (module->file_name); -#if defined (G_OS_WIN32) && !defined(_WIN64) - g_free (module->cp_file_name); -#endif - g_free (module); - } - - g_static_rec_mutex_unlock (&g_module_global_lock); - return g_module_error() == NULL; -} - -void -g_module_make_resident (GModule *module) -{ - g_return_if_fail (module != NULL); - - module->is_resident = TRUE; -} - -const gchar * -g_module_error (void) -{ - return g_static_private_get (&module_error_private); -} - -gboolean -g_module_symbol (GModule *module, - const gchar *symbol_name, - gpointer *symbol) -{ - const gchar *module_error; - - if (symbol) - *symbol = NULL; - SUPPORT_OR_RETURN (FALSE); - - g_return_val_if_fail (module != NULL, FALSE); - g_return_val_if_fail (symbol_name != NULL, FALSE); - g_return_val_if_fail (symbol != NULL, FALSE); - - g_static_rec_mutex_lock (&g_module_global_lock); - -#ifdef G_MODULE_NEED_USCORE - { - gchar *name; - - name = g_strconcat ("_", symbol_name, NULL); - *symbol = _g_module_symbol (module->handle, name); - g_free (name); - } -#else /* !G_MODULE_NEED_USCORE */ - *symbol = _g_module_symbol (module->handle, symbol_name); -#endif /* !G_MODULE_NEED_USCORE */ - - module_error = g_module_error (); - if (module_error) - { - gchar *error; - - error = g_strconcat ("`", symbol_name, "': ", module_error, NULL); - g_module_set_error (error); - g_free (error); - *symbol = NULL; - } - - g_static_rec_mutex_unlock (&g_module_global_lock); - return !module_error; -} - -const gchar * -g_module_name (GModule *module) -{ - g_return_val_if_fail (module != NULL, NULL); - - if (module == main_module) - return "main"; - - return module->file_name; -} - -#if defined (G_OS_WIN32) && !defined(_WIN64) - -#undef g_module_name - -const gchar * -g_module_name (GModule *module) -{ - g_return_val_if_fail (module != NULL, NULL); - - if (module == main_module) - return "main"; - - return module->cp_file_name; -} - -#endif - -gchar* -g_module_build_path (const gchar *directory, - const gchar *module_name) -{ - g_return_val_if_fail (module_name != NULL, NULL); - - return _g_module_build_path (directory, module_name); -} diff --git a/deps/gmodule/gmodule.h b/deps/gmodule/gmodule.h deleted file mode 100644 index dc13a8bb..00000000 --- a/deps/gmodule/gmodule.h +++ /dev/null @@ -1,99 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -/* - * Modified by the GLib Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GLib Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GLib at ftp://ftp.gtk.org/pub/gtk/. - */ - -#ifndef __GMODULE_H__ -#define __GMODULE_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -/* exporting and importing functions, this is special cased - * to feature Windows dll stubs. - */ -#define G_MODULE_IMPORT extern -#ifdef G_PLATFORM_WIN32 -# define G_MODULE_EXPORT __declspec(dllexport) -#else /* !G_PLATFORM_WIN32 */ -# define G_MODULE_EXPORT -#endif /* !G_PLATFORM_WIN32 */ - -typedef enum -{ - G_MODULE_BIND_LAZY = 1 << 0, - G_MODULE_BIND_LOCAL = 1 << 1, - G_MODULE_BIND_MASK = 0x03 -} GModuleFlags; - -typedef struct _GModule GModule; -typedef const gchar* (*GModuleCheckInit) (GModule *module); -typedef void (*GModuleUnload) (GModule *module); - -#ifdef G_OS_WIN32 -#define g_module_open g_module_open_utf8 -#define g_module_name g_module_name_utf8 -#endif - -/* return TRUE if dynamic module loading is supported */ -gboolean g_module_supported (void) G_GNUC_CONST; - -/* open a module `file_name' and return handle, which is NULL on error */ -GModule* g_module_open (const gchar *file_name, - GModuleFlags flags); - -/* close a previously opened module, returns TRUE on success */ -gboolean g_module_close (GModule *module); - -/* make a module resident so g_module_close on it will be ignored */ -void g_module_make_resident (GModule *module); - -/* query the last module error as a string */ -const gchar * g_module_error (void); - -/* retrieve a symbol pointer from `module', returns TRUE on success */ -gboolean g_module_symbol (GModule *module, - const gchar *symbol_name, - gpointer *symbol); - -/* retrieve the file name from an existing module */ -const gchar * g_module_name (GModule *module); - -/* Build the actual file name containing a module. `directory' is the - * directory where the module file is supposed to be, or NULL or empty - * in which case it should either be in the current directory or, on - * some operating systems, in some standard place, for instance on the - * PATH. Hence, to be absoultely sure to get the correct module, - * always pass in a directory. The file name consists of the directory, - * if supplied, and `module_name' suitably decorated according to - * the operating system's conventions (for instance lib*.so or *.dll). - * - * No checks are made that the file exists, or is of correct type. - */ -gchar* g_module_build_path (const gchar *directory, - const gchar *module_name); - - -G_END_DECLS - -#endif /* __GMODULE_H__ */ diff --git a/deps/gmodule/gmoduleconf.h.in b/deps/gmodule/gmoduleconf.h.in deleted file mode 100644 index 0b90aa2d..00000000 --- a/deps/gmodule/gmoduleconf.h.in +++ /dev/null @@ -1,52 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ -#ifndef __G_MODULE_CONF_H__ -#define __G_MODULE_CONF_H__ - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define G_MODULE_IMPL_NONE 0 -#define G_MODULE_IMPL_DL 1 -#define G_MODULE_IMPL_DLD 2 -#define G_MODULE_IMPL_WIN32 3 -#define G_MODULE_IMPL_OS2 4 -#define G_MODULE_IMPL_BEOS 5 -#define G_MODULE_IMPL_DYLD 6 -#define G_MODULE_IMPL_AR 7 - -#define G_MODULE_IMPL @G_MODULE_IMPL@ -#undef G_MODULE_HAVE_DLERROR -#if (@G_MODULE_HAVE_DLERROR@) -#define G_MODULE_HAVE_DLERROR -#endif -#if (@G_MODULE_NEED_USCORE@) || defined (hp9000s300) || defined (__hp9000s300) || defined (__hp9000s300__) -#define G_MODULE_NEED_USCORE -#endif -#if (@G_MODULE_BROKEN_RTLD_GLOBAL@) -#define G_MODULE_BROKEN_RTLD_GLOBAL -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __G_MODULE_CONF_H__ */ diff --git a/deps/gmodule/gmoduleconf.h.win32 b/deps/gmodule/gmoduleconf.h.win32 deleted file mode 100644 index 890e2f10..00000000 --- a/deps/gmodule/gmoduleconf.h.win32 +++ /dev/null @@ -1,42 +0,0 @@ -/* GMODULE - GLIB wrapper code for dynamic module loading - * Copyright (C) 1998 Tim Janik - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ -#ifndef __G_MODULE_CONF_H__ -#define __G_MODULE_CONF_H__ - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define G_MODULE_IMPL_NONE 0 -#define G_MODULE_IMPL_DL 1 -#define G_MODULE_IMPL_DLD 2 -#define G_MODULE_IMPL_WIN32 3 -#define G_MODULE_IMPL_OS2 4 -#define G_MODULE_IMPL_BEOS 5 -#define G_MODULE_IMPL_DYLD 6 - -#define G_MODULE_IMPL G_MODULE_IMPL_WIN32 -#undef G_MODULE_HAVE_DLERROR - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __G_MODULE_CONF_H__ */ diff --git a/examples/Makefile.am b/examples/Makefile.am index d9198a91..47a21571 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -3,10 +3,6 @@ include $(top_srcdir)/build/autotools/Makefile.am.silent AM_CPPFLAGS = \ -I$(top_srcdir) -if !USE_GLIB -AM_CPPFLAGS += -I$(top_builddir)/deps/glib -endif - AM_CFLAGS = \ $(COGL_DEP_CFLAGS) \ $(COGL_EXTRA_CFLAGS) @@ -23,7 +19,7 @@ common_ldadd = \ $(LIBM) if !USE_GLIB -common_ldadd += $(top_builddir)/deps/glib/libglib.la +common_ldadd += $(top_builddir)/deps/eglib/src/libeglib.la endif programs = cogl-info diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am index ccbf5d88..083d734b 100644 --- a/tests/conform/Makefile.am +++ b/tests/conform/Makefile.am @@ -145,8 +145,7 @@ if BUILD_COGL_PATH test_conformance_LDADD += $(top_builddir)/cogl-path/libcogl-path.la endif if !USE_GLIB -test_conformance_LDADD += $(top_builddir)/deps/glib/libglib.la -test_conformance_LDADD += $(top_builddir)/deps/gmodule/libgmodule.la +test_conformance_LDADD += $(top_builddir)/deps/eglib/src/libeglib.la endif test_conformance_LDFLAGS = -export-dynamic diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index e9ca43ed..4e0c1f5c 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -71,8 +71,7 @@ test_unit_LDADD = \ $(top_builddir)/cogl/libcogl2.la \ $(LIBM) if !USE_GLIB -test_unit_LDADD += $(top_builddir)/deps/glib/libglib.la -test_unit_LDADD += $(top_builddir)/deps/gmodule/libgmodule.la +test_unit_LDADD += $(top_builddir)/deps/eglib/src/libeglib.la endif test_unit_LDFLAGS = -export-dynamic |