diff --git a/desmume/src/GPU_osd.cpp b/desmume/src/GPU_osd.cpp
index 4e261aba9..e27acdc9c 100644
--- a/desmume/src/GPU_osd.cpp
+++ b/desmume/src/GPU_osd.cpp
@@ -262,4 +262,4 @@ void OSDCLASS::addFixed(u16 x, u16 y, const char *fmt, ...)
void OSDCLASS::border(bool enabled)
{
render51.setTextBoxBorder(enabled);
-}
\ No newline at end of file
+}
diff --git a/desmume/src/Makefile.am b/desmume/src/Makefile.am
index 7ad319a66..c82c2522b 100644
--- a/desmume/src/Makefile.am
+++ b/desmume/src/Makefile.am
@@ -1,5 +1,7 @@
include $(top_srcdir)/src/desmume.mk
+AM_CPPFLAGS += $(SDL_CFLAGS) $(GTK_CFLAGS) $(GTHREAD_CFLAGS)
+
EXTRA_DIST = build.bat instruction_tabdef.inc thumb_tabdef.inc fs-linux.cpp fs-windows.cpp \
matrix_sse2-x64.asm matrix_sse2-x86.asm
if HAVE_GDB_STUB
@@ -14,8 +16,8 @@ libdesmume_a_SOURCES = \
arm_instructions.cpp arm_instructions.h \
bios.cpp bios.h bits.h cp15.cpp cp15.h \
cflash.cpp cflash.h fs.h \
- common.cpp common.h \
- debug.cpp debug.h \
+ common.cpp common.h commandline.h commandline.cpp \
+ debug.cpp debug.h driver.h \
Disassembler.cpp Disassembler.h \
dscard.h fat.h FIFO.cpp FIFO.h \
GPU_osd.cpp GPU_osd.h \
diff --git a/desmume/src/common.cpp b/desmume/src/common.cpp
index 56c259bf7..0b3d664f9 100644
--- a/desmume/src/common.cpp
+++ b/desmume/src/common.cpp
@@ -118,7 +118,7 @@ std::string RomName = ""; //Stores the name of the Rom currently loaded in me
* Known Usage:
* LoadRom
**/
-void SetRomName(char *filename)
+void SetRomName(const char *filename)
{
std::string str = filename;
diff --git a/desmume/src/common.h b/desmume/src/common.h
index 121e4ca6c..1a0fa1ca2 100644
--- a/desmume/src/common.h
+++ b/desmume/src/common.h
@@ -29,7 +29,7 @@
extern u8 gba_header_data_0x04[156];
const char* GetRomName(); //adelikat: return the name of the Rom currently loaded
-void SetRomName(char *filename);
+void SetRomName(const char *filename);
#ifdef WIN32
diff --git a/desmume/src/gtk/main.cpp b/desmume/src/gtk/main.cpp
index d620f5999..ef95e353f 100644
--- a/desmume/src/gtk/main.cpp
+++ b/desmume/src/gtk/main.cpp
@@ -45,6 +45,8 @@
#include "dTool.h"
#include "desmume_config.h"
+#include "commandline.h"
+
#ifdef GDB_STUB
#include "gdbstub.h"
#endif
@@ -327,9 +329,9 @@ static u16 Cur_Keypad = 0;
static u16 gdk_shift_pressed = 0;
u16 Keypad_Temp[NB_KEYS];
-struct configured_features {
- int load_slot;
-
+class configured_features : public CommandLine
+{
+public:
int disable_sound;
int engine_3d;
int disable_limiter;
@@ -340,7 +342,6 @@ struct configured_features {
int firmware_language;
- const char *nds_file;
const char *cflash_disk_image_file;
#ifdef HAVE_TIMEOUT
int timeout;
@@ -350,8 +351,6 @@ struct configured_features {
static void
init_configured_features( struct configured_features *config)
{
- config->load_slot = 0;
-
config->arm9_gdb_port = 0;
config->arm7_gdb_port = 0;
@@ -361,7 +360,6 @@ init_configured_features( struct configured_features *config)
config->disable_limiter = 0;
- config->nds_file = NULL;
config->savetype = 0;
config->cflash_disk_image_file = NULL;
@@ -379,7 +377,6 @@ fill_configured_features( struct configured_features *config,
int argc, char ** argv)
{
GOptionEntry options[] = {
- { "load-slot", 0, 0, G_OPTION_ARG_INT, &config->load_slot, "Loads savegame from slot NUM", "NUM"},
{ "disable-sound", 0, 0, G_OPTION_ARG_NONE, &config->disable_sound, "Disables the sound emulation", NULL},
{ "disable-limiter", 0, 0, G_OPTION_ARG_NONE, &config->disable_limiter, "Disables the 60fps limiter", NULL},
{ "3d-engine", 0, 0, G_OPTION_ARG_INT, &config->engine_3d, "Select 3d rendering engine. Available engines:\n"
@@ -416,40 +413,25 @@ fill_configured_features( struct configured_features *config,
#endif
{ NULL }
};
- GOptionContext *ctx;
- GError *error = NULL;
- ctx = g_option_context_new ("");
- g_option_context_add_main_entries (ctx, options, "options");
- g_option_context_add_group (ctx, gtk_get_option_group (TRUE));
- g_option_context_parse (ctx, &argc, &argv, &error);
- g_option_context_free (ctx);
+ config->loadCommonOptions();
+ g_option_context_add_main_entries (config->ctx, options, "options");
+ g_option_context_add_group (config->ctx, gtk_get_option_group (TRUE));
+ config->parse(argc,argv);
- if (error) {
- g_printerr("Error parsing command line arguments: %s\n", error->message);
- g_error_free (error);
- return 0;
- }
+ if(!config->validate())
+ goto error;
- if (argc == 2)
- config->nds_file = argv[1];
- if (argc > 2)
- goto error;
-
- if (config->savetype < 0 || config->savetype > 6) {
- g_printerr("Accepted savetypes are from 0 to 6.\n");
- goto error;
- }
+ if (config->savetype < 0 || config->savetype > 6) {
+ g_printerr("Accepted savetypes are from 0 to 6.\n");
+ return false;
+ }
if (config->firmware_language < -1 || config->firmware_language > 5) {
g_printerr("Firmware language must be set to a value from 0 to 5.\n");
goto error;
}
- if (config->load_slot < 0 || config->load_slot > 10) {
- g_printerr("I only know how to load from slots 1-10, 0 means 'do not load savegame' and is default\n");
- goto error;
- }
if (config->engine_3d != 0 && config->engine_3d != 1
#if defined(HAVE_LIBOSMESA)
@@ -479,8 +461,8 @@ fill_configured_features( struct configured_features *config,
return 1;
error:
- g_printerr("USAGE: %s [options] [nds-file]\n", argv[0]);
- g_printerr("USAGE: %s --help - for help\n", argv[0]);
+ config->errorHelp(argv[0]);
+
return 0;
}
@@ -1808,8 +1790,8 @@ common_gtk_main( struct configured_features *my_config)
mmu_select_savetype(my_config->savetype, &backupmemorytype, &backupmemorysize);
/* Command line arg */
- if( my_config->nds_file != NULL) {
- if(Open( my_config->nds_file, bad_glob_cflash_disk_image_file) >= 0) {
+ if( my_config->nds_file != "") {
+ if(Open( my_config->nds_file.c_str(), bad_glob_cflash_disk_image_file) >= 0) {
if(my_config->load_slot){
loadstate_slot(my_config->load_slot);
}
@@ -1820,7 +1802,7 @@ common_gtk_main( struct configured_features *my_config)
GTK_DIALOG_MODAL,
GTK_MESSAGE_INFO,
GTK_BUTTONS_OK,
- "Unable to load :\n%s", my_config->nds_file);
+ "Unable to load :\n%s", my_config->nds_file.c_str());
gtk_dialog_run(GTK_DIALOG(pDialog));
gtk_widget_destroy(pDialog);
}
@@ -1870,7 +1852,7 @@ common_gtk_main( struct configured_features *my_config)
int
main (int argc, char *argv[])
{
- struct configured_features my_config;
+ configured_features my_config;
init_configured_features( &my_config);
diff --git a/desmume/src/windows/DeSmuME_2005.vcproj b/desmume/src/windows/DeSmuME_2005.vcproj
index bad5744e6..3077f093c 100644
--- a/desmume/src/windows/DeSmuME_2005.vcproj
+++ b/desmume/src/windows/DeSmuME_2005.vcproj
@@ -50,7 +50,7 @@
FavorSizeOrSpeed="0"
EnableFiberSafeOptimizations="false"
WholeProgramOptimization="false"
- AdditionalIncludeDirectories=".;..;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig"
+ AdditionalIncludeDirectories=".;..;"glib-2.20.1\build";"glib-2.20.1\build\glib";.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig"
PreprocessorDefinitions="DEBUG;_CRT_SECURE_NO_DEPRECATE;WIN32;SPU_INTERPOLATE;HAVE_LIBZ;HAVE_LIBZZIP;NOMINMAX;DEBUG;EXPERIMENTAL_WIFI"
ExceptionHandling="1"
BasicRuntimeChecks="0"
@@ -74,12 +74,13 @@
/>
+
+
+
+
+
+
+
diff --git a/desmume/src/windows/DeSmuME_2008.vcproj b/desmume/src/windows/DeSmuME_2008.vcproj
index b561d2182..03ae46427 100644
--- a/desmume/src/windows/DeSmuME_2008.vcproj
+++ b/desmume/src/windows/DeSmuME_2008.vcproj
@@ -51,7 +51,7 @@
FavorSizeOrSpeed="0"
EnableFiberSafeOptimizations="false"
WholeProgramOptimization="false"
- AdditionalIncludeDirectories=".;..;.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig"
+ AdditionalIncludeDirectories=".;..;"glib-2.20.1\build";"glib-2.20.1\build\glib";.\zlib123;.\zziplib;.\winpcap;userconfig;defaultconfig"
PreprocessorDefinitions="DEBUG;_CRT_SECURE_NO_DEPRECATE;WIN32;BETA_VERSION;SPU_INTERPOLATE;NOMINMAX;EXPERIMENTAL_WIFI;HAVE_LIBZZIP"
ExceptionHandling="1"
BasicRuntimeChecks="0"
@@ -73,9 +73,9 @@
/>
+
+
+
+
+
@@ -946,6 +960,10 @@
RelativePath="..\cheatSystem.h"
>
+
+
diff --git a/desmume/src/windows/glib-2.20.1/build/dependencies/proxy-libintl-20080918/include/libintl.h b/desmume/src/windows/glib-2.20.1/build/dependencies/proxy-libintl-20080918/include/libintl.h
new file mode 100644
index 000000000..82d96e7d2
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/dependencies/proxy-libintl-20080918/include/libintl.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2008 Tor Lillqvist
+ *
+ * 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; see the file COPYING.LIB.txt. If
+ * not, write to the Free Software Foundation, Inc., 51 Franklin
+ * Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _LIBINTL_H
+#define _LIBINTL_H 1
+
+#include
+
+#ifndef LC_MESSAGES
+# define LC_MESSAGES 1729 /* Use same value as in GNU gettext */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern char *gettext (const char *msgid);
+
+extern char *dgettext (const char *domainname,
+ const char *msgid);
+
+extern char *dcgettext (const char *domainname,
+ const char *msgid,
+ int category);
+
+extern char *ngettext (const char *msgid1,
+ const char *msgid2,
+ unsigned long int n);
+
+extern char *dngettext (const char *domainname,
+ const char *msgid1,
+ const char *msgid2,
+ unsigned long int n);
+
+extern char *dcngettext (const char *domainname,
+ const char *msgid1,
+ const char *msgid2,
+ unsigned long int n,
+ int category);
+
+extern char *textdomain (const char *domainname);
+
+extern char *bindtextdomain (const char *domainname,
+ const char *dirname);
+
+extern char *bind_textdomain_codeset (const char *domainname,
+ const char *codeset);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBINTL_H */
diff --git a/desmume/src/windows/glib-2.20.1/build/dirent/README b/desmume/src/windows/glib-2.20.1/build/dirent/README
new file mode 100644
index 000000000..e31ac1f90
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/dirent/README
@@ -0,0 +1,2 @@
+This is dirent from mingw-runtime-3.3, separated for MSVC user's
+benefit.
diff --git a/desmume/src/windows/glib-2.20.1/build/dirent/dirent.c b/desmume/src/windows/glib-2.20.1/build/dirent/dirent.c
new file mode 100644
index 000000000..26b6cb1e5
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/dirent/dirent.c
@@ -0,0 +1,341 @@
+/*
+ * dirent.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Peters
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "dirent.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include /* for GetFileAttributes */
+
+#include
+
+#ifdef _UNICODE
+#define _tdirent _wdirent
+#define _TDIR _WDIR
+#define _topendir _wopendir
+#define _tclosedir _wclosedir
+#define _treaddir _wreaddir
+#define _trewinddir _wrewinddir
+#define _ttelldir _wtelldir
+#define _tseekdir _wseekdir
+#else
+#define _tdirent dirent
+#define _TDIR DIR
+#define _topendir opendir
+#define _tclosedir closedir
+#define _treaddir readdir
+#define _trewinddir rewinddir
+#define _ttelldir telldir
+#define _tseekdir seekdir
+#endif
+
+#define SUFFIX _T("*")
+#define SLASH _T("\\")
+
+
+/*
+ * opendir
+ *
+ * Returns a pointer to a DIR structure appropriately filled in to begin
+ * searching a directory.
+ */
+_TDIR *
+_topendir (const _TCHAR *szPath)
+{
+ _TDIR *nd;
+ unsigned int rc;
+ _TCHAR szFullPath[MAX_PATH];
+
+ errno = 0;
+
+ if (!szPath)
+ {
+ errno = EFAULT;
+ return (_TDIR *) 0;
+ }
+
+ if (szPath[0] == _T('\0'))
+ {
+ errno = ENOTDIR;
+ return (_TDIR *) 0;
+ }
+
+ /* Attempt to determine if the given path really is a directory. */
+ rc = GetFileAttributes (szPath);
+ if (rc == (unsigned int)-1)
+ {
+ /* call GetLastError for more error info */
+ errno = ENOENT;
+ return (_TDIR *) 0;
+ }
+ if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ /* Error, entry exists but not a directory. */
+ errno = ENOTDIR;
+ return (_TDIR *) 0;
+ }
+
+ /* Make an absolute pathname. */
+ _tfullpath (szFullPath, szPath, MAX_PATH);
+
+ /* Allocate enough space to store DIR structure and the complete
+ * directory path given. */
+ nd = (_TDIR *) malloc (sizeof (_TDIR) + (_tcslen(szFullPath) + _tcslen (SLASH) +
+ _tcslen(SUFFIX) + 1) * sizeof(_TCHAR));
+
+ if (!nd)
+ {
+ /* Error, out of memory. */
+ errno = ENOMEM;
+ return (_TDIR *) 0;
+ }
+
+ /* Create the search expression. */
+ _tcscpy (nd->dd_name, szFullPath);
+
+ /* Add on a slash if the path does not end with one. */
+ if (nd->dd_name[0] != _T('\0') &&
+ nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('/') &&
+ nd->dd_name[_tcslen (nd->dd_name) - 1] != _T('\\'))
+ {
+ _tcscat (nd->dd_name, SLASH);
+ }
+
+ /* Add on the search pattern */
+ _tcscat (nd->dd_name, SUFFIX);
+
+ /* Initialize handle to -1 so that a premature closedir doesn't try
+ * to call _findclose on it. */
+ nd->dd_handle = -1;
+
+ /* Initialize the status. */
+ nd->dd_stat = 0;
+
+ /* Initialize the dirent structure. ino and reclen are invalid under
+ * Win32, and name simply points at the appropriate part of the
+ * findfirst_t structure. */
+ nd->dd_dir.d_ino = 0;
+ nd->dd_dir.d_reclen = 0;
+ nd->dd_dir.d_namlen = 0;
+ memset (nd->dd_dir.d_name, 0, FILENAME_MAX);
+
+ return nd;
+}
+
+
+/*
+ * readdir
+ *
+ * Return a pointer to a dirent structure filled with the information on the
+ * next entry in the directory.
+ */
+struct _tdirent *
+_treaddir (_TDIR * dirp)
+{
+ errno = 0;
+
+ /* Check for valid DIR struct. */
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return (struct _tdirent *) 0;
+ }
+
+ if (dirp->dd_stat < 0)
+ {
+ /* We have already returned all files in the directory
+ * (or the structure has an invalid dd_stat). */
+ return (struct _tdirent *) 0;
+ }
+ else if (dirp->dd_stat == 0)
+ {
+ /* We haven't started the search yet. */
+ /* Start the search */
+ dirp->dd_handle = _tfindfirst (dirp->dd_name, &(dirp->dd_dta));
+
+ if (dirp->dd_handle == -1)
+ {
+ /* Whoops! Seems there are no files in that
+ * directory. */
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ dirp->dd_stat = 1;
+ }
+ }
+ else
+ {
+ /* Get the next search entry. */
+ if (_tfindnext (dirp->dd_handle, &(dirp->dd_dta)))
+ {
+ /* We are off the end or otherwise error.
+ _findnext sets errno to ENOENT if no more file
+ Undo this. */
+ DWORD winerr = GetLastError();
+ if (winerr == ERROR_NO_MORE_FILES)
+ errno = 0;
+ _findclose (dirp->dd_handle);
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Update the status to indicate the correct
+ * number. */
+ dirp->dd_stat++;
+ }
+ }
+
+ if (dirp->dd_stat > 0)
+ {
+ /* Successfully got an entry. Everything about the file is
+ * already appropriately filled in except the length of the
+ * file name. */
+ dirp->dd_dir.d_namlen = _tcslen (dirp->dd_dta.name);
+ _tcscpy (dirp->dd_dir.d_name, dirp->dd_dta.name);
+ return &dirp->dd_dir;
+ }
+
+ return (struct _tdirent *) 0;
+}
+
+
+/*
+ * closedir
+ *
+ * Frees up resources allocated by opendir.
+ */
+int
+_tclosedir (_TDIR * dirp)
+{
+ int rc;
+
+ errno = 0;
+ rc = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ rc = _findclose (dirp->dd_handle);
+ }
+
+ /* Delete the dir structure. */
+ free (dirp);
+
+ return rc;
+}
+
+/*
+ * rewinddir
+ *
+ * Return to the beginning of the directory "stream". We simply call findclose
+ * and then reset things like an opendir.
+ */
+void
+_trewinddir (_TDIR * dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+
+ dirp->dd_handle = -1;
+ dirp->dd_stat = 0;
+}
+
+/*
+ * telldir
+ *
+ * Returns the "position" in the "directory stream" which can be used with
+ * seekdir to go back to an old entry. We simply return the value in stat.
+ */
+long
+_ttelldir (_TDIR * dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ return dirp->dd_stat;
+}
+
+/*
+ * seekdir
+ *
+ * Seek to an entry previously returned by telldir. We rewind the directory
+ * and call readdir repeatedly until either dd_stat is the position number
+ * or -1 (off the end). This is not perfect, in that the directory may
+ * have changed while we weren't looking. But that is probably the case with
+ * any such system.
+ */
+void
+_tseekdir (_TDIR * dirp, long lPos)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (lPos < -1)
+ {
+ /* Seeking to an invalid position. */
+ errno = EINVAL;
+ return;
+ }
+ else if (lPos == -1)
+ {
+ /* Seek past end. */
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Rewind and read forward to the appropriate index. */
+ _trewinddir (dirp);
+
+ while ((dirp->dd_stat < lPos) && _treaddir (dirp))
+ ;
+ }
+}
diff --git a/desmume/src/windows/glib-2.20.1/build/dirent/dirent.h b/desmume/src/windows/glib-2.20.1/build/dirent/dirent.h
new file mode 100644
index 000000000..237665b4e
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/dirent/dirent.h
@@ -0,0 +1,127 @@
+/*
+ * DIRENT.H (formerly DIRLIB.H)
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ */
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+#include
+#include
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char d_name[FILENAME_MAX]; /* File name. */
+};
+
+#ifdef _WIN64
+#define INTPTR __int64
+#else
+#define INTPTR long
+#endif
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ * dd_stat field is now int (was short in older versions).
+ */
+typedef struct
+{
+ /* disk transfer area for this dir */
+ struct _finddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /* _findnext handle */
+ INTPTR dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ char dd_name[1];
+} DIR;
+
+DIR* __cdecl opendir (const char*);
+struct dirent* __cdecl readdir (DIR*);
+int __cdecl closedir (DIR*);
+void __cdecl rewinddir (DIR*);
+long __cdecl telldir (DIR*);
+void __cdecl seekdir (DIR*, long);
+
+
+/* wide char versions */
+
+struct _wdirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ wchar_t d_name[FILENAME_MAX]; /* File name. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+typedef struct
+{
+ /* disk transfer area for this dir */
+ struct _wfinddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct _wdirent dd_dir;
+
+ /* _findnext handle */
+ INTPTR dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ int dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ wchar_t dd_name[1];
+} _WDIR;
+
+
+
+_WDIR* __cdecl _wopendir (const wchar_t*);
+struct _wdirent* __cdecl _wreaddir (_WDIR*);
+int __cdecl _wclosedir (_WDIR*);
+void __cdecl _wrewinddir (_WDIR*);
+long __cdecl _wtelldir (_WDIR*);
+void __cdecl _wseekdir (_WDIR*, long);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* Not _DIRENT_H_ */
diff --git a/desmume/src/windows/glib-2.20.1/build/dirent/wdirent.c b/desmume/src/windows/glib-2.20.1/build/dirent/wdirent.c
new file mode 100644
index 000000000..098d8542e
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/dirent/wdirent.c
@@ -0,0 +1,3 @@
+#define _UNICODE 1
+#define UNICODE 1
+#include "dirent.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/config.h b/desmume/src/windows/glib-2.20.1/build/glib/config.h
new file mode 100644
index 000000000..cd2ca555d
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/config.h
@@ -0,0 +1,742 @@
+/* config.h.win32.in Merged from two versions generated by configure for gcc and MSVC. */
+/* config.h. Generated by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+
+/* define if asm blocks can use numeric local labels */
+/* #undef ASM_NUMERIC_LABELS */
+
+/* poll doesn't work on devices */
+#define BROKEN_POLL 1
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Whether to disable memory pools */
+/* #undef DISABLE_MEM_POOLS */
+
+/* Whether to enable GC friendliness by default */
+/* #undef ENABLE_GC_FRIENDLY_DEFAULT */
+
+/* always defined to indicate that i18n is enabled */
+#define ENABLE_NLS 1
+
+/* Define the gettext package to be used */
+#define GETTEXT_PACKAGE "glib20"
+
+/* Define to the GLIB binary age */
+#define GLIB_BINARY_AGE 2001
+
+/* Byte contents of gmutex */
+/* #undef GLIB_BYTE_CONTENTS_GMUTEX */
+
+/* Define to the GLIB interface age */
+#define GLIB_INTERFACE_AGE 1
+
+/* Define the location where the catalogs will be installed */
+#define GLIB_LOCALE_DIR "NONE/share/locale"
+
+/* Define to the GLIB major version */
+#define GLIB_MAJOR_VERSION 2
+
+/* Define to the GLIB micro version */
+#define GLIB_MICRO_VERSION 1
+
+/* Define to the GLIB minor version */
+#define GLIB_MINOR_VERSION 20
+
+/* The size of gmutex, as computed by sizeof. */
+/* #undef GLIB_SIZEOF_GMUTEX */
+
+/* The size of system_thread, as computed by sizeof. */
+#define GLIB_SIZEOF_SYSTEM_THREAD 4
+
+/* alpha atomic implementation */
+/* #undef G_ATOMIC_ALPHA */
+
+/* arm atomic implementation */
+/* #undef G_ATOMIC_ARM */
+
+/* i486 atomic implementation */
+#ifndef _MSC_VER
+#define G_ATOMIC_I486 1
+#endif /* _MSC_VER */
+
+/* ia64 atomic implementation */
+/* #undef G_ATOMIC_IA64 */
+
+/* powerpc atomic implementation */
+/* #undef G_ATOMIC_POWERPC */
+
+/* s390 atomic implementation */
+/* #undef G_ATOMIC_S390 */
+
+/* sparcv9 atomic implementation */
+/* #undef G_ATOMIC_SPARCV9 */
+
+/* x86_64 atomic implementation */
+/* #undef G_ATOMIC_X86_64 */
+
+/* Have inline keyword */
+#ifndef _MSC_VER
+#define G_HAVE_INLINE 1
+#else /* _MSC_VER */
+/* #undef G_HAVE_INLINE */
+#endif /* _MSC_VER */
+
+/* Have __inline keyword */
+#define G_HAVE___INLINE 1
+
+/* Have __inline__ keyword */
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define G_HAVE___INLINE__ 1
+#else /* _MSC_VER or __DMC__ */
+/* #undef G_HAVE___INLINE__ */
+#endif /* _MSC_VER or __DMC__ */
+
+/* Source file containing theread implementation */
+#define G_THREAD_SOURCE "gthread-win32.c"
+
+/* A 'va_copy' style function */
+#ifndef _MSC_VER
+#define G_VA_COPY va_copy
+#else /* _MSC_VER */
+/* #undef G_VA_COPY */
+#endif /* _MSC_VER */
+
+/* 'va_lists' cannot be copies as values */
+/* #undef G_VA_COPY_AS_ARRAY */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have and it should be used (not on Ultrix).
+ */
+/* #undef HAVE_ALLOCA_H */
+
+/* Define to 1 if you have the `atexit' function. */
+#define HAVE_ATEXIT 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_ATTR_XATTR_H */
+
+/* Define to 1 if you have the `bind_textdomain_codeset' function. */
+#define HAVE_BIND_TEXTDOMAIN_CODESET 1
+
+/* Define if you have a version of the snprintf function with semantics as
+ specified by the ISO C99 standard. */
+/* #undef HAVE_C99_SNPRINTF */
+
+/* Define if you have a version of the vsnprintf function with semantics as
+ specified by the ISO C99 standard. */
+/* #undef HAVE_C99_VSNPRINTF */
+
+/* define to 1 if Carbon is available */
+/* #undef HAVE_CARBON */
+
+/* Define to 1 if you have the `chown' function. */
+/* #undef HAVE_CHOWN */
+
+/* Define to 1 if you have the `clock_gettime' function. */
+/* #undef HAVE_CLOCK_GETTIME */
+
+/* Have nl_langinfo (CODESET) */
+/* #undef HAVE_CODESET */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_CRT_EXTERNS_H */
+
+/* Define to 1 if you have the `dcgettext' function. */
+#define HAVE_DCGETTEXT 1
+
+/* Define to 1 if you have the header file. */
+#ifndef _MSC_VER
+#define HAVE_DIRENT_H 1
+#else
+/* #undef HAVE_DIRENT_H */
+#endif
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_DLFCN_H */
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* define for working do while(0) macros */
+#define HAVE_DOWHILE_MACROS 1
+
+/* Define to 1 if you have the `endmntent' function. */
+/* #undef HAVE_ENDMNTENT */
+
+/* Define if we have FAM */
+/* #undef HAVE_FAM */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_FAM_H */
+
+/* Define if we have FAMNoExists in fam */
+/* #undef HAVE_FAM_NO_EXISTS */
+
+/* Define to 1 if you have the `fchmod' function. */
+/* #undef HAVE_FCHMOD */
+
+/* Define to 1 if you have the `fchown' function. */
+/* #undef HAVE_FCHOWN */
+
+/* Define to 1 if you have the `fdwalk' function. */
+/* #undef HAVE_FDWALK */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_FSTAB_H */
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getc_unlocked' function. */
+/* #undef HAVE_GETC_UNLOCKED */
+
+/* Define to 1 if you have the `getgrgid' function. */
+/* #undef HAVE_GETGRGID */
+
+/* Define to 1 if you have the `getmntent_r' function. */
+/* #undef HAVE_GETMNTENT_R */
+
+/* Define to 1 if you have the `getmntinfo' function. */
+/* #undef HAVE_GETMNTINFO */
+
+/* Define to 1 if you have the `getpwuid' function. */
+/* #undef HAVE_GETPWUID */
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#define HAVE_GETTEXT 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+/* #undef HAVE_GMTIME_R */
+
+/* define to use system printf */
+/* #undef HAVE_GOOD_PRINTF */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_GRP_H */
+
+/* Define to 1 if you have the `hasmntopt' function. */
+/* #undef HAVE_HASMNTOPT */
+
+/* define to support printing 64-bit integers with format I64 */
+#define HAVE_INT64_AND_I64 1
+
+/* Define if you have the 'intmax_t' type in or . */
+#ifndef _MSC_VER
+#define HAVE_INTMAX_T 1
+#else /* _MSC_VER */
+/* #undef HAVE_INTMAX_T */
+#endif /* _MSC_VER */
+
+/* Define to 1 if you have the header file. */
+#ifndef _MSC_VER
+#define HAVE_INTTYPES_H 1
+#else /* _MSC_VER */
+/* #undef HAVE_INTTYPES_H */
+#endif /* _MSC_VER */
+
+/* Define if exists, doesn't clash with , and
+ declares uintmax_t. */
+#ifndef _MSC_VER
+#define HAVE_INTTYPES_H_WITH_UINTMAX 1
+#else /* _MSC_VER */
+/* #undef HAVE_INTTYPES_H_WITH_UINTMAX */
+#endif /* _MSC_VER */
+
+/* Define if you have and nl_langinfo(CODESET). */
+/* #undef HAVE_LANGINFO_CODESET */
+
+/* Define to 1 if you have the `lchown' function. */
+/* #undef HAVE_LCHOWN */
+
+/* Define if your file defines LC_MESSAGES. */
+/* #undef HAVE_LC_MESSAGES */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `link' function. */
+/* #undef HAVE_LINK */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+/* #undef HAVE_LOCALTIME_R */
+
+/* Define if you have the 'long double' type. */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define if you have the 'long long' type. */
+#ifndef _MSC_VER
+#define HAVE_LONG_LONG 1
+#else /* _MSC_VER */
+/* #undef HAVE_LONG_LONG */
+#endif /* _MSC_VER */
+
+/* define if system printf can print long long */
+#define HAVE_LONG_LONG_FORMAT 1
+
+/* Define to 1 if you have the `lstat' function. */
+/* #undef HAVE_LSTAT */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the `memalign' function. */
+/* #undef HAVE_MEMALIGN */
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' system call. */
+/* #undef HAVE_MMAP */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_MNTENT_H */
+
+/* Have a monotonic clock */
+/* #undef HAVE_MONOTONIC_CLOCK */
+
+/* Define to 1 if you have the `nanosleep' function. */
+/* #undef HAVE_NANOSLEEP */
+
+/* Have non-POSIX function getgrgid_r */
+/* #undef HAVE_NONPOSIX_GETGRGID_R */
+
+/* Have non-POSIX function getpwuid_r */
+/* #undef HAVE_NONPOSIX_GETPWUID_R */
+
+/* Define to 1 if you have the `nsleep' function. */
+/* #undef HAVE_NSLEEP */
+
+/* Define to 1 if you have the `on_exit' function. */
+/* #undef HAVE_ON_EXIT */
+
+/* Define to 1 if you have the `poll' function. */
+/* #undef HAVE_POLL */
+
+/* Have POSIX function getgrgid_r */
+/* #undef HAVE_POSIX_GETGRGID_R */
+
+/* Have POSIX function getpwuid_r */
+/* #undef HAVE_POSIX_GETPWUID_R */
+
+/* Define to 1 if you have the `posix_memalign' function. */
+/* #undef HAVE_POSIX_MEMALIGN */
+
+/* Have function pthread_attr_setstacksize */
+/* #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE */
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#define HAVE_PTRDIFF_T 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_PWD_H */
+
+/* Define to 1 if you have the `readlink' function. */
+/* #undef HAVE_READLINK */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SCHED_H */
+
+/* Define to 1 if libselinux is available */
+/* #undef HAVE_SELINUX */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SELINUX_SELINUX_H */
+
+/* Define to 1 if you have the `setenv' function. */
+/* #undef HAVE_SETENV */
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmntent' function. */
+/* #undef HAVE_SETMNTENT */
+
+/* Define to 1 if you have the `snprintf' function. */
+#ifndef _MSC_VER
+#define HAVE_SNPRINTF 1
+#ifdef __DMC__
+#define snprintf _snprintf
+#endif
+#else /* _MSC_VER */
+/* #undef HAVE_SNPRINTF */
+#endif /* _MSC_VER */
+
+/* Define to 1 if you have the `statfs' function. */
+/* #undef HAVE_STATFS */
+
+/* Define to 1 if you have the `statvfs' function. */
+/* #undef HAVE_STATVFS */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the header file. */
+#ifndef _MSC_VER
+#define HAVE_STDINT_H 1
+#else /* _MSC_VER */
+/* #undef HAVE_STDINT_H */
+#endif /* _MSC_VER */
+
+/* Define if exists, doesn't clash with , and
+ declares uintmax_t. */
+#ifndef _MSC_VER
+#define HAVE_STDINT_H_WITH_UINTMAX 1
+#else /* _MSC_VER */
+/* #undef HAVE_STDINT_H_WITH_UINTMAX */
+#endif /* _MSC_VER */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `stpcpy' function. */
+/* #undef HAVE_STPCPY */
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define HAVE_STRCASECMP 1
+#else /* _MSC_VER or __DMC__ */
+/* #undef HAVE_STRCASECMP */
+#endif /* _MSC_VER or __DMC__ */
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the header file. */
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define HAVE_STRINGS_H 1
+#else /* _MSC_VER or __DMC__ */
+/* #undef HAVE_STRINGS_H */
+#endif /* _MSC_VER or __DMC__ */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_STRING_H 1
+
+/* Have functions strlcpy and strlcat */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define HAVE_STRNCASECMP 1
+#else /* _MSC_VER or __DMC__ */
+/* #undef HAVE_STRNCASECMP */
+#endif /* _MSC_VER or __DMC__ */
+
+/* Define to 1 if you have the `strsignal' function. */
+/* #undef HAVE_STRSIGNAL */
+
+/* Define to 1 if `f_bavail' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_BAVAIL */
+
+/* Define to 1 if `f_fstypename' is member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FSTYPENAME */
+
+/* Define to 1 if `f_basetype' is member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_BASETYPE */
+
+/* Define to 1 if `st_atimensec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */
+
+/* Define to 1 if `st_atim.tv_nsec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */
+
+/* Define to 1 if `st_blksize' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_BLKSIZE */
+
+/* Define to 1 if `st_blocks' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_BLOCKS */
+
+/* Define to 1 if `st_ctimensec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_CTIMENSEC */
+
+/* Define to 1 if `st_ctim.tv_nsec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC */
+
+/* Define to 1 if `st_mtimensec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_MTIMENSEC */
+
+/* Define to 1 if `st_mtim.tv_nsec' is member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC */
+
+/* Define to 1 if you have the `symlink' function. */
+/* #undef HAVE_SYMLINK */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_INOTIFY_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_MNTCTL_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_MNTTAB_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_MOUNT_H */
+
+/* Define to 1 if you have the header file. */
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define HAVE_SYS_PARAM_H 1
+#else /* _MSC_VER or __DMC__ */
+/* #undef HAVE_SYS_PARAM_H */
+#endif /* _MSC_VER or __DMC__ */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_RESOURCE_H */
+
+/* found fd_set in sys/select.h */
+/* #undef HAVE_SYS_SELECT_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_STATFS_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_STATVFS_H */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_SYSCTL_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_TIMES_H */
+
+/* Define to 1 if you have the header file. */
+#ifndef _MSC_VER
+#define HAVE_SYS_TIME_H 1
+#else /* _MSC_VER */
+/* #undef HAVE_SYS_TIME_H */
+#endif /* _MSC_VER */
+
+/* Define to 1 if you have the header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_VFSTAB_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_VFS_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_VMOUNT_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_WAIT_H */
+
+/* Define to 1 if you have the header file. */
+/* #undef HAVE_SYS_XATTR_H */
+
+/* Define to 1 if you have the `timegm' function. */
+/* #undef HAVE_TIMEGM */
+
+/* Define to 1 if you have the header file. */
+#ifndef _MSC_VER
+#define HAVE_UNISTD_H 1
+#else /* _MSC_VER */
+/* #undef HAVE_UNISTD_H */
+#endif /* _MSC_VER */
+
+/* Define if your printf function family supports positional parameters as
+ specified by Unix98. */
+/* #undef HAVE_UNIX98_PRINTF */
+
+/* Define to 1 if you have the `unsetenv' function. */
+/* #undef HAVE_UNSETENV */
+
+/* Define to 1 if you have the `utimes' function. */
+/* #undef HAVE_UTIMES */
+
+/* Define to 1 if you have the `valloc' function. */
+/* #undef HAVE_VALLOC */
+
+/* Define to 1 if you have the header file. */
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define HAVE_VALUES_H 1
+#else /* _MSC_VER or __DMC__ */
+/* #undef HAVE_VALUES_H */
+#endif /* _MSC_VER or __DMC__ */
+
+/* Define to 1 if you have the `vasprintf' function. */
+#define HAVE_VASPRINTF 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#ifndef _MSC_VER
+#define HAVE_VSNPRINTF 1
+#ifdef __DMC__
+#define vsnprintf _vsnprintf
+#endif
+#else /* _MSC_VER */
+/* #undef HAVE_VSNPRINTF */
+#endif /* _MSC_VER */
+
+/* Define if you have the 'wchar_t' type. */
+#define HAVE_WCHAR_T 1
+
+/* Define to 1 if you have the `wcslen' function. */
+#define HAVE_WCSLEN 1
+
+/* Define if you have the 'wint_t' type. */
+#define HAVE_WINT_T 1
+
+/* Have a working bcopy */
+/* #undef HAVE_WORKING_BCOPY */
+
+/* Define to 1 if xattr is available */
+/* #undef HAVE_XATTR */
+
+/* Define to 1 if xattr API uses XATTR_NOFOLLOW */
+/* #undef HAVE_XATTR_NOFOLLOW */
+
+/* Define to 1 if you have the `_NSGetEnviron' function. */
+/* #undef HAVE__NSGETENVIRON */
+
+/* Do we cache iconv descriptors */
+#define NEED_ICONV_CACHE 1
+
+/* didn't find fd_set */
+#define NO_FD_SET 1
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* global 'sys_errlist' not found */
+#define NO_SYS_ERRLIST 1
+
+/* global 'sys_siglist' not found */
+#define NO_SYS_SIGLIST 1
+
+/* global 'sys_siglist' not declared */
+#define NO_SYS_SIGLIST_DECL 1
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://bugzilla.gnome.org/enter_bug.cgi?product=glib"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "glib"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "glib 2.20.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "glib"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.20.1"
+
+/* Maximum POSIX RT priority */
+/* #undef POSIX_MAX_PRIORITY */
+
+/* define if posix_memalign() can allocate any size */
+/* #undef POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS */
+
+/* Minimum POSIX RT priority */
+/* #undef POSIX_MIN_PRIORITY */
+
+/* The POSIX RT yield function */
+/* #undef POSIX_YIELD_FUNC */
+
+/* whether realloc (NULL,) works */
+#define REALLOC_0_WORKS 1
+
+/* Define if you have correct malloc prototypes */
+#ifndef _MSC_VER
+#define SANE_MALLOC_PROTOS 1
+#else /* _MSC_VER */
+/* #undef SANE_MALLOC_PROTOS */
+#endif /* _MSC_VER */
+
+/* The size of `char', as computed by sizeof. */
+#define SIZEOF_CHAR 1
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `long long', as computed by sizeof. */
+#ifndef _MSC_VER
+#define SIZEOF_LONG_LONG 8
+#else /* _MSC_VER */
+#define SIZEOF_LONG_LONG 0
+#endif /* _MSC_VER */
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 4
+
+/* The size of `__int64', as computed by sizeof. */
+#define SIZEOF___INT64 8
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Number of arguments to statfs() */
+/* #undef STATFS_ARGS */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Using GNU libiconv */
+/* #undef USE_LIBICONV_GNU */
+
+/* Using a native implementation of iconv in a separate library */
+#define USE_LIBICONV_NATIVE 1
+
+/* using the system-supplied PCRE library */
+/* #undef USE_SYSTEM_PCRE */
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to long or long long if and don't define. */
+/* #undef intmax_t */
+
+/* Define to empty if the C compiler doesn't support this keyword. */
+/* #undef signed */
+
+/* Define to `unsigned int' if does not define. */
+/* #undef size_t */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/galias.h b/desmume/src/windows/glib-2.20.1/build/glib/galias.h
new file mode 100644
index 000000000..9131fa69b
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/galias.h
@@ -0,0 +1,3886 @@
+/* Generated by makegalias.pl */
+
+#ifndef DISABLE_VISIBILITY
+
+#include "glibconfig.h"
+
+#ifdef G_HAVE_GNUC_VISIBILITY
+
+#define IN_FILE(x) 1
+#define IN_HEADER defined
+
+#if IN_HEADER(__G_ARRAY_H__)
+#if IN_FILE(__G_ARRAY_C__)
+extern __typeof (g_array_append_vals) IA__g_array_append_vals __attribute((visibility("hidden")));
+#define g_array_append_vals IA__g_array_append_vals
+
+extern __typeof (g_array_free) IA__g_array_free __attribute((visibility("hidden")));
+#define g_array_free IA__g_array_free
+
+extern __typeof (g_array_insert_vals) IA__g_array_insert_vals __attribute((visibility("hidden")));
+#define g_array_insert_vals IA__g_array_insert_vals
+
+extern __typeof (g_array_new) IA__g_array_new __attribute((visibility("hidden")));
+#define g_array_new IA__g_array_new
+
+extern __typeof (g_array_prepend_vals) IA__g_array_prepend_vals __attribute((visibility("hidden")));
+#define g_array_prepend_vals IA__g_array_prepend_vals
+
+extern __typeof (g_array_remove_index) IA__g_array_remove_index __attribute((visibility("hidden")));
+#define g_array_remove_index IA__g_array_remove_index
+
+extern __typeof (g_array_remove_index_fast) IA__g_array_remove_index_fast __attribute((visibility("hidden")));
+#define g_array_remove_index_fast IA__g_array_remove_index_fast
+
+extern __typeof (g_array_remove_range) IA__g_array_remove_range __attribute((visibility("hidden")));
+#define g_array_remove_range IA__g_array_remove_range
+
+extern __typeof (g_array_set_size) IA__g_array_set_size __attribute((visibility("hidden")));
+#define g_array_set_size IA__g_array_set_size
+
+extern __typeof (g_array_sized_new) IA__g_array_sized_new __attribute((visibility("hidden")));
+#define g_array_sized_new IA__g_array_sized_new
+
+extern __typeof (g_array_sort) IA__g_array_sort __attribute((visibility("hidden")));
+#define g_array_sort IA__g_array_sort
+
+extern __typeof (g_array_sort_with_data) IA__g_array_sort_with_data __attribute((visibility("hidden")));
+#define g_array_sort_with_data IA__g_array_sort_with_data
+
+extern __typeof (g_byte_array_append) IA__g_byte_array_append __attribute((visibility("hidden")));
+#define g_byte_array_append IA__g_byte_array_append
+
+extern __typeof (g_byte_array_free) IA__g_byte_array_free __attribute((visibility("hidden")));
+#define g_byte_array_free IA__g_byte_array_free
+
+extern __typeof (g_byte_array_new) IA__g_byte_array_new __attribute((visibility("hidden")));
+#define g_byte_array_new IA__g_byte_array_new
+
+extern __typeof (g_byte_array_prepend) IA__g_byte_array_prepend __attribute((visibility("hidden")));
+#define g_byte_array_prepend IA__g_byte_array_prepend
+
+extern __typeof (g_byte_array_remove_index) IA__g_byte_array_remove_index __attribute((visibility("hidden")));
+#define g_byte_array_remove_index IA__g_byte_array_remove_index
+
+extern __typeof (g_byte_array_remove_index_fast) IA__g_byte_array_remove_index_fast __attribute((visibility("hidden")));
+#define g_byte_array_remove_index_fast IA__g_byte_array_remove_index_fast
+
+extern __typeof (g_byte_array_remove_range) IA__g_byte_array_remove_range __attribute((visibility("hidden")));
+#define g_byte_array_remove_range IA__g_byte_array_remove_range
+
+extern __typeof (g_byte_array_set_size) IA__g_byte_array_set_size __attribute((visibility("hidden")));
+#define g_byte_array_set_size IA__g_byte_array_set_size
+
+extern __typeof (g_byte_array_sized_new) IA__g_byte_array_sized_new __attribute((visibility("hidden")));
+#define g_byte_array_sized_new IA__g_byte_array_sized_new
+
+extern __typeof (g_byte_array_sort) IA__g_byte_array_sort __attribute((visibility("hidden")));
+#define g_byte_array_sort IA__g_byte_array_sort
+
+extern __typeof (g_byte_array_sort_with_data) IA__g_byte_array_sort_with_data __attribute((visibility("hidden")));
+#define g_byte_array_sort_with_data IA__g_byte_array_sort_with_data
+
+extern __typeof (g_ptr_array_add) IA__g_ptr_array_add __attribute((visibility("hidden")));
+#define g_ptr_array_add IA__g_ptr_array_add
+
+extern __typeof (g_ptr_array_foreach) IA__g_ptr_array_foreach __attribute((visibility("hidden")));
+#define g_ptr_array_foreach IA__g_ptr_array_foreach
+
+extern __typeof (g_ptr_array_free) IA__g_ptr_array_free __attribute((visibility("hidden")));
+#define g_ptr_array_free IA__g_ptr_array_free
+
+extern __typeof (g_ptr_array_new) IA__g_ptr_array_new __attribute((visibility("hidden")));
+#define g_ptr_array_new IA__g_ptr_array_new
+
+extern __typeof (g_ptr_array_remove) IA__g_ptr_array_remove __attribute((visibility("hidden")));
+#define g_ptr_array_remove IA__g_ptr_array_remove
+
+extern __typeof (g_ptr_array_remove_fast) IA__g_ptr_array_remove_fast __attribute((visibility("hidden")));
+#define g_ptr_array_remove_fast IA__g_ptr_array_remove_fast
+
+extern __typeof (g_ptr_array_remove_index) IA__g_ptr_array_remove_index __attribute((visibility("hidden")));
+#define g_ptr_array_remove_index IA__g_ptr_array_remove_index
+
+extern __typeof (g_ptr_array_remove_index_fast) IA__g_ptr_array_remove_index_fast __attribute((visibility("hidden")));
+#define g_ptr_array_remove_index_fast IA__g_ptr_array_remove_index_fast
+
+extern __typeof (g_ptr_array_remove_range) IA__g_ptr_array_remove_range __attribute((visibility("hidden")));
+#define g_ptr_array_remove_range IA__g_ptr_array_remove_range
+
+extern __typeof (g_ptr_array_set_size) IA__g_ptr_array_set_size __attribute((visibility("hidden")));
+#define g_ptr_array_set_size IA__g_ptr_array_set_size
+
+extern __typeof (g_ptr_array_sized_new) IA__g_ptr_array_sized_new __attribute((visibility("hidden")));
+#define g_ptr_array_sized_new IA__g_ptr_array_sized_new
+
+extern __typeof (g_ptr_array_sort) IA__g_ptr_array_sort __attribute((visibility("hidden")));
+#define g_ptr_array_sort IA__g_ptr_array_sort
+
+extern __typeof (g_ptr_array_sort_with_data) IA__g_ptr_array_sort_with_data __attribute((visibility("hidden")));
+#define g_ptr_array_sort_with_data IA__g_ptr_array_sort_with_data
+
+#endif
+#endif
+#if IN_HEADER(__G_ASYNCQUEUE_H__)
+#if IN_FILE(__G_ASYNCQUEUE_C__)
+extern __typeof (g_async_queue_length) IA__g_async_queue_length __attribute((visibility("hidden")));
+#define g_async_queue_length IA__g_async_queue_length
+
+extern __typeof (g_async_queue_length_unlocked) IA__g_async_queue_length_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_length_unlocked IA__g_async_queue_length_unlocked
+
+extern __typeof (g_async_queue_lock) IA__g_async_queue_lock __attribute((visibility("hidden")));
+#define g_async_queue_lock IA__g_async_queue_lock
+
+extern __typeof (g_async_queue_new) IA__g_async_queue_new __attribute((visibility("hidden")));
+#define g_async_queue_new IA__g_async_queue_new
+
+extern __typeof (g_async_queue_new_full) IA__g_async_queue_new_full __attribute((visibility("hidden")));
+#define g_async_queue_new_full IA__g_async_queue_new_full
+
+extern __typeof (g_async_queue_pop) IA__g_async_queue_pop __attribute((visibility("hidden")));
+#define g_async_queue_pop IA__g_async_queue_pop
+
+extern __typeof (g_async_queue_pop_unlocked) IA__g_async_queue_pop_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_pop_unlocked IA__g_async_queue_pop_unlocked
+
+extern __typeof (g_async_queue_push) IA__g_async_queue_push __attribute((visibility("hidden")));
+#define g_async_queue_push IA__g_async_queue_push
+
+extern __typeof (g_async_queue_push_unlocked) IA__g_async_queue_push_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_push_unlocked IA__g_async_queue_push_unlocked
+
+extern __typeof (g_async_queue_push_sorted) IA__g_async_queue_push_sorted __attribute((visibility("hidden")));
+#define g_async_queue_push_sorted IA__g_async_queue_push_sorted
+
+extern __typeof (g_async_queue_push_sorted_unlocked) IA__g_async_queue_push_sorted_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_push_sorted_unlocked IA__g_async_queue_push_sorted_unlocked
+
+extern __typeof (g_async_queue_ref) IA__g_async_queue_ref __attribute((visibility("hidden")));
+#define g_async_queue_ref IA__g_async_queue_ref
+
+extern __typeof (g_async_queue_sort) IA__g_async_queue_sort __attribute((visibility("hidden")));
+#define g_async_queue_sort IA__g_async_queue_sort
+
+extern __typeof (g_async_queue_sort_unlocked) IA__g_async_queue_sort_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_sort_unlocked IA__g_async_queue_sort_unlocked
+
+extern __typeof (g_async_queue_timed_pop) IA__g_async_queue_timed_pop __attribute((visibility("hidden")));
+#define g_async_queue_timed_pop IA__g_async_queue_timed_pop
+
+extern __typeof (g_async_queue_timed_pop_unlocked) IA__g_async_queue_timed_pop_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_timed_pop_unlocked IA__g_async_queue_timed_pop_unlocked
+
+extern __typeof (g_async_queue_try_pop) IA__g_async_queue_try_pop __attribute((visibility("hidden")));
+#define g_async_queue_try_pop IA__g_async_queue_try_pop
+
+extern __typeof (g_async_queue_try_pop_unlocked) IA__g_async_queue_try_pop_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_try_pop_unlocked IA__g_async_queue_try_pop_unlocked
+
+extern __typeof (g_async_queue_unlock) IA__g_async_queue_unlock __attribute((visibility("hidden")));
+#define g_async_queue_unlock IA__g_async_queue_unlock
+
+extern __typeof (g_async_queue_unref) IA__g_async_queue_unref __attribute((visibility("hidden")));
+#define g_async_queue_unref IA__g_async_queue_unref
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_async_queue_ref_unlocked) IA__g_async_queue_ref_unlocked __attribute((visibility("hidden")));
+#define g_async_queue_ref_unlocked IA__g_async_queue_ref_unlocked
+
+extern __typeof (g_async_queue_unref_and_unlock) IA__g_async_queue_unref_and_unlock __attribute((visibility("hidden")));
+#define g_async_queue_unref_and_unlock IA__g_async_queue_unref_and_unlock
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_ATOMIC_H__)
+#if IN_FILE(__G_ATOMIC_C__)
+extern __typeof (g_atomic_int_add) IA__g_atomic_int_add __attribute((visibility("hidden")));
+#define g_atomic_int_add IA__g_atomic_int_add
+
+extern __typeof (g_atomic_int_compare_and_exchange) IA__g_atomic_int_compare_and_exchange __attribute((visibility("hidden")));
+#define g_atomic_int_compare_and_exchange IA__g_atomic_int_compare_and_exchange
+
+extern __typeof (g_atomic_int_exchange_and_add) IA__g_atomic_int_exchange_and_add __attribute((visibility("hidden")));
+#define g_atomic_int_exchange_and_add IA__g_atomic_int_exchange_and_add
+
+extern __typeof (g_atomic_pointer_compare_and_exchange) IA__g_atomic_pointer_compare_and_exchange __attribute((visibility("hidden")));
+#define g_atomic_pointer_compare_and_exchange IA__g_atomic_pointer_compare_and_exchange
+
+#endif
+#endif
+#if IN_HEADER(__G_BACKTRACE_H__)
+#if IN_FILE(__G_BACKTRACE_C__)
+extern __typeof (g_on_error_query) IA__g_on_error_query __attribute((visibility("hidden")));
+#define g_on_error_query IA__g_on_error_query
+
+extern __typeof (g_on_error_stack_trace) IA__g_on_error_stack_trace __attribute((visibility("hidden")));
+#define g_on_error_stack_trace IA__g_on_error_stack_trace
+
+#endif
+#endif
+#if IN_HEADER(__G_BASE64_H__)
+#if IN_FILE(__G_BASE64_C__)
+extern __typeof (g_base64_encode_step) IA__g_base64_encode_step __attribute((visibility("hidden")));
+#define g_base64_encode_step IA__g_base64_encode_step
+
+extern __typeof (g_base64_encode_close) IA__g_base64_encode_close __attribute((visibility("hidden")));
+#define g_base64_encode_close IA__g_base64_encode_close
+
+extern __typeof (g_base64_encode) IA__g_base64_encode __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_base64_encode IA__g_base64_encode
+
+extern __typeof (g_base64_decode_step) IA__g_base64_decode_step __attribute((visibility("hidden")));
+#define g_base64_decode_step IA__g_base64_decode_step
+
+extern __typeof (g_base64_decode) IA__g_base64_decode __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_base64_decode IA__g_base64_decode
+
+extern __typeof (g_base64_decode_inplace) IA__g_base64_decode_inplace __attribute((visibility("hidden")));
+#define g_base64_decode_inplace IA__g_base64_decode_inplace
+
+#endif
+#endif
+#if IN_HEADER(__G_BOOKMARK_FILE_H__)
+#if IN_FILE(__G_BOOKMARK_FILE_C__)
+extern __typeof (g_bookmark_file_error_quark) IA__g_bookmark_file_error_quark __attribute((visibility("hidden")));
+#define g_bookmark_file_error_quark IA__g_bookmark_file_error_quark
+
+extern __typeof (g_bookmark_file_new) IA__g_bookmark_file_new __attribute((visibility("hidden")));
+#define g_bookmark_file_new IA__g_bookmark_file_new
+
+extern __typeof (g_bookmark_file_free) IA__g_bookmark_file_free __attribute((visibility("hidden")));
+#define g_bookmark_file_free IA__g_bookmark_file_free
+
+extern __typeof (g_bookmark_file_load_from_file) IA__g_bookmark_file_load_from_file __attribute((visibility("hidden")));
+#define g_bookmark_file_load_from_file IA__g_bookmark_file_load_from_file
+
+extern __typeof (g_bookmark_file_load_from_data) IA__g_bookmark_file_load_from_data __attribute((visibility("hidden")));
+#define g_bookmark_file_load_from_data IA__g_bookmark_file_load_from_data
+
+extern __typeof (g_bookmark_file_load_from_data_dirs) IA__g_bookmark_file_load_from_data_dirs __attribute((visibility("hidden")));
+#define g_bookmark_file_load_from_data_dirs IA__g_bookmark_file_load_from_data_dirs
+
+extern __typeof (g_bookmark_file_to_data) IA__g_bookmark_file_to_data __attribute((visibility("hidden")));
+#define g_bookmark_file_to_data IA__g_bookmark_file_to_data
+
+extern __typeof (g_bookmark_file_to_file) IA__g_bookmark_file_to_file __attribute((visibility("hidden")));
+#define g_bookmark_file_to_file IA__g_bookmark_file_to_file
+
+extern __typeof (g_bookmark_file_set_title) IA__g_bookmark_file_set_title __attribute((visibility("hidden")));
+#define g_bookmark_file_set_title IA__g_bookmark_file_set_title
+
+extern __typeof (g_bookmark_file_get_title) IA__g_bookmark_file_get_title __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_bookmark_file_get_title IA__g_bookmark_file_get_title
+
+extern __typeof (g_bookmark_file_set_description) IA__g_bookmark_file_set_description __attribute((visibility("hidden")));
+#define g_bookmark_file_set_description IA__g_bookmark_file_set_description
+
+extern __typeof (g_bookmark_file_get_description) IA__g_bookmark_file_get_description __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_bookmark_file_get_description IA__g_bookmark_file_get_description
+
+extern __typeof (g_bookmark_file_set_mime_type) IA__g_bookmark_file_set_mime_type __attribute((visibility("hidden")));
+#define g_bookmark_file_set_mime_type IA__g_bookmark_file_set_mime_type
+
+extern __typeof (g_bookmark_file_get_mime_type) IA__g_bookmark_file_get_mime_type __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_bookmark_file_get_mime_type IA__g_bookmark_file_get_mime_type
+
+extern __typeof (g_bookmark_file_set_groups) IA__g_bookmark_file_set_groups __attribute((visibility("hidden")));
+#define g_bookmark_file_set_groups IA__g_bookmark_file_set_groups
+
+extern __typeof (g_bookmark_file_add_group) IA__g_bookmark_file_add_group __attribute((visibility("hidden")));
+#define g_bookmark_file_add_group IA__g_bookmark_file_add_group
+
+extern __typeof (g_bookmark_file_has_group) IA__g_bookmark_file_has_group __attribute((visibility("hidden")));
+#define g_bookmark_file_has_group IA__g_bookmark_file_has_group
+
+extern __typeof (g_bookmark_file_get_groups) IA__g_bookmark_file_get_groups __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_bookmark_file_get_groups IA__g_bookmark_file_get_groups
+
+extern __typeof (g_bookmark_file_add_application) IA__g_bookmark_file_add_application __attribute((visibility("hidden")));
+#define g_bookmark_file_add_application IA__g_bookmark_file_add_application
+
+extern __typeof (g_bookmark_file_has_application) IA__g_bookmark_file_has_application __attribute((visibility("hidden")));
+#define g_bookmark_file_has_application IA__g_bookmark_file_has_application
+
+extern __typeof (g_bookmark_file_get_applications) IA__g_bookmark_file_get_applications __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_bookmark_file_get_applications IA__g_bookmark_file_get_applications
+
+extern __typeof (g_bookmark_file_set_app_info) IA__g_bookmark_file_set_app_info __attribute((visibility("hidden")));
+#define g_bookmark_file_set_app_info IA__g_bookmark_file_set_app_info
+
+extern __typeof (g_bookmark_file_get_app_info) IA__g_bookmark_file_get_app_info __attribute((visibility("hidden")));
+#define g_bookmark_file_get_app_info IA__g_bookmark_file_get_app_info
+
+extern __typeof (g_bookmark_file_set_is_private) IA__g_bookmark_file_set_is_private __attribute((visibility("hidden")));
+#define g_bookmark_file_set_is_private IA__g_bookmark_file_set_is_private
+
+extern __typeof (g_bookmark_file_get_is_private) IA__g_bookmark_file_get_is_private __attribute((visibility("hidden")));
+#define g_bookmark_file_get_is_private IA__g_bookmark_file_get_is_private
+
+extern __typeof (g_bookmark_file_set_icon) IA__g_bookmark_file_set_icon __attribute((visibility("hidden")));
+#define g_bookmark_file_set_icon IA__g_bookmark_file_set_icon
+
+extern __typeof (g_bookmark_file_get_icon) IA__g_bookmark_file_get_icon __attribute((visibility("hidden")));
+#define g_bookmark_file_get_icon IA__g_bookmark_file_get_icon
+
+extern __typeof (g_bookmark_file_set_added) IA__g_bookmark_file_set_added __attribute((visibility("hidden")));
+#define g_bookmark_file_set_added IA__g_bookmark_file_set_added
+
+extern __typeof (g_bookmark_file_get_added) IA__g_bookmark_file_get_added __attribute((visibility("hidden")));
+#define g_bookmark_file_get_added IA__g_bookmark_file_get_added
+
+extern __typeof (g_bookmark_file_set_modified) IA__g_bookmark_file_set_modified __attribute((visibility("hidden")));
+#define g_bookmark_file_set_modified IA__g_bookmark_file_set_modified
+
+extern __typeof (g_bookmark_file_get_modified) IA__g_bookmark_file_get_modified __attribute((visibility("hidden")));
+#define g_bookmark_file_get_modified IA__g_bookmark_file_get_modified
+
+extern __typeof (g_bookmark_file_set_visited) IA__g_bookmark_file_set_visited __attribute((visibility("hidden")));
+#define g_bookmark_file_set_visited IA__g_bookmark_file_set_visited
+
+extern __typeof (g_bookmark_file_get_visited) IA__g_bookmark_file_get_visited __attribute((visibility("hidden")));
+#define g_bookmark_file_get_visited IA__g_bookmark_file_get_visited
+
+extern __typeof (g_bookmark_file_has_item) IA__g_bookmark_file_has_item __attribute((visibility("hidden")));
+#define g_bookmark_file_has_item IA__g_bookmark_file_has_item
+
+extern __typeof (g_bookmark_file_get_size) IA__g_bookmark_file_get_size __attribute((visibility("hidden")));
+#define g_bookmark_file_get_size IA__g_bookmark_file_get_size
+
+extern __typeof (g_bookmark_file_get_uris) IA__g_bookmark_file_get_uris __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_bookmark_file_get_uris IA__g_bookmark_file_get_uris
+
+extern __typeof (g_bookmark_file_remove_group) IA__g_bookmark_file_remove_group __attribute((visibility("hidden")));
+#define g_bookmark_file_remove_group IA__g_bookmark_file_remove_group
+
+extern __typeof (g_bookmark_file_remove_application) IA__g_bookmark_file_remove_application __attribute((visibility("hidden")));
+#define g_bookmark_file_remove_application IA__g_bookmark_file_remove_application
+
+extern __typeof (g_bookmark_file_remove_item) IA__g_bookmark_file_remove_item __attribute((visibility("hidden")));
+#define g_bookmark_file_remove_item IA__g_bookmark_file_remove_item
+
+extern __typeof (g_bookmark_file_move_item) IA__g_bookmark_file_move_item __attribute((visibility("hidden")));
+#define g_bookmark_file_move_item IA__g_bookmark_file_move_item
+
+#endif
+#endif
+#if IN_HEADER(__G_CACHE_H__)
+#if IN_FILE(__G_CACHE_C__)
+extern __typeof (g_cache_destroy) IA__g_cache_destroy __attribute((visibility("hidden")));
+#define g_cache_destroy IA__g_cache_destroy
+
+extern __typeof (g_cache_insert) IA__g_cache_insert __attribute((visibility("hidden")));
+#define g_cache_insert IA__g_cache_insert
+
+extern __typeof (g_cache_key_foreach) IA__g_cache_key_foreach __attribute((visibility("hidden")));
+#define g_cache_key_foreach IA__g_cache_key_foreach
+
+extern __typeof (g_cache_new) IA__g_cache_new __attribute((visibility("hidden")));
+#define g_cache_new IA__g_cache_new
+
+extern __typeof (g_cache_remove) IA__g_cache_remove __attribute((visibility("hidden")));
+#define g_cache_remove IA__g_cache_remove
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_cache_value_foreach) IA__g_cache_value_foreach __attribute((visibility("hidden")));
+#define g_cache_value_foreach IA__g_cache_value_foreach
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_CHECKSUM_H__)
+#if IN_FILE(__G_CHECKSUM_C__)
+extern __typeof (g_checksum_type_get_length) IA__g_checksum_type_get_length __attribute((visibility("hidden")));
+#define g_checksum_type_get_length IA__g_checksum_type_get_length
+
+extern __typeof (g_checksum_new) IA__g_checksum_new __attribute((visibility("hidden")));
+#define g_checksum_new IA__g_checksum_new
+
+extern __typeof (g_checksum_copy) IA__g_checksum_copy __attribute((visibility("hidden")));
+#define g_checksum_copy IA__g_checksum_copy
+
+extern __typeof (g_checksum_free) IA__g_checksum_free __attribute((visibility("hidden")));
+#define g_checksum_free IA__g_checksum_free
+
+extern __typeof (g_checksum_update) IA__g_checksum_update __attribute((visibility("hidden")));
+#define g_checksum_update IA__g_checksum_update
+
+extern __typeof (g_checksum_reset) IA__g_checksum_reset __attribute((visibility("hidden")));
+#define g_checksum_reset IA__g_checksum_reset
+
+extern __typeof (g_checksum_get_string) IA__g_checksum_get_string __attribute((visibility("hidden")));
+#define g_checksum_get_string IA__g_checksum_get_string
+
+extern __typeof (g_checksum_get_digest) IA__g_checksum_get_digest __attribute((visibility("hidden")));
+#define g_checksum_get_digest IA__g_checksum_get_digest
+
+extern __typeof (g_compute_checksum_for_data) IA__g_compute_checksum_for_data __attribute((visibility("hidden")));
+#define g_compute_checksum_for_data IA__g_compute_checksum_for_data
+
+extern __typeof (g_compute_checksum_for_string) IA__g_compute_checksum_for_string __attribute((visibility("hidden")));
+#define g_compute_checksum_for_string IA__g_compute_checksum_for_string
+
+#endif
+#endif
+#if IN_HEADER(__G_COMPLETION_H__)
+#if IN_FILE(__G_COMPLETION_C__)
+extern __typeof (g_completion_add_items) IA__g_completion_add_items __attribute((visibility("hidden")));
+#define g_completion_add_items IA__g_completion_add_items
+
+extern __typeof (g_completion_clear_items) IA__g_completion_clear_items __attribute((visibility("hidden")));
+#define g_completion_clear_items IA__g_completion_clear_items
+
+extern __typeof (g_completion_complete) IA__g_completion_complete __attribute((visibility("hidden")));
+#define g_completion_complete IA__g_completion_complete
+
+extern __typeof (g_completion_complete_utf8) IA__g_completion_complete_utf8 __attribute((visibility("hidden")));
+#define g_completion_complete_utf8 IA__g_completion_complete_utf8
+
+extern __typeof (g_completion_free) IA__g_completion_free __attribute((visibility("hidden")));
+#define g_completion_free IA__g_completion_free
+
+extern __typeof (g_completion_new) IA__g_completion_new __attribute((visibility("hidden")));
+#define g_completion_new IA__g_completion_new
+
+extern __typeof (g_completion_remove_items) IA__g_completion_remove_items __attribute((visibility("hidden")));
+#define g_completion_remove_items IA__g_completion_remove_items
+
+extern __typeof (g_completion_set_compare) IA__g_completion_set_compare __attribute((visibility("hidden")));
+#define g_completion_set_compare IA__g_completion_set_compare
+
+#endif
+#endif
+#if IN_HEADER(__G_CONVERT_H__)
+#if IN_FILE(__G_CONVERT_C__)
+extern __typeof (g_get_filename_charsets) IA__g_get_filename_charsets __attribute((visibility("hidden")));
+#define g_get_filename_charsets IA__g_get_filename_charsets
+
+extern __typeof (g_convert) IA__g_convert __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_convert IA__g_convert
+
+extern __typeof (g_convert_error_quark) IA__g_convert_error_quark __attribute((visibility("hidden")));
+#define g_convert_error_quark IA__g_convert_error_quark
+
+extern __typeof (g_convert_with_fallback) IA__g_convert_with_fallback __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_convert_with_fallback IA__g_convert_with_fallback
+
+extern __typeof (g_convert_with_iconv) IA__g_convert_with_iconv __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_convert_with_iconv IA__g_convert_with_iconv
+
+extern __typeof (g_iconv) IA__g_iconv __attribute((visibility("hidden")));
+#define g_iconv IA__g_iconv
+
+extern __typeof (g_iconv_close) IA__g_iconv_close __attribute((visibility("hidden")));
+#define g_iconv_close IA__g_iconv_close
+
+extern __typeof (g_iconv_open) IA__g_iconv_open __attribute((visibility("hidden")));
+#define g_iconv_open IA__g_iconv_open
+
+extern __typeof (g_locale_from_utf8) IA__g_locale_from_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_locale_from_utf8 IA__g_locale_from_utf8
+
+extern __typeof (g_locale_to_utf8) IA__g_locale_to_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_locale_to_utf8 IA__g_locale_to_utf8
+
+extern __typeof (g_filename_display_name) IA__g_filename_display_name __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_display_name IA__g_filename_display_name
+
+extern __typeof (g_filename_display_basename) IA__g_filename_display_basename __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_display_basename IA__g_filename_display_basename
+
+#ifndef _WIN64
+extern __typeof (g_filename_from_uri) IA__g_filename_from_uri __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_from_uri IA__g_filename_from_uri
+
+extern __typeof (g_filename_from_utf8) IA__g_filename_from_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_from_utf8 IA__g_filename_from_utf8
+
+extern __typeof (g_filename_to_uri) IA__g_filename_to_uri __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_to_uri IA__g_filename_to_uri
+
+extern __typeof (g_filename_to_utf8) IA__g_filename_to_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_to_utf8 IA__g_filename_to_utf8
+
+#endif
+#ifdef G_OS_WIN32
+extern __typeof (g_filename_from_uri_utf8) IA__g_filename_from_uri_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_from_uri_utf8 IA__g_filename_from_uri_utf8
+
+extern __typeof (g_filename_from_utf8_utf8) IA__g_filename_from_utf8_utf8 __attribute((visibility("hidden")));
+#define g_filename_from_utf8_utf8 IA__g_filename_from_utf8_utf8
+
+extern __typeof (g_filename_to_uri_utf8) IA__g_filename_to_uri_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_filename_to_uri_utf8 IA__g_filename_to_uri_utf8
+
+extern __typeof (g_filename_to_utf8_utf8) IA__g_filename_to_utf8_utf8 __attribute((visibility("hidden")));
+#define g_filename_to_utf8_utf8 IA__g_filename_to_utf8_utf8
+
+#endif
+extern __typeof (g_uri_list_extract_uris) IA__g_uri_list_extract_uris __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_uri_list_extract_uris IA__g_uri_list_extract_uris
+
+#endif
+#endif
+#if IN_HEADER(__G_DATASET_H__)
+#if IN_FILE(__G_DATASET_C__)
+extern __typeof (g_datalist_clear) IA__g_datalist_clear __attribute((visibility("hidden")));
+#define g_datalist_clear IA__g_datalist_clear
+
+extern __typeof (g_datalist_foreach) IA__g_datalist_foreach __attribute((visibility("hidden")));
+#define g_datalist_foreach IA__g_datalist_foreach
+
+extern __typeof (g_datalist_get_flags) IA__g_datalist_get_flags __attribute((visibility("hidden")));
+#define g_datalist_get_flags IA__g_datalist_get_flags
+
+extern __typeof (g_datalist_id_get_data) IA__g_datalist_id_get_data __attribute((visibility("hidden")));
+#define g_datalist_id_get_data IA__g_datalist_id_get_data
+
+extern __typeof (g_datalist_id_remove_no_notify) IA__g_datalist_id_remove_no_notify __attribute((visibility("hidden")));
+#define g_datalist_id_remove_no_notify IA__g_datalist_id_remove_no_notify
+
+extern __typeof (g_datalist_id_set_data_full) IA__g_datalist_id_set_data_full __attribute((visibility("hidden")));
+#define g_datalist_id_set_data_full IA__g_datalist_id_set_data_full
+
+extern __typeof (g_datalist_set_flags) IA__g_datalist_set_flags __attribute((visibility("hidden")));
+#define g_datalist_set_flags IA__g_datalist_set_flags
+
+extern __typeof (g_datalist_unset_flags) IA__g_datalist_unset_flags __attribute((visibility("hidden")));
+#define g_datalist_unset_flags IA__g_datalist_unset_flags
+
+extern __typeof (g_datalist_init) IA__g_datalist_init __attribute((visibility("hidden")));
+#define g_datalist_init IA__g_datalist_init
+
+extern __typeof (g_dataset_destroy) IA__g_dataset_destroy __attribute((visibility("hidden")));
+#define g_dataset_destroy IA__g_dataset_destroy
+
+extern __typeof (g_dataset_foreach) IA__g_dataset_foreach __attribute((visibility("hidden")));
+#define g_dataset_foreach IA__g_dataset_foreach
+
+extern __typeof (g_dataset_id_get_data) IA__g_dataset_id_get_data __attribute((visibility("hidden")));
+#define g_dataset_id_get_data IA__g_dataset_id_get_data
+
+extern __typeof (g_dataset_id_remove_no_notify) IA__g_dataset_id_remove_no_notify __attribute((visibility("hidden")));
+#define g_dataset_id_remove_no_notify IA__g_dataset_id_remove_no_notify
+
+extern __typeof (g_dataset_id_set_data_full) IA__g_dataset_id_set_data_full __attribute((visibility("hidden")));
+#define g_dataset_id_set_data_full IA__g_dataset_id_set_data_full
+
+#endif
+#endif
+#if IN_HEADER(__G_QUARK_H__)
+#if IN_FILE(__G_DATASET_C__)
+extern __typeof (g_quark_from_static_string) IA__g_quark_from_static_string __attribute((visibility("hidden")));
+#define g_quark_from_static_string IA__g_quark_from_static_string
+
+extern __typeof (g_quark_from_string) IA__g_quark_from_string __attribute((visibility("hidden")));
+#define g_quark_from_string IA__g_quark_from_string
+
+extern __typeof (g_quark_to_string) IA__g_quark_to_string __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_quark_to_string IA__g_quark_to_string
+
+extern __typeof (g_quark_try_string) IA__g_quark_try_string __attribute((visibility("hidden")));
+#define g_quark_try_string IA__g_quark_try_string
+
+extern __typeof (g_intern_string) IA__g_intern_string __attribute((visibility("hidden")));
+#define g_intern_string IA__g_intern_string
+
+extern __typeof (g_intern_static_string) IA__g_intern_static_string __attribute((visibility("hidden")));
+#define g_intern_static_string IA__g_intern_static_string
+
+#endif
+#endif
+#if IN_HEADER(__G_DATE_H__)
+#if IN_FILE(__G_DATE_C__)
+extern __typeof (g_date_add_days) IA__g_date_add_days __attribute((visibility("hidden")));
+#define g_date_add_days IA__g_date_add_days
+
+extern __typeof (g_date_add_months) IA__g_date_add_months __attribute((visibility("hidden")));
+#define g_date_add_months IA__g_date_add_months
+
+extern __typeof (g_date_add_years) IA__g_date_add_years __attribute((visibility("hidden")));
+#define g_date_add_years IA__g_date_add_years
+
+extern __typeof (g_date_clamp) IA__g_date_clamp __attribute((visibility("hidden")));
+#define g_date_clamp IA__g_date_clamp
+
+extern __typeof (g_date_clear) IA__g_date_clear __attribute((visibility("hidden")));
+#define g_date_clear IA__g_date_clear
+
+extern __typeof (g_date_compare) IA__g_date_compare __attribute((visibility("hidden")));
+#define g_date_compare IA__g_date_compare
+
+extern __typeof (g_date_days_between) IA__g_date_days_between __attribute((visibility("hidden")));
+#define g_date_days_between IA__g_date_days_between
+
+extern __typeof (g_date_free) IA__g_date_free __attribute((visibility("hidden")));
+#define g_date_free IA__g_date_free
+
+extern __typeof (g_date_get_day) IA__g_date_get_day __attribute((visibility("hidden")));
+#define g_date_get_day IA__g_date_get_day
+
+extern __typeof (g_date_get_day_of_year) IA__g_date_get_day_of_year __attribute((visibility("hidden")));
+#define g_date_get_day_of_year IA__g_date_get_day_of_year
+
+extern __typeof (g_date_get_days_in_month) IA__g_date_get_days_in_month __attribute((visibility("hidden")));
+#define g_date_get_days_in_month IA__g_date_get_days_in_month
+
+extern __typeof (g_date_get_iso8601_week_of_year) IA__g_date_get_iso8601_week_of_year __attribute((visibility("hidden")));
+#define g_date_get_iso8601_week_of_year IA__g_date_get_iso8601_week_of_year
+
+extern __typeof (g_date_get_julian) IA__g_date_get_julian __attribute((visibility("hidden")));
+#define g_date_get_julian IA__g_date_get_julian
+
+extern __typeof (g_date_get_monday_week_of_year) IA__g_date_get_monday_week_of_year __attribute((visibility("hidden")));
+#define g_date_get_monday_week_of_year IA__g_date_get_monday_week_of_year
+
+extern __typeof (g_date_get_monday_weeks_in_year) IA__g_date_get_monday_weeks_in_year __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_get_monday_weeks_in_year IA__g_date_get_monday_weeks_in_year
+
+extern __typeof (g_date_get_month) IA__g_date_get_month __attribute((visibility("hidden")));
+#define g_date_get_month IA__g_date_get_month
+
+extern __typeof (g_date_get_sunday_week_of_year) IA__g_date_get_sunday_week_of_year __attribute((visibility("hidden")));
+#define g_date_get_sunday_week_of_year IA__g_date_get_sunday_week_of_year
+
+extern __typeof (g_date_get_sunday_weeks_in_year) IA__g_date_get_sunday_weeks_in_year __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_get_sunday_weeks_in_year IA__g_date_get_sunday_weeks_in_year
+
+extern __typeof (g_date_get_weekday) IA__g_date_get_weekday __attribute((visibility("hidden")));
+#define g_date_get_weekday IA__g_date_get_weekday
+
+extern __typeof (g_date_get_year) IA__g_date_get_year __attribute((visibility("hidden")));
+#define g_date_get_year IA__g_date_get_year
+
+extern __typeof (g_date_is_first_of_month) IA__g_date_is_first_of_month __attribute((visibility("hidden")));
+#define g_date_is_first_of_month IA__g_date_is_first_of_month
+
+extern __typeof (g_date_is_last_of_month) IA__g_date_is_last_of_month __attribute((visibility("hidden")));
+#define g_date_is_last_of_month IA__g_date_is_last_of_month
+
+extern __typeof (g_date_is_leap_year) IA__g_date_is_leap_year __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_is_leap_year IA__g_date_is_leap_year
+
+extern __typeof (g_date_new) IA__g_date_new __attribute((visibility("hidden")));
+#define g_date_new IA__g_date_new
+
+extern __typeof (g_date_new_dmy) IA__g_date_new_dmy __attribute((visibility("hidden")));
+#define g_date_new_dmy IA__g_date_new_dmy
+
+extern __typeof (g_date_new_julian) IA__g_date_new_julian __attribute((visibility("hidden")));
+#define g_date_new_julian IA__g_date_new_julian
+
+extern __typeof (g_date_order) IA__g_date_order __attribute((visibility("hidden")));
+#define g_date_order IA__g_date_order
+
+extern __typeof (g_date_set_day) IA__g_date_set_day __attribute((visibility("hidden")));
+#define g_date_set_day IA__g_date_set_day
+
+extern __typeof (g_date_set_dmy) IA__g_date_set_dmy __attribute((visibility("hidden")));
+#define g_date_set_dmy IA__g_date_set_dmy
+
+extern __typeof (g_date_set_julian) IA__g_date_set_julian __attribute((visibility("hidden")));
+#define g_date_set_julian IA__g_date_set_julian
+
+extern __typeof (g_date_set_month) IA__g_date_set_month __attribute((visibility("hidden")));
+#define g_date_set_month IA__g_date_set_month
+
+extern __typeof (g_date_set_parse) IA__g_date_set_parse __attribute((visibility("hidden")));
+#define g_date_set_parse IA__g_date_set_parse
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_date_set_time) IA__g_date_set_time __attribute((visibility("hidden")));
+#define g_date_set_time IA__g_date_set_time
+
+#endif
+extern __typeof (g_date_set_time_t) IA__g_date_set_time_t __attribute((visibility("hidden")));
+#define g_date_set_time_t IA__g_date_set_time_t
+
+extern __typeof (g_date_set_time_val) IA__g_date_set_time_val __attribute((visibility("hidden")));
+#define g_date_set_time_val IA__g_date_set_time_val
+
+extern __typeof (g_date_set_year) IA__g_date_set_year __attribute((visibility("hidden")));
+#define g_date_set_year IA__g_date_set_year
+
+extern __typeof (g_date_strftime) IA__g_date_strftime __attribute((visibility("hidden")));
+#define g_date_strftime IA__g_date_strftime
+
+extern __typeof (g_date_subtract_days) IA__g_date_subtract_days __attribute((visibility("hidden")));
+#define g_date_subtract_days IA__g_date_subtract_days
+
+extern __typeof (g_date_subtract_months) IA__g_date_subtract_months __attribute((visibility("hidden")));
+#define g_date_subtract_months IA__g_date_subtract_months
+
+extern __typeof (g_date_subtract_years) IA__g_date_subtract_years __attribute((visibility("hidden")));
+#define g_date_subtract_years IA__g_date_subtract_years
+
+extern __typeof (g_date_to_struct_tm) IA__g_date_to_struct_tm __attribute((visibility("hidden")));
+#define g_date_to_struct_tm IA__g_date_to_struct_tm
+
+extern __typeof (g_date_valid) IA__g_date_valid __attribute((visibility("hidden")));
+#define g_date_valid IA__g_date_valid
+
+extern __typeof (g_date_valid_day) IA__g_date_valid_day __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_valid_day IA__g_date_valid_day
+
+extern __typeof (g_date_valid_dmy) IA__g_date_valid_dmy __attribute((visibility("hidden")));
+#define g_date_valid_dmy IA__g_date_valid_dmy
+
+extern __typeof (g_date_valid_julian) IA__g_date_valid_julian __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_valid_julian IA__g_date_valid_julian
+
+extern __typeof (g_date_valid_month) IA__g_date_valid_month __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_valid_month IA__g_date_valid_month
+
+extern __typeof (g_date_valid_weekday) IA__g_date_valid_weekday __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_valid_weekday IA__g_date_valid_weekday
+
+extern __typeof (g_date_valid_year) IA__g_date_valid_year __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_date_valid_year IA__g_date_valid_year
+
+#endif
+#endif
+#if IN_HEADER(__G_DIR_H__)
+#if IN_FILE(__G_DIR_C__)
+extern __typeof (g_dir_close) IA__g_dir_close __attribute((visibility("hidden")));
+#define g_dir_close IA__g_dir_close
+
+#ifndef _WIN64
+extern __typeof (g_dir_open) IA__g_dir_open __attribute((visibility("hidden")));
+#define g_dir_open IA__g_dir_open
+
+extern __typeof (g_dir_read_name) IA__g_dir_read_name __attribute((visibility("hidden")));
+#define g_dir_read_name IA__g_dir_read_name
+
+#endif
+#ifdef G_OS_WIN32
+extern __typeof (g_dir_open_utf8) IA__g_dir_open_utf8 __attribute((visibility("hidden")));
+#define g_dir_open_utf8 IA__g_dir_open_utf8
+
+extern __typeof (g_dir_read_name_utf8) IA__g_dir_read_name_utf8 __attribute((visibility("hidden")));
+#define g_dir_read_name_utf8 IA__g_dir_read_name_utf8
+
+#endif
+extern __typeof (g_dir_rewind) IA__g_dir_rewind __attribute((visibility("hidden")));
+#define g_dir_rewind IA__g_dir_rewind
+
+#endif
+#endif
+#if IN_HEADER(__G_ERROR_H__)
+#if IN_FILE(__G_ERROR_C__)
+extern __typeof (g_clear_error) IA__g_clear_error __attribute((visibility("hidden")));
+#define g_clear_error IA__g_clear_error
+
+extern __typeof (g_error_copy) IA__g_error_copy __attribute((visibility("hidden")));
+#define g_error_copy IA__g_error_copy
+
+extern __typeof (g_error_free) IA__g_error_free __attribute((visibility("hidden")));
+#define g_error_free IA__g_error_free
+
+extern __typeof (g_error_matches) IA__g_error_matches __attribute((visibility("hidden")));
+#define g_error_matches IA__g_error_matches
+
+extern __typeof (g_error_new) IA__g_error_new __attribute((visibility("hidden"))) G_GNUC_PRINTF(3,4);
+#define g_error_new IA__g_error_new
+
+extern __typeof (g_error_new_literal) IA__g_error_new_literal __attribute((visibility("hidden")));
+#define g_error_new_literal IA__g_error_new_literal
+
+extern __typeof (g_propagate_error) IA__g_propagate_error __attribute((visibility("hidden")));
+#define g_propagate_error IA__g_propagate_error
+
+extern __typeof (g_set_error) IA__g_set_error __attribute((visibility("hidden"))) G_GNUC_PRINTF(4,5);
+#define g_set_error IA__g_set_error
+
+extern __typeof (g_set_error_literal) IA__g_set_error_literal __attribute((visibility("hidden")));
+#define g_set_error_literal IA__g_set_error_literal
+
+extern __typeof (g_prefix_error) IA__g_prefix_error __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_prefix_error IA__g_prefix_error
+
+extern __typeof (g_propagate_prefixed_error) IA__g_propagate_prefixed_error __attribute((visibility("hidden"))) G_GNUC_PRINTF(3,4);
+#define g_propagate_prefixed_error IA__g_propagate_prefixed_error
+
+#endif
+#endif
+#if IN_HEADER(__G_FILEUTILS_H__)
+#if IN_FILE(__G_FILEUTILS_C__)
+extern __typeof (g_build_filename) IA__g_build_filename __attribute((visibility("hidden"))) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+#define g_build_filename IA__g_build_filename
+
+extern __typeof (g_build_filenamev) IA__g_build_filenamev __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_build_filenamev IA__g_build_filenamev
+
+extern __typeof (g_build_path) IA__g_build_path __attribute((visibility("hidden"))) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+#define g_build_path IA__g_build_path
+
+extern __typeof (g_build_pathv) IA__g_build_pathv __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_build_pathv IA__g_build_pathv
+
+extern __typeof (g_file_error_from_errno) IA__g_file_error_from_errno __attribute((visibility("hidden")));
+#define g_file_error_from_errno IA__g_file_error_from_errno
+
+extern __typeof (g_file_error_quark) IA__g_file_error_quark __attribute((visibility("hidden")));
+#define g_file_error_quark IA__g_file_error_quark
+
+#ifndef _WIN64
+extern __typeof (g_file_get_contents) IA__g_file_get_contents __attribute((visibility("hidden")));
+#define g_file_get_contents IA__g_file_get_contents
+
+#endif
+extern __typeof (g_file_set_contents) IA__g_file_set_contents __attribute((visibility("hidden")));
+#define g_file_set_contents IA__g_file_set_contents
+
+#ifndef _WIN64
+extern __typeof (g_file_open_tmp) IA__g_file_open_tmp __attribute((visibility("hidden")));
+#define g_file_open_tmp IA__g_file_open_tmp
+
+extern __typeof (g_file_test) IA__g_file_test __attribute((visibility("hidden")));
+#define g_file_test IA__g_file_test
+
+#endif
+extern __typeof (g_file_read_link) IA__g_file_read_link __attribute((visibility("hidden")));
+#define g_file_read_link IA__g_file_read_link
+
+extern __typeof (g_format_size_for_display) IA__g_format_size_for_display __attribute((visibility("hidden")));
+#define g_format_size_for_display IA__g_format_size_for_display
+
+#ifndef _WIN64
+extern __typeof (g_mkstemp) IA__g_mkstemp __attribute((visibility("hidden")));
+#define g_mkstemp IA__g_mkstemp
+
+#endif
+extern __typeof (g_mkdir_with_parents) IA__g_mkdir_with_parents __attribute((visibility("hidden")));
+#define g_mkdir_with_parents IA__g_mkdir_with_parents
+
+#ifdef G_OS_WIN32
+extern __typeof (g_file_get_contents_utf8) IA__g_file_get_contents_utf8 __attribute((visibility("hidden")));
+#define g_file_get_contents_utf8 IA__g_file_get_contents_utf8
+
+extern __typeof (g_file_open_tmp_utf8) IA__g_file_open_tmp_utf8 __attribute((visibility("hidden")));
+#define g_file_open_tmp_utf8 IA__g_file_open_tmp_utf8
+
+extern __typeof (g_file_test_utf8) IA__g_file_test_utf8 __attribute((visibility("hidden")));
+#define g_file_test_utf8 IA__g_file_test_utf8
+
+extern __typeof (g_mkstemp_utf8) IA__g_mkstemp_utf8 __attribute((visibility("hidden")));
+#define g_mkstemp_utf8 IA__g_mkstemp_utf8
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_HASH_H__)
+#if IN_FILE(__G_HASH_C__)
+extern __typeof (g_hash_table_destroy) IA__g_hash_table_destroy __attribute((visibility("hidden")));
+#define g_hash_table_destroy IA__g_hash_table_destroy
+
+extern __typeof (g_hash_table_unref) IA__g_hash_table_unref __attribute((visibility("hidden")));
+#define g_hash_table_unref IA__g_hash_table_unref
+
+extern __typeof (g_hash_table_ref) IA__g_hash_table_ref __attribute((visibility("hidden")));
+#define g_hash_table_ref IA__g_hash_table_ref
+
+extern __typeof (g_hash_table_find) IA__g_hash_table_find __attribute((visibility("hidden")));
+#define g_hash_table_find IA__g_hash_table_find
+
+extern __typeof (g_hash_table_foreach) IA__g_hash_table_foreach __attribute((visibility("hidden")));
+#define g_hash_table_foreach IA__g_hash_table_foreach
+
+extern __typeof (g_hash_table_foreach_remove) IA__g_hash_table_foreach_remove __attribute((visibility("hidden")));
+#define g_hash_table_foreach_remove IA__g_hash_table_foreach_remove
+
+extern __typeof (g_hash_table_foreach_steal) IA__g_hash_table_foreach_steal __attribute((visibility("hidden")));
+#define g_hash_table_foreach_steal IA__g_hash_table_foreach_steal
+
+extern __typeof (g_hash_table_get_keys) IA__g_hash_table_get_keys __attribute((visibility("hidden")));
+#define g_hash_table_get_keys IA__g_hash_table_get_keys
+
+extern __typeof (g_hash_table_get_values) IA__g_hash_table_get_values __attribute((visibility("hidden")));
+#define g_hash_table_get_values IA__g_hash_table_get_values
+
+extern __typeof (g_hash_table_insert) IA__g_hash_table_insert __attribute((visibility("hidden")));
+#define g_hash_table_insert IA__g_hash_table_insert
+
+extern __typeof (g_hash_table_lookup) IA__g_hash_table_lookup __attribute((visibility("hidden")));
+#define g_hash_table_lookup IA__g_hash_table_lookup
+
+extern __typeof (g_hash_table_lookup_extended) IA__g_hash_table_lookup_extended __attribute((visibility("hidden")));
+#define g_hash_table_lookup_extended IA__g_hash_table_lookup_extended
+
+extern __typeof (g_hash_table_new) IA__g_hash_table_new __attribute((visibility("hidden")));
+#define g_hash_table_new IA__g_hash_table_new
+
+extern __typeof (g_hash_table_new_full) IA__g_hash_table_new_full __attribute((visibility("hidden")));
+#define g_hash_table_new_full IA__g_hash_table_new_full
+
+extern __typeof (g_hash_table_remove) IA__g_hash_table_remove __attribute((visibility("hidden")));
+#define g_hash_table_remove IA__g_hash_table_remove
+
+extern __typeof (g_hash_table_remove_all) IA__g_hash_table_remove_all __attribute((visibility("hidden")));
+#define g_hash_table_remove_all IA__g_hash_table_remove_all
+
+extern __typeof (g_hash_table_replace) IA__g_hash_table_replace __attribute((visibility("hidden")));
+#define g_hash_table_replace IA__g_hash_table_replace
+
+extern __typeof (g_hash_table_size) IA__g_hash_table_size __attribute((visibility("hidden")));
+#define g_hash_table_size IA__g_hash_table_size
+
+extern __typeof (g_hash_table_steal) IA__g_hash_table_steal __attribute((visibility("hidden")));
+#define g_hash_table_steal IA__g_hash_table_steal
+
+extern __typeof (g_hash_table_steal_all) IA__g_hash_table_steal_all __attribute((visibility("hidden")));
+#define g_hash_table_steal_all IA__g_hash_table_steal_all
+
+extern __typeof (g_hash_table_iter_init) IA__g_hash_table_iter_init __attribute((visibility("hidden")));
+#define g_hash_table_iter_init IA__g_hash_table_iter_init
+
+extern __typeof (g_hash_table_iter_next) IA__g_hash_table_iter_next __attribute((visibility("hidden")));
+#define g_hash_table_iter_next IA__g_hash_table_iter_next
+
+extern __typeof (g_hash_table_iter_get_hash_table) IA__g_hash_table_iter_get_hash_table __attribute((visibility("hidden")));
+#define g_hash_table_iter_get_hash_table IA__g_hash_table_iter_get_hash_table
+
+extern __typeof (g_hash_table_iter_remove) IA__g_hash_table_iter_remove __attribute((visibility("hidden")));
+#define g_hash_table_iter_remove IA__g_hash_table_iter_remove
+
+extern __typeof (g_hash_table_iter_steal) IA__g_hash_table_iter_steal __attribute((visibility("hidden")));
+#define g_hash_table_iter_steal IA__g_hash_table_iter_steal
+
+#endif
+#endif
+#if IN_HEADER(__G_HOOK_H__)
+#if IN_FILE(__G_HOOK_C__)
+extern __typeof (g_hook_alloc) IA__g_hook_alloc __attribute((visibility("hidden")));
+#define g_hook_alloc IA__g_hook_alloc
+
+extern __typeof (g_hook_compare_ids) IA__g_hook_compare_ids __attribute((visibility("hidden")));
+#define g_hook_compare_ids IA__g_hook_compare_ids
+
+extern __typeof (g_hook_destroy) IA__g_hook_destroy __attribute((visibility("hidden")));
+#define g_hook_destroy IA__g_hook_destroy
+
+extern __typeof (g_hook_destroy_link) IA__g_hook_destroy_link __attribute((visibility("hidden")));
+#define g_hook_destroy_link IA__g_hook_destroy_link
+
+extern __typeof (g_hook_find) IA__g_hook_find __attribute((visibility("hidden")));
+#define g_hook_find IA__g_hook_find
+
+extern __typeof (g_hook_find_data) IA__g_hook_find_data __attribute((visibility("hidden")));
+#define g_hook_find_data IA__g_hook_find_data
+
+extern __typeof (g_hook_find_func) IA__g_hook_find_func __attribute((visibility("hidden")));
+#define g_hook_find_func IA__g_hook_find_func
+
+extern __typeof (g_hook_find_func_data) IA__g_hook_find_func_data __attribute((visibility("hidden")));
+#define g_hook_find_func_data IA__g_hook_find_func_data
+
+extern __typeof (g_hook_first_valid) IA__g_hook_first_valid __attribute((visibility("hidden")));
+#define g_hook_first_valid IA__g_hook_first_valid
+
+extern __typeof (g_hook_free) IA__g_hook_free __attribute((visibility("hidden")));
+#define g_hook_free IA__g_hook_free
+
+extern __typeof (g_hook_get) IA__g_hook_get __attribute((visibility("hidden")));
+#define g_hook_get IA__g_hook_get
+
+extern __typeof (g_hook_insert_before) IA__g_hook_insert_before __attribute((visibility("hidden")));
+#define g_hook_insert_before IA__g_hook_insert_before
+
+extern __typeof (g_hook_insert_sorted) IA__g_hook_insert_sorted __attribute((visibility("hidden")));
+#define g_hook_insert_sorted IA__g_hook_insert_sorted
+
+extern __typeof (g_hook_list_clear) IA__g_hook_list_clear __attribute((visibility("hidden")));
+#define g_hook_list_clear IA__g_hook_list_clear
+
+extern __typeof (g_hook_list_init) IA__g_hook_list_init __attribute((visibility("hidden")));
+#define g_hook_list_init IA__g_hook_list_init
+
+extern __typeof (g_hook_list_invoke) IA__g_hook_list_invoke __attribute((visibility("hidden")));
+#define g_hook_list_invoke IA__g_hook_list_invoke
+
+extern __typeof (g_hook_list_invoke_check) IA__g_hook_list_invoke_check __attribute((visibility("hidden")));
+#define g_hook_list_invoke_check IA__g_hook_list_invoke_check
+
+extern __typeof (g_hook_list_marshal) IA__g_hook_list_marshal __attribute((visibility("hidden")));
+#define g_hook_list_marshal IA__g_hook_list_marshal
+
+extern __typeof (g_hook_list_marshal_check) IA__g_hook_list_marshal_check __attribute((visibility("hidden")));
+#define g_hook_list_marshal_check IA__g_hook_list_marshal_check
+
+extern __typeof (g_hook_next_valid) IA__g_hook_next_valid __attribute((visibility("hidden")));
+#define g_hook_next_valid IA__g_hook_next_valid
+
+extern __typeof (g_hook_prepend) IA__g_hook_prepend __attribute((visibility("hidden")));
+#define g_hook_prepend IA__g_hook_prepend
+
+extern __typeof (g_hook_ref) IA__g_hook_ref __attribute((visibility("hidden")));
+#define g_hook_ref IA__g_hook_ref
+
+extern __typeof (g_hook_unref) IA__g_hook_unref __attribute((visibility("hidden")));
+#define g_hook_unref IA__g_hook_unref
+
+#endif
+#endif
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IOCHANNEL_C__)
+extern __typeof (g_io_add_watch) IA__g_io_add_watch __attribute((visibility("hidden")));
+#define g_io_add_watch IA__g_io_add_watch
+
+extern __typeof (g_io_add_watch_full) IA__g_io_add_watch_full __attribute((visibility("hidden")));
+#define g_io_add_watch_full IA__g_io_add_watch_full
+
+extern __typeof (g_io_create_watch) IA__g_io_create_watch __attribute((visibility("hidden")));
+#define g_io_create_watch IA__g_io_create_watch
+
+extern __typeof (g_io_channel_error_from_errno) IA__g_io_channel_error_from_errno __attribute((visibility("hidden")));
+#define g_io_channel_error_from_errno IA__g_io_channel_error_from_errno
+
+extern __typeof (g_io_channel_error_quark) IA__g_io_channel_error_quark __attribute((visibility("hidden")));
+#define g_io_channel_error_quark IA__g_io_channel_error_quark
+
+extern __typeof (g_io_channel_flush) IA__g_io_channel_flush __attribute((visibility("hidden")));
+#define g_io_channel_flush IA__g_io_channel_flush
+
+extern __typeof (g_io_channel_get_buffer_condition) IA__g_io_channel_get_buffer_condition __attribute((visibility("hidden")));
+#define g_io_channel_get_buffer_condition IA__g_io_channel_get_buffer_condition
+
+extern __typeof (g_io_channel_get_buffered) IA__g_io_channel_get_buffered __attribute((visibility("hidden")));
+#define g_io_channel_get_buffered IA__g_io_channel_get_buffered
+
+extern __typeof (g_io_channel_get_buffer_size) IA__g_io_channel_get_buffer_size __attribute((visibility("hidden")));
+#define g_io_channel_get_buffer_size IA__g_io_channel_get_buffer_size
+
+extern __typeof (g_io_channel_get_close_on_unref) IA__g_io_channel_get_close_on_unref __attribute((visibility("hidden")));
+#define g_io_channel_get_close_on_unref IA__g_io_channel_get_close_on_unref
+
+extern __typeof (g_io_channel_get_encoding) IA__g_io_channel_get_encoding __attribute((visibility("hidden")));
+#define g_io_channel_get_encoding IA__g_io_channel_get_encoding
+
+extern __typeof (g_io_channel_get_flags) IA__g_io_channel_get_flags __attribute((visibility("hidden")));
+#define g_io_channel_get_flags IA__g_io_channel_get_flags
+
+extern __typeof (g_io_channel_get_line_term) IA__g_io_channel_get_line_term __attribute((visibility("hidden")));
+#define g_io_channel_get_line_term IA__g_io_channel_get_line_term
+
+extern __typeof (g_io_channel_init) IA__g_io_channel_init __attribute((visibility("hidden")));
+#define g_io_channel_init IA__g_io_channel_init
+
+extern __typeof (g_io_channel_read_chars) IA__g_io_channel_read_chars __attribute((visibility("hidden")));
+#define g_io_channel_read_chars IA__g_io_channel_read_chars
+
+extern __typeof (g_io_channel_read_line) IA__g_io_channel_read_line __attribute((visibility("hidden")));
+#define g_io_channel_read_line IA__g_io_channel_read_line
+
+extern __typeof (g_io_channel_read_line_string) IA__g_io_channel_read_line_string __attribute((visibility("hidden")));
+#define g_io_channel_read_line_string IA__g_io_channel_read_line_string
+
+extern __typeof (g_io_channel_read_to_end) IA__g_io_channel_read_to_end __attribute((visibility("hidden")));
+#define g_io_channel_read_to_end IA__g_io_channel_read_to_end
+
+extern __typeof (g_io_channel_read_unichar) IA__g_io_channel_read_unichar __attribute((visibility("hidden")));
+#define g_io_channel_read_unichar IA__g_io_channel_read_unichar
+
+extern __typeof (g_io_channel_ref) IA__g_io_channel_ref __attribute((visibility("hidden")));
+#define g_io_channel_ref IA__g_io_channel_ref
+
+extern __typeof (g_io_channel_seek_position) IA__g_io_channel_seek_position __attribute((visibility("hidden")));
+#define g_io_channel_seek_position IA__g_io_channel_seek_position
+
+extern __typeof (g_io_channel_set_buffered) IA__g_io_channel_set_buffered __attribute((visibility("hidden")));
+#define g_io_channel_set_buffered IA__g_io_channel_set_buffered
+
+extern __typeof (g_io_channel_set_buffer_size) IA__g_io_channel_set_buffer_size __attribute((visibility("hidden")));
+#define g_io_channel_set_buffer_size IA__g_io_channel_set_buffer_size
+
+extern __typeof (g_io_channel_set_close_on_unref) IA__g_io_channel_set_close_on_unref __attribute((visibility("hidden")));
+#define g_io_channel_set_close_on_unref IA__g_io_channel_set_close_on_unref
+
+extern __typeof (g_io_channel_set_encoding) IA__g_io_channel_set_encoding __attribute((visibility("hidden")));
+#define g_io_channel_set_encoding IA__g_io_channel_set_encoding
+
+extern __typeof (g_io_channel_set_flags) IA__g_io_channel_set_flags __attribute((visibility("hidden")));
+#define g_io_channel_set_flags IA__g_io_channel_set_flags
+
+extern __typeof (g_io_channel_set_line_term) IA__g_io_channel_set_line_term __attribute((visibility("hidden")));
+#define g_io_channel_set_line_term IA__g_io_channel_set_line_term
+
+extern __typeof (g_io_channel_shutdown) IA__g_io_channel_shutdown __attribute((visibility("hidden")));
+#define g_io_channel_shutdown IA__g_io_channel_shutdown
+
+extern __typeof (g_io_channel_unref) IA__g_io_channel_unref __attribute((visibility("hidden")));
+#define g_io_channel_unref IA__g_io_channel_unref
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_io_channel_close) IA__g_io_channel_close __attribute((visibility("hidden")));
+#define g_io_channel_close IA__g_io_channel_close
+
+extern __typeof (g_io_channel_read) IA__g_io_channel_read __attribute((visibility("hidden")));
+#define g_io_channel_read IA__g_io_channel_read
+
+extern __typeof (g_io_channel_seek) IA__g_io_channel_seek __attribute((visibility("hidden")));
+#define g_io_channel_seek IA__g_io_channel_seek
+
+extern __typeof (g_io_channel_write) IA__g_io_channel_write __attribute((visibility("hidden")));
+#define g_io_channel_write IA__g_io_channel_write
+
+#endif
+extern __typeof (g_io_channel_write_chars) IA__g_io_channel_write_chars __attribute((visibility("hidden")));
+#define g_io_channel_write_chars IA__g_io_channel_write_chars
+
+extern __typeof (g_io_channel_write_unichar) IA__g_io_channel_write_unichar __attribute((visibility("hidden")));
+#define g_io_channel_write_unichar IA__g_io_channel_write_unichar
+
+#endif
+#endif
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IO_UNIX_C__)
+#ifdef G_OS_UNIX
+extern __typeof (g_io_channel_unix_get_fd) IA__g_io_channel_unix_get_fd __attribute((visibility("hidden")));
+#define g_io_channel_unix_get_fd IA__g_io_channel_unix_get_fd
+
+extern __typeof (g_io_channel_unix_new) IA__g_io_channel_unix_new __attribute((visibility("hidden")));
+#define g_io_channel_unix_new IA__g_io_channel_unix_new
+
+extern __typeof (g_io_channel_new_file) IA__g_io_channel_new_file __attribute((visibility("hidden")));
+#define g_io_channel_new_file IA__g_io_channel_new_file
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IO_WIN32_C__)
+#ifdef G_OS_WIN32
+extern __typeof (g_io_channel_unix_get_fd) IA__g_io_channel_unix_get_fd __attribute((visibility("hidden")));
+#define g_io_channel_unix_get_fd IA__g_io_channel_unix_get_fd
+
+extern __typeof (g_io_channel_unix_new) IA__g_io_channel_unix_new __attribute((visibility("hidden")));
+#define g_io_channel_unix_new IA__g_io_channel_unix_new
+
+#ifndef _WIN64
+extern __typeof (g_io_channel_new_file) IA__g_io_channel_new_file __attribute((visibility("hidden")));
+#define g_io_channel_new_file IA__g_io_channel_new_file
+
+#endif
+extern __typeof (g_io_channel_new_file_utf8) IA__g_io_channel_new_file_utf8 __attribute((visibility("hidden")));
+#define g_io_channel_new_file_utf8 IA__g_io_channel_new_file_utf8
+
+extern __typeof (g_io_channel_win32_get_fd) IA__g_io_channel_win32_get_fd __attribute((visibility("hidden")));
+#define g_io_channel_win32_get_fd IA__g_io_channel_win32_get_fd
+
+extern __typeof (g_io_channel_win32_make_pollfd) IA__g_io_channel_win32_make_pollfd __attribute((visibility("hidden")));
+#define g_io_channel_win32_make_pollfd IA__g_io_channel_win32_make_pollfd
+
+extern __typeof (g_io_channel_win32_new_fd) IA__g_io_channel_win32_new_fd __attribute((visibility("hidden")));
+#define g_io_channel_win32_new_fd IA__g_io_channel_win32_new_fd
+
+extern __typeof (g_io_channel_win32_new_messages) IA__g_io_channel_win32_new_messages __attribute((visibility("hidden")));
+#define g_io_channel_win32_new_messages IA__g_io_channel_win32_new_messages
+
+extern __typeof (g_io_channel_win32_new_socket) IA__g_io_channel_win32_new_socket __attribute((visibility("hidden")));
+#define g_io_channel_win32_new_socket IA__g_io_channel_win32_new_socket
+
+#ifndef _WIN64
+extern __typeof (g_io_channel_win32_new_stream_socket) IA__g_io_channel_win32_new_stream_socket __attribute((visibility("hidden")));
+#define g_io_channel_win32_new_stream_socket IA__g_io_channel_win32_new_stream_socket
+
+#endif
+extern __typeof (g_io_channel_win32_poll) IA__g_io_channel_win32_poll __attribute((visibility("hidden")));
+#define g_io_channel_win32_poll IA__g_io_channel_win32_poll
+
+extern __typeof (g_io_channel_win32_set_debug) IA__g_io_channel_win32_set_debug __attribute((visibility("hidden")));
+#define g_io_channel_win32_set_debug IA__g_io_channel_win32_set_debug
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_KEY_FILE_H__)
+#if IN_FILE(__G_KEY_FILE_C__)
+extern __typeof (g_key_file_error_quark) IA__g_key_file_error_quark __attribute((visibility("hidden")));
+#define g_key_file_error_quark IA__g_key_file_error_quark
+
+extern __typeof (g_key_file_free) IA__g_key_file_free __attribute((visibility("hidden")));
+#define g_key_file_free IA__g_key_file_free
+
+extern __typeof (g_key_file_get_boolean) IA__g_key_file_get_boolean __attribute((visibility("hidden")));
+#define g_key_file_get_boolean IA__g_key_file_get_boolean
+
+extern __typeof (g_key_file_get_boolean_list) IA__g_key_file_get_boolean_list __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_boolean_list IA__g_key_file_get_boolean_list
+
+extern __typeof (g_key_file_get_comment) IA__g_key_file_get_comment __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_comment IA__g_key_file_get_comment
+
+extern __typeof (g_key_file_get_groups) IA__g_key_file_get_groups __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_groups IA__g_key_file_get_groups
+
+extern __typeof (g_key_file_get_double) IA__g_key_file_get_double __attribute((visibility("hidden")));
+#define g_key_file_get_double IA__g_key_file_get_double
+
+extern __typeof (g_key_file_get_double_list) IA__g_key_file_get_double_list __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_double_list IA__g_key_file_get_double_list
+
+extern __typeof (g_key_file_get_integer) IA__g_key_file_get_integer __attribute((visibility("hidden")));
+#define g_key_file_get_integer IA__g_key_file_get_integer
+
+extern __typeof (g_key_file_get_integer_list) IA__g_key_file_get_integer_list __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_integer_list IA__g_key_file_get_integer_list
+
+extern __typeof (g_key_file_get_keys) IA__g_key_file_get_keys __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_keys IA__g_key_file_get_keys
+
+extern __typeof (g_key_file_get_locale_string) IA__g_key_file_get_locale_string __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_locale_string IA__g_key_file_get_locale_string
+
+extern __typeof (g_key_file_get_locale_string_list) IA__g_key_file_get_locale_string_list __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_locale_string_list IA__g_key_file_get_locale_string_list
+
+extern __typeof (g_key_file_get_start_group) IA__g_key_file_get_start_group __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_start_group IA__g_key_file_get_start_group
+
+extern __typeof (g_key_file_get_string) IA__g_key_file_get_string __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_string IA__g_key_file_get_string
+
+extern __typeof (g_key_file_get_string_list) IA__g_key_file_get_string_list __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_string_list IA__g_key_file_get_string_list
+
+extern __typeof (g_key_file_get_value) IA__g_key_file_get_value __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_get_value IA__g_key_file_get_value
+
+extern __typeof (g_key_file_has_group) IA__g_key_file_has_group __attribute((visibility("hidden")));
+#define g_key_file_has_group IA__g_key_file_has_group
+
+extern __typeof (g_key_file_has_key) IA__g_key_file_has_key __attribute((visibility("hidden")));
+#define g_key_file_has_key IA__g_key_file_has_key
+
+extern __typeof (g_key_file_load_from_dirs) IA__g_key_file_load_from_dirs __attribute((visibility("hidden")));
+#define g_key_file_load_from_dirs IA__g_key_file_load_from_dirs
+
+extern __typeof (g_key_file_load_from_data) IA__g_key_file_load_from_data __attribute((visibility("hidden")));
+#define g_key_file_load_from_data IA__g_key_file_load_from_data
+
+extern __typeof (g_key_file_load_from_data_dirs) IA__g_key_file_load_from_data_dirs __attribute((visibility("hidden")));
+#define g_key_file_load_from_data_dirs IA__g_key_file_load_from_data_dirs
+
+extern __typeof (g_key_file_load_from_file) IA__g_key_file_load_from_file __attribute((visibility("hidden")));
+#define g_key_file_load_from_file IA__g_key_file_load_from_file
+
+extern __typeof (g_key_file_new) IA__g_key_file_new __attribute((visibility("hidden")));
+#define g_key_file_new IA__g_key_file_new
+
+extern __typeof (g_key_file_remove_comment) IA__g_key_file_remove_comment __attribute((visibility("hidden")));
+#define g_key_file_remove_comment IA__g_key_file_remove_comment
+
+extern __typeof (g_key_file_remove_group) IA__g_key_file_remove_group __attribute((visibility("hidden")));
+#define g_key_file_remove_group IA__g_key_file_remove_group
+
+extern __typeof (g_key_file_remove_key) IA__g_key_file_remove_key __attribute((visibility("hidden")));
+#define g_key_file_remove_key IA__g_key_file_remove_key
+
+extern __typeof (g_key_file_set_boolean) IA__g_key_file_set_boolean __attribute((visibility("hidden")));
+#define g_key_file_set_boolean IA__g_key_file_set_boolean
+
+extern __typeof (g_key_file_set_boolean_list) IA__g_key_file_set_boolean_list __attribute((visibility("hidden")));
+#define g_key_file_set_boolean_list IA__g_key_file_set_boolean_list
+
+extern __typeof (g_key_file_set_comment) IA__g_key_file_set_comment __attribute((visibility("hidden")));
+#define g_key_file_set_comment IA__g_key_file_set_comment
+
+extern __typeof (g_key_file_set_double) IA__g_key_file_set_double __attribute((visibility("hidden")));
+#define g_key_file_set_double IA__g_key_file_set_double
+
+extern __typeof (g_key_file_set_double_list) IA__g_key_file_set_double_list __attribute((visibility("hidden")));
+#define g_key_file_set_double_list IA__g_key_file_set_double_list
+
+extern __typeof (g_key_file_set_integer) IA__g_key_file_set_integer __attribute((visibility("hidden")));
+#define g_key_file_set_integer IA__g_key_file_set_integer
+
+extern __typeof (g_key_file_set_integer_list) IA__g_key_file_set_integer_list __attribute((visibility("hidden")));
+#define g_key_file_set_integer_list IA__g_key_file_set_integer_list
+
+extern __typeof (g_key_file_set_list_separator) IA__g_key_file_set_list_separator __attribute((visibility("hidden")));
+#define g_key_file_set_list_separator IA__g_key_file_set_list_separator
+
+extern __typeof (g_key_file_set_locale_string) IA__g_key_file_set_locale_string __attribute((visibility("hidden")));
+#define g_key_file_set_locale_string IA__g_key_file_set_locale_string
+
+extern __typeof (g_key_file_set_locale_string_list) IA__g_key_file_set_locale_string_list __attribute((visibility("hidden")));
+#define g_key_file_set_locale_string_list IA__g_key_file_set_locale_string_list
+
+extern __typeof (g_key_file_set_string) IA__g_key_file_set_string __attribute((visibility("hidden")));
+#define g_key_file_set_string IA__g_key_file_set_string
+
+extern __typeof (g_key_file_set_string_list) IA__g_key_file_set_string_list __attribute((visibility("hidden")));
+#define g_key_file_set_string_list IA__g_key_file_set_string_list
+
+extern __typeof (g_key_file_set_value) IA__g_key_file_set_value __attribute((visibility("hidden")));
+#define g_key_file_set_value IA__g_key_file_set_value
+
+extern __typeof (g_key_file_to_data) IA__g_key_file_to_data __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_key_file_to_data IA__g_key_file_to_data
+
+#endif
+#endif
+#if IN_HEADER(__G_LIST_H__)
+#if IN_FILE(__G_LIST_C__)
+extern __typeof (g_list_alloc) IA__g_list_alloc __attribute((visibility("hidden")));
+#define g_list_alloc IA__g_list_alloc
+
+extern __typeof (g_list_append) IA__g_list_append __attribute((visibility("hidden")));
+#define g_list_append IA__g_list_append
+
+extern __typeof (g_list_concat) IA__g_list_concat __attribute((visibility("hidden")));
+#define g_list_concat IA__g_list_concat
+
+extern __typeof (g_list_copy) IA__g_list_copy __attribute((visibility("hidden")));
+#define g_list_copy IA__g_list_copy
+
+extern __typeof (g_list_delete_link) IA__g_list_delete_link __attribute((visibility("hidden")));
+#define g_list_delete_link IA__g_list_delete_link
+
+extern __typeof (g_list_find) IA__g_list_find __attribute((visibility("hidden")));
+#define g_list_find IA__g_list_find
+
+extern __typeof (g_list_find_custom) IA__g_list_find_custom __attribute((visibility("hidden")));
+#define g_list_find_custom IA__g_list_find_custom
+
+extern __typeof (g_list_first) IA__g_list_first __attribute((visibility("hidden")));
+#define g_list_first IA__g_list_first
+
+extern __typeof (g_list_foreach) IA__g_list_foreach __attribute((visibility("hidden")));
+#define g_list_foreach IA__g_list_foreach
+
+extern __typeof (g_list_free) IA__g_list_free __attribute((visibility("hidden")));
+#define g_list_free IA__g_list_free
+
+extern __typeof (g_list_free_1) IA__g_list_free_1 __attribute((visibility("hidden")));
+#define g_list_free_1 IA__g_list_free_1
+
+extern __typeof (g_list_index) IA__g_list_index __attribute((visibility("hidden")));
+#define g_list_index IA__g_list_index
+
+extern __typeof (g_list_insert) IA__g_list_insert __attribute((visibility("hidden")));
+#define g_list_insert IA__g_list_insert
+
+extern __typeof (g_list_insert_before) IA__g_list_insert_before __attribute((visibility("hidden")));
+#define g_list_insert_before IA__g_list_insert_before
+
+extern __typeof (g_list_insert_sorted) IA__g_list_insert_sorted __attribute((visibility("hidden")));
+#define g_list_insert_sorted IA__g_list_insert_sorted
+
+extern __typeof (g_list_insert_sorted_with_data) IA__g_list_insert_sorted_with_data __attribute((visibility("hidden")));
+#define g_list_insert_sorted_with_data IA__g_list_insert_sorted_with_data
+
+extern __typeof (g_list_last) IA__g_list_last __attribute((visibility("hidden")));
+#define g_list_last IA__g_list_last
+
+extern __typeof (g_list_length) IA__g_list_length __attribute((visibility("hidden")));
+#define g_list_length IA__g_list_length
+
+extern __typeof (g_list_nth) IA__g_list_nth __attribute((visibility("hidden")));
+#define g_list_nth IA__g_list_nth
+
+extern __typeof (g_list_nth_data) IA__g_list_nth_data __attribute((visibility("hidden")));
+#define g_list_nth_data IA__g_list_nth_data
+
+extern __typeof (g_list_nth_prev) IA__g_list_nth_prev __attribute((visibility("hidden")));
+#define g_list_nth_prev IA__g_list_nth_prev
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_list_pop_allocator) IA__g_list_pop_allocator __attribute((visibility("hidden")));
+#define g_list_pop_allocator IA__g_list_pop_allocator
+
+#endif
+extern __typeof (g_list_position) IA__g_list_position __attribute((visibility("hidden")));
+#define g_list_position IA__g_list_position
+
+extern __typeof (g_list_prepend) IA__g_list_prepend __attribute((visibility("hidden")));
+#define g_list_prepend IA__g_list_prepend
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_list_push_allocator) IA__g_list_push_allocator __attribute((visibility("hidden")));
+#define g_list_push_allocator IA__g_list_push_allocator
+
+#endif
+extern __typeof (g_list_remove) IA__g_list_remove __attribute((visibility("hidden")));
+#define g_list_remove IA__g_list_remove
+
+extern __typeof (g_list_remove_all) IA__g_list_remove_all __attribute((visibility("hidden")));
+#define g_list_remove_all IA__g_list_remove_all
+
+extern __typeof (g_list_remove_link) IA__g_list_remove_link __attribute((visibility("hidden")));
+#define g_list_remove_link IA__g_list_remove_link
+
+extern __typeof (g_list_reverse) IA__g_list_reverse __attribute((visibility("hidden")));
+#define g_list_reverse IA__g_list_reverse
+
+extern __typeof (g_list_sort) IA__g_list_sort __attribute((visibility("hidden")));
+#define g_list_sort IA__g_list_sort
+
+extern __typeof (g_list_sort_with_data) IA__g_list_sort_with_data __attribute((visibility("hidden")));
+#define g_list_sort_with_data IA__g_list_sort_with_data
+
+#endif
+#endif
+#if IN_HEADER(__G_MAIN_H__)
+#if IN_FILE(__G_MAIN_C__)
+extern __typeof (g_child_watch_add) IA__g_child_watch_add __attribute((visibility("hidden")));
+#define g_child_watch_add IA__g_child_watch_add
+
+extern __typeof (g_child_watch_add_full) IA__g_child_watch_add_full __attribute((visibility("hidden")));
+#define g_child_watch_add_full IA__g_child_watch_add_full
+
+extern __typeof (g_child_watch_source_new) IA__g_child_watch_source_new __attribute((visibility("hidden")));
+#define g_child_watch_source_new IA__g_child_watch_source_new
+
+extern __typeof (g_get_current_time) IA__g_get_current_time __attribute((visibility("hidden")));
+#define g_get_current_time IA__g_get_current_time
+
+extern __typeof (g_main_context_acquire) IA__g_main_context_acquire __attribute((visibility("hidden")));
+#define g_main_context_acquire IA__g_main_context_acquire
+
+extern __typeof (g_main_context_add_poll) IA__g_main_context_add_poll __attribute((visibility("hidden")));
+#define g_main_context_add_poll IA__g_main_context_add_poll
+
+extern __typeof (g_main_context_check) IA__g_main_context_check __attribute((visibility("hidden")));
+#define g_main_context_check IA__g_main_context_check
+
+extern __typeof (g_main_context_default) IA__g_main_context_default __attribute((visibility("hidden")));
+#define g_main_context_default IA__g_main_context_default
+
+extern __typeof (g_main_context_dispatch) IA__g_main_context_dispatch __attribute((visibility("hidden")));
+#define g_main_context_dispatch IA__g_main_context_dispatch
+
+extern __typeof (g_main_context_find_source_by_funcs_user_data) IA__g_main_context_find_source_by_funcs_user_data __attribute((visibility("hidden")));
+#define g_main_context_find_source_by_funcs_user_data IA__g_main_context_find_source_by_funcs_user_data
+
+extern __typeof (g_main_context_find_source_by_id) IA__g_main_context_find_source_by_id __attribute((visibility("hidden")));
+#define g_main_context_find_source_by_id IA__g_main_context_find_source_by_id
+
+extern __typeof (g_main_context_find_source_by_user_data) IA__g_main_context_find_source_by_user_data __attribute((visibility("hidden")));
+#define g_main_context_find_source_by_user_data IA__g_main_context_find_source_by_user_data
+
+extern __typeof (g_main_context_get_poll_func) IA__g_main_context_get_poll_func __attribute((visibility("hidden")));
+#define g_main_context_get_poll_func IA__g_main_context_get_poll_func
+
+extern __typeof (g_main_context_is_owner) IA__g_main_context_is_owner __attribute((visibility("hidden")));
+#define g_main_context_is_owner IA__g_main_context_is_owner
+
+extern __typeof (g_main_context_iteration) IA__g_main_context_iteration __attribute((visibility("hidden")));
+#define g_main_context_iteration IA__g_main_context_iteration
+
+extern __typeof (g_main_context_new) IA__g_main_context_new __attribute((visibility("hidden")));
+#define g_main_context_new IA__g_main_context_new
+
+extern __typeof (g_main_context_pending) IA__g_main_context_pending __attribute((visibility("hidden")));
+#define g_main_context_pending IA__g_main_context_pending
+
+extern __typeof (g_main_context_prepare) IA__g_main_context_prepare __attribute((visibility("hidden")));
+#define g_main_context_prepare IA__g_main_context_prepare
+
+extern __typeof (g_main_context_query) IA__g_main_context_query __attribute((visibility("hidden")));
+#define g_main_context_query IA__g_main_context_query
+
+extern __typeof (g_main_context_ref) IA__g_main_context_ref __attribute((visibility("hidden")));
+#define g_main_context_ref IA__g_main_context_ref
+
+extern __typeof (g_main_context_release) IA__g_main_context_release __attribute((visibility("hidden")));
+#define g_main_context_release IA__g_main_context_release
+
+extern __typeof (g_main_context_remove_poll) IA__g_main_context_remove_poll __attribute((visibility("hidden")));
+#define g_main_context_remove_poll IA__g_main_context_remove_poll
+
+extern __typeof (g_main_context_set_poll_func) IA__g_main_context_set_poll_func __attribute((visibility("hidden")));
+#define g_main_context_set_poll_func IA__g_main_context_set_poll_func
+
+extern __typeof (g_main_context_unref) IA__g_main_context_unref __attribute((visibility("hidden")));
+#define g_main_context_unref IA__g_main_context_unref
+
+extern __typeof (g_main_context_wait) IA__g_main_context_wait __attribute((visibility("hidden")));
+#define g_main_context_wait IA__g_main_context_wait
+
+extern __typeof (g_main_context_wakeup) IA__g_main_context_wakeup __attribute((visibility("hidden")));
+#define g_main_context_wakeup IA__g_main_context_wakeup
+
+extern __typeof (g_main_depth) IA__g_main_depth __attribute((visibility("hidden")));
+#define g_main_depth IA__g_main_depth
+
+extern __typeof (g_main_current_source) IA__g_main_current_source __attribute((visibility("hidden")));
+#define g_main_current_source IA__g_main_current_source
+
+extern __typeof (g_main_loop_get_context) IA__g_main_loop_get_context __attribute((visibility("hidden")));
+#define g_main_loop_get_context IA__g_main_loop_get_context
+
+extern __typeof (g_main_loop_is_running) IA__g_main_loop_is_running __attribute((visibility("hidden")));
+#define g_main_loop_is_running IA__g_main_loop_is_running
+
+extern __typeof (g_main_loop_new) IA__g_main_loop_new __attribute((visibility("hidden")));
+#define g_main_loop_new IA__g_main_loop_new
+
+extern __typeof (g_main_loop_quit) IA__g_main_loop_quit __attribute((visibility("hidden")));
+#define g_main_loop_quit IA__g_main_loop_quit
+
+extern __typeof (g_main_loop_ref) IA__g_main_loop_ref __attribute((visibility("hidden")));
+#define g_main_loop_ref IA__g_main_loop_ref
+
+extern __typeof (g_main_loop_run) IA__g_main_loop_run __attribute((visibility("hidden")));
+#define g_main_loop_run IA__g_main_loop_run
+
+extern __typeof (g_main_loop_unref) IA__g_main_loop_unref __attribute((visibility("hidden")));
+#define g_main_loop_unref IA__g_main_loop_unref
+
+extern __typeof (g_source_add_poll) IA__g_source_add_poll __attribute((visibility("hidden")));
+#define g_source_add_poll IA__g_source_add_poll
+
+extern __typeof (g_source_attach) IA__g_source_attach __attribute((visibility("hidden")));
+#define g_source_attach IA__g_source_attach
+
+extern __typeof (g_source_destroy) IA__g_source_destroy __attribute((visibility("hidden")));
+#define g_source_destroy IA__g_source_destroy
+
+extern __typeof (g_source_get_can_recurse) IA__g_source_get_can_recurse __attribute((visibility("hidden")));
+#define g_source_get_can_recurse IA__g_source_get_can_recurse
+
+extern __typeof (g_source_get_context) IA__g_source_get_context __attribute((visibility("hidden")));
+#define g_source_get_context IA__g_source_get_context
+
+extern __typeof (g_source_get_current_time) IA__g_source_get_current_time __attribute((visibility("hidden")));
+#define g_source_get_current_time IA__g_source_get_current_time
+
+extern __typeof (g_source_get_id) IA__g_source_get_id __attribute((visibility("hidden")));
+#define g_source_get_id IA__g_source_get_id
+
+extern __typeof (g_source_get_priority) IA__g_source_get_priority __attribute((visibility("hidden")));
+#define g_source_get_priority IA__g_source_get_priority
+
+extern __typeof (g_source_new) IA__g_source_new __attribute((visibility("hidden")));
+#define g_source_new IA__g_source_new
+
+extern __typeof (g_source_ref) IA__g_source_ref __attribute((visibility("hidden")));
+#define g_source_ref IA__g_source_ref
+
+extern __typeof (g_source_remove) IA__g_source_remove __attribute((visibility("hidden")));
+#define g_source_remove IA__g_source_remove
+
+extern __typeof (g_source_remove_by_funcs_user_data) IA__g_source_remove_by_funcs_user_data __attribute((visibility("hidden")));
+#define g_source_remove_by_funcs_user_data IA__g_source_remove_by_funcs_user_data
+
+extern __typeof (g_source_remove_by_user_data) IA__g_source_remove_by_user_data __attribute((visibility("hidden")));
+#define g_source_remove_by_user_data IA__g_source_remove_by_user_data
+
+extern __typeof (g_source_remove_poll) IA__g_source_remove_poll __attribute((visibility("hidden")));
+#define g_source_remove_poll IA__g_source_remove_poll
+
+extern __typeof (g_source_set_callback) IA__g_source_set_callback __attribute((visibility("hidden")));
+#define g_source_set_callback IA__g_source_set_callback
+
+extern __typeof (g_source_set_callback_indirect) IA__g_source_set_callback_indirect __attribute((visibility("hidden")));
+#define g_source_set_callback_indirect IA__g_source_set_callback_indirect
+
+extern __typeof (g_source_set_can_recurse) IA__g_source_set_can_recurse __attribute((visibility("hidden")));
+#define g_source_set_can_recurse IA__g_source_set_can_recurse
+
+extern __typeof (g_source_set_funcs) IA__g_source_set_funcs __attribute((visibility("hidden")));
+#define g_source_set_funcs IA__g_source_set_funcs
+
+extern __typeof (g_source_is_destroyed) IA__g_source_is_destroyed __attribute((visibility("hidden")));
+#define g_source_is_destroyed IA__g_source_is_destroyed
+
+extern __typeof (g_source_set_priority) IA__g_source_set_priority __attribute((visibility("hidden")));
+#define g_source_set_priority IA__g_source_set_priority
+
+extern __typeof (g_source_unref) IA__g_source_unref __attribute((visibility("hidden")));
+#define g_source_unref IA__g_source_unref
+
+extern __typeof (g_idle_add) IA__g_idle_add __attribute((visibility("hidden")));
+#define g_idle_add IA__g_idle_add
+
+extern __typeof (g_idle_add_full) IA__g_idle_add_full __attribute((visibility("hidden")));
+#define g_idle_add_full IA__g_idle_add_full
+
+extern __typeof (g_idle_remove_by_data) IA__g_idle_remove_by_data __attribute((visibility("hidden")));
+#define g_idle_remove_by_data IA__g_idle_remove_by_data
+
+extern __typeof (g_idle_source_new) IA__g_idle_source_new __attribute((visibility("hidden")));
+#define g_idle_source_new IA__g_idle_source_new
+
+extern __typeof (g_timeout_add) IA__g_timeout_add __attribute((visibility("hidden")));
+#define g_timeout_add IA__g_timeout_add
+
+extern __typeof (g_timeout_add_seconds) IA__g_timeout_add_seconds __attribute((visibility("hidden")));
+#define g_timeout_add_seconds IA__g_timeout_add_seconds
+
+extern __typeof (g_timeout_add_full) IA__g_timeout_add_full __attribute((visibility("hidden")));
+#define g_timeout_add_full IA__g_timeout_add_full
+
+extern __typeof (g_timeout_add_seconds_full) IA__g_timeout_add_seconds_full __attribute((visibility("hidden")));
+#define g_timeout_add_seconds_full IA__g_timeout_add_seconds_full
+
+extern __typeof (g_timeout_source_new) IA__g_timeout_source_new __attribute((visibility("hidden")));
+#define g_timeout_source_new IA__g_timeout_source_new
+
+extern __typeof (g_timeout_source_new_seconds) IA__g_timeout_source_new_seconds __attribute((visibility("hidden")));
+#define g_timeout_source_new_seconds IA__g_timeout_source_new_seconds
+
+#endif
+#endif
+#if IN_HEADER(__G_MAPPED_FILE_H__)
+#if IN_FILE(__G_MAPPED_FILE_C__)
+extern __typeof (g_mapped_file_new) IA__g_mapped_file_new __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_mapped_file_new IA__g_mapped_file_new
+
+extern __typeof (g_mapped_file_get_length) IA__g_mapped_file_get_length __attribute((visibility("hidden")));
+#define g_mapped_file_get_length IA__g_mapped_file_get_length
+
+extern __typeof (g_mapped_file_get_contents) IA__g_mapped_file_get_contents __attribute((visibility("hidden")));
+#define g_mapped_file_get_contents IA__g_mapped_file_get_contents
+
+extern __typeof (g_mapped_file_free) IA__g_mapped_file_free __attribute((visibility("hidden")));
+#define g_mapped_file_free IA__g_mapped_file_free
+
+#endif
+#endif
+#if IN_HEADER(__G_MARKUP_H__)
+#if IN_FILE(__G_MARKUP_C__)
+extern __typeof (g_markup_error_quark) IA__g_markup_error_quark __attribute((visibility("hidden")));
+#define g_markup_error_quark IA__g_markup_error_quark
+
+extern __typeof (g_markup_escape_text) IA__g_markup_escape_text __attribute((visibility("hidden")));
+#define g_markup_escape_text IA__g_markup_escape_text
+
+extern __typeof (g_markup_parse_context_end_parse) IA__g_markup_parse_context_end_parse __attribute((visibility("hidden")));
+#define g_markup_parse_context_end_parse IA__g_markup_parse_context_end_parse
+
+extern __typeof (g_markup_parse_context_free) IA__g_markup_parse_context_free __attribute((visibility("hidden")));
+#define g_markup_parse_context_free IA__g_markup_parse_context_free
+
+extern __typeof (g_markup_parse_context_get_element) IA__g_markup_parse_context_get_element __attribute((visibility("hidden")));
+#define g_markup_parse_context_get_element IA__g_markup_parse_context_get_element
+
+extern __typeof (g_markup_parse_context_get_element_stack) IA__g_markup_parse_context_get_element_stack __attribute((visibility("hidden")));
+#define g_markup_parse_context_get_element_stack IA__g_markup_parse_context_get_element_stack
+
+extern __typeof (g_markup_parse_context_get_position) IA__g_markup_parse_context_get_position __attribute((visibility("hidden")));
+#define g_markup_parse_context_get_position IA__g_markup_parse_context_get_position
+
+extern __typeof (g_markup_parse_context_get_user_data) IA__g_markup_parse_context_get_user_data __attribute((visibility("hidden")));
+#define g_markup_parse_context_get_user_data IA__g_markup_parse_context_get_user_data
+
+extern __typeof (g_markup_parse_context_new) IA__g_markup_parse_context_new __attribute((visibility("hidden")));
+#define g_markup_parse_context_new IA__g_markup_parse_context_new
+
+extern __typeof (g_markup_parse_context_parse) IA__g_markup_parse_context_parse __attribute((visibility("hidden")));
+#define g_markup_parse_context_parse IA__g_markup_parse_context_parse
+
+extern __typeof (g_markup_parse_context_push) IA__g_markup_parse_context_push __attribute((visibility("hidden")));
+#define g_markup_parse_context_push IA__g_markup_parse_context_push
+
+extern __typeof (g_markup_parse_context_pop) IA__g_markup_parse_context_pop __attribute((visibility("hidden")));
+#define g_markup_parse_context_pop IA__g_markup_parse_context_pop
+
+extern __typeof (g_markup_printf_escaped) IA__g_markup_printf_escaped __attribute((visibility("hidden"))) G_GNUC_PRINTF(1,2);
+#define g_markup_printf_escaped IA__g_markup_printf_escaped
+
+extern __typeof (g_markup_vprintf_escaped) IA__g_markup_vprintf_escaped __attribute((visibility("hidden")));
+#define g_markup_vprintf_escaped IA__g_markup_vprintf_escaped
+
+extern __typeof (g_markup_collect_attributes) IA__g_markup_collect_attributes __attribute((visibility("hidden")));
+#define g_markup_collect_attributes IA__g_markup_collect_attributes
+
+#endif
+#endif
+#if IN_HEADER(__G_MEM_H__)
+#if IN_FILE(__G_MEM_C__)
+extern __typeof (g_free) IA__g_free __attribute((visibility("hidden")));
+#define g_free IA__g_free
+
+extern __typeof (g_malloc) IA__g_malloc __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_malloc IA__g_malloc
+
+extern __typeof (g_malloc0) IA__g_malloc0 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_malloc0 IA__g_malloc0
+
+extern __typeof (g_mem_is_system_malloc) IA__g_mem_is_system_malloc __attribute((visibility("hidden")));
+#define g_mem_is_system_malloc IA__g_mem_is_system_malloc
+
+extern __typeof (g_mem_profile) IA__g_mem_profile __attribute((visibility("hidden")));
+#define g_mem_profile IA__g_mem_profile
+
+extern __typeof (g_mem_set_vtable) IA__g_mem_set_vtable __attribute((visibility("hidden")));
+#define g_mem_set_vtable IA__g_mem_set_vtable
+
+extern __typeof (g_realloc) IA__g_realloc __attribute((visibility("hidden")));
+#define g_realloc IA__g_realloc
+
+extern __typeof (g_try_malloc) IA__g_try_malloc __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_try_malloc IA__g_try_malloc
+
+extern __typeof (g_try_malloc0) IA__g_try_malloc0 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_try_malloc0 IA__g_try_malloc0
+
+extern __typeof (g_try_realloc) IA__g_try_realloc __attribute((visibility("hidden")));
+#define g_try_realloc IA__g_try_realloc
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_allocator_free) IA__g_allocator_free __attribute((visibility("hidden")));
+#define g_allocator_free IA__g_allocator_free
+
+extern __typeof (g_allocator_new) IA__g_allocator_new __attribute((visibility("hidden")));
+#define g_allocator_new IA__g_allocator_new
+
+extern __typeof (g_mem_chunk_alloc) IA__g_mem_chunk_alloc __attribute((visibility("hidden")));
+#define g_mem_chunk_alloc IA__g_mem_chunk_alloc
+
+extern __typeof (g_mem_chunk_alloc0) IA__g_mem_chunk_alloc0 __attribute((visibility("hidden")));
+#define g_mem_chunk_alloc0 IA__g_mem_chunk_alloc0
+
+extern __typeof (g_mem_chunk_clean) IA__g_mem_chunk_clean __attribute((visibility("hidden")));
+#define g_mem_chunk_clean IA__g_mem_chunk_clean
+
+extern __typeof (g_mem_chunk_destroy) IA__g_mem_chunk_destroy __attribute((visibility("hidden")));
+#define g_mem_chunk_destroy IA__g_mem_chunk_destroy
+
+extern __typeof (g_mem_chunk_free) IA__g_mem_chunk_free __attribute((visibility("hidden")));
+#define g_mem_chunk_free IA__g_mem_chunk_free
+
+extern __typeof (g_mem_chunk_info) IA__g_mem_chunk_info __attribute((visibility("hidden")));
+#define g_mem_chunk_info IA__g_mem_chunk_info
+
+extern __typeof (g_mem_chunk_new) IA__g_mem_chunk_new __attribute((visibility("hidden")));
+#define g_mem_chunk_new IA__g_mem_chunk_new
+
+extern __typeof (g_mem_chunk_print) IA__g_mem_chunk_print __attribute((visibility("hidden")));
+#define g_mem_chunk_print IA__g_mem_chunk_print
+
+extern __typeof (g_mem_chunk_reset) IA__g_mem_chunk_reset __attribute((visibility("hidden")));
+#define g_mem_chunk_reset IA__g_mem_chunk_reset
+
+extern __typeof (g_blow_chunks) IA__g_blow_chunks __attribute((visibility("hidden")));
+#define g_blow_chunks IA__g_blow_chunks
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_SLICE_H__)
+#if IN_FILE(__G_SLICE_C__)
+extern __typeof (g_slice_alloc) IA__g_slice_alloc __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_slice_alloc IA__g_slice_alloc
+
+extern __typeof (g_slice_alloc0) IA__g_slice_alloc0 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_slice_alloc0 IA__g_slice_alloc0
+
+extern __typeof (g_slice_copy) IA__g_slice_copy __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_slice_copy IA__g_slice_copy
+
+extern __typeof (g_slice_free1) IA__g_slice_free1 __attribute((visibility("hidden")));
+#define g_slice_free1 IA__g_slice_free1
+
+extern __typeof (g_slice_free_chain_with_offset) IA__g_slice_free_chain_with_offset __attribute((visibility("hidden")));
+#define g_slice_free_chain_with_offset IA__g_slice_free_chain_with_offset
+
+extern __typeof (g_slice_set_config) IA__g_slice_set_config __attribute((visibility("hidden")));
+#define g_slice_set_config IA__g_slice_set_config
+
+extern __typeof (g_slice_get_config) IA__g_slice_get_config __attribute((visibility("hidden")));
+#define g_slice_get_config IA__g_slice_get_config
+
+extern __typeof (g_slice_get_config_state) IA__g_slice_get_config_state __attribute((visibility("hidden")));
+#define g_slice_get_config_state IA__g_slice_get_config_state
+
+#ifdef G_ENABLE_DEBUG
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_MESSAGES_H__)
+#if IN_FILE(__G_MESSAGES_C__)
+extern __typeof (g_printf_string_upper_bound) IA__g_printf_string_upper_bound __attribute((visibility("hidden")));
+#define g_printf_string_upper_bound IA__g_printf_string_upper_bound
+
+extern __typeof (g_log) IA__g_log __attribute((visibility("hidden"))) G_GNUC_PRINTF(3,4);
+#define g_log IA__g_log
+
+extern __typeof (g_log_default_handler) IA__g_log_default_handler __attribute((visibility("hidden")));
+#define g_log_default_handler IA__g_log_default_handler
+
+extern __typeof (g_log_remove_handler) IA__g_log_remove_handler __attribute((visibility("hidden")));
+#define g_log_remove_handler IA__g_log_remove_handler
+
+extern __typeof (g_log_set_always_fatal) IA__g_log_set_always_fatal __attribute((visibility("hidden")));
+#define g_log_set_always_fatal IA__g_log_set_always_fatal
+
+extern __typeof (g_log_set_default_handler) IA__g_log_set_default_handler __attribute((visibility("hidden")));
+#define g_log_set_default_handler IA__g_log_set_default_handler
+
+extern __typeof (g_log_set_fatal_mask) IA__g_log_set_fatal_mask __attribute((visibility("hidden")));
+#define g_log_set_fatal_mask IA__g_log_set_fatal_mask
+
+extern __typeof (g_log_set_handler) IA__g_log_set_handler __attribute((visibility("hidden")));
+#define g_log_set_handler IA__g_log_set_handler
+
+extern __typeof (g_logv) IA__g_logv __attribute((visibility("hidden")));
+#define g_logv IA__g_logv
+
+extern __typeof (g_return_if_fail_warning) IA__g_return_if_fail_warning __attribute((visibility("hidden")));
+#define g_return_if_fail_warning IA__g_return_if_fail_warning
+
+extern __typeof (g_warn_message) IA__g_warn_message __attribute((visibility("hidden")));
+#define g_warn_message IA__g_warn_message
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_assert_warning) IA__g_assert_warning __attribute((visibility("hidden"))) G_GNUC_NORETURN;
+#define g_assert_warning IA__g_assert_warning
+
+#endif
+extern __typeof (g_print) IA__g_print __attribute((visibility("hidden"))) G_GNUC_PRINTF(1,2);
+#define g_print IA__g_print
+
+extern __typeof (g_printerr) IA__g_printerr __attribute((visibility("hidden"))) G_GNUC_PRINTF(1,2);
+#define g_printerr IA__g_printerr
+
+extern __typeof (g_set_printerr_handler) IA__g_set_printerr_handler __attribute((visibility("hidden")));
+#define g_set_printerr_handler IA__g_set_printerr_handler
+
+extern __typeof (g_set_print_handler) IA__g_set_print_handler __attribute((visibility("hidden")));
+#define g_set_print_handler IA__g_set_print_handler
+
+#endif
+#endif
+#if IN_HEADER(__G_NODE_H__)
+#if IN_FILE(__G_NODE_C__)
+extern __typeof (g_node_child_index) IA__g_node_child_index __attribute((visibility("hidden")));
+#define g_node_child_index IA__g_node_child_index
+
+extern __typeof (g_node_child_position) IA__g_node_child_position __attribute((visibility("hidden")));
+#define g_node_child_position IA__g_node_child_position
+
+extern __typeof (g_node_children_foreach) IA__g_node_children_foreach __attribute((visibility("hidden")));
+#define g_node_children_foreach IA__g_node_children_foreach
+
+extern __typeof (g_node_copy) IA__g_node_copy __attribute((visibility("hidden")));
+#define g_node_copy IA__g_node_copy
+
+extern __typeof (g_node_copy_deep) IA__g_node_copy_deep __attribute((visibility("hidden")));
+#define g_node_copy_deep IA__g_node_copy_deep
+
+extern __typeof (g_node_depth) IA__g_node_depth __attribute((visibility("hidden")));
+#define g_node_depth IA__g_node_depth
+
+extern __typeof (g_node_destroy) IA__g_node_destroy __attribute((visibility("hidden")));
+#define g_node_destroy IA__g_node_destroy
+
+extern __typeof (g_node_find) IA__g_node_find __attribute((visibility("hidden")));
+#define g_node_find IA__g_node_find
+
+extern __typeof (g_node_find_child) IA__g_node_find_child __attribute((visibility("hidden")));
+#define g_node_find_child IA__g_node_find_child
+
+extern __typeof (g_node_first_sibling) IA__g_node_first_sibling __attribute((visibility("hidden")));
+#define g_node_first_sibling IA__g_node_first_sibling
+
+extern __typeof (g_node_get_root) IA__g_node_get_root __attribute((visibility("hidden")));
+#define g_node_get_root IA__g_node_get_root
+
+extern __typeof (g_node_insert) IA__g_node_insert __attribute((visibility("hidden")));
+#define g_node_insert IA__g_node_insert
+
+extern __typeof (g_node_insert_after) IA__g_node_insert_after __attribute((visibility("hidden")));
+#define g_node_insert_after IA__g_node_insert_after
+
+extern __typeof (g_node_insert_before) IA__g_node_insert_before __attribute((visibility("hidden")));
+#define g_node_insert_before IA__g_node_insert_before
+
+extern __typeof (g_node_is_ancestor) IA__g_node_is_ancestor __attribute((visibility("hidden")));
+#define g_node_is_ancestor IA__g_node_is_ancestor
+
+extern __typeof (g_node_last_child) IA__g_node_last_child __attribute((visibility("hidden")));
+#define g_node_last_child IA__g_node_last_child
+
+extern __typeof (g_node_last_sibling) IA__g_node_last_sibling __attribute((visibility("hidden")));
+#define g_node_last_sibling IA__g_node_last_sibling
+
+extern __typeof (g_node_max_height) IA__g_node_max_height __attribute((visibility("hidden")));
+#define g_node_max_height IA__g_node_max_height
+
+extern __typeof (g_node_n_children) IA__g_node_n_children __attribute((visibility("hidden")));
+#define g_node_n_children IA__g_node_n_children
+
+extern __typeof (g_node_new) IA__g_node_new __attribute((visibility("hidden")));
+#define g_node_new IA__g_node_new
+
+extern __typeof (g_node_n_nodes) IA__g_node_n_nodes __attribute((visibility("hidden")));
+#define g_node_n_nodes IA__g_node_n_nodes
+
+extern __typeof (g_node_nth_child) IA__g_node_nth_child __attribute((visibility("hidden")));
+#define g_node_nth_child IA__g_node_nth_child
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_node_pop_allocator) IA__g_node_pop_allocator __attribute((visibility("hidden")));
+#define g_node_pop_allocator IA__g_node_pop_allocator
+
+#endif
+extern __typeof (g_node_prepend) IA__g_node_prepend __attribute((visibility("hidden")));
+#define g_node_prepend IA__g_node_prepend
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_node_push_allocator) IA__g_node_push_allocator __attribute((visibility("hidden")));
+#define g_node_push_allocator IA__g_node_push_allocator
+
+#endif
+extern __typeof (g_node_reverse_children) IA__g_node_reverse_children __attribute((visibility("hidden")));
+#define g_node_reverse_children IA__g_node_reverse_children
+
+extern __typeof (g_node_traverse) IA__g_node_traverse __attribute((visibility("hidden")));
+#define g_node_traverse IA__g_node_traverse
+
+extern __typeof (g_node_unlink) IA__g_node_unlink __attribute((visibility("hidden")));
+#define g_node_unlink IA__g_node_unlink
+
+#endif
+#endif
+#if IN_HEADER(__G_OPTION_H__)
+#if IN_FILE(__G_OPTION_C__)
+extern __typeof (g_option_context_add_group) IA__g_option_context_add_group __attribute((visibility("hidden")));
+#define g_option_context_add_group IA__g_option_context_add_group
+
+extern __typeof (g_option_context_add_main_entries) IA__g_option_context_add_main_entries __attribute((visibility("hidden")));
+#define g_option_context_add_main_entries IA__g_option_context_add_main_entries
+
+extern __typeof (g_option_error_quark) IA__g_option_error_quark __attribute((visibility("hidden")));
+#define g_option_error_quark IA__g_option_error_quark
+
+extern __typeof (g_option_context_free) IA__g_option_context_free __attribute((visibility("hidden")));
+#define g_option_context_free IA__g_option_context_free
+
+extern __typeof (g_option_context_get_description) IA__g_option_context_get_description __attribute((visibility("hidden")));
+#define g_option_context_get_description IA__g_option_context_get_description
+
+extern __typeof (g_option_context_get_help_enabled) IA__g_option_context_get_help_enabled __attribute((visibility("hidden")));
+#define g_option_context_get_help_enabled IA__g_option_context_get_help_enabled
+
+extern __typeof (g_option_context_get_ignore_unknown_options) IA__g_option_context_get_ignore_unknown_options __attribute((visibility("hidden")));
+#define g_option_context_get_ignore_unknown_options IA__g_option_context_get_ignore_unknown_options
+
+extern __typeof (g_option_context_get_main_group) IA__g_option_context_get_main_group __attribute((visibility("hidden")));
+#define g_option_context_get_main_group IA__g_option_context_get_main_group
+
+extern __typeof (g_option_context_get_summary) IA__g_option_context_get_summary __attribute((visibility("hidden")));
+#define g_option_context_get_summary IA__g_option_context_get_summary
+
+extern __typeof (g_option_context_new) IA__g_option_context_new __attribute((visibility("hidden")));
+#define g_option_context_new IA__g_option_context_new
+
+extern __typeof (g_option_context_parse) IA__g_option_context_parse __attribute((visibility("hidden")));
+#define g_option_context_parse IA__g_option_context_parse
+
+extern __typeof (g_option_context_set_description) IA__g_option_context_set_description __attribute((visibility("hidden")));
+#define g_option_context_set_description IA__g_option_context_set_description
+
+extern __typeof (g_option_context_set_help_enabled) IA__g_option_context_set_help_enabled __attribute((visibility("hidden")));
+#define g_option_context_set_help_enabled IA__g_option_context_set_help_enabled
+
+extern __typeof (g_option_context_set_ignore_unknown_options) IA__g_option_context_set_ignore_unknown_options __attribute((visibility("hidden")));
+#define g_option_context_set_ignore_unknown_options IA__g_option_context_set_ignore_unknown_options
+
+extern __typeof (g_option_context_set_main_group) IA__g_option_context_set_main_group __attribute((visibility("hidden")));
+#define g_option_context_set_main_group IA__g_option_context_set_main_group
+
+extern __typeof (g_option_context_set_summary) IA__g_option_context_set_summary __attribute((visibility("hidden")));
+#define g_option_context_set_summary IA__g_option_context_set_summary
+
+extern __typeof (g_option_context_set_translate_func) IA__g_option_context_set_translate_func __attribute((visibility("hidden")));
+#define g_option_context_set_translate_func IA__g_option_context_set_translate_func
+
+extern __typeof (g_option_context_set_translation_domain) IA__g_option_context_set_translation_domain __attribute((visibility("hidden")));
+#define g_option_context_set_translation_domain IA__g_option_context_set_translation_domain
+
+extern __typeof (g_option_context_get_help) IA__g_option_context_get_help __attribute((visibility("hidden")));
+#define g_option_context_get_help IA__g_option_context_get_help
+
+extern __typeof (g_option_group_add_entries) IA__g_option_group_add_entries __attribute((visibility("hidden")));
+#define g_option_group_add_entries IA__g_option_group_add_entries
+
+extern __typeof (g_option_group_free) IA__g_option_group_free __attribute((visibility("hidden")));
+#define g_option_group_free IA__g_option_group_free
+
+extern __typeof (g_option_group_new) IA__g_option_group_new __attribute((visibility("hidden")));
+#define g_option_group_new IA__g_option_group_new
+
+extern __typeof (g_option_group_set_error_hook) IA__g_option_group_set_error_hook __attribute((visibility("hidden")));
+#define g_option_group_set_error_hook IA__g_option_group_set_error_hook
+
+extern __typeof (g_option_group_set_parse_hooks) IA__g_option_group_set_parse_hooks __attribute((visibility("hidden")));
+#define g_option_group_set_parse_hooks IA__g_option_group_set_parse_hooks
+
+extern __typeof (g_option_group_set_translate_func) IA__g_option_group_set_translate_func __attribute((visibility("hidden")));
+#define g_option_group_set_translate_func IA__g_option_group_set_translate_func
+
+extern __typeof (g_option_group_set_translation_domain) IA__g_option_group_set_translation_domain __attribute((visibility("hidden")));
+#define g_option_group_set_translation_domain IA__g_option_group_set_translation_domain
+
+#endif
+#endif
+#if IN_HEADER(__G_PATTERN_H__)
+#if IN_FILE(__G_PATTERN_C__)
+extern __typeof (g_pattern_match) IA__g_pattern_match __attribute((visibility("hidden")));
+#define g_pattern_match IA__g_pattern_match
+
+extern __typeof (g_pattern_match_simple) IA__g_pattern_match_simple __attribute((visibility("hidden")));
+#define g_pattern_match_simple IA__g_pattern_match_simple
+
+extern __typeof (g_pattern_match_string) IA__g_pattern_match_string __attribute((visibility("hidden")));
+#define g_pattern_match_string IA__g_pattern_match_string
+
+extern __typeof (g_pattern_spec_equal) IA__g_pattern_spec_equal __attribute((visibility("hidden")));
+#define g_pattern_spec_equal IA__g_pattern_spec_equal
+
+extern __typeof (g_pattern_spec_free) IA__g_pattern_spec_free __attribute((visibility("hidden")));
+#define g_pattern_spec_free IA__g_pattern_spec_free
+
+extern __typeof (g_pattern_spec_new) IA__g_pattern_spec_new __attribute((visibility("hidden")));
+#define g_pattern_spec_new IA__g_pattern_spec_new
+
+#endif
+#endif
+#if IN_HEADER(__G_POLL_H__)
+#if IN_FILE(__G_POLL_C__)
+extern __typeof (g_poll) IA__g_poll __attribute((visibility("hidden")));
+#define g_poll IA__g_poll
+
+#endif
+#endif
+#if IN_HEADER(__G_PRIMES_H__)
+#if IN_FILE(__G_PRIMES_C__)
+extern __typeof (g_spaced_primes_closest) IA__g_spaced_primes_closest __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_spaced_primes_closest IA__g_spaced_primes_closest
+
+#endif
+#endif
+#if IN_HEADER(__G_PRINTF_H__)
+#if IN_FILE(__G_PRINTF_C__)
+extern __typeof (g_fprintf) IA__g_fprintf __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_fprintf IA__g_fprintf
+
+extern __typeof (g_printf) IA__g_printf __attribute((visibility("hidden"))) G_GNUC_PRINTF(1,2);
+#define g_printf IA__g_printf
+
+extern __typeof (g_sprintf) IA__g_sprintf __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_sprintf IA__g_sprintf
+
+extern __typeof (g_vasprintf) IA__g_vasprintf __attribute((visibility("hidden")));
+#define g_vasprintf IA__g_vasprintf
+
+extern __typeof (g_vfprintf) IA__g_vfprintf __attribute((visibility("hidden")));
+#define g_vfprintf IA__g_vfprintf
+
+extern __typeof (g_vprintf) IA__g_vprintf __attribute((visibility("hidden")));
+#define g_vprintf IA__g_vprintf
+
+extern __typeof (g_vsprintf) IA__g_vsprintf __attribute((visibility("hidden")));
+#define g_vsprintf IA__g_vsprintf
+
+#endif
+#endif
+#if IN_HEADER(__G_UTILS_H__)
+#if IN_FILE(__G_PRINTF_C__)
+extern __typeof (g_snprintf) IA__g_snprintf __attribute((visibility("hidden"))) G_GNUC_PRINTF(3,4);
+#define g_snprintf IA__g_snprintf
+
+extern __typeof (g_vsnprintf) IA__g_vsnprintf __attribute((visibility("hidden")));
+#define g_vsnprintf IA__g_vsnprintf
+
+#endif
+#endif
+#if IN_HEADER(__G_QSORT_H__)
+#if IN_FILE(__G_QSORT_C__)
+extern __typeof (g_qsort_with_data) IA__g_qsort_with_data __attribute((visibility("hidden")));
+#define g_qsort_with_data IA__g_qsort_with_data
+
+#endif
+#endif
+#if IN_HEADER(__G_QUEUE_H__)
+#if IN_FILE(__G_QUEUE_C__)
+extern __typeof (g_queue_clear) IA__g_queue_clear __attribute((visibility("hidden")));
+#define g_queue_clear IA__g_queue_clear
+
+extern __typeof (g_queue_copy) IA__g_queue_copy __attribute((visibility("hidden")));
+#define g_queue_copy IA__g_queue_copy
+
+extern __typeof (g_queue_delete_link) IA__g_queue_delete_link __attribute((visibility("hidden")));
+#define g_queue_delete_link IA__g_queue_delete_link
+
+extern __typeof (g_queue_find) IA__g_queue_find __attribute((visibility("hidden")));
+#define g_queue_find IA__g_queue_find
+
+extern __typeof (g_queue_find_custom) IA__g_queue_find_custom __attribute((visibility("hidden")));
+#define g_queue_find_custom IA__g_queue_find_custom
+
+extern __typeof (g_queue_foreach) IA__g_queue_foreach __attribute((visibility("hidden")));
+#define g_queue_foreach IA__g_queue_foreach
+
+extern __typeof (g_queue_free) IA__g_queue_free __attribute((visibility("hidden")));
+#define g_queue_free IA__g_queue_free
+
+extern __typeof (g_queue_get_length) IA__g_queue_get_length __attribute((visibility("hidden")));
+#define g_queue_get_length IA__g_queue_get_length
+
+extern __typeof (g_queue_index) IA__g_queue_index __attribute((visibility("hidden")));
+#define g_queue_index IA__g_queue_index
+
+extern __typeof (g_queue_init) IA__g_queue_init __attribute((visibility("hidden")));
+#define g_queue_init IA__g_queue_init
+
+extern __typeof (g_queue_insert_after) IA__g_queue_insert_after __attribute((visibility("hidden")));
+#define g_queue_insert_after IA__g_queue_insert_after
+
+extern __typeof (g_queue_insert_before) IA__g_queue_insert_before __attribute((visibility("hidden")));
+#define g_queue_insert_before IA__g_queue_insert_before
+
+extern __typeof (g_queue_insert_sorted) IA__g_queue_insert_sorted __attribute((visibility("hidden")));
+#define g_queue_insert_sorted IA__g_queue_insert_sorted
+
+extern __typeof (g_queue_is_empty) IA__g_queue_is_empty __attribute((visibility("hidden")));
+#define g_queue_is_empty IA__g_queue_is_empty
+
+extern __typeof (g_queue_link_index) IA__g_queue_link_index __attribute((visibility("hidden")));
+#define g_queue_link_index IA__g_queue_link_index
+
+extern __typeof (g_queue_new) IA__g_queue_new __attribute((visibility("hidden")));
+#define g_queue_new IA__g_queue_new
+
+extern __typeof (g_queue_peek_head) IA__g_queue_peek_head __attribute((visibility("hidden")));
+#define g_queue_peek_head IA__g_queue_peek_head
+
+extern __typeof (g_queue_peek_head_link) IA__g_queue_peek_head_link __attribute((visibility("hidden")));
+#define g_queue_peek_head_link IA__g_queue_peek_head_link
+
+extern __typeof (g_queue_peek_nth) IA__g_queue_peek_nth __attribute((visibility("hidden")));
+#define g_queue_peek_nth IA__g_queue_peek_nth
+
+extern __typeof (g_queue_peek_nth_link) IA__g_queue_peek_nth_link __attribute((visibility("hidden")));
+#define g_queue_peek_nth_link IA__g_queue_peek_nth_link
+
+extern __typeof (g_queue_peek_tail) IA__g_queue_peek_tail __attribute((visibility("hidden")));
+#define g_queue_peek_tail IA__g_queue_peek_tail
+
+extern __typeof (g_queue_peek_tail_link) IA__g_queue_peek_tail_link __attribute((visibility("hidden")));
+#define g_queue_peek_tail_link IA__g_queue_peek_tail_link
+
+extern __typeof (g_queue_pop_head) IA__g_queue_pop_head __attribute((visibility("hidden")));
+#define g_queue_pop_head IA__g_queue_pop_head
+
+extern __typeof (g_queue_pop_head_link) IA__g_queue_pop_head_link __attribute((visibility("hidden")));
+#define g_queue_pop_head_link IA__g_queue_pop_head_link
+
+extern __typeof (g_queue_pop_nth) IA__g_queue_pop_nth __attribute((visibility("hidden")));
+#define g_queue_pop_nth IA__g_queue_pop_nth
+
+extern __typeof (g_queue_pop_nth_link) IA__g_queue_pop_nth_link __attribute((visibility("hidden")));
+#define g_queue_pop_nth_link IA__g_queue_pop_nth_link
+
+extern __typeof (g_queue_pop_tail) IA__g_queue_pop_tail __attribute((visibility("hidden")));
+#define g_queue_pop_tail IA__g_queue_pop_tail
+
+extern __typeof (g_queue_pop_tail_link) IA__g_queue_pop_tail_link __attribute((visibility("hidden")));
+#define g_queue_pop_tail_link IA__g_queue_pop_tail_link
+
+extern __typeof (g_queue_push_head) IA__g_queue_push_head __attribute((visibility("hidden")));
+#define g_queue_push_head IA__g_queue_push_head
+
+extern __typeof (g_queue_push_head_link) IA__g_queue_push_head_link __attribute((visibility("hidden")));
+#define g_queue_push_head_link IA__g_queue_push_head_link
+
+extern __typeof (g_queue_push_nth) IA__g_queue_push_nth __attribute((visibility("hidden")));
+#define g_queue_push_nth IA__g_queue_push_nth
+
+extern __typeof (g_queue_push_nth_link) IA__g_queue_push_nth_link __attribute((visibility("hidden")));
+#define g_queue_push_nth_link IA__g_queue_push_nth_link
+
+extern __typeof (g_queue_push_tail) IA__g_queue_push_tail __attribute((visibility("hidden")));
+#define g_queue_push_tail IA__g_queue_push_tail
+
+extern __typeof (g_queue_push_tail_link) IA__g_queue_push_tail_link __attribute((visibility("hidden")));
+#define g_queue_push_tail_link IA__g_queue_push_tail_link
+
+extern __typeof (g_queue_remove) IA__g_queue_remove __attribute((visibility("hidden")));
+#define g_queue_remove IA__g_queue_remove
+
+extern __typeof (g_queue_remove_all) IA__g_queue_remove_all __attribute((visibility("hidden")));
+#define g_queue_remove_all IA__g_queue_remove_all
+
+extern __typeof (g_queue_reverse) IA__g_queue_reverse __attribute((visibility("hidden")));
+#define g_queue_reverse IA__g_queue_reverse
+
+extern __typeof (g_queue_sort) IA__g_queue_sort __attribute((visibility("hidden")));
+#define g_queue_sort IA__g_queue_sort
+
+extern __typeof (g_queue_unlink) IA__g_queue_unlink __attribute((visibility("hidden")));
+#define g_queue_unlink IA__g_queue_unlink
+
+#endif
+#endif
+#if IN_HEADER(__G_RAND_H__)
+#if IN_FILE(__G_RAND_C__)
+extern __typeof (g_rand_copy) IA__g_rand_copy __attribute((visibility("hidden")));
+#define g_rand_copy IA__g_rand_copy
+
+extern __typeof (g_rand_double) IA__g_rand_double __attribute((visibility("hidden")));
+#define g_rand_double IA__g_rand_double
+
+extern __typeof (g_rand_double_range) IA__g_rand_double_range __attribute((visibility("hidden")));
+#define g_rand_double_range IA__g_rand_double_range
+
+extern __typeof (g_rand_free) IA__g_rand_free __attribute((visibility("hidden")));
+#define g_rand_free IA__g_rand_free
+
+extern __typeof (g_rand_int) IA__g_rand_int __attribute((visibility("hidden")));
+#define g_rand_int IA__g_rand_int
+
+extern __typeof (g_rand_int_range) IA__g_rand_int_range __attribute((visibility("hidden")));
+#define g_rand_int_range IA__g_rand_int_range
+
+extern __typeof (g_rand_new) IA__g_rand_new __attribute((visibility("hidden")));
+#define g_rand_new IA__g_rand_new
+
+extern __typeof (g_rand_new_with_seed) IA__g_rand_new_with_seed __attribute((visibility("hidden")));
+#define g_rand_new_with_seed IA__g_rand_new_with_seed
+
+extern __typeof (g_rand_new_with_seed_array) IA__g_rand_new_with_seed_array __attribute((visibility("hidden")));
+#define g_rand_new_with_seed_array IA__g_rand_new_with_seed_array
+
+extern __typeof (g_random_double) IA__g_random_double __attribute((visibility("hidden")));
+#define g_random_double IA__g_random_double
+
+extern __typeof (g_random_double_range) IA__g_random_double_range __attribute((visibility("hidden")));
+#define g_random_double_range IA__g_random_double_range
+
+extern __typeof (g_random_int) IA__g_random_int __attribute((visibility("hidden")));
+#define g_random_int IA__g_random_int
+
+extern __typeof (g_random_int_range) IA__g_random_int_range __attribute((visibility("hidden")));
+#define g_random_int_range IA__g_random_int_range
+
+extern __typeof (g_random_set_seed) IA__g_random_set_seed __attribute((visibility("hidden")));
+#define g_random_set_seed IA__g_random_set_seed
+
+extern __typeof (g_rand_set_seed) IA__g_rand_set_seed __attribute((visibility("hidden")));
+#define g_rand_set_seed IA__g_rand_set_seed
+
+extern __typeof (g_rand_set_seed_array) IA__g_rand_set_seed_array __attribute((visibility("hidden")));
+#define g_rand_set_seed_array IA__g_rand_set_seed_array
+
+#endif
+#endif
+#if IN_HEADER(__G_REL_H__)
+#if IN_FILE(__G_REL_C__)
+extern __typeof (g_relation_count) IA__g_relation_count __attribute((visibility("hidden")));
+#define g_relation_count IA__g_relation_count
+
+extern __typeof (g_relation_delete) IA__g_relation_delete __attribute((visibility("hidden")));
+#define g_relation_delete IA__g_relation_delete
+
+extern __typeof (g_relation_destroy) IA__g_relation_destroy __attribute((visibility("hidden")));
+#define g_relation_destroy IA__g_relation_destroy
+
+extern __typeof (g_relation_exists) IA__g_relation_exists __attribute((visibility("hidden")));
+#define g_relation_exists IA__g_relation_exists
+
+extern __typeof (g_relation_index) IA__g_relation_index __attribute((visibility("hidden")));
+#define g_relation_index IA__g_relation_index
+
+extern __typeof (g_relation_insert) IA__g_relation_insert __attribute((visibility("hidden")));
+#define g_relation_insert IA__g_relation_insert
+
+extern __typeof (g_relation_new) IA__g_relation_new __attribute((visibility("hidden")));
+#define g_relation_new IA__g_relation_new
+
+extern __typeof (g_relation_print) IA__g_relation_print __attribute((visibility("hidden")));
+#define g_relation_print IA__g_relation_print
+
+extern __typeof (g_relation_select) IA__g_relation_select __attribute((visibility("hidden")));
+#define g_relation_select IA__g_relation_select
+
+extern __typeof (g_tuples_destroy) IA__g_tuples_destroy __attribute((visibility("hidden")));
+#define g_tuples_destroy IA__g_tuples_destroy
+
+extern __typeof (g_tuples_index) IA__g_tuples_index __attribute((visibility("hidden")));
+#define g_tuples_index IA__g_tuples_index
+
+#endif
+#endif
+#if IN_HEADER(__G_SCANNER_H__)
+#if IN_FILE(__G_SCANNER_C__)
+extern __typeof (g_scanner_cur_line) IA__g_scanner_cur_line __attribute((visibility("hidden")));
+#define g_scanner_cur_line IA__g_scanner_cur_line
+
+extern __typeof (g_scanner_cur_position) IA__g_scanner_cur_position __attribute((visibility("hidden")));
+#define g_scanner_cur_position IA__g_scanner_cur_position
+
+extern __typeof (g_scanner_cur_token) IA__g_scanner_cur_token __attribute((visibility("hidden")));
+#define g_scanner_cur_token IA__g_scanner_cur_token
+
+extern __typeof (g_scanner_cur_value) IA__g_scanner_cur_value __attribute((visibility("hidden")));
+#define g_scanner_cur_value IA__g_scanner_cur_value
+
+extern __typeof (g_scanner_destroy) IA__g_scanner_destroy __attribute((visibility("hidden")));
+#define g_scanner_destroy IA__g_scanner_destroy
+
+extern __typeof (g_scanner_eof) IA__g_scanner_eof __attribute((visibility("hidden")));
+#define g_scanner_eof IA__g_scanner_eof
+
+extern __typeof (g_scanner_error) IA__g_scanner_error __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_scanner_error IA__g_scanner_error
+
+extern __typeof (g_scanner_get_next_token) IA__g_scanner_get_next_token __attribute((visibility("hidden")));
+#define g_scanner_get_next_token IA__g_scanner_get_next_token
+
+extern __typeof (g_scanner_input_file) IA__g_scanner_input_file __attribute((visibility("hidden")));
+#define g_scanner_input_file IA__g_scanner_input_file
+
+extern __typeof (g_scanner_input_text) IA__g_scanner_input_text __attribute((visibility("hidden")));
+#define g_scanner_input_text IA__g_scanner_input_text
+
+extern __typeof (g_scanner_lookup_symbol) IA__g_scanner_lookup_symbol __attribute((visibility("hidden")));
+#define g_scanner_lookup_symbol IA__g_scanner_lookup_symbol
+
+extern __typeof (g_scanner_new) IA__g_scanner_new __attribute((visibility("hidden")));
+#define g_scanner_new IA__g_scanner_new
+
+extern __typeof (g_scanner_peek_next_token) IA__g_scanner_peek_next_token __attribute((visibility("hidden")));
+#define g_scanner_peek_next_token IA__g_scanner_peek_next_token
+
+extern __typeof (g_scanner_scope_add_symbol) IA__g_scanner_scope_add_symbol __attribute((visibility("hidden")));
+#define g_scanner_scope_add_symbol IA__g_scanner_scope_add_symbol
+
+extern __typeof (g_scanner_scope_foreach_symbol) IA__g_scanner_scope_foreach_symbol __attribute((visibility("hidden")));
+#define g_scanner_scope_foreach_symbol IA__g_scanner_scope_foreach_symbol
+
+extern __typeof (g_scanner_scope_lookup_symbol) IA__g_scanner_scope_lookup_symbol __attribute((visibility("hidden")));
+#define g_scanner_scope_lookup_symbol IA__g_scanner_scope_lookup_symbol
+
+extern __typeof (g_scanner_scope_remove_symbol) IA__g_scanner_scope_remove_symbol __attribute((visibility("hidden")));
+#define g_scanner_scope_remove_symbol IA__g_scanner_scope_remove_symbol
+
+extern __typeof (g_scanner_set_scope) IA__g_scanner_set_scope __attribute((visibility("hidden")));
+#define g_scanner_set_scope IA__g_scanner_set_scope
+
+extern __typeof (g_scanner_sync_file_offset) IA__g_scanner_sync_file_offset __attribute((visibility("hidden")));
+#define g_scanner_sync_file_offset IA__g_scanner_sync_file_offset
+
+extern __typeof (g_scanner_unexp_token) IA__g_scanner_unexp_token __attribute((visibility("hidden")));
+#define g_scanner_unexp_token IA__g_scanner_unexp_token
+
+extern __typeof (g_scanner_warn) IA__g_scanner_warn __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_scanner_warn IA__g_scanner_warn
+
+#endif
+#endif
+#if IN_HEADER(__G_SEQUENCE_H__)
+#if IN_FILE(__G_SEQUENCE_C__)
+extern __typeof (g_sequence_new) IA__g_sequence_new __attribute((visibility("hidden")));
+#define g_sequence_new IA__g_sequence_new
+
+extern __typeof (g_sequence_free) IA__g_sequence_free __attribute((visibility("hidden")));
+#define g_sequence_free IA__g_sequence_free
+
+extern __typeof (g_sequence_get_length) IA__g_sequence_get_length __attribute((visibility("hidden")));
+#define g_sequence_get_length IA__g_sequence_get_length
+
+extern __typeof (g_sequence_foreach) IA__g_sequence_foreach __attribute((visibility("hidden")));
+#define g_sequence_foreach IA__g_sequence_foreach
+
+extern __typeof (g_sequence_foreach_range) IA__g_sequence_foreach_range __attribute((visibility("hidden")));
+#define g_sequence_foreach_range IA__g_sequence_foreach_range
+
+extern __typeof (g_sequence_sort) IA__g_sequence_sort __attribute((visibility("hidden")));
+#define g_sequence_sort IA__g_sequence_sort
+
+extern __typeof (g_sequence_sort_iter) IA__g_sequence_sort_iter __attribute((visibility("hidden")));
+#define g_sequence_sort_iter IA__g_sequence_sort_iter
+
+extern __typeof (g_sequence_get_begin_iter) IA__g_sequence_get_begin_iter __attribute((visibility("hidden")));
+#define g_sequence_get_begin_iter IA__g_sequence_get_begin_iter
+
+extern __typeof (g_sequence_get_end_iter) IA__g_sequence_get_end_iter __attribute((visibility("hidden")));
+#define g_sequence_get_end_iter IA__g_sequence_get_end_iter
+
+extern __typeof (g_sequence_get_iter_at_pos) IA__g_sequence_get_iter_at_pos __attribute((visibility("hidden")));
+#define g_sequence_get_iter_at_pos IA__g_sequence_get_iter_at_pos
+
+extern __typeof (g_sequence_append) IA__g_sequence_append __attribute((visibility("hidden")));
+#define g_sequence_append IA__g_sequence_append
+
+extern __typeof (g_sequence_prepend) IA__g_sequence_prepend __attribute((visibility("hidden")));
+#define g_sequence_prepend IA__g_sequence_prepend
+
+extern __typeof (g_sequence_insert_before) IA__g_sequence_insert_before __attribute((visibility("hidden")));
+#define g_sequence_insert_before IA__g_sequence_insert_before
+
+extern __typeof (g_sequence_move) IA__g_sequence_move __attribute((visibility("hidden")));
+#define g_sequence_move IA__g_sequence_move
+
+extern __typeof (g_sequence_swap) IA__g_sequence_swap __attribute((visibility("hidden")));
+#define g_sequence_swap IA__g_sequence_swap
+
+extern __typeof (g_sequence_insert_sorted) IA__g_sequence_insert_sorted __attribute((visibility("hidden")));
+#define g_sequence_insert_sorted IA__g_sequence_insert_sorted
+
+extern __typeof (g_sequence_insert_sorted_iter) IA__g_sequence_insert_sorted_iter __attribute((visibility("hidden")));
+#define g_sequence_insert_sorted_iter IA__g_sequence_insert_sorted_iter
+
+extern __typeof (g_sequence_sort_changed) IA__g_sequence_sort_changed __attribute((visibility("hidden")));
+#define g_sequence_sort_changed IA__g_sequence_sort_changed
+
+extern __typeof (g_sequence_sort_changed_iter) IA__g_sequence_sort_changed_iter __attribute((visibility("hidden")));
+#define g_sequence_sort_changed_iter IA__g_sequence_sort_changed_iter
+
+extern __typeof (g_sequence_remove) IA__g_sequence_remove __attribute((visibility("hidden")));
+#define g_sequence_remove IA__g_sequence_remove
+
+extern __typeof (g_sequence_remove_range) IA__g_sequence_remove_range __attribute((visibility("hidden")));
+#define g_sequence_remove_range IA__g_sequence_remove_range
+
+extern __typeof (g_sequence_move_range) IA__g_sequence_move_range __attribute((visibility("hidden")));
+#define g_sequence_move_range IA__g_sequence_move_range
+
+extern __typeof (g_sequence_search) IA__g_sequence_search __attribute((visibility("hidden")));
+#define g_sequence_search IA__g_sequence_search
+
+extern __typeof (g_sequence_search_iter) IA__g_sequence_search_iter __attribute((visibility("hidden")));
+#define g_sequence_search_iter IA__g_sequence_search_iter
+
+extern __typeof (g_sequence_get) IA__g_sequence_get __attribute((visibility("hidden")));
+#define g_sequence_get IA__g_sequence_get
+
+extern __typeof (g_sequence_set) IA__g_sequence_set __attribute((visibility("hidden")));
+#define g_sequence_set IA__g_sequence_set
+
+extern __typeof (g_sequence_iter_is_begin) IA__g_sequence_iter_is_begin __attribute((visibility("hidden")));
+#define g_sequence_iter_is_begin IA__g_sequence_iter_is_begin
+
+extern __typeof (g_sequence_iter_is_end) IA__g_sequence_iter_is_end __attribute((visibility("hidden")));
+#define g_sequence_iter_is_end IA__g_sequence_iter_is_end
+
+extern __typeof (g_sequence_iter_next) IA__g_sequence_iter_next __attribute((visibility("hidden")));
+#define g_sequence_iter_next IA__g_sequence_iter_next
+
+extern __typeof (g_sequence_iter_prev) IA__g_sequence_iter_prev __attribute((visibility("hidden")));
+#define g_sequence_iter_prev IA__g_sequence_iter_prev
+
+extern __typeof (g_sequence_iter_get_position) IA__g_sequence_iter_get_position __attribute((visibility("hidden")));
+#define g_sequence_iter_get_position IA__g_sequence_iter_get_position
+
+extern __typeof (g_sequence_iter_move) IA__g_sequence_iter_move __attribute((visibility("hidden")));
+#define g_sequence_iter_move IA__g_sequence_iter_move
+
+extern __typeof (g_sequence_iter_get_sequence) IA__g_sequence_iter_get_sequence __attribute((visibility("hidden")));
+#define g_sequence_iter_get_sequence IA__g_sequence_iter_get_sequence
+
+extern __typeof (g_sequence_iter_compare) IA__g_sequence_iter_compare __attribute((visibility("hidden")));
+#define g_sequence_iter_compare IA__g_sequence_iter_compare
+
+extern __typeof (g_sequence_range_get_midpoint) IA__g_sequence_range_get_midpoint __attribute((visibility("hidden")));
+#define g_sequence_range_get_midpoint IA__g_sequence_range_get_midpoint
+
+#endif
+#endif
+#if IN_HEADER(__G_SHELL_H__)
+#if IN_FILE(__G_SHELL_C__)
+extern __typeof (g_shell_error_quark) IA__g_shell_error_quark __attribute((visibility("hidden")));
+#define g_shell_error_quark IA__g_shell_error_quark
+
+extern __typeof (g_shell_parse_argv) IA__g_shell_parse_argv __attribute((visibility("hidden")));
+#define g_shell_parse_argv IA__g_shell_parse_argv
+
+extern __typeof (g_shell_quote) IA__g_shell_quote __attribute((visibility("hidden")));
+#define g_shell_quote IA__g_shell_quote
+
+extern __typeof (g_shell_unquote) IA__g_shell_unquote __attribute((visibility("hidden")));
+#define g_shell_unquote IA__g_shell_unquote
+
+#endif
+#endif
+#if IN_HEADER(__G_SLIST_H__)
+#if IN_FILE(__G_SLIST_C__)
+extern __typeof (g_slist_alloc) IA__g_slist_alloc __attribute((visibility("hidden")));
+#define g_slist_alloc IA__g_slist_alloc
+
+extern __typeof (g_slist_append) IA__g_slist_append __attribute((visibility("hidden")));
+#define g_slist_append IA__g_slist_append
+
+extern __typeof (g_slist_concat) IA__g_slist_concat __attribute((visibility("hidden")));
+#define g_slist_concat IA__g_slist_concat
+
+extern __typeof (g_slist_copy) IA__g_slist_copy __attribute((visibility("hidden")));
+#define g_slist_copy IA__g_slist_copy
+
+extern __typeof (g_slist_delete_link) IA__g_slist_delete_link __attribute((visibility("hidden")));
+#define g_slist_delete_link IA__g_slist_delete_link
+
+extern __typeof (g_slist_find) IA__g_slist_find __attribute((visibility("hidden")));
+#define g_slist_find IA__g_slist_find
+
+extern __typeof (g_slist_find_custom) IA__g_slist_find_custom __attribute((visibility("hidden")));
+#define g_slist_find_custom IA__g_slist_find_custom
+
+extern __typeof (g_slist_foreach) IA__g_slist_foreach __attribute((visibility("hidden")));
+#define g_slist_foreach IA__g_slist_foreach
+
+extern __typeof (g_slist_free) IA__g_slist_free __attribute((visibility("hidden")));
+#define g_slist_free IA__g_slist_free
+
+extern __typeof (g_slist_free_1) IA__g_slist_free_1 __attribute((visibility("hidden")));
+#define g_slist_free_1 IA__g_slist_free_1
+
+extern __typeof (g_slist_index) IA__g_slist_index __attribute((visibility("hidden")));
+#define g_slist_index IA__g_slist_index
+
+extern __typeof (g_slist_insert) IA__g_slist_insert __attribute((visibility("hidden")));
+#define g_slist_insert IA__g_slist_insert
+
+extern __typeof (g_slist_insert_before) IA__g_slist_insert_before __attribute((visibility("hidden")));
+#define g_slist_insert_before IA__g_slist_insert_before
+
+extern __typeof (g_slist_insert_sorted) IA__g_slist_insert_sorted __attribute((visibility("hidden")));
+#define g_slist_insert_sorted IA__g_slist_insert_sorted
+
+extern __typeof (g_slist_insert_sorted_with_data) IA__g_slist_insert_sorted_with_data __attribute((visibility("hidden")));
+#define g_slist_insert_sorted_with_data IA__g_slist_insert_sorted_with_data
+
+extern __typeof (g_slist_last) IA__g_slist_last __attribute((visibility("hidden")));
+#define g_slist_last IA__g_slist_last
+
+extern __typeof (g_slist_length) IA__g_slist_length __attribute((visibility("hidden")));
+#define g_slist_length IA__g_slist_length
+
+extern __typeof (g_slist_nth) IA__g_slist_nth __attribute((visibility("hidden")));
+#define g_slist_nth IA__g_slist_nth
+
+extern __typeof (g_slist_nth_data) IA__g_slist_nth_data __attribute((visibility("hidden")));
+#define g_slist_nth_data IA__g_slist_nth_data
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_slist_pop_allocator) IA__g_slist_pop_allocator __attribute((visibility("hidden")));
+#define g_slist_pop_allocator IA__g_slist_pop_allocator
+
+#endif
+extern __typeof (g_slist_position) IA__g_slist_position __attribute((visibility("hidden")));
+#define g_slist_position IA__g_slist_position
+
+extern __typeof (g_slist_prepend) IA__g_slist_prepend __attribute((visibility("hidden")));
+#define g_slist_prepend IA__g_slist_prepend
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_slist_push_allocator) IA__g_slist_push_allocator __attribute((visibility("hidden")));
+#define g_slist_push_allocator IA__g_slist_push_allocator
+
+#endif
+extern __typeof (g_slist_remove) IA__g_slist_remove __attribute((visibility("hidden")));
+#define g_slist_remove IA__g_slist_remove
+
+extern __typeof (g_slist_remove_all) IA__g_slist_remove_all __attribute((visibility("hidden")));
+#define g_slist_remove_all IA__g_slist_remove_all
+
+extern __typeof (g_slist_remove_link) IA__g_slist_remove_link __attribute((visibility("hidden")));
+#define g_slist_remove_link IA__g_slist_remove_link
+
+extern __typeof (g_slist_reverse) IA__g_slist_reverse __attribute((visibility("hidden")));
+#define g_slist_reverse IA__g_slist_reverse
+
+extern __typeof (g_slist_sort) IA__g_slist_sort __attribute((visibility("hidden")));
+#define g_slist_sort IA__g_slist_sort
+
+extern __typeof (g_slist_sort_with_data) IA__g_slist_sort_with_data __attribute((visibility("hidden")));
+#define g_slist_sort_with_data IA__g_slist_sort_with_data
+
+#endif
+#endif
+#if IN_HEADER(__G_SPAWN_H__)
+#if IN_FILE(__G_SPAWN_C__)
+#ifndef _WIN64
+extern __typeof (g_spawn_async) IA__g_spawn_async __attribute((visibility("hidden")));
+#define g_spawn_async IA__g_spawn_async
+
+extern __typeof (g_spawn_async_with_pipes) IA__g_spawn_async_with_pipes __attribute((visibility("hidden")));
+#define g_spawn_async_with_pipes IA__g_spawn_async_with_pipes
+
+#endif
+extern __typeof (g_spawn_close_pid) IA__g_spawn_close_pid __attribute((visibility("hidden")));
+#define g_spawn_close_pid IA__g_spawn_close_pid
+
+#ifndef _WIN64
+extern __typeof (g_spawn_command_line_async) IA__g_spawn_command_line_async __attribute((visibility("hidden")));
+#define g_spawn_command_line_async IA__g_spawn_command_line_async
+
+extern __typeof (g_spawn_command_line_sync) IA__g_spawn_command_line_sync __attribute((visibility("hidden")));
+#define g_spawn_command_line_sync IA__g_spawn_command_line_sync
+
+#endif
+extern __typeof (g_spawn_error_quark) IA__g_spawn_error_quark __attribute((visibility("hidden")));
+#define g_spawn_error_quark IA__g_spawn_error_quark
+
+#ifndef _WIN64
+extern __typeof (g_spawn_sync) IA__g_spawn_sync __attribute((visibility("hidden")));
+#define g_spawn_sync IA__g_spawn_sync
+
+#endif
+#ifdef G_OS_WIN32
+extern __typeof (g_spawn_async_utf8) IA__g_spawn_async_utf8 __attribute((visibility("hidden")));
+#define g_spawn_async_utf8 IA__g_spawn_async_utf8
+
+extern __typeof (g_spawn_async_with_pipes_utf8) IA__g_spawn_async_with_pipes_utf8 __attribute((visibility("hidden")));
+#define g_spawn_async_with_pipes_utf8 IA__g_spawn_async_with_pipes_utf8
+
+extern __typeof (g_spawn_command_line_async_utf8) IA__g_spawn_command_line_async_utf8 __attribute((visibility("hidden")));
+#define g_spawn_command_line_async_utf8 IA__g_spawn_command_line_async_utf8
+
+extern __typeof (g_spawn_command_line_sync_utf8) IA__g_spawn_command_line_sync_utf8 __attribute((visibility("hidden")));
+#define g_spawn_command_line_sync_utf8 IA__g_spawn_command_line_sync_utf8
+
+extern __typeof (g_spawn_sync_utf8) IA__g_spawn_sync_utf8 __attribute((visibility("hidden")));
+#define g_spawn_sync_utf8 IA__g_spawn_sync_utf8
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_STDIO_H__)
+#if IN_FILE(__G_STDIO_C__)
+#if !defined(G_OS_UNIX) || defined(G_STDIO_NO_WRAP_ON_UNIX)
+extern __typeof (g_chmod) IA__g_chmod __attribute((visibility("hidden")));
+#define g_chmod IA__g_chmod
+
+extern __typeof (g_open) IA__g_open __attribute((visibility("hidden")));
+#define g_open IA__g_open
+
+extern __typeof (g_creat) IA__g_creat __attribute((visibility("hidden")));
+#define g_creat IA__g_creat
+
+extern __typeof (g_rename) IA__g_rename __attribute((visibility("hidden")));
+#define g_rename IA__g_rename
+
+extern __typeof (g_mkdir) IA__g_mkdir __attribute((visibility("hidden")));
+#define g_mkdir IA__g_mkdir
+
+extern __typeof (g_stat) IA__g_stat __attribute((visibility("hidden")));
+#define g_stat IA__g_stat
+
+extern __typeof (g_lstat) IA__g_lstat __attribute((visibility("hidden")));
+#define g_lstat IA__g_lstat
+
+extern __typeof (g_remove) IA__g_remove __attribute((visibility("hidden")));
+#define g_remove IA__g_remove
+
+extern __typeof (g_fopen) IA__g_fopen __attribute((visibility("hidden")));
+#define g_fopen IA__g_fopen
+
+extern __typeof (g_freopen) IA__g_freopen __attribute((visibility("hidden")));
+#define g_freopen IA__g_freopen
+
+extern __typeof (g_utime) IA__g_utime __attribute((visibility("hidden")));
+#define g_utime IA__g_utime
+
+#endif
+extern __typeof (g_access) IA__g_access __attribute((visibility("hidden")));
+#define g_access IA__g_access
+
+extern __typeof (g_chdir) IA__g_chdir __attribute((visibility("hidden")));
+#define g_chdir IA__g_chdir
+
+extern __typeof (g_unlink) IA__g_unlink __attribute((visibility("hidden")));
+#define g_unlink IA__g_unlink
+
+extern __typeof (g_rmdir) IA__g_rmdir __attribute((visibility("hidden")));
+#define g_rmdir IA__g_rmdir
+
+#endif
+#endif
+#if IN_HEADER(__G_STRFUNCS_H__)
+#if IN_FILE(__G_STRFUNCS_C__)
+extern __typeof (g_ascii_digit_value) IA__g_ascii_digit_value __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_ascii_digit_value IA__g_ascii_digit_value
+
+extern __typeof (g_ascii_dtostr) IA__g_ascii_dtostr __attribute((visibility("hidden")));
+#define g_ascii_dtostr IA__g_ascii_dtostr
+
+extern __typeof (g_ascii_formatd) IA__g_ascii_formatd __attribute((visibility("hidden")));
+#define g_ascii_formatd IA__g_ascii_formatd
+
+extern __typeof (g_ascii_strdown) IA__g_ascii_strdown __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_ascii_strdown IA__g_ascii_strdown
+
+extern __typeof (g_ascii_strtod) IA__g_ascii_strtod __attribute((visibility("hidden")));
+#define g_ascii_strtod IA__g_ascii_strtod
+
+extern __typeof (g_ascii_strtoull) IA__g_ascii_strtoull __attribute((visibility("hidden")));
+#define g_ascii_strtoull IA__g_ascii_strtoull
+
+extern __typeof (g_ascii_strtoll) IA__g_ascii_strtoll __attribute((visibility("hidden")));
+#define g_ascii_strtoll IA__g_ascii_strtoll
+
+extern __typeof (g_ascii_strup) IA__g_ascii_strup __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_ascii_strup IA__g_ascii_strup
+
+extern __typeof (g_ascii_tolower) IA__g_ascii_tolower __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_ascii_tolower IA__g_ascii_tolower
+
+extern __typeof (g_ascii_toupper) IA__g_ascii_toupper __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_ascii_toupper IA__g_ascii_toupper
+
+extern __typeof (g_ascii_xdigit_value) IA__g_ascii_xdigit_value __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_ascii_xdigit_value IA__g_ascii_xdigit_value
+
+extern __typeof (g_ascii_strcasecmp) IA__g_ascii_strcasecmp __attribute((visibility("hidden")));
+#define g_ascii_strcasecmp IA__g_ascii_strcasecmp
+
+extern __typeof (g_ascii_strncasecmp) IA__g_ascii_strncasecmp __attribute((visibility("hidden")));
+#define g_ascii_strncasecmp IA__g_ascii_strncasecmp
+
+extern __typeof (g_memdup) IA__g_memdup __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_memdup IA__g_memdup
+
+extern __typeof (g_stpcpy) IA__g_stpcpy __attribute((visibility("hidden")));
+#define g_stpcpy IA__g_stpcpy
+
+extern __typeof (g_strcanon) IA__g_strcanon __attribute((visibility("hidden")));
+#define g_strcanon IA__g_strcanon
+
+extern __typeof (g_strchomp) IA__g_strchomp __attribute((visibility("hidden")));
+#define g_strchomp IA__g_strchomp
+
+extern __typeof (g_strchug) IA__g_strchug __attribute((visibility("hidden")));
+#define g_strchug IA__g_strchug
+
+extern __typeof (g_strcompress) IA__g_strcompress __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strcompress IA__g_strcompress
+
+extern __typeof (g_strconcat) IA__g_strconcat __attribute((visibility("hidden"))) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+#define g_strconcat IA__g_strconcat
+
+extern __typeof (g_strdelimit) IA__g_strdelimit __attribute((visibility("hidden")));
+#define g_strdelimit IA__g_strdelimit
+
+extern __typeof (g_strdup) IA__g_strdup __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strdup IA__g_strdup
+
+extern __typeof (g_strdup_printf) IA__g_strdup_printf __attribute((visibility("hidden"))) G_GNUC_PRINTF(1,2) G_GNUC_MALLOC;
+#define g_strdup_printf IA__g_strdup_printf
+
+extern __typeof (g_strdupv) IA__g_strdupv __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strdupv IA__g_strdupv
+
+extern __typeof (g_strdup_vprintf) IA__g_strdup_vprintf __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strdup_vprintf IA__g_strdup_vprintf
+
+extern __typeof (g_strerror) IA__g_strerror __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_strerror IA__g_strerror
+
+extern __typeof (g_strescape) IA__g_strescape __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strescape IA__g_strescape
+
+extern __typeof (g_strfreev) IA__g_strfreev __attribute((visibility("hidden")));
+#define g_strfreev IA__g_strfreev
+
+extern __typeof (g_str_has_prefix) IA__g_str_has_prefix __attribute((visibility("hidden")));
+#define g_str_has_prefix IA__g_str_has_prefix
+
+extern __typeof (g_str_has_suffix) IA__g_str_has_suffix __attribute((visibility("hidden")));
+#define g_str_has_suffix IA__g_str_has_suffix
+
+extern __typeof (g_strjoin) IA__g_strjoin __attribute((visibility("hidden"))) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+#define g_strjoin IA__g_strjoin
+
+extern __typeof (g_strjoinv) IA__g_strjoinv __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strjoinv IA__g_strjoinv
+
+extern __typeof (g_strlcat) IA__g_strlcat __attribute((visibility("hidden")));
+#define g_strlcat IA__g_strlcat
+
+extern __typeof (g_strlcpy) IA__g_strlcpy __attribute((visibility("hidden")));
+#define g_strlcpy IA__g_strlcpy
+
+extern __typeof (g_strndup) IA__g_strndup __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strndup IA__g_strndup
+
+extern __typeof (g_strnfill) IA__g_strnfill __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strnfill IA__g_strnfill
+
+extern __typeof (g_strreverse) IA__g_strreverse __attribute((visibility("hidden")));
+#define g_strreverse IA__g_strreverse
+
+extern __typeof (g_strrstr) IA__g_strrstr __attribute((visibility("hidden")));
+#define g_strrstr IA__g_strrstr
+
+extern __typeof (g_strrstr_len) IA__g_strrstr_len __attribute((visibility("hidden")));
+#define g_strrstr_len IA__g_strrstr_len
+
+extern __typeof (g_strsignal) IA__g_strsignal __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_strsignal IA__g_strsignal
+
+extern __typeof (g_strsplit) IA__g_strsplit __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strsplit IA__g_strsplit
+
+extern __typeof (g_strsplit_set) IA__g_strsplit_set __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_strsplit_set IA__g_strsplit_set
+
+extern __typeof (g_strstr_len) IA__g_strstr_len __attribute((visibility("hidden")));
+#define g_strstr_len IA__g_strstr_len
+
+extern __typeof (g_strtod) IA__g_strtod __attribute((visibility("hidden")));
+#define g_strtod IA__g_strtod
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_strcasecmp) IA__g_strcasecmp __attribute((visibility("hidden")));
+#define g_strcasecmp IA__g_strcasecmp
+
+extern __typeof (g_strncasecmp) IA__g_strncasecmp __attribute((visibility("hidden")));
+#define g_strncasecmp IA__g_strncasecmp
+
+extern __typeof (g_strup) IA__g_strup __attribute((visibility("hidden")));
+#define g_strup IA__g_strup
+
+extern __typeof (g_strdown) IA__g_strdown __attribute((visibility("hidden")));
+#define g_strdown IA__g_strdown
+
+#endif
+extern __typeof (g_strv_length) IA__g_strv_length __attribute((visibility("hidden")));
+#define g_strv_length IA__g_strv_length
+
+extern __typeof (g_strip_context) IA__g_strip_context __attribute((visibility("hidden"))) G_GNUC_FORMAT(1);
+#define g_strip_context IA__g_strip_context
+
+extern __typeof (g_dgettext) IA__g_dgettext __attribute((visibility("hidden"))) G_GNUC_FORMAT(2);
+#define g_dgettext IA__g_dgettext
+
+extern __typeof (g_dngettext) IA__g_dngettext __attribute((visibility("hidden"))) G_GNUC_FORMAT(3);
+#define g_dngettext IA__g_dngettext
+
+extern __typeof (g_dpgettext) IA__g_dpgettext __attribute((visibility("hidden"))) G_GNUC_FORMAT(2);
+#define g_dpgettext IA__g_dpgettext
+
+extern __typeof (g_dpgettext2) IA__g_dpgettext2 __attribute((visibility("hidden"))) G_GNUC_FORMAT(3);
+#define g_dpgettext2 IA__g_dpgettext2
+
+#endif
+#endif
+#if IN_HEADER(__G_URI_FUNCS_H__)
+#if IN_FILE(__G_URI_FUNCS_C__)
+extern __typeof (g_uri_unescape_string) IA__g_uri_unescape_string __attribute((visibility("hidden")));
+#define g_uri_unescape_string IA__g_uri_unescape_string
+
+extern __typeof (g_uri_unescape_segment) IA__g_uri_unescape_segment __attribute((visibility("hidden")));
+#define g_uri_unescape_segment IA__g_uri_unescape_segment
+
+extern __typeof (g_uri_parse_scheme) IA__g_uri_parse_scheme __attribute((visibility("hidden")));
+#define g_uri_parse_scheme IA__g_uri_parse_scheme
+
+extern __typeof (g_uri_escape_string) IA__g_uri_escape_string __attribute((visibility("hidden")));
+#define g_uri_escape_string IA__g_uri_escape_string
+
+#endif
+#endif
+#if IN_HEADER(__G_STRING_H__)
+#if IN_FILE(__G_STRING_C__)
+extern __typeof (g_string_append) IA__g_string_append __attribute((visibility("hidden")));
+#define g_string_append IA__g_string_append
+
+extern __typeof (g_string_append_len) IA__g_string_append_len __attribute((visibility("hidden")));
+#define g_string_append_len IA__g_string_append_len
+
+extern __typeof (g_string_append_printf) IA__g_string_append_printf __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_string_append_printf IA__g_string_append_printf
+
+extern __typeof (g_string_append_unichar) IA__g_string_append_unichar __attribute((visibility("hidden")));
+#define g_string_append_unichar IA__g_string_append_unichar
+
+extern __typeof (g_string_append_vprintf) IA__g_string_append_vprintf __attribute((visibility("hidden")));
+#define g_string_append_vprintf IA__g_string_append_vprintf
+
+extern __typeof (g_string_ascii_down) IA__g_string_ascii_down __attribute((visibility("hidden")));
+#define g_string_ascii_down IA__g_string_ascii_down
+
+extern __typeof (g_string_ascii_up) IA__g_string_ascii_up __attribute((visibility("hidden")));
+#define g_string_ascii_up IA__g_string_ascii_up
+
+extern __typeof (g_string_assign) IA__g_string_assign __attribute((visibility("hidden")));
+#define g_string_assign IA__g_string_assign
+
+extern __typeof (g_string_chunk_free) IA__g_string_chunk_free __attribute((visibility("hidden")));
+#define g_string_chunk_free IA__g_string_chunk_free
+
+extern __typeof (g_string_chunk_clear) IA__g_string_chunk_clear __attribute((visibility("hidden")));
+#define g_string_chunk_clear IA__g_string_chunk_clear
+
+extern __typeof (g_string_chunk_insert) IA__g_string_chunk_insert __attribute((visibility("hidden")));
+#define g_string_chunk_insert IA__g_string_chunk_insert
+
+extern __typeof (g_string_chunk_insert_const) IA__g_string_chunk_insert_const __attribute((visibility("hidden")));
+#define g_string_chunk_insert_const IA__g_string_chunk_insert_const
+
+extern __typeof (g_string_chunk_insert_len) IA__g_string_chunk_insert_len __attribute((visibility("hidden")));
+#define g_string_chunk_insert_len IA__g_string_chunk_insert_len
+
+extern __typeof (g_string_chunk_new) IA__g_string_chunk_new __attribute((visibility("hidden")));
+#define g_string_chunk_new IA__g_string_chunk_new
+
+extern __typeof (g_string_equal) IA__g_string_equal __attribute((visibility("hidden")));
+#define g_string_equal IA__g_string_equal
+
+extern __typeof (g_string_erase) IA__g_string_erase __attribute((visibility("hidden")));
+#define g_string_erase IA__g_string_erase
+
+extern __typeof (g_string_free) IA__g_string_free __attribute((visibility("hidden")));
+#define g_string_free IA__g_string_free
+
+extern __typeof (g_string_hash) IA__g_string_hash __attribute((visibility("hidden")));
+#define g_string_hash IA__g_string_hash
+
+extern __typeof (g_string_insert) IA__g_string_insert __attribute((visibility("hidden")));
+#define g_string_insert IA__g_string_insert
+
+extern __typeof (g_string_insert_c) IA__g_string_insert_c __attribute((visibility("hidden")));
+#define g_string_insert_c IA__g_string_insert_c
+
+extern __typeof (g_string_insert_len) IA__g_string_insert_len __attribute((visibility("hidden")));
+#define g_string_insert_len IA__g_string_insert_len
+
+extern __typeof (g_string_insert_unichar) IA__g_string_insert_unichar __attribute((visibility("hidden")));
+#define g_string_insert_unichar IA__g_string_insert_unichar
+
+extern __typeof (g_string_new) IA__g_string_new __attribute((visibility("hidden")));
+#define g_string_new IA__g_string_new
+
+extern __typeof (g_string_new_len) IA__g_string_new_len __attribute((visibility("hidden")));
+#define g_string_new_len IA__g_string_new_len
+
+extern __typeof (g_string_overwrite) IA__g_string_overwrite __attribute((visibility("hidden")));
+#define g_string_overwrite IA__g_string_overwrite
+
+extern __typeof (g_string_overwrite_len) IA__g_string_overwrite_len __attribute((visibility("hidden")));
+#define g_string_overwrite_len IA__g_string_overwrite_len
+
+extern __typeof (g_string_prepend) IA__g_string_prepend __attribute((visibility("hidden")));
+#define g_string_prepend IA__g_string_prepend
+
+extern __typeof (g_string_prepend_c) IA__g_string_prepend_c __attribute((visibility("hidden")));
+#define g_string_prepend_c IA__g_string_prepend_c
+
+extern __typeof (g_string_prepend_len) IA__g_string_prepend_len __attribute((visibility("hidden")));
+#define g_string_prepend_len IA__g_string_prepend_len
+
+extern __typeof (g_string_prepend_unichar) IA__g_string_prepend_unichar __attribute((visibility("hidden")));
+#define g_string_prepend_unichar IA__g_string_prepend_unichar
+
+extern __typeof (g_string_printf) IA__g_string_printf __attribute((visibility("hidden"))) G_GNUC_PRINTF(2,3);
+#define g_string_printf IA__g_string_printf
+
+extern __typeof (g_string_set_size) IA__g_string_set_size __attribute((visibility("hidden")));
+#define g_string_set_size IA__g_string_set_size
+
+extern __typeof (g_string_sized_new) IA__g_string_sized_new __attribute((visibility("hidden")));
+#define g_string_sized_new IA__g_string_sized_new
+
+extern __typeof (g_string_truncate) IA__g_string_truncate __attribute((visibility("hidden")));
+#define g_string_truncate IA__g_string_truncate
+
+extern __typeof (g_string_append_uri_escaped) IA__g_string_append_uri_escaped __attribute((visibility("hidden")));
+#define g_string_append_uri_escaped IA__g_string_append_uri_escaped
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_string_down) IA__g_string_down __attribute((visibility("hidden")));
+#define g_string_down IA__g_string_down
+
+extern __typeof (g_string_up) IA__g_string_up __attribute((visibility("hidden")));
+#define g_string_up IA__g_string_up
+
+#endif
+extern __typeof (g_string_vprintf) IA__g_string_vprintf __attribute((visibility("hidden")));
+#define g_string_vprintf IA__g_string_vprintf
+
+extern __typeof (g_str_equal) IA__g_str_equal __attribute((visibility("hidden")));
+#define g_str_equal IA__g_str_equal
+
+extern __typeof (g_str_hash) IA__g_str_hash __attribute((visibility("hidden")));
+#define g_str_hash IA__g_str_hash
+
+#endif
+#endif
+#if IN_HEADER(__G_THREAD_H__)
+#if IN_FILE(__G_THREAD_C__)
+extern __typeof (g_once_impl) IA__g_once_impl __attribute((visibility("hidden")));
+#define g_once_impl IA__g_once_impl
+
+extern __typeof (g_once_init_enter_impl) IA__g_once_init_enter_impl __attribute((visibility("hidden")));
+#define g_once_init_enter_impl IA__g_once_init_enter_impl
+
+extern __typeof (g_once_init_leave) IA__g_once_init_leave __attribute((visibility("hidden")));
+#define g_once_init_leave IA__g_once_init_leave
+
+extern __typeof (g_thread_create_full) IA__g_thread_create_full __attribute((visibility("hidden")));
+#define g_thread_create_full IA__g_thread_create_full
+
+extern __typeof (g_thread_error_quark) IA__g_thread_error_quark __attribute((visibility("hidden")));
+#define g_thread_error_quark IA__g_thread_error_quark
+
+extern __typeof (g_thread_exit) IA__g_thread_exit __attribute((visibility("hidden")));
+#define g_thread_exit IA__g_thread_exit
+
+extern __typeof (g_thread_join) IA__g_thread_join __attribute((visibility("hidden")));
+#define g_thread_join IA__g_thread_join
+
+extern __typeof (g_thread_self) IA__g_thread_self __attribute((visibility("hidden")));
+#define g_thread_self IA__g_thread_self
+
+extern __typeof (g_thread_set_priority) IA__g_thread_set_priority __attribute((visibility("hidden")));
+#define g_thread_set_priority IA__g_thread_set_priority
+
+extern __typeof (g_static_mutex_free) IA__g_static_mutex_free __attribute((visibility("hidden")));
+#define g_static_mutex_free IA__g_static_mutex_free
+
+extern __typeof (g_static_mutex_get_mutex_impl) IA__g_static_mutex_get_mutex_impl __attribute((visibility("hidden")));
+#define g_static_mutex_get_mutex_impl IA__g_static_mutex_get_mutex_impl
+
+extern __typeof (g_static_mutex_init) IA__g_static_mutex_init __attribute((visibility("hidden")));
+#define g_static_mutex_init IA__g_static_mutex_init
+
+extern __typeof (g_static_private_free) IA__g_static_private_free __attribute((visibility("hidden")));
+#define g_static_private_free IA__g_static_private_free
+
+extern __typeof (g_static_private_get) IA__g_static_private_get __attribute((visibility("hidden")));
+#define g_static_private_get IA__g_static_private_get
+
+extern __typeof (g_static_private_init) IA__g_static_private_init __attribute((visibility("hidden")));
+#define g_static_private_init IA__g_static_private_init
+
+extern __typeof (g_static_private_set) IA__g_static_private_set __attribute((visibility("hidden")));
+#define g_static_private_set IA__g_static_private_set
+
+extern __typeof (g_static_rec_mutex_free) IA__g_static_rec_mutex_free __attribute((visibility("hidden")));
+#define g_static_rec_mutex_free IA__g_static_rec_mutex_free
+
+extern __typeof (g_static_rec_mutex_init) IA__g_static_rec_mutex_init __attribute((visibility("hidden")));
+#define g_static_rec_mutex_init IA__g_static_rec_mutex_init
+
+extern __typeof (g_static_rec_mutex_lock) IA__g_static_rec_mutex_lock __attribute((visibility("hidden")));
+#define g_static_rec_mutex_lock IA__g_static_rec_mutex_lock
+
+extern __typeof (g_static_rec_mutex_lock_full) IA__g_static_rec_mutex_lock_full __attribute((visibility("hidden")));
+#define g_static_rec_mutex_lock_full IA__g_static_rec_mutex_lock_full
+
+extern __typeof (g_static_rec_mutex_trylock) IA__g_static_rec_mutex_trylock __attribute((visibility("hidden")));
+#define g_static_rec_mutex_trylock IA__g_static_rec_mutex_trylock
+
+extern __typeof (g_static_rec_mutex_unlock) IA__g_static_rec_mutex_unlock __attribute((visibility("hidden")));
+#define g_static_rec_mutex_unlock IA__g_static_rec_mutex_unlock
+
+extern __typeof (g_static_rec_mutex_unlock_full) IA__g_static_rec_mutex_unlock_full __attribute((visibility("hidden")));
+#define g_static_rec_mutex_unlock_full IA__g_static_rec_mutex_unlock_full
+
+extern __typeof (g_static_rw_lock_free) IA__g_static_rw_lock_free __attribute((visibility("hidden")));
+#define g_static_rw_lock_free IA__g_static_rw_lock_free
+
+extern __typeof (g_static_rw_lock_init) IA__g_static_rw_lock_init __attribute((visibility("hidden")));
+#define g_static_rw_lock_init IA__g_static_rw_lock_init
+
+extern __typeof (g_static_rw_lock_reader_lock) IA__g_static_rw_lock_reader_lock __attribute((visibility("hidden")));
+#define g_static_rw_lock_reader_lock IA__g_static_rw_lock_reader_lock
+
+extern __typeof (g_static_rw_lock_reader_trylock) IA__g_static_rw_lock_reader_trylock __attribute((visibility("hidden")));
+#define g_static_rw_lock_reader_trylock IA__g_static_rw_lock_reader_trylock
+
+extern __typeof (g_static_rw_lock_reader_unlock) IA__g_static_rw_lock_reader_unlock __attribute((visibility("hidden")));
+#define g_static_rw_lock_reader_unlock IA__g_static_rw_lock_reader_unlock
+
+extern __typeof (g_static_rw_lock_writer_lock) IA__g_static_rw_lock_writer_lock __attribute((visibility("hidden")));
+#define g_static_rw_lock_writer_lock IA__g_static_rw_lock_writer_lock
+
+extern __typeof (g_static_rw_lock_writer_trylock) IA__g_static_rw_lock_writer_trylock __attribute((visibility("hidden")));
+#define g_static_rw_lock_writer_trylock IA__g_static_rw_lock_writer_trylock
+
+extern __typeof (g_static_rw_lock_writer_unlock) IA__g_static_rw_lock_writer_unlock __attribute((visibility("hidden")));
+#define g_static_rw_lock_writer_unlock IA__g_static_rw_lock_writer_unlock
+
+extern __typeof (g_thread_foreach) IA__g_thread_foreach __attribute((visibility("hidden")));
+#define g_thread_foreach IA__g_thread_foreach
+
+extern __typeof (g_thread_get_initialized) IA__g_thread_get_initialized __attribute((visibility("hidden")));
+#define g_thread_get_initialized IA__g_thread_get_initialized
+
+#endif
+#endif
+#if IN_HEADER(__G_THREADPOOL_H__)
+#if IN_FILE(__G_THREADPOOL_C__)
+extern __typeof (g_thread_pool_free) IA__g_thread_pool_free __attribute((visibility("hidden")));
+#define g_thread_pool_free IA__g_thread_pool_free
+
+extern __typeof (g_thread_pool_get_max_threads) IA__g_thread_pool_get_max_threads __attribute((visibility("hidden")));
+#define g_thread_pool_get_max_threads IA__g_thread_pool_get_max_threads
+
+extern __typeof (g_thread_pool_get_max_unused_threads) IA__g_thread_pool_get_max_unused_threads __attribute((visibility("hidden")));
+#define g_thread_pool_get_max_unused_threads IA__g_thread_pool_get_max_unused_threads
+
+extern __typeof (g_thread_pool_get_max_idle_time) IA__g_thread_pool_get_max_idle_time __attribute((visibility("hidden")));
+#define g_thread_pool_get_max_idle_time IA__g_thread_pool_get_max_idle_time
+
+extern __typeof (g_thread_pool_get_num_threads) IA__g_thread_pool_get_num_threads __attribute((visibility("hidden")));
+#define g_thread_pool_get_num_threads IA__g_thread_pool_get_num_threads
+
+extern __typeof (g_thread_pool_get_num_unused_threads) IA__g_thread_pool_get_num_unused_threads __attribute((visibility("hidden")));
+#define g_thread_pool_get_num_unused_threads IA__g_thread_pool_get_num_unused_threads
+
+extern __typeof (g_thread_pool_new) IA__g_thread_pool_new __attribute((visibility("hidden")));
+#define g_thread_pool_new IA__g_thread_pool_new
+
+extern __typeof (g_thread_pool_push) IA__g_thread_pool_push __attribute((visibility("hidden")));
+#define g_thread_pool_push IA__g_thread_pool_push
+
+extern __typeof (g_thread_pool_set_max_threads) IA__g_thread_pool_set_max_threads __attribute((visibility("hidden")));
+#define g_thread_pool_set_max_threads IA__g_thread_pool_set_max_threads
+
+extern __typeof (g_thread_pool_set_max_unused_threads) IA__g_thread_pool_set_max_unused_threads __attribute((visibility("hidden")));
+#define g_thread_pool_set_max_unused_threads IA__g_thread_pool_set_max_unused_threads
+
+extern __typeof (g_thread_pool_set_max_idle_time) IA__g_thread_pool_set_max_idle_time __attribute((visibility("hidden")));
+#define g_thread_pool_set_max_idle_time IA__g_thread_pool_set_max_idle_time
+
+extern __typeof (g_thread_pool_stop_unused_threads) IA__g_thread_pool_stop_unused_threads __attribute((visibility("hidden")));
+#define g_thread_pool_stop_unused_threads IA__g_thread_pool_stop_unused_threads
+
+extern __typeof (g_thread_pool_unprocessed) IA__g_thread_pool_unprocessed __attribute((visibility("hidden")));
+#define g_thread_pool_unprocessed IA__g_thread_pool_unprocessed
+
+extern __typeof (g_thread_pool_set_sort_function) IA__g_thread_pool_set_sort_function __attribute((visibility("hidden")));
+#define g_thread_pool_set_sort_function IA__g_thread_pool_set_sort_function
+
+#endif
+#endif
+#if IN_HEADER(__G_TEST_UTILS_H__)
+#if IN_FILE(__G_TEST_UTILS_C__)
+extern __typeof (g_assertion_message) IA__g_assertion_message __attribute((visibility("hidden"))) G_GNUC_NORETURN;
+#define g_assertion_message IA__g_assertion_message
+
+extern __typeof (g_assertion_message_cmpnum) IA__g_assertion_message_cmpnum __attribute((visibility("hidden"))) G_GNUC_NORETURN;
+#define g_assertion_message_cmpnum IA__g_assertion_message_cmpnum
+
+extern __typeof (g_assertion_message_cmpstr) IA__g_assertion_message_cmpstr __attribute((visibility("hidden"))) G_GNUC_NORETURN;
+#define g_assertion_message_cmpstr IA__g_assertion_message_cmpstr
+
+extern __typeof (g_assertion_message_expr) IA__g_assertion_message_expr __attribute((visibility("hidden"))) G_GNUC_NORETURN;
+#define g_assertion_message_expr IA__g_assertion_message_expr
+
+extern __typeof (g_assertion_message_error) IA__g_assertion_message_error __attribute((visibility("hidden"))) G_GNUC_NORETURN;
+#define g_assertion_message_error IA__g_assertion_message_error
+
+extern __typeof (g_strcmp0) IA__g_strcmp0 __attribute((visibility("hidden")));
+#define g_strcmp0 IA__g_strcmp0
+
+extern __typeof (g_test_add_data_func) IA__g_test_add_data_func __attribute((visibility("hidden")));
+#define g_test_add_data_func IA__g_test_add_data_func
+
+extern __typeof (g_test_add_func) IA__g_test_add_func __attribute((visibility("hidden")));
+#define g_test_add_func IA__g_test_add_func
+
+extern __typeof (g_test_add_vtable) IA__g_test_add_vtable __attribute((visibility("hidden")));
+#define g_test_add_vtable IA__g_test_add_vtable
+
+extern __typeof (g_test_bug) IA__g_test_bug __attribute((visibility("hidden")));
+#define g_test_bug IA__g_test_bug
+
+extern __typeof (g_test_bug_base) IA__g_test_bug_base __attribute((visibility("hidden")));
+#define g_test_bug_base IA__g_test_bug_base
+
+extern __typeof (g_test_create_case) IA__g_test_create_case __attribute((visibility("hidden")));
+#define g_test_create_case IA__g_test_create_case
+
+extern __typeof (g_test_create_suite) IA__g_test_create_suite __attribute((visibility("hidden")));
+#define g_test_create_suite IA__g_test_create_suite
+
+extern __typeof (g_test_get_root) IA__g_test_get_root __attribute((visibility("hidden")));
+#define g_test_get_root IA__g_test_get_root
+
+extern __typeof (g_test_init) IA__g_test_init __attribute((visibility("hidden")));
+#define g_test_init IA__g_test_init
+
+extern __typeof (g_test_log_buffer_free) IA__g_test_log_buffer_free __attribute((visibility("hidden")));
+#define g_test_log_buffer_free IA__g_test_log_buffer_free
+
+extern __typeof (g_test_log_buffer_new) IA__g_test_log_buffer_new __attribute((visibility("hidden")));
+#define g_test_log_buffer_new IA__g_test_log_buffer_new
+
+extern __typeof (g_test_log_buffer_pop) IA__g_test_log_buffer_pop __attribute((visibility("hidden")));
+#define g_test_log_buffer_pop IA__g_test_log_buffer_pop
+
+extern __typeof (g_test_log_buffer_push) IA__g_test_log_buffer_push __attribute((visibility("hidden")));
+#define g_test_log_buffer_push IA__g_test_log_buffer_push
+
+extern __typeof (g_test_log_msg_free) IA__g_test_log_msg_free __attribute((visibility("hidden")));
+#define g_test_log_msg_free IA__g_test_log_msg_free
+
+extern __typeof (g_test_log_type_name) IA__g_test_log_type_name __attribute((visibility("hidden")));
+#define g_test_log_type_name IA__g_test_log_type_name
+
+extern __typeof (g_test_maximized_result) IA__g_test_maximized_result __attribute((visibility("hidden")));
+#define g_test_maximized_result IA__g_test_maximized_result
+
+extern __typeof (g_test_message) IA__g_test_message __attribute((visibility("hidden")));
+#define g_test_message IA__g_test_message
+
+extern __typeof (g_test_minimized_result) IA__g_test_minimized_result __attribute((visibility("hidden")));
+#define g_test_minimized_result IA__g_test_minimized_result
+
+extern __typeof (g_test_queue_destroy) IA__g_test_queue_destroy __attribute((visibility("hidden")));
+#define g_test_queue_destroy IA__g_test_queue_destroy
+
+extern __typeof (g_test_queue_free) IA__g_test_queue_free __attribute((visibility("hidden")));
+#define g_test_queue_free IA__g_test_queue_free
+
+extern __typeof (g_test_rand_double) IA__g_test_rand_double __attribute((visibility("hidden")));
+#define g_test_rand_double IA__g_test_rand_double
+
+extern __typeof (g_test_rand_double_range) IA__g_test_rand_double_range __attribute((visibility("hidden")));
+#define g_test_rand_double_range IA__g_test_rand_double_range
+
+extern __typeof (g_test_rand_int) IA__g_test_rand_int __attribute((visibility("hidden")));
+#define g_test_rand_int IA__g_test_rand_int
+
+extern __typeof (g_test_rand_int_range) IA__g_test_rand_int_range __attribute((visibility("hidden")));
+#define g_test_rand_int_range IA__g_test_rand_int_range
+
+extern __typeof (g_test_run) IA__g_test_run __attribute((visibility("hidden")));
+#define g_test_run IA__g_test_run
+
+extern __typeof (g_test_run_suite) IA__g_test_run_suite __attribute((visibility("hidden")));
+#define g_test_run_suite IA__g_test_run_suite
+
+extern __typeof (g_test_suite_add) IA__g_test_suite_add __attribute((visibility("hidden")));
+#define g_test_suite_add IA__g_test_suite_add
+
+extern __typeof (g_test_suite_add_suite) IA__g_test_suite_add_suite __attribute((visibility("hidden")));
+#define g_test_suite_add_suite IA__g_test_suite_add_suite
+
+extern __typeof (g_test_timer_elapsed) IA__g_test_timer_elapsed __attribute((visibility("hidden")));
+#define g_test_timer_elapsed IA__g_test_timer_elapsed
+
+extern __typeof (g_test_timer_last) IA__g_test_timer_last __attribute((visibility("hidden")));
+#define g_test_timer_last IA__g_test_timer_last
+
+extern __typeof (g_test_timer_start) IA__g_test_timer_start __attribute((visibility("hidden")));
+#define g_test_timer_start IA__g_test_timer_start
+
+extern __typeof (g_test_trap_assertions) IA__g_test_trap_assertions __attribute((visibility("hidden")));
+#define g_test_trap_assertions IA__g_test_trap_assertions
+
+extern __typeof (g_test_trap_fork) IA__g_test_trap_fork __attribute((visibility("hidden")));
+#define g_test_trap_fork IA__g_test_trap_fork
+
+extern __typeof (g_test_trap_has_passed) IA__g_test_trap_has_passed __attribute((visibility("hidden")));
+#define g_test_trap_has_passed IA__g_test_trap_has_passed
+
+extern __typeof (g_test_trap_reached_timeout) IA__g_test_trap_reached_timeout __attribute((visibility("hidden")));
+#define g_test_trap_reached_timeout IA__g_test_trap_reached_timeout
+
+#endif
+#endif
+#if IN_HEADER(__G_TIMER_H__)
+#if IN_FILE(__G_TIMER_C__)
+extern __typeof (g_timer_continue) IA__g_timer_continue __attribute((visibility("hidden")));
+#define g_timer_continue IA__g_timer_continue
+
+extern __typeof (g_timer_destroy) IA__g_timer_destroy __attribute((visibility("hidden")));
+#define g_timer_destroy IA__g_timer_destroy
+
+extern __typeof (g_timer_elapsed) IA__g_timer_elapsed __attribute((visibility("hidden")));
+#define g_timer_elapsed IA__g_timer_elapsed
+
+extern __typeof (g_timer_new) IA__g_timer_new __attribute((visibility("hidden")));
+#define g_timer_new IA__g_timer_new
+
+extern __typeof (g_timer_reset) IA__g_timer_reset __attribute((visibility("hidden")));
+#define g_timer_reset IA__g_timer_reset
+
+extern __typeof (g_timer_start) IA__g_timer_start __attribute((visibility("hidden")));
+#define g_timer_start IA__g_timer_start
+
+extern __typeof (g_timer_stop) IA__g_timer_stop __attribute((visibility("hidden")));
+#define g_timer_stop IA__g_timer_stop
+
+extern __typeof (g_time_val_add) IA__g_time_val_add __attribute((visibility("hidden")));
+#define g_time_val_add IA__g_time_val_add
+
+extern __typeof (g_time_val_from_iso8601) IA__g_time_val_from_iso8601 __attribute((visibility("hidden")));
+#define g_time_val_from_iso8601 IA__g_time_val_from_iso8601
+
+extern __typeof (g_time_val_to_iso8601) IA__g_time_val_to_iso8601 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_time_val_to_iso8601 IA__g_time_val_to_iso8601
+
+extern __typeof (g_usleep) IA__g_usleep __attribute((visibility("hidden")));
+#define g_usleep IA__g_usleep
+
+#endif
+#endif
+#if IN_HEADER(__G_TREE_H__)
+#if IN_FILE(__G_TREE_C__)
+extern __typeof (g_tree_destroy) IA__g_tree_destroy __attribute((visibility("hidden")));
+#define g_tree_destroy IA__g_tree_destroy
+
+extern __typeof (g_tree_foreach) IA__g_tree_foreach __attribute((visibility("hidden")));
+#define g_tree_foreach IA__g_tree_foreach
+
+extern __typeof (g_tree_height) IA__g_tree_height __attribute((visibility("hidden")));
+#define g_tree_height IA__g_tree_height
+
+extern __typeof (g_tree_insert) IA__g_tree_insert __attribute((visibility("hidden")));
+#define g_tree_insert IA__g_tree_insert
+
+extern __typeof (g_tree_lookup) IA__g_tree_lookup __attribute((visibility("hidden")));
+#define g_tree_lookup IA__g_tree_lookup
+
+extern __typeof (g_tree_lookup_extended) IA__g_tree_lookup_extended __attribute((visibility("hidden")));
+#define g_tree_lookup_extended IA__g_tree_lookup_extended
+
+extern __typeof (g_tree_new) IA__g_tree_new __attribute((visibility("hidden")));
+#define g_tree_new IA__g_tree_new
+
+extern __typeof (g_tree_new_full) IA__g_tree_new_full __attribute((visibility("hidden")));
+#define g_tree_new_full IA__g_tree_new_full
+
+extern __typeof (g_tree_new_with_data) IA__g_tree_new_with_data __attribute((visibility("hidden")));
+#define g_tree_new_with_data IA__g_tree_new_with_data
+
+extern __typeof (g_tree_nnodes) IA__g_tree_nnodes __attribute((visibility("hidden")));
+#define g_tree_nnodes IA__g_tree_nnodes
+
+extern __typeof (g_tree_remove) IA__g_tree_remove __attribute((visibility("hidden")));
+#define g_tree_remove IA__g_tree_remove
+
+extern __typeof (g_tree_replace) IA__g_tree_replace __attribute((visibility("hidden")));
+#define g_tree_replace IA__g_tree_replace
+
+extern __typeof (g_tree_search) IA__g_tree_search __attribute((visibility("hidden")));
+#define g_tree_search IA__g_tree_search
+
+extern __typeof (g_tree_steal) IA__g_tree_steal __attribute((visibility("hidden")));
+#define g_tree_steal IA__g_tree_steal
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_tree_traverse) IA__g_tree_traverse __attribute((visibility("hidden")));
+#define g_tree_traverse IA__g_tree_traverse
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIBREAK_C__)
+extern __typeof (g_unichar_break_type) IA__g_unichar_break_type __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_break_type IA__g_unichar_break_type
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNICOLLATE_C__)
+extern __typeof (g_utf8_collate) IA__g_utf8_collate __attribute((visibility("hidden")));
+#define g_utf8_collate IA__g_utf8_collate
+
+extern __typeof (g_utf8_collate_key) IA__g_utf8_collate_key __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_collate_key IA__g_utf8_collate_key
+
+extern __typeof (g_utf8_collate_key_for_filename) IA__g_utf8_collate_key_for_filename __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_collate_key_for_filename IA__g_utf8_collate_key_for_filename
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIDECOMP_C__)
+extern __typeof (g_unicode_canonical_decomposition) IA__g_unicode_canonical_decomposition __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_unicode_canonical_decomposition IA__g_unicode_canonical_decomposition
+
+extern __typeof (g_unicode_canonical_ordering) IA__g_unicode_canonical_ordering __attribute((visibility("hidden")));
+#define g_unicode_canonical_ordering IA__g_unicode_canonical_ordering
+
+extern __typeof (g_unichar_combining_class) IA__g_unichar_combining_class __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_combining_class IA__g_unichar_combining_class
+
+extern __typeof (g_utf8_normalize) IA__g_utf8_normalize __attribute((visibility("hidden")));
+#define g_utf8_normalize IA__g_utf8_normalize
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIPROP_C__)
+extern __typeof (g_unichar_isalnum) IA__g_unichar_isalnum __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isalnum IA__g_unichar_isalnum
+
+extern __typeof (g_unichar_isalpha) IA__g_unichar_isalpha __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isalpha IA__g_unichar_isalpha
+
+extern __typeof (g_unichar_iscntrl) IA__g_unichar_iscntrl __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_iscntrl IA__g_unichar_iscntrl
+
+extern __typeof (g_unichar_isdefined) IA__g_unichar_isdefined __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isdefined IA__g_unichar_isdefined
+
+extern __typeof (g_unichar_isdigit) IA__g_unichar_isdigit __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isdigit IA__g_unichar_isdigit
+
+extern __typeof (g_unichar_isgraph) IA__g_unichar_isgraph __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isgraph IA__g_unichar_isgraph
+
+extern __typeof (g_unichar_islower) IA__g_unichar_islower __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_islower IA__g_unichar_islower
+
+extern __typeof (g_unichar_isprint) IA__g_unichar_isprint __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isprint IA__g_unichar_isprint
+
+extern __typeof (g_unichar_ispunct) IA__g_unichar_ispunct __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_ispunct IA__g_unichar_ispunct
+
+extern __typeof (g_unichar_isspace) IA__g_unichar_isspace __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isspace IA__g_unichar_isspace
+
+extern __typeof (g_unichar_istitle) IA__g_unichar_istitle __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_istitle IA__g_unichar_istitle
+
+extern __typeof (g_unichar_isupper) IA__g_unichar_isupper __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isupper IA__g_unichar_isupper
+
+extern __typeof (g_unichar_iswide) IA__g_unichar_iswide __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_iswide IA__g_unichar_iswide
+
+extern __typeof (g_unichar_iswide_cjk) IA__g_unichar_iswide_cjk __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_iswide_cjk IA__g_unichar_iswide_cjk
+
+extern __typeof (g_unichar_isxdigit) IA__g_unichar_isxdigit __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_isxdigit IA__g_unichar_isxdigit
+
+extern __typeof (g_unichar_iszerowidth) IA__g_unichar_iszerowidth __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_iszerowidth IA__g_unichar_iszerowidth
+
+extern __typeof (g_unichar_tolower) IA__g_unichar_tolower __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_tolower IA__g_unichar_tolower
+
+extern __typeof (g_unichar_totitle) IA__g_unichar_totitle __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_totitle IA__g_unichar_totitle
+
+extern __typeof (g_unichar_toupper) IA__g_unichar_toupper __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_toupper IA__g_unichar_toupper
+
+extern __typeof (g_unichar_ismark) IA__g_unichar_ismark __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_ismark IA__g_unichar_ismark
+
+extern __typeof (g_unichar_get_mirror_char) IA__g_unichar_get_mirror_char __attribute((visibility("hidden")));
+#define g_unichar_get_mirror_char IA__g_unichar_get_mirror_char
+
+extern __typeof (g_unichar_get_script) IA__g_unichar_get_script __attribute((visibility("hidden")));
+#define g_unichar_get_script IA__g_unichar_get_script
+
+extern __typeof (g_unichar_digit_value) IA__g_unichar_digit_value __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_digit_value IA__g_unichar_digit_value
+
+extern __typeof (g_unichar_xdigit_value) IA__g_unichar_xdigit_value __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_xdigit_value IA__g_unichar_xdigit_value
+
+extern __typeof (g_unichar_type) IA__g_unichar_type __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_unichar_type IA__g_unichar_type
+
+extern __typeof (g_utf8_casefold) IA__g_utf8_casefold __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_casefold IA__g_utf8_casefold
+
+extern __typeof (g_utf8_strup) IA__g_utf8_strup __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_strup IA__g_utf8_strup
+
+extern __typeof (g_utf8_strdown) IA__g_utf8_strdown __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_strdown IA__g_utf8_strdown
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UTF8_C__)
+extern __typeof (g_get_charset) IA__g_get_charset __attribute((visibility("hidden")));
+#define g_get_charset IA__g_get_charset
+
+extern __typeof (g_ucs4_to_utf16) IA__g_ucs4_to_utf16 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_ucs4_to_utf16 IA__g_ucs4_to_utf16
+
+extern __typeof (g_ucs4_to_utf8) IA__g_ucs4_to_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_ucs4_to_utf8 IA__g_ucs4_to_utf8
+
+extern __typeof (g_utf16_to_ucs4) IA__g_utf16_to_ucs4 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf16_to_ucs4 IA__g_utf16_to_ucs4
+
+extern __typeof (g_utf16_to_utf8) IA__g_utf16_to_utf8 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf16_to_utf8 IA__g_utf16_to_utf8
+
+extern __typeof (g_utf8_find_next_char) IA__g_utf8_find_next_char __attribute((visibility("hidden")));
+#define g_utf8_find_next_char IA__g_utf8_find_next_char
+
+extern __typeof (g_utf8_find_prev_char) IA__g_utf8_find_prev_char __attribute((visibility("hidden")));
+#define g_utf8_find_prev_char IA__g_utf8_find_prev_char
+
+extern __typeof (g_utf8_get_char) IA__g_utf8_get_char __attribute((visibility("hidden")));
+#define g_utf8_get_char IA__g_utf8_get_char
+
+extern __typeof (g_utf8_get_char_validated) IA__g_utf8_get_char_validated __attribute((visibility("hidden")));
+#define g_utf8_get_char_validated IA__g_utf8_get_char_validated
+
+extern __typeof (g_utf8_offset_to_pointer) IA__g_utf8_offset_to_pointer __attribute((visibility("hidden")));
+#define g_utf8_offset_to_pointer IA__g_utf8_offset_to_pointer
+
+extern __typeof (g_utf8_pointer_to_offset) IA__g_utf8_pointer_to_offset __attribute((visibility("hidden")));
+#define g_utf8_pointer_to_offset IA__g_utf8_pointer_to_offset
+
+extern __typeof (g_utf8_prev_char) IA__g_utf8_prev_char __attribute((visibility("hidden")));
+#define g_utf8_prev_char IA__g_utf8_prev_char
+
+extern __typeof (g_utf8_strchr) IA__g_utf8_strchr __attribute((visibility("hidden")));
+#define g_utf8_strchr IA__g_utf8_strchr
+
+extern __typeof (g_utf8_strlen) IA__g_utf8_strlen __attribute((visibility("hidden")));
+#define g_utf8_strlen IA__g_utf8_strlen
+
+extern __typeof (g_utf8_strncpy) IA__g_utf8_strncpy __attribute((visibility("hidden")));
+#define g_utf8_strncpy IA__g_utf8_strncpy
+
+extern __typeof (g_utf8_strrchr) IA__g_utf8_strrchr __attribute((visibility("hidden")));
+#define g_utf8_strrchr IA__g_utf8_strrchr
+
+extern __typeof (g_utf8_strreverse) IA__g_utf8_strreverse __attribute((visibility("hidden")));
+#define g_utf8_strreverse IA__g_utf8_strreverse
+
+extern __typeof (g_utf8_to_ucs4) IA__g_utf8_to_ucs4 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_to_ucs4 IA__g_utf8_to_ucs4
+
+extern __typeof (g_utf8_to_ucs4_fast) IA__g_utf8_to_ucs4_fast __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_to_ucs4_fast IA__g_utf8_to_ucs4_fast
+
+extern __typeof (g_utf8_to_utf16) IA__g_utf8_to_utf16 __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_utf8_to_utf16 IA__g_utf8_to_utf16
+
+extern __typeof (g_utf8_validate) IA__g_utf8_validate __attribute((visibility("hidden")));
+#define g_utf8_validate IA__g_utf8_validate
+
+extern __typeof (g_unichar_to_utf8) IA__g_unichar_to_utf8 __attribute((visibility("hidden")));
+#define g_unichar_to_utf8 IA__g_unichar_to_utf8
+
+extern __typeof (g_unichar_validate) IA__g_unichar_validate __attribute((visibility("hidden")));
+#define g_unichar_validate IA__g_unichar_validate
+
+#endif
+#endif
+#if IN_HEADER(__GLIBINTL_H__)
+#if IN_FILE(__G_UTILS_C__)
+extern __typeof (glib_gettext) IA__glib_gettext __attribute((visibility("hidden"))) G_GNUC_FORMAT(1);
+#define glib_gettext IA__glib_gettext
+
+#endif
+#endif
+#if IN_HEADER(__G_HASH_H__)
+#if IN_FILE(__G_UTILS_C__)
+extern __typeof (g_int_equal) IA__g_int_equal __attribute((visibility("hidden")));
+#define g_int_equal IA__g_int_equal
+
+extern __typeof (g_int_hash) IA__g_int_hash __attribute((visibility("hidden")));
+#define g_int_hash IA__g_int_hash
+
+extern __typeof (g_direct_equal) IA__g_direct_equal __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_direct_equal IA__g_direct_equal
+
+extern __typeof (g_direct_hash) IA__g_direct_hash __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define g_direct_hash IA__g_direct_hash
+
+#endif
+#endif
+#if IN_HEADER(__G_UTILS_H__)
+#if IN_FILE(__G_UTILS_C__)
+extern __typeof (g_atexit) IA__g_atexit __attribute((visibility("hidden")));
+#define g_atexit IA__g_atexit
+
+#ifndef G_DISABLE_DEPRECATED
+extern __typeof (g_basename) IA__g_basename __attribute((visibility("hidden")));
+#define g_basename IA__g_basename
+
+#endif
+extern __typeof (g_get_application_name) IA__g_get_application_name __attribute((visibility("hidden")));
+#define g_get_application_name IA__g_get_application_name
+
+#ifndef _WIN64
+extern __typeof (g_find_program_in_path) IA__g_find_program_in_path __attribute((visibility("hidden")));
+#define g_find_program_in_path IA__g_find_program_in_path
+
+extern __typeof (g_get_current_dir) IA__g_get_current_dir __attribute((visibility("hidden")));
+#define g_get_current_dir IA__g_get_current_dir
+
+extern __typeof (g_getenv) IA__g_getenv __attribute((visibility("hidden")));
+#define g_getenv IA__g_getenv
+
+extern __typeof (g_unsetenv) IA__g_unsetenv __attribute((visibility("hidden")));
+#define g_unsetenv IA__g_unsetenv
+
+extern __typeof (g_get_home_dir) IA__g_get_home_dir __attribute((visibility("hidden")));
+#define g_get_home_dir IA__g_get_home_dir
+
+#endif
+extern __typeof (g_get_host_name) IA__g_get_host_name __attribute((visibility("hidden")));
+#define g_get_host_name IA__g_get_host_name
+
+#ifndef _WIN64
+extern __typeof (g_setenv) IA__g_setenv __attribute((visibility("hidden")));
+#define g_setenv IA__g_setenv
+
+#endif
+extern __typeof (g_listenv) IA__g_listenv __attribute((visibility("hidden")));
+#define g_listenv IA__g_listenv
+
+#ifdef G_OS_WIN32
+extern __typeof (g_find_program_in_path_utf8) IA__g_find_program_in_path_utf8 __attribute((visibility("hidden")));
+#define g_find_program_in_path_utf8 IA__g_find_program_in_path_utf8
+
+extern __typeof (g_get_current_dir_utf8) IA__g_get_current_dir_utf8 __attribute((visibility("hidden")));
+#define g_get_current_dir_utf8 IA__g_get_current_dir_utf8
+
+extern __typeof (g_getenv_utf8) IA__g_getenv_utf8 __attribute((visibility("hidden")));
+#define g_getenv_utf8 IA__g_getenv_utf8
+
+extern __typeof (g_unsetenv_utf8) IA__g_unsetenv_utf8 __attribute((visibility("hidden")));
+#define g_unsetenv_utf8 IA__g_unsetenv_utf8
+
+extern __typeof (g_setenv_utf8) IA__g_setenv_utf8 __attribute((visibility("hidden")));
+#define g_setenv_utf8 IA__g_setenv_utf8
+
+extern __typeof (g_get_home_dir_utf8) IA__g_get_home_dir_utf8 __attribute((visibility("hidden")));
+#define g_get_home_dir_utf8 IA__g_get_home_dir_utf8
+
+#endif
+extern __typeof (g_get_language_names) IA__g_get_language_names __attribute((visibility("hidden")));
+#define g_get_language_names IA__g_get_language_names
+
+extern __typeof (g_get_prgname) IA__g_get_prgname __attribute((visibility("hidden")));
+#define g_get_prgname IA__g_get_prgname
+
+#ifndef _WIN64
+extern __typeof (g_get_real_name) IA__g_get_real_name __attribute((visibility("hidden")));
+#define g_get_real_name IA__g_get_real_name
+
+#endif
+#ifdef G_OS_WIN32
+extern __typeof (g_get_real_name_utf8) IA__g_get_real_name_utf8 __attribute((visibility("hidden")));
+#define g_get_real_name_utf8 IA__g_get_real_name_utf8
+
+#endif
+extern __typeof (g_get_system_config_dirs) IA__g_get_system_config_dirs __attribute((visibility("hidden")));
+#define g_get_system_config_dirs IA__g_get_system_config_dirs
+
+extern __typeof (g_get_system_data_dirs) IA__g_get_system_data_dirs __attribute((visibility("hidden")));
+#define g_get_system_data_dirs IA__g_get_system_data_dirs
+
+#ifdef G_OS_WIN32
+extern __typeof (g_win32_get_system_data_dirs_for_module) IA__g_win32_get_system_data_dirs_for_module __attribute((visibility("hidden")));
+#define g_win32_get_system_data_dirs_for_module IA__g_win32_get_system_data_dirs_for_module
+
+#endif
+#ifndef _WIN64
+extern __typeof (g_get_tmp_dir) IA__g_get_tmp_dir __attribute((visibility("hidden")));
+#define g_get_tmp_dir IA__g_get_tmp_dir
+
+#endif
+#ifdef G_OS_WIN32
+extern __typeof (g_get_tmp_dir_utf8) IA__g_get_tmp_dir_utf8 __attribute((visibility("hidden")));
+#define g_get_tmp_dir_utf8 IA__g_get_tmp_dir_utf8
+
+#endif
+extern __typeof (g_get_user_cache_dir) IA__g_get_user_cache_dir __attribute((visibility("hidden")));
+#define g_get_user_cache_dir IA__g_get_user_cache_dir
+
+extern __typeof (g_get_user_config_dir) IA__g_get_user_config_dir __attribute((visibility("hidden")));
+#define g_get_user_config_dir IA__g_get_user_config_dir
+
+extern __typeof (g_get_user_data_dir) IA__g_get_user_data_dir __attribute((visibility("hidden")));
+#define g_get_user_data_dir IA__g_get_user_data_dir
+
+extern __typeof (g_get_user_special_dir) IA__g_get_user_special_dir __attribute((visibility("hidden")));
+#define g_get_user_special_dir IA__g_get_user_special_dir
+
+#ifndef _WIN64
+extern __typeof (g_get_user_name) IA__g_get_user_name __attribute((visibility("hidden")));
+#define g_get_user_name IA__g_get_user_name
+
+#endif
+#ifdef G_OS_WIN32
+extern __typeof (g_get_user_name_utf8) IA__g_get_user_name_utf8 __attribute((visibility("hidden")));
+#define g_get_user_name_utf8 IA__g_get_user_name_utf8
+
+#endif
+extern __typeof (glib_check_version) IA__glib_check_version __attribute((visibility("hidden")));
+#define glib_check_version IA__glib_check_version
+
+extern __typeof (g_nullify_pointer) IA__g_nullify_pointer __attribute((visibility("hidden")));
+#define g_nullify_pointer IA__g_nullify_pointer
+
+extern __typeof (g_parse_debug_string) IA__g_parse_debug_string __attribute((visibility("hidden")));
+#define g_parse_debug_string IA__g_parse_debug_string
+
+extern __typeof (g_path_get_basename) IA__g_path_get_basename __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_path_get_basename IA__g_path_get_basename
+
+extern __typeof (g_path_get_dirname) IA__g_path_get_dirname __attribute((visibility("hidden"))) G_GNUC_MALLOC;
+#define g_path_get_dirname IA__g_path_get_dirname
+
+extern __typeof (g_path_is_absolute) IA__g_path_is_absolute __attribute((visibility("hidden")));
+#define g_path_is_absolute IA__g_path_is_absolute
+
+extern __typeof (g_path_skip_root) IA__g_path_skip_root __attribute((visibility("hidden")));
+#define g_path_skip_root IA__g_path_skip_root
+
+extern __typeof (g_set_application_name) IA__g_set_application_name __attribute((visibility("hidden")));
+#define g_set_application_name IA__g_set_application_name
+
+extern __typeof (g_set_prgname) IA__g_set_prgname __attribute((visibility("hidden")));
+#define g_set_prgname IA__g_set_prgname
+
+#endif
+#endif
+#if IN_HEADER(__G_REGEX_H__)
+#if IN_FILE(__G_REGEX_C__)
+extern __typeof (g_regex_error_quark) IA__g_regex_error_quark __attribute((visibility("hidden")));
+#define g_regex_error_quark IA__g_regex_error_quark
+
+extern __typeof (g_regex_new) IA__g_regex_new __attribute((visibility("hidden")));
+#define g_regex_new IA__g_regex_new
+
+extern __typeof (g_regex_ref) IA__g_regex_ref __attribute((visibility("hidden")));
+#define g_regex_ref IA__g_regex_ref
+
+extern __typeof (g_regex_unref) IA__g_regex_unref __attribute((visibility("hidden")));
+#define g_regex_unref IA__g_regex_unref
+
+extern __typeof (g_regex_get_pattern) IA__g_regex_get_pattern __attribute((visibility("hidden")));
+#define g_regex_get_pattern IA__g_regex_get_pattern
+
+extern __typeof (g_regex_get_max_backref) IA__g_regex_get_max_backref __attribute((visibility("hidden")));
+#define g_regex_get_max_backref IA__g_regex_get_max_backref
+
+extern __typeof (g_regex_get_capture_count) IA__g_regex_get_capture_count __attribute((visibility("hidden")));
+#define g_regex_get_capture_count IA__g_regex_get_capture_count
+
+extern __typeof (g_regex_get_string_number) IA__g_regex_get_string_number __attribute((visibility("hidden")));
+#define g_regex_get_string_number IA__g_regex_get_string_number
+
+extern __typeof (g_regex_escape_string) IA__g_regex_escape_string __attribute((visibility("hidden")));
+#define g_regex_escape_string IA__g_regex_escape_string
+
+extern __typeof (g_regex_match_simple) IA__g_regex_match_simple __attribute((visibility("hidden")));
+#define g_regex_match_simple IA__g_regex_match_simple
+
+extern __typeof (g_regex_match) IA__g_regex_match __attribute((visibility("hidden")));
+#define g_regex_match IA__g_regex_match
+
+extern __typeof (g_regex_match_full) IA__g_regex_match_full __attribute((visibility("hidden")));
+#define g_regex_match_full IA__g_regex_match_full
+
+extern __typeof (g_regex_match_all) IA__g_regex_match_all __attribute((visibility("hidden")));
+#define g_regex_match_all IA__g_regex_match_all
+
+extern __typeof (g_regex_match_all_full) IA__g_regex_match_all_full __attribute((visibility("hidden")));
+#define g_regex_match_all_full IA__g_regex_match_all_full
+
+extern __typeof (g_regex_split_simple) IA__g_regex_split_simple __attribute((visibility("hidden")));
+#define g_regex_split_simple IA__g_regex_split_simple
+
+extern __typeof (g_regex_split) IA__g_regex_split __attribute((visibility("hidden")));
+#define g_regex_split IA__g_regex_split
+
+extern __typeof (g_regex_split_full) IA__g_regex_split_full __attribute((visibility("hidden")));
+#define g_regex_split_full IA__g_regex_split_full
+
+extern __typeof (g_regex_replace) IA__g_regex_replace __attribute((visibility("hidden")));
+#define g_regex_replace IA__g_regex_replace
+
+extern __typeof (g_regex_replace_literal) IA__g_regex_replace_literal __attribute((visibility("hidden")));
+#define g_regex_replace_literal IA__g_regex_replace_literal
+
+extern __typeof (g_regex_replace_eval) IA__g_regex_replace_eval __attribute((visibility("hidden")));
+#define g_regex_replace_eval IA__g_regex_replace_eval
+
+extern __typeof (g_regex_check_replacement) IA__g_regex_check_replacement __attribute((visibility("hidden")));
+#define g_regex_check_replacement IA__g_regex_check_replacement
+
+extern __typeof (g_match_info_get_regex) IA__g_match_info_get_regex __attribute((visibility("hidden")));
+#define g_match_info_get_regex IA__g_match_info_get_regex
+
+extern __typeof (g_match_info_get_string) IA__g_match_info_get_string __attribute((visibility("hidden")));
+#define g_match_info_get_string IA__g_match_info_get_string
+
+extern __typeof (g_match_info_free) IA__g_match_info_free __attribute((visibility("hidden")));
+#define g_match_info_free IA__g_match_info_free
+
+extern __typeof (g_match_info_next) IA__g_match_info_next __attribute((visibility("hidden")));
+#define g_match_info_next IA__g_match_info_next
+
+extern __typeof (g_match_info_matches) IA__g_match_info_matches __attribute((visibility("hidden")));
+#define g_match_info_matches IA__g_match_info_matches
+
+extern __typeof (g_match_info_get_match_count) IA__g_match_info_get_match_count __attribute((visibility("hidden")));
+#define g_match_info_get_match_count IA__g_match_info_get_match_count
+
+extern __typeof (g_match_info_is_partial_match) IA__g_match_info_is_partial_match __attribute((visibility("hidden")));
+#define g_match_info_is_partial_match IA__g_match_info_is_partial_match
+
+extern __typeof (g_match_info_expand_references) IA__g_match_info_expand_references __attribute((visibility("hidden")));
+#define g_match_info_expand_references IA__g_match_info_expand_references
+
+extern __typeof (g_match_info_fetch) IA__g_match_info_fetch __attribute((visibility("hidden")));
+#define g_match_info_fetch IA__g_match_info_fetch
+
+extern __typeof (g_match_info_fetch_pos) IA__g_match_info_fetch_pos __attribute((visibility("hidden")));
+#define g_match_info_fetch_pos IA__g_match_info_fetch_pos
+
+extern __typeof (g_match_info_fetch_named) IA__g_match_info_fetch_named __attribute((visibility("hidden")));
+#define g_match_info_fetch_named IA__g_match_info_fetch_named
+
+extern __typeof (g_match_info_fetch_named_pos) IA__g_match_info_fetch_named_pos __attribute((visibility("hidden")));
+#define g_match_info_fetch_named_pos IA__g_match_info_fetch_named_pos
+
+extern __typeof (g_match_info_fetch_all) IA__g_match_info_fetch_all __attribute((visibility("hidden")));
+#define g_match_info_fetch_all IA__g_match_info_fetch_all
+
+#endif
+#endif
+#if IN_HEADER(__G_WIN32_H__)
+#if IN_FILE(__G_WIN32_H__)
+#ifdef G_OS_WIN32
+extern __typeof (g_win32_error_message) IA__g_win32_error_message __attribute((visibility("hidden")));
+#define g_win32_error_message IA__g_win32_error_message
+
+extern __typeof (g_win32_ftruncate) IA__g_win32_ftruncate __attribute((visibility("hidden")));
+#define g_win32_ftruncate IA__g_win32_ftruncate
+
+extern __typeof (g_win32_get_package_installation_directory_of_module) IA__g_win32_get_package_installation_directory_of_module __attribute((visibility("hidden")));
+#define g_win32_get_package_installation_directory_of_module IA__g_win32_get_package_installation_directory_of_module
+
+#ifndef _WIN64
+extern __typeof (g_win32_get_package_installation_directory) IA__g_win32_get_package_installation_directory __attribute((visibility("hidden")));
+#define g_win32_get_package_installation_directory IA__g_win32_get_package_installation_directory
+
+#endif
+extern __typeof (g_win32_get_package_installation_directory_utf8) IA__g_win32_get_package_installation_directory_utf8 __attribute((visibility("hidden")));
+#define g_win32_get_package_installation_directory_utf8 IA__g_win32_get_package_installation_directory_utf8
+
+#ifndef _WIN64
+extern __typeof (g_win32_get_package_installation_subdirectory) IA__g_win32_get_package_installation_subdirectory __attribute((visibility("hidden")));
+#define g_win32_get_package_installation_subdirectory IA__g_win32_get_package_installation_subdirectory
+
+#endif
+extern __typeof (g_win32_get_package_installation_subdirectory_utf8) IA__g_win32_get_package_installation_subdirectory_utf8 __attribute((visibility("hidden")));
+#define g_win32_get_package_installation_subdirectory_utf8 IA__g_win32_get_package_installation_subdirectory_utf8
+
+extern __typeof (g_win32_get_windows_version) IA__g_win32_get_windows_version __attribute((visibility("hidden")));
+#define g_win32_get_windows_version IA__g_win32_get_windows_version
+
+extern __typeof (g_win32_getlocale) IA__g_win32_getlocale __attribute((visibility("hidden")));
+#define g_win32_getlocale IA__g_win32_getlocale
+
+extern __typeof (g_win32_locale_filename_from_utf8) IA__g_win32_locale_filename_from_utf8 __attribute((visibility("hidden")));
+#define g_win32_locale_filename_from_utf8 IA__g_win32_locale_filename_from_utf8
+
+#endif
+#endif
+#endif
+
+#endif /* G_HAVE_GNUC_VISIBILITY */
+#endif /* DISABLE_VISIBILITY */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/galiasdef.c b/desmume/src/windows/glib-2.20.1/build/glib/galiasdef.c
new file mode 100644
index 000000000..8f1ec7ff5
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/galiasdef.c
@@ -0,0 +1,3889 @@
+/* Generated by makegalias.pl */
+
+#ifndef DISABLE_VISIBILITY
+
+#include "glibconfig.h"
+
+#ifdef G_HAVE_GNUC_VISIBILITY
+
+#undef IN_FILE
+#define IN_FILE defined
+
+#undef IN_HEADER
+#define IN_HEADER(x) 1
+
+#if IN_HEADER(__G_ARRAY_H__)
+#if IN_FILE(__G_ARRAY_C__)
+#undef g_array_append_vals
+extern __typeof (g_array_append_vals) g_array_append_vals __attribute((alias("IA__g_array_append_vals"), visibility("default")));
+
+#undef g_array_free
+extern __typeof (g_array_free) g_array_free __attribute((alias("IA__g_array_free"), visibility("default")));
+
+#undef g_array_insert_vals
+extern __typeof (g_array_insert_vals) g_array_insert_vals __attribute((alias("IA__g_array_insert_vals"), visibility("default")));
+
+#undef g_array_new
+extern __typeof (g_array_new) g_array_new __attribute((alias("IA__g_array_new"), visibility("default")));
+
+#undef g_array_prepend_vals
+extern __typeof (g_array_prepend_vals) g_array_prepend_vals __attribute((alias("IA__g_array_prepend_vals"), visibility("default")));
+
+#undef g_array_remove_index
+extern __typeof (g_array_remove_index) g_array_remove_index __attribute((alias("IA__g_array_remove_index"), visibility("default")));
+
+#undef g_array_remove_index_fast
+extern __typeof (g_array_remove_index_fast) g_array_remove_index_fast __attribute((alias("IA__g_array_remove_index_fast"), visibility("default")));
+
+#undef g_array_remove_range
+extern __typeof (g_array_remove_range) g_array_remove_range __attribute((alias("IA__g_array_remove_range"), visibility("default")));
+
+#undef g_array_set_size
+extern __typeof (g_array_set_size) g_array_set_size __attribute((alias("IA__g_array_set_size"), visibility("default")));
+
+#undef g_array_sized_new
+extern __typeof (g_array_sized_new) g_array_sized_new __attribute((alias("IA__g_array_sized_new"), visibility("default")));
+
+#undef g_array_sort
+extern __typeof (g_array_sort) g_array_sort __attribute((alias("IA__g_array_sort"), visibility("default")));
+
+#undef g_array_sort_with_data
+extern __typeof (g_array_sort_with_data) g_array_sort_with_data __attribute((alias("IA__g_array_sort_with_data"), visibility("default")));
+
+#undef g_byte_array_append
+extern __typeof (g_byte_array_append) g_byte_array_append __attribute((alias("IA__g_byte_array_append"), visibility("default")));
+
+#undef g_byte_array_free
+extern __typeof (g_byte_array_free) g_byte_array_free __attribute((alias("IA__g_byte_array_free"), visibility("default")));
+
+#undef g_byte_array_new
+extern __typeof (g_byte_array_new) g_byte_array_new __attribute((alias("IA__g_byte_array_new"), visibility("default")));
+
+#undef g_byte_array_prepend
+extern __typeof (g_byte_array_prepend) g_byte_array_prepend __attribute((alias("IA__g_byte_array_prepend"), visibility("default")));
+
+#undef g_byte_array_remove_index
+extern __typeof (g_byte_array_remove_index) g_byte_array_remove_index __attribute((alias("IA__g_byte_array_remove_index"), visibility("default")));
+
+#undef g_byte_array_remove_index_fast
+extern __typeof (g_byte_array_remove_index_fast) g_byte_array_remove_index_fast __attribute((alias("IA__g_byte_array_remove_index_fast"), visibility("default")));
+
+#undef g_byte_array_remove_range
+extern __typeof (g_byte_array_remove_range) g_byte_array_remove_range __attribute((alias("IA__g_byte_array_remove_range"), visibility("default")));
+
+#undef g_byte_array_set_size
+extern __typeof (g_byte_array_set_size) g_byte_array_set_size __attribute((alias("IA__g_byte_array_set_size"), visibility("default")));
+
+#undef g_byte_array_sized_new
+extern __typeof (g_byte_array_sized_new) g_byte_array_sized_new __attribute((alias("IA__g_byte_array_sized_new"), visibility("default")));
+
+#undef g_byte_array_sort
+extern __typeof (g_byte_array_sort) g_byte_array_sort __attribute((alias("IA__g_byte_array_sort"), visibility("default")));
+
+#undef g_byte_array_sort_with_data
+extern __typeof (g_byte_array_sort_with_data) g_byte_array_sort_with_data __attribute((alias("IA__g_byte_array_sort_with_data"), visibility("default")));
+
+#undef g_ptr_array_add
+extern __typeof (g_ptr_array_add) g_ptr_array_add __attribute((alias("IA__g_ptr_array_add"), visibility("default")));
+
+#undef g_ptr_array_foreach
+extern __typeof (g_ptr_array_foreach) g_ptr_array_foreach __attribute((alias("IA__g_ptr_array_foreach"), visibility("default")));
+
+#undef g_ptr_array_free
+extern __typeof (g_ptr_array_free) g_ptr_array_free __attribute((alias("IA__g_ptr_array_free"), visibility("default")));
+
+#undef g_ptr_array_new
+extern __typeof (g_ptr_array_new) g_ptr_array_new __attribute((alias("IA__g_ptr_array_new"), visibility("default")));
+
+#undef g_ptr_array_remove
+extern __typeof (g_ptr_array_remove) g_ptr_array_remove __attribute((alias("IA__g_ptr_array_remove"), visibility("default")));
+
+#undef g_ptr_array_remove_fast
+extern __typeof (g_ptr_array_remove_fast) g_ptr_array_remove_fast __attribute((alias("IA__g_ptr_array_remove_fast"), visibility("default")));
+
+#undef g_ptr_array_remove_index
+extern __typeof (g_ptr_array_remove_index) g_ptr_array_remove_index __attribute((alias("IA__g_ptr_array_remove_index"), visibility("default")));
+
+#undef g_ptr_array_remove_index_fast
+extern __typeof (g_ptr_array_remove_index_fast) g_ptr_array_remove_index_fast __attribute((alias("IA__g_ptr_array_remove_index_fast"), visibility("default")));
+
+#undef g_ptr_array_remove_range
+extern __typeof (g_ptr_array_remove_range) g_ptr_array_remove_range __attribute((alias("IA__g_ptr_array_remove_range"), visibility("default")));
+
+#undef g_ptr_array_set_size
+extern __typeof (g_ptr_array_set_size) g_ptr_array_set_size __attribute((alias("IA__g_ptr_array_set_size"), visibility("default")));
+
+#undef g_ptr_array_sized_new
+extern __typeof (g_ptr_array_sized_new) g_ptr_array_sized_new __attribute((alias("IA__g_ptr_array_sized_new"), visibility("default")));
+
+#undef g_ptr_array_sort
+extern __typeof (g_ptr_array_sort) g_ptr_array_sort __attribute((alias("IA__g_ptr_array_sort"), visibility("default")));
+
+#undef g_ptr_array_sort_with_data
+extern __typeof (g_ptr_array_sort_with_data) g_ptr_array_sort_with_data __attribute((alias("IA__g_ptr_array_sort_with_data"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_ASYNCQUEUE_H__)
+#if IN_FILE(__G_ASYNCQUEUE_C__)
+#undef g_async_queue_length
+extern __typeof (g_async_queue_length) g_async_queue_length __attribute((alias("IA__g_async_queue_length"), visibility("default")));
+
+#undef g_async_queue_length_unlocked
+extern __typeof (g_async_queue_length_unlocked) g_async_queue_length_unlocked __attribute((alias("IA__g_async_queue_length_unlocked"), visibility("default")));
+
+#undef g_async_queue_lock
+extern __typeof (g_async_queue_lock) g_async_queue_lock __attribute((alias("IA__g_async_queue_lock"), visibility("default")));
+
+#undef g_async_queue_new
+extern __typeof (g_async_queue_new) g_async_queue_new __attribute((alias("IA__g_async_queue_new"), visibility("default")));
+
+#undef g_async_queue_new_full
+extern __typeof (g_async_queue_new_full) g_async_queue_new_full __attribute((alias("IA__g_async_queue_new_full"), visibility("default")));
+
+#undef g_async_queue_pop
+extern __typeof (g_async_queue_pop) g_async_queue_pop __attribute((alias("IA__g_async_queue_pop"), visibility("default")));
+
+#undef g_async_queue_pop_unlocked
+extern __typeof (g_async_queue_pop_unlocked) g_async_queue_pop_unlocked __attribute((alias("IA__g_async_queue_pop_unlocked"), visibility("default")));
+
+#undef g_async_queue_push
+extern __typeof (g_async_queue_push) g_async_queue_push __attribute((alias("IA__g_async_queue_push"), visibility("default")));
+
+#undef g_async_queue_push_unlocked
+extern __typeof (g_async_queue_push_unlocked) g_async_queue_push_unlocked __attribute((alias("IA__g_async_queue_push_unlocked"), visibility("default")));
+
+#undef g_async_queue_push_sorted
+extern __typeof (g_async_queue_push_sorted) g_async_queue_push_sorted __attribute((alias("IA__g_async_queue_push_sorted"), visibility("default")));
+
+#undef g_async_queue_push_sorted_unlocked
+extern __typeof (g_async_queue_push_sorted_unlocked) g_async_queue_push_sorted_unlocked __attribute((alias("IA__g_async_queue_push_sorted_unlocked"), visibility("default")));
+
+#undef g_async_queue_ref
+extern __typeof (g_async_queue_ref) g_async_queue_ref __attribute((alias("IA__g_async_queue_ref"), visibility("default")));
+
+#undef g_async_queue_sort
+extern __typeof (g_async_queue_sort) g_async_queue_sort __attribute((alias("IA__g_async_queue_sort"), visibility("default")));
+
+#undef g_async_queue_sort_unlocked
+extern __typeof (g_async_queue_sort_unlocked) g_async_queue_sort_unlocked __attribute((alias("IA__g_async_queue_sort_unlocked"), visibility("default")));
+
+#undef g_async_queue_timed_pop
+extern __typeof (g_async_queue_timed_pop) g_async_queue_timed_pop __attribute((alias("IA__g_async_queue_timed_pop"), visibility("default")));
+
+#undef g_async_queue_timed_pop_unlocked
+extern __typeof (g_async_queue_timed_pop_unlocked) g_async_queue_timed_pop_unlocked __attribute((alias("IA__g_async_queue_timed_pop_unlocked"), visibility("default")));
+
+#undef g_async_queue_try_pop
+extern __typeof (g_async_queue_try_pop) g_async_queue_try_pop __attribute((alias("IA__g_async_queue_try_pop"), visibility("default")));
+
+#undef g_async_queue_try_pop_unlocked
+extern __typeof (g_async_queue_try_pop_unlocked) g_async_queue_try_pop_unlocked __attribute((alias("IA__g_async_queue_try_pop_unlocked"), visibility("default")));
+
+#undef g_async_queue_unlock
+extern __typeof (g_async_queue_unlock) g_async_queue_unlock __attribute((alias("IA__g_async_queue_unlock"), visibility("default")));
+
+#undef g_async_queue_unref
+extern __typeof (g_async_queue_unref) g_async_queue_unref __attribute((alias("IA__g_async_queue_unref"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_async_queue_ref_unlocked
+extern __typeof (g_async_queue_ref_unlocked) g_async_queue_ref_unlocked __attribute((alias("IA__g_async_queue_ref_unlocked"), visibility("default")));
+
+#undef g_async_queue_unref_and_unlock
+extern __typeof (g_async_queue_unref_and_unlock) g_async_queue_unref_and_unlock __attribute((alias("IA__g_async_queue_unref_and_unlock"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_ATOMIC_H__)
+#if IN_FILE(__G_ATOMIC_C__)
+#undef g_atomic_int_add
+extern __typeof (g_atomic_int_add) g_atomic_int_add __attribute((alias("IA__g_atomic_int_add"), visibility("default")));
+
+#undef g_atomic_int_compare_and_exchange
+extern __typeof (g_atomic_int_compare_and_exchange) g_atomic_int_compare_and_exchange __attribute((alias("IA__g_atomic_int_compare_and_exchange"), visibility("default")));
+
+#undef g_atomic_int_exchange_and_add
+extern __typeof (g_atomic_int_exchange_and_add) g_atomic_int_exchange_and_add __attribute((alias("IA__g_atomic_int_exchange_and_add"), visibility("default")));
+
+#undef g_atomic_pointer_compare_and_exchange
+extern __typeof (g_atomic_pointer_compare_and_exchange) g_atomic_pointer_compare_and_exchange __attribute((alias("IA__g_atomic_pointer_compare_and_exchange"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_BACKTRACE_H__)
+#if IN_FILE(__G_BACKTRACE_C__)
+#undef g_on_error_query
+extern __typeof (g_on_error_query) g_on_error_query __attribute((alias("IA__g_on_error_query"), visibility("default")));
+
+#undef g_on_error_stack_trace
+extern __typeof (g_on_error_stack_trace) g_on_error_stack_trace __attribute((alias("IA__g_on_error_stack_trace"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_BASE64_H__)
+#if IN_FILE(__G_BASE64_C__)
+#undef g_base64_encode_step
+extern __typeof (g_base64_encode_step) g_base64_encode_step __attribute((alias("IA__g_base64_encode_step"), visibility("default")));
+
+#undef g_base64_encode_close
+extern __typeof (g_base64_encode_close) g_base64_encode_close __attribute((alias("IA__g_base64_encode_close"), visibility("default")));
+
+#undef g_base64_encode
+extern __typeof (g_base64_encode) g_base64_encode __attribute((alias("IA__g_base64_encode"), visibility("default")));
+
+#undef g_base64_decode_step
+extern __typeof (g_base64_decode_step) g_base64_decode_step __attribute((alias("IA__g_base64_decode_step"), visibility("default")));
+
+#undef g_base64_decode
+extern __typeof (g_base64_decode) g_base64_decode __attribute((alias("IA__g_base64_decode"), visibility("default")));
+
+#undef g_base64_decode_inplace
+extern __typeof (g_base64_decode_inplace) g_base64_decode_inplace __attribute((alias("IA__g_base64_decode_inplace"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_BOOKMARK_FILE_H__)
+#if IN_FILE(__G_BOOKMARK_FILE_C__)
+#undef g_bookmark_file_error_quark
+extern __typeof (g_bookmark_file_error_quark) g_bookmark_file_error_quark __attribute((alias("IA__g_bookmark_file_error_quark"), visibility("default")));
+
+#undef g_bookmark_file_new
+extern __typeof (g_bookmark_file_new) g_bookmark_file_new __attribute((alias("IA__g_bookmark_file_new"), visibility("default")));
+
+#undef g_bookmark_file_free
+extern __typeof (g_bookmark_file_free) g_bookmark_file_free __attribute((alias("IA__g_bookmark_file_free"), visibility("default")));
+
+#undef g_bookmark_file_load_from_file
+extern __typeof (g_bookmark_file_load_from_file) g_bookmark_file_load_from_file __attribute((alias("IA__g_bookmark_file_load_from_file"), visibility("default")));
+
+#undef g_bookmark_file_load_from_data
+extern __typeof (g_bookmark_file_load_from_data) g_bookmark_file_load_from_data __attribute((alias("IA__g_bookmark_file_load_from_data"), visibility("default")));
+
+#undef g_bookmark_file_load_from_data_dirs
+extern __typeof (g_bookmark_file_load_from_data_dirs) g_bookmark_file_load_from_data_dirs __attribute((alias("IA__g_bookmark_file_load_from_data_dirs"), visibility("default")));
+
+#undef g_bookmark_file_to_data
+extern __typeof (g_bookmark_file_to_data) g_bookmark_file_to_data __attribute((alias("IA__g_bookmark_file_to_data"), visibility("default")));
+
+#undef g_bookmark_file_to_file
+extern __typeof (g_bookmark_file_to_file) g_bookmark_file_to_file __attribute((alias("IA__g_bookmark_file_to_file"), visibility("default")));
+
+#undef g_bookmark_file_set_title
+extern __typeof (g_bookmark_file_set_title) g_bookmark_file_set_title __attribute((alias("IA__g_bookmark_file_set_title"), visibility("default")));
+
+#undef g_bookmark_file_get_title
+extern __typeof (g_bookmark_file_get_title) g_bookmark_file_get_title __attribute((alias("IA__g_bookmark_file_get_title"), visibility("default")));
+
+#undef g_bookmark_file_set_description
+extern __typeof (g_bookmark_file_set_description) g_bookmark_file_set_description __attribute((alias("IA__g_bookmark_file_set_description"), visibility("default")));
+
+#undef g_bookmark_file_get_description
+extern __typeof (g_bookmark_file_get_description) g_bookmark_file_get_description __attribute((alias("IA__g_bookmark_file_get_description"), visibility("default")));
+
+#undef g_bookmark_file_set_mime_type
+extern __typeof (g_bookmark_file_set_mime_type) g_bookmark_file_set_mime_type __attribute((alias("IA__g_bookmark_file_set_mime_type"), visibility("default")));
+
+#undef g_bookmark_file_get_mime_type
+extern __typeof (g_bookmark_file_get_mime_type) g_bookmark_file_get_mime_type __attribute((alias("IA__g_bookmark_file_get_mime_type"), visibility("default")));
+
+#undef g_bookmark_file_set_groups
+extern __typeof (g_bookmark_file_set_groups) g_bookmark_file_set_groups __attribute((alias("IA__g_bookmark_file_set_groups"), visibility("default")));
+
+#undef g_bookmark_file_add_group
+extern __typeof (g_bookmark_file_add_group) g_bookmark_file_add_group __attribute((alias("IA__g_bookmark_file_add_group"), visibility("default")));
+
+#undef g_bookmark_file_has_group
+extern __typeof (g_bookmark_file_has_group) g_bookmark_file_has_group __attribute((alias("IA__g_bookmark_file_has_group"), visibility("default")));
+
+#undef g_bookmark_file_get_groups
+extern __typeof (g_bookmark_file_get_groups) g_bookmark_file_get_groups __attribute((alias("IA__g_bookmark_file_get_groups"), visibility("default")));
+
+#undef g_bookmark_file_add_application
+extern __typeof (g_bookmark_file_add_application) g_bookmark_file_add_application __attribute((alias("IA__g_bookmark_file_add_application"), visibility("default")));
+
+#undef g_bookmark_file_has_application
+extern __typeof (g_bookmark_file_has_application) g_bookmark_file_has_application __attribute((alias("IA__g_bookmark_file_has_application"), visibility("default")));
+
+#undef g_bookmark_file_get_applications
+extern __typeof (g_bookmark_file_get_applications) g_bookmark_file_get_applications __attribute((alias("IA__g_bookmark_file_get_applications"), visibility("default")));
+
+#undef g_bookmark_file_set_app_info
+extern __typeof (g_bookmark_file_set_app_info) g_bookmark_file_set_app_info __attribute((alias("IA__g_bookmark_file_set_app_info"), visibility("default")));
+
+#undef g_bookmark_file_get_app_info
+extern __typeof (g_bookmark_file_get_app_info) g_bookmark_file_get_app_info __attribute((alias("IA__g_bookmark_file_get_app_info"), visibility("default")));
+
+#undef g_bookmark_file_set_is_private
+extern __typeof (g_bookmark_file_set_is_private) g_bookmark_file_set_is_private __attribute((alias("IA__g_bookmark_file_set_is_private"), visibility("default")));
+
+#undef g_bookmark_file_get_is_private
+extern __typeof (g_bookmark_file_get_is_private) g_bookmark_file_get_is_private __attribute((alias("IA__g_bookmark_file_get_is_private"), visibility("default")));
+
+#undef g_bookmark_file_set_icon
+extern __typeof (g_bookmark_file_set_icon) g_bookmark_file_set_icon __attribute((alias("IA__g_bookmark_file_set_icon"), visibility("default")));
+
+#undef g_bookmark_file_get_icon
+extern __typeof (g_bookmark_file_get_icon) g_bookmark_file_get_icon __attribute((alias("IA__g_bookmark_file_get_icon"), visibility("default")));
+
+#undef g_bookmark_file_set_added
+extern __typeof (g_bookmark_file_set_added) g_bookmark_file_set_added __attribute((alias("IA__g_bookmark_file_set_added"), visibility("default")));
+
+#undef g_bookmark_file_get_added
+extern __typeof (g_bookmark_file_get_added) g_bookmark_file_get_added __attribute((alias("IA__g_bookmark_file_get_added"), visibility("default")));
+
+#undef g_bookmark_file_set_modified
+extern __typeof (g_bookmark_file_set_modified) g_bookmark_file_set_modified __attribute((alias("IA__g_bookmark_file_set_modified"), visibility("default")));
+
+#undef g_bookmark_file_get_modified
+extern __typeof (g_bookmark_file_get_modified) g_bookmark_file_get_modified __attribute((alias("IA__g_bookmark_file_get_modified"), visibility("default")));
+
+#undef g_bookmark_file_set_visited
+extern __typeof (g_bookmark_file_set_visited) g_bookmark_file_set_visited __attribute((alias("IA__g_bookmark_file_set_visited"), visibility("default")));
+
+#undef g_bookmark_file_get_visited
+extern __typeof (g_bookmark_file_get_visited) g_bookmark_file_get_visited __attribute((alias("IA__g_bookmark_file_get_visited"), visibility("default")));
+
+#undef g_bookmark_file_has_item
+extern __typeof (g_bookmark_file_has_item) g_bookmark_file_has_item __attribute((alias("IA__g_bookmark_file_has_item"), visibility("default")));
+
+#undef g_bookmark_file_get_size
+extern __typeof (g_bookmark_file_get_size) g_bookmark_file_get_size __attribute((alias("IA__g_bookmark_file_get_size"), visibility("default")));
+
+#undef g_bookmark_file_get_uris
+extern __typeof (g_bookmark_file_get_uris) g_bookmark_file_get_uris __attribute((alias("IA__g_bookmark_file_get_uris"), visibility("default")));
+
+#undef g_bookmark_file_remove_group
+extern __typeof (g_bookmark_file_remove_group) g_bookmark_file_remove_group __attribute((alias("IA__g_bookmark_file_remove_group"), visibility("default")));
+
+#undef g_bookmark_file_remove_application
+extern __typeof (g_bookmark_file_remove_application) g_bookmark_file_remove_application __attribute((alias("IA__g_bookmark_file_remove_application"), visibility("default")));
+
+#undef g_bookmark_file_remove_item
+extern __typeof (g_bookmark_file_remove_item) g_bookmark_file_remove_item __attribute((alias("IA__g_bookmark_file_remove_item"), visibility("default")));
+
+#undef g_bookmark_file_move_item
+extern __typeof (g_bookmark_file_move_item) g_bookmark_file_move_item __attribute((alias("IA__g_bookmark_file_move_item"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_CACHE_H__)
+#if IN_FILE(__G_CACHE_C__)
+#undef g_cache_destroy
+extern __typeof (g_cache_destroy) g_cache_destroy __attribute((alias("IA__g_cache_destroy"), visibility("default")));
+
+#undef g_cache_insert
+extern __typeof (g_cache_insert) g_cache_insert __attribute((alias("IA__g_cache_insert"), visibility("default")));
+
+#undef g_cache_key_foreach
+extern __typeof (g_cache_key_foreach) g_cache_key_foreach __attribute((alias("IA__g_cache_key_foreach"), visibility("default")));
+
+#undef g_cache_new
+extern __typeof (g_cache_new) g_cache_new __attribute((alias("IA__g_cache_new"), visibility("default")));
+
+#undef g_cache_remove
+extern __typeof (g_cache_remove) g_cache_remove __attribute((alias("IA__g_cache_remove"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_cache_value_foreach
+extern __typeof (g_cache_value_foreach) g_cache_value_foreach __attribute((alias("IA__g_cache_value_foreach"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_CHECKSUM_H__)
+#if IN_FILE(__G_CHECKSUM_C__)
+#undef g_checksum_type_get_length
+extern __typeof (g_checksum_type_get_length) g_checksum_type_get_length __attribute((alias("IA__g_checksum_type_get_length"), visibility("default")));
+
+#undef g_checksum_new
+extern __typeof (g_checksum_new) g_checksum_new __attribute((alias("IA__g_checksum_new"), visibility("default")));
+
+#undef g_checksum_copy
+extern __typeof (g_checksum_copy) g_checksum_copy __attribute((alias("IA__g_checksum_copy"), visibility("default")));
+
+#undef g_checksum_free
+extern __typeof (g_checksum_free) g_checksum_free __attribute((alias("IA__g_checksum_free"), visibility("default")));
+
+#undef g_checksum_update
+extern __typeof (g_checksum_update) g_checksum_update __attribute((alias("IA__g_checksum_update"), visibility("default")));
+
+#undef g_checksum_reset
+extern __typeof (g_checksum_reset) g_checksum_reset __attribute((alias("IA__g_checksum_reset"), visibility("default")));
+
+#undef g_checksum_get_string
+extern __typeof (g_checksum_get_string) g_checksum_get_string __attribute((alias("IA__g_checksum_get_string"), visibility("default")));
+
+#undef g_checksum_get_digest
+extern __typeof (g_checksum_get_digest) g_checksum_get_digest __attribute((alias("IA__g_checksum_get_digest"), visibility("default")));
+
+#undef g_compute_checksum_for_data
+extern __typeof (g_compute_checksum_for_data) g_compute_checksum_for_data __attribute((alias("IA__g_compute_checksum_for_data"), visibility("default")));
+
+#undef g_compute_checksum_for_string
+extern __typeof (g_compute_checksum_for_string) g_compute_checksum_for_string __attribute((alias("IA__g_compute_checksum_for_string"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_COMPLETION_H__)
+#if IN_FILE(__G_COMPLETION_C__)
+#undef g_completion_add_items
+extern __typeof (g_completion_add_items) g_completion_add_items __attribute((alias("IA__g_completion_add_items"), visibility("default")));
+
+#undef g_completion_clear_items
+extern __typeof (g_completion_clear_items) g_completion_clear_items __attribute((alias("IA__g_completion_clear_items"), visibility("default")));
+
+#undef g_completion_complete
+extern __typeof (g_completion_complete) g_completion_complete __attribute((alias("IA__g_completion_complete"), visibility("default")));
+
+#undef g_completion_complete_utf8
+extern __typeof (g_completion_complete_utf8) g_completion_complete_utf8 __attribute((alias("IA__g_completion_complete_utf8"), visibility("default")));
+
+#undef g_completion_free
+extern __typeof (g_completion_free) g_completion_free __attribute((alias("IA__g_completion_free"), visibility("default")));
+
+#undef g_completion_new
+extern __typeof (g_completion_new) g_completion_new __attribute((alias("IA__g_completion_new"), visibility("default")));
+
+#undef g_completion_remove_items
+extern __typeof (g_completion_remove_items) g_completion_remove_items __attribute((alias("IA__g_completion_remove_items"), visibility("default")));
+
+#undef g_completion_set_compare
+extern __typeof (g_completion_set_compare) g_completion_set_compare __attribute((alias("IA__g_completion_set_compare"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_CONVERT_H__)
+#if IN_FILE(__G_CONVERT_C__)
+#undef g_get_filename_charsets
+extern __typeof (g_get_filename_charsets) g_get_filename_charsets __attribute((alias("IA__g_get_filename_charsets"), visibility("default")));
+
+#undef g_convert
+extern __typeof (g_convert) g_convert __attribute((alias("IA__g_convert"), visibility("default")));
+
+#undef g_convert_error_quark
+extern __typeof (g_convert_error_quark) g_convert_error_quark __attribute((alias("IA__g_convert_error_quark"), visibility("default")));
+
+#undef g_convert_with_fallback
+extern __typeof (g_convert_with_fallback) g_convert_with_fallback __attribute((alias("IA__g_convert_with_fallback"), visibility("default")));
+
+#undef g_convert_with_iconv
+extern __typeof (g_convert_with_iconv) g_convert_with_iconv __attribute((alias("IA__g_convert_with_iconv"), visibility("default")));
+
+#undef g_iconv
+extern __typeof (g_iconv) g_iconv __attribute((alias("IA__g_iconv"), visibility("default")));
+
+#undef g_iconv_close
+extern __typeof (g_iconv_close) g_iconv_close __attribute((alias("IA__g_iconv_close"), visibility("default")));
+
+#undef g_iconv_open
+extern __typeof (g_iconv_open) g_iconv_open __attribute((alias("IA__g_iconv_open"), visibility("default")));
+
+#undef g_locale_from_utf8
+extern __typeof (g_locale_from_utf8) g_locale_from_utf8 __attribute((alias("IA__g_locale_from_utf8"), visibility("default")));
+
+#undef g_locale_to_utf8
+extern __typeof (g_locale_to_utf8) g_locale_to_utf8 __attribute((alias("IA__g_locale_to_utf8"), visibility("default")));
+
+#undef g_filename_display_name
+extern __typeof (g_filename_display_name) g_filename_display_name __attribute((alias("IA__g_filename_display_name"), visibility("default")));
+
+#undef g_filename_display_basename
+extern __typeof (g_filename_display_basename) g_filename_display_basename __attribute((alias("IA__g_filename_display_basename"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_filename_from_uri
+extern __typeof (g_filename_from_uri) g_filename_from_uri __attribute((alias("IA__g_filename_from_uri"), visibility("default")));
+
+#undef g_filename_from_utf8
+extern __typeof (g_filename_from_utf8) g_filename_from_utf8 __attribute((alias("IA__g_filename_from_utf8"), visibility("default")));
+
+#undef g_filename_to_uri
+extern __typeof (g_filename_to_uri) g_filename_to_uri __attribute((alias("IA__g_filename_to_uri"), visibility("default")));
+
+#undef g_filename_to_utf8
+extern __typeof (g_filename_to_utf8) g_filename_to_utf8 __attribute((alias("IA__g_filename_to_utf8"), visibility("default")));
+
+#endif
+#ifdef G_OS_WIN32
+#undef g_filename_from_uri_utf8
+extern __typeof (g_filename_from_uri_utf8) g_filename_from_uri_utf8 __attribute((alias("IA__g_filename_from_uri_utf8"), visibility("default")));
+
+#undef g_filename_from_utf8_utf8
+extern __typeof (g_filename_from_utf8_utf8) g_filename_from_utf8_utf8 __attribute((alias("IA__g_filename_from_utf8_utf8"), visibility("default")));
+
+#undef g_filename_to_uri_utf8
+extern __typeof (g_filename_to_uri_utf8) g_filename_to_uri_utf8 __attribute((alias("IA__g_filename_to_uri_utf8"), visibility("default")));
+
+#undef g_filename_to_utf8_utf8
+extern __typeof (g_filename_to_utf8_utf8) g_filename_to_utf8_utf8 __attribute((alias("IA__g_filename_to_utf8_utf8"), visibility("default")));
+
+#endif
+#undef g_uri_list_extract_uris
+extern __typeof (g_uri_list_extract_uris) g_uri_list_extract_uris __attribute((alias("IA__g_uri_list_extract_uris"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_DATASET_H__)
+#if IN_FILE(__G_DATASET_C__)
+#undef g_datalist_clear
+extern __typeof (g_datalist_clear) g_datalist_clear __attribute((alias("IA__g_datalist_clear"), visibility("default")));
+
+#undef g_datalist_foreach
+extern __typeof (g_datalist_foreach) g_datalist_foreach __attribute((alias("IA__g_datalist_foreach"), visibility("default")));
+
+#undef g_datalist_get_flags
+extern __typeof (g_datalist_get_flags) g_datalist_get_flags __attribute((alias("IA__g_datalist_get_flags"), visibility("default")));
+
+#undef g_datalist_id_get_data
+extern __typeof (g_datalist_id_get_data) g_datalist_id_get_data __attribute((alias("IA__g_datalist_id_get_data"), visibility("default")));
+
+#undef g_datalist_id_remove_no_notify
+extern __typeof (g_datalist_id_remove_no_notify) g_datalist_id_remove_no_notify __attribute((alias("IA__g_datalist_id_remove_no_notify"), visibility("default")));
+
+#undef g_datalist_id_set_data_full
+extern __typeof (g_datalist_id_set_data_full) g_datalist_id_set_data_full __attribute((alias("IA__g_datalist_id_set_data_full"), visibility("default")));
+
+#undef g_datalist_set_flags
+extern __typeof (g_datalist_set_flags) g_datalist_set_flags __attribute((alias("IA__g_datalist_set_flags"), visibility("default")));
+
+#undef g_datalist_unset_flags
+extern __typeof (g_datalist_unset_flags) g_datalist_unset_flags __attribute((alias("IA__g_datalist_unset_flags"), visibility("default")));
+
+#undef g_datalist_init
+extern __typeof (g_datalist_init) g_datalist_init __attribute((alias("IA__g_datalist_init"), visibility("default")));
+
+#undef g_dataset_destroy
+extern __typeof (g_dataset_destroy) g_dataset_destroy __attribute((alias("IA__g_dataset_destroy"), visibility("default")));
+
+#undef g_dataset_foreach
+extern __typeof (g_dataset_foreach) g_dataset_foreach __attribute((alias("IA__g_dataset_foreach"), visibility("default")));
+
+#undef g_dataset_id_get_data
+extern __typeof (g_dataset_id_get_data) g_dataset_id_get_data __attribute((alias("IA__g_dataset_id_get_data"), visibility("default")));
+
+#undef g_dataset_id_remove_no_notify
+extern __typeof (g_dataset_id_remove_no_notify) g_dataset_id_remove_no_notify __attribute((alias("IA__g_dataset_id_remove_no_notify"), visibility("default")));
+
+#undef g_dataset_id_set_data_full
+extern __typeof (g_dataset_id_set_data_full) g_dataset_id_set_data_full __attribute((alias("IA__g_dataset_id_set_data_full"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_QUARK_H__)
+#if IN_FILE(__G_DATASET_C__)
+#undef g_quark_from_static_string
+extern __typeof (g_quark_from_static_string) g_quark_from_static_string __attribute((alias("IA__g_quark_from_static_string"), visibility("default")));
+
+#undef g_quark_from_string
+extern __typeof (g_quark_from_string) g_quark_from_string __attribute((alias("IA__g_quark_from_string"), visibility("default")));
+
+#undef g_quark_to_string
+extern __typeof (g_quark_to_string) g_quark_to_string __attribute((alias("IA__g_quark_to_string"), visibility("default")));
+
+#undef g_quark_try_string
+extern __typeof (g_quark_try_string) g_quark_try_string __attribute((alias("IA__g_quark_try_string"), visibility("default")));
+
+#undef g_intern_string
+extern __typeof (g_intern_string) g_intern_string __attribute((alias("IA__g_intern_string"), visibility("default")));
+
+#undef g_intern_static_string
+extern __typeof (g_intern_static_string) g_intern_static_string __attribute((alias("IA__g_intern_static_string"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_DATE_H__)
+#if IN_FILE(__G_DATE_C__)
+#undef g_date_add_days
+extern __typeof (g_date_add_days) g_date_add_days __attribute((alias("IA__g_date_add_days"), visibility("default")));
+
+#undef g_date_add_months
+extern __typeof (g_date_add_months) g_date_add_months __attribute((alias("IA__g_date_add_months"), visibility("default")));
+
+#undef g_date_add_years
+extern __typeof (g_date_add_years) g_date_add_years __attribute((alias("IA__g_date_add_years"), visibility("default")));
+
+#undef g_date_clamp
+extern __typeof (g_date_clamp) g_date_clamp __attribute((alias("IA__g_date_clamp"), visibility("default")));
+
+#undef g_date_clear
+extern __typeof (g_date_clear) g_date_clear __attribute((alias("IA__g_date_clear"), visibility("default")));
+
+#undef g_date_compare
+extern __typeof (g_date_compare) g_date_compare __attribute((alias("IA__g_date_compare"), visibility("default")));
+
+#undef g_date_days_between
+extern __typeof (g_date_days_between) g_date_days_between __attribute((alias("IA__g_date_days_between"), visibility("default")));
+
+#undef g_date_free
+extern __typeof (g_date_free) g_date_free __attribute((alias("IA__g_date_free"), visibility("default")));
+
+#undef g_date_get_day
+extern __typeof (g_date_get_day) g_date_get_day __attribute((alias("IA__g_date_get_day"), visibility("default")));
+
+#undef g_date_get_day_of_year
+extern __typeof (g_date_get_day_of_year) g_date_get_day_of_year __attribute((alias("IA__g_date_get_day_of_year"), visibility("default")));
+
+#undef g_date_get_days_in_month
+extern __typeof (g_date_get_days_in_month) g_date_get_days_in_month __attribute((alias("IA__g_date_get_days_in_month"), visibility("default")));
+
+#undef g_date_get_iso8601_week_of_year
+extern __typeof (g_date_get_iso8601_week_of_year) g_date_get_iso8601_week_of_year __attribute((alias("IA__g_date_get_iso8601_week_of_year"), visibility("default")));
+
+#undef g_date_get_julian
+extern __typeof (g_date_get_julian) g_date_get_julian __attribute((alias("IA__g_date_get_julian"), visibility("default")));
+
+#undef g_date_get_monday_week_of_year
+extern __typeof (g_date_get_monday_week_of_year) g_date_get_monday_week_of_year __attribute((alias("IA__g_date_get_monday_week_of_year"), visibility("default")));
+
+#undef g_date_get_monday_weeks_in_year
+extern __typeof (g_date_get_monday_weeks_in_year) g_date_get_monday_weeks_in_year __attribute((alias("IA__g_date_get_monday_weeks_in_year"), visibility("default")));
+
+#undef g_date_get_month
+extern __typeof (g_date_get_month) g_date_get_month __attribute((alias("IA__g_date_get_month"), visibility("default")));
+
+#undef g_date_get_sunday_week_of_year
+extern __typeof (g_date_get_sunday_week_of_year) g_date_get_sunday_week_of_year __attribute((alias("IA__g_date_get_sunday_week_of_year"), visibility("default")));
+
+#undef g_date_get_sunday_weeks_in_year
+extern __typeof (g_date_get_sunday_weeks_in_year) g_date_get_sunday_weeks_in_year __attribute((alias("IA__g_date_get_sunday_weeks_in_year"), visibility("default")));
+
+#undef g_date_get_weekday
+extern __typeof (g_date_get_weekday) g_date_get_weekday __attribute((alias("IA__g_date_get_weekday"), visibility("default")));
+
+#undef g_date_get_year
+extern __typeof (g_date_get_year) g_date_get_year __attribute((alias("IA__g_date_get_year"), visibility("default")));
+
+#undef g_date_is_first_of_month
+extern __typeof (g_date_is_first_of_month) g_date_is_first_of_month __attribute((alias("IA__g_date_is_first_of_month"), visibility("default")));
+
+#undef g_date_is_last_of_month
+extern __typeof (g_date_is_last_of_month) g_date_is_last_of_month __attribute((alias("IA__g_date_is_last_of_month"), visibility("default")));
+
+#undef g_date_is_leap_year
+extern __typeof (g_date_is_leap_year) g_date_is_leap_year __attribute((alias("IA__g_date_is_leap_year"), visibility("default")));
+
+#undef g_date_new
+extern __typeof (g_date_new) g_date_new __attribute((alias("IA__g_date_new"), visibility("default")));
+
+#undef g_date_new_dmy
+extern __typeof (g_date_new_dmy) g_date_new_dmy __attribute((alias("IA__g_date_new_dmy"), visibility("default")));
+
+#undef g_date_new_julian
+extern __typeof (g_date_new_julian) g_date_new_julian __attribute((alias("IA__g_date_new_julian"), visibility("default")));
+
+#undef g_date_order
+extern __typeof (g_date_order) g_date_order __attribute((alias("IA__g_date_order"), visibility("default")));
+
+#undef g_date_set_day
+extern __typeof (g_date_set_day) g_date_set_day __attribute((alias("IA__g_date_set_day"), visibility("default")));
+
+#undef g_date_set_dmy
+extern __typeof (g_date_set_dmy) g_date_set_dmy __attribute((alias("IA__g_date_set_dmy"), visibility("default")));
+
+#undef g_date_set_julian
+extern __typeof (g_date_set_julian) g_date_set_julian __attribute((alias("IA__g_date_set_julian"), visibility("default")));
+
+#undef g_date_set_month
+extern __typeof (g_date_set_month) g_date_set_month __attribute((alias("IA__g_date_set_month"), visibility("default")));
+
+#undef g_date_set_parse
+extern __typeof (g_date_set_parse) g_date_set_parse __attribute((alias("IA__g_date_set_parse"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_date_set_time
+extern __typeof (g_date_set_time) g_date_set_time __attribute((alias("IA__g_date_set_time"), visibility("default")));
+
+#endif
+#undef g_date_set_time_t
+extern __typeof (g_date_set_time_t) g_date_set_time_t __attribute((alias("IA__g_date_set_time_t"), visibility("default")));
+
+#undef g_date_set_time_val
+extern __typeof (g_date_set_time_val) g_date_set_time_val __attribute((alias("IA__g_date_set_time_val"), visibility("default")));
+
+#undef g_date_set_year
+extern __typeof (g_date_set_year) g_date_set_year __attribute((alias("IA__g_date_set_year"), visibility("default")));
+
+#undef g_date_strftime
+extern __typeof (g_date_strftime) g_date_strftime __attribute((alias("IA__g_date_strftime"), visibility("default")));
+
+#undef g_date_subtract_days
+extern __typeof (g_date_subtract_days) g_date_subtract_days __attribute((alias("IA__g_date_subtract_days"), visibility("default")));
+
+#undef g_date_subtract_months
+extern __typeof (g_date_subtract_months) g_date_subtract_months __attribute((alias("IA__g_date_subtract_months"), visibility("default")));
+
+#undef g_date_subtract_years
+extern __typeof (g_date_subtract_years) g_date_subtract_years __attribute((alias("IA__g_date_subtract_years"), visibility("default")));
+
+#undef g_date_to_struct_tm
+extern __typeof (g_date_to_struct_tm) g_date_to_struct_tm __attribute((alias("IA__g_date_to_struct_tm"), visibility("default")));
+
+#undef g_date_valid
+extern __typeof (g_date_valid) g_date_valid __attribute((alias("IA__g_date_valid"), visibility("default")));
+
+#undef g_date_valid_day
+extern __typeof (g_date_valid_day) g_date_valid_day __attribute((alias("IA__g_date_valid_day"), visibility("default")));
+
+#undef g_date_valid_dmy
+extern __typeof (g_date_valid_dmy) g_date_valid_dmy __attribute((alias("IA__g_date_valid_dmy"), visibility("default")));
+
+#undef g_date_valid_julian
+extern __typeof (g_date_valid_julian) g_date_valid_julian __attribute((alias("IA__g_date_valid_julian"), visibility("default")));
+
+#undef g_date_valid_month
+extern __typeof (g_date_valid_month) g_date_valid_month __attribute((alias("IA__g_date_valid_month"), visibility("default")));
+
+#undef g_date_valid_weekday
+extern __typeof (g_date_valid_weekday) g_date_valid_weekday __attribute((alias("IA__g_date_valid_weekday"), visibility("default")));
+
+#undef g_date_valid_year
+extern __typeof (g_date_valid_year) g_date_valid_year __attribute((alias("IA__g_date_valid_year"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_DIR_H__)
+#if IN_FILE(__G_DIR_C__)
+#undef g_dir_close
+extern __typeof (g_dir_close) g_dir_close __attribute((alias("IA__g_dir_close"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_dir_open
+extern __typeof (g_dir_open) g_dir_open __attribute((alias("IA__g_dir_open"), visibility("default")));
+
+#undef g_dir_read_name
+extern __typeof (g_dir_read_name) g_dir_read_name __attribute((alias("IA__g_dir_read_name"), visibility("default")));
+
+#endif
+#ifdef G_OS_WIN32
+#undef g_dir_open_utf8
+extern __typeof (g_dir_open_utf8) g_dir_open_utf8 __attribute((alias("IA__g_dir_open_utf8"), visibility("default")));
+
+#undef g_dir_read_name_utf8
+extern __typeof (g_dir_read_name_utf8) g_dir_read_name_utf8 __attribute((alias("IA__g_dir_read_name_utf8"), visibility("default")));
+
+#endif
+#undef g_dir_rewind
+extern __typeof (g_dir_rewind) g_dir_rewind __attribute((alias("IA__g_dir_rewind"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_ERROR_H__)
+#if IN_FILE(__G_ERROR_C__)
+#undef g_clear_error
+extern __typeof (g_clear_error) g_clear_error __attribute((alias("IA__g_clear_error"), visibility("default")));
+
+#undef g_error_copy
+extern __typeof (g_error_copy) g_error_copy __attribute((alias("IA__g_error_copy"), visibility("default")));
+
+#undef g_error_free
+extern __typeof (g_error_free) g_error_free __attribute((alias("IA__g_error_free"), visibility("default")));
+
+#undef g_error_matches
+extern __typeof (g_error_matches) g_error_matches __attribute((alias("IA__g_error_matches"), visibility("default")));
+
+#undef g_error_new
+extern __typeof (g_error_new) g_error_new __attribute((alias("IA__g_error_new"), visibility("default")));
+
+#undef g_error_new_literal
+extern __typeof (g_error_new_literal) g_error_new_literal __attribute((alias("IA__g_error_new_literal"), visibility("default")));
+
+#undef g_propagate_error
+extern __typeof (g_propagate_error) g_propagate_error __attribute((alias("IA__g_propagate_error"), visibility("default")));
+
+#undef g_set_error
+extern __typeof (g_set_error) g_set_error __attribute((alias("IA__g_set_error"), visibility("default")));
+
+#undef g_set_error_literal
+extern __typeof (g_set_error_literal) g_set_error_literal __attribute((alias("IA__g_set_error_literal"), visibility("default")));
+
+#undef g_prefix_error
+extern __typeof (g_prefix_error) g_prefix_error __attribute((alias("IA__g_prefix_error"), visibility("default")));
+
+#undef g_propagate_prefixed_error
+extern __typeof (g_propagate_prefixed_error) g_propagate_prefixed_error __attribute((alias("IA__g_propagate_prefixed_error"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_FILEUTILS_H__)
+#if IN_FILE(__G_FILEUTILS_C__)
+#undef g_build_filename
+extern __typeof (g_build_filename) g_build_filename __attribute((alias("IA__g_build_filename"), visibility("default")));
+
+#undef g_build_filenamev
+extern __typeof (g_build_filenamev) g_build_filenamev __attribute((alias("IA__g_build_filenamev"), visibility("default")));
+
+#undef g_build_path
+extern __typeof (g_build_path) g_build_path __attribute((alias("IA__g_build_path"), visibility("default")));
+
+#undef g_build_pathv
+extern __typeof (g_build_pathv) g_build_pathv __attribute((alias("IA__g_build_pathv"), visibility("default")));
+
+#undef g_file_error_from_errno
+extern __typeof (g_file_error_from_errno) g_file_error_from_errno __attribute((alias("IA__g_file_error_from_errno"), visibility("default")));
+
+#undef g_file_error_quark
+extern __typeof (g_file_error_quark) g_file_error_quark __attribute((alias("IA__g_file_error_quark"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_file_get_contents
+extern __typeof (g_file_get_contents) g_file_get_contents __attribute((alias("IA__g_file_get_contents"), visibility("default")));
+
+#endif
+#undef g_file_set_contents
+extern __typeof (g_file_set_contents) g_file_set_contents __attribute((alias("IA__g_file_set_contents"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_file_open_tmp
+extern __typeof (g_file_open_tmp) g_file_open_tmp __attribute((alias("IA__g_file_open_tmp"), visibility("default")));
+
+#undef g_file_test
+extern __typeof (g_file_test) g_file_test __attribute((alias("IA__g_file_test"), visibility("default")));
+
+#endif
+#undef g_file_read_link
+extern __typeof (g_file_read_link) g_file_read_link __attribute((alias("IA__g_file_read_link"), visibility("default")));
+
+#undef g_format_size_for_display
+extern __typeof (g_format_size_for_display) g_format_size_for_display __attribute((alias("IA__g_format_size_for_display"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_mkstemp
+extern __typeof (g_mkstemp) g_mkstemp __attribute((alias("IA__g_mkstemp"), visibility("default")));
+
+#endif
+#undef g_mkdir_with_parents
+extern __typeof (g_mkdir_with_parents) g_mkdir_with_parents __attribute((alias("IA__g_mkdir_with_parents"), visibility("default")));
+
+#ifdef G_OS_WIN32
+#undef g_file_get_contents_utf8
+extern __typeof (g_file_get_contents_utf8) g_file_get_contents_utf8 __attribute((alias("IA__g_file_get_contents_utf8"), visibility("default")));
+
+#undef g_file_open_tmp_utf8
+extern __typeof (g_file_open_tmp_utf8) g_file_open_tmp_utf8 __attribute((alias("IA__g_file_open_tmp_utf8"), visibility("default")));
+
+#undef g_file_test_utf8
+extern __typeof (g_file_test_utf8) g_file_test_utf8 __attribute((alias("IA__g_file_test_utf8"), visibility("default")));
+
+#undef g_mkstemp_utf8
+extern __typeof (g_mkstemp_utf8) g_mkstemp_utf8 __attribute((alias("IA__g_mkstemp_utf8"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_HASH_H__)
+#if IN_FILE(__G_HASH_C__)
+#undef g_hash_table_destroy
+extern __typeof (g_hash_table_destroy) g_hash_table_destroy __attribute((alias("IA__g_hash_table_destroy"), visibility("default")));
+
+#undef g_hash_table_unref
+extern __typeof (g_hash_table_unref) g_hash_table_unref __attribute((alias("IA__g_hash_table_unref"), visibility("default")));
+
+#undef g_hash_table_ref
+extern __typeof (g_hash_table_ref) g_hash_table_ref __attribute((alias("IA__g_hash_table_ref"), visibility("default")));
+
+#undef g_hash_table_find
+extern __typeof (g_hash_table_find) g_hash_table_find __attribute((alias("IA__g_hash_table_find"), visibility("default")));
+
+#undef g_hash_table_foreach
+extern __typeof (g_hash_table_foreach) g_hash_table_foreach __attribute((alias("IA__g_hash_table_foreach"), visibility("default")));
+
+#undef g_hash_table_foreach_remove
+extern __typeof (g_hash_table_foreach_remove) g_hash_table_foreach_remove __attribute((alias("IA__g_hash_table_foreach_remove"), visibility("default")));
+
+#undef g_hash_table_foreach_steal
+extern __typeof (g_hash_table_foreach_steal) g_hash_table_foreach_steal __attribute((alias("IA__g_hash_table_foreach_steal"), visibility("default")));
+
+#undef g_hash_table_get_keys
+extern __typeof (g_hash_table_get_keys) g_hash_table_get_keys __attribute((alias("IA__g_hash_table_get_keys"), visibility("default")));
+
+#undef g_hash_table_get_values
+extern __typeof (g_hash_table_get_values) g_hash_table_get_values __attribute((alias("IA__g_hash_table_get_values"), visibility("default")));
+
+#undef g_hash_table_insert
+extern __typeof (g_hash_table_insert) g_hash_table_insert __attribute((alias("IA__g_hash_table_insert"), visibility("default")));
+
+#undef g_hash_table_lookup
+extern __typeof (g_hash_table_lookup) g_hash_table_lookup __attribute((alias("IA__g_hash_table_lookup"), visibility("default")));
+
+#undef g_hash_table_lookup_extended
+extern __typeof (g_hash_table_lookup_extended) g_hash_table_lookup_extended __attribute((alias("IA__g_hash_table_lookup_extended"), visibility("default")));
+
+#undef g_hash_table_new
+extern __typeof (g_hash_table_new) g_hash_table_new __attribute((alias("IA__g_hash_table_new"), visibility("default")));
+
+#undef g_hash_table_new_full
+extern __typeof (g_hash_table_new_full) g_hash_table_new_full __attribute((alias("IA__g_hash_table_new_full"), visibility("default")));
+
+#undef g_hash_table_remove
+extern __typeof (g_hash_table_remove) g_hash_table_remove __attribute((alias("IA__g_hash_table_remove"), visibility("default")));
+
+#undef g_hash_table_remove_all
+extern __typeof (g_hash_table_remove_all) g_hash_table_remove_all __attribute((alias("IA__g_hash_table_remove_all"), visibility("default")));
+
+#undef g_hash_table_replace
+extern __typeof (g_hash_table_replace) g_hash_table_replace __attribute((alias("IA__g_hash_table_replace"), visibility("default")));
+
+#undef g_hash_table_size
+extern __typeof (g_hash_table_size) g_hash_table_size __attribute((alias("IA__g_hash_table_size"), visibility("default")));
+
+#undef g_hash_table_steal
+extern __typeof (g_hash_table_steal) g_hash_table_steal __attribute((alias("IA__g_hash_table_steal"), visibility("default")));
+
+#undef g_hash_table_steal_all
+extern __typeof (g_hash_table_steal_all) g_hash_table_steal_all __attribute((alias("IA__g_hash_table_steal_all"), visibility("default")));
+
+#undef g_hash_table_iter_init
+extern __typeof (g_hash_table_iter_init) g_hash_table_iter_init __attribute((alias("IA__g_hash_table_iter_init"), visibility("default")));
+
+#undef g_hash_table_iter_next
+extern __typeof (g_hash_table_iter_next) g_hash_table_iter_next __attribute((alias("IA__g_hash_table_iter_next"), visibility("default")));
+
+#undef g_hash_table_iter_get_hash_table
+extern __typeof (g_hash_table_iter_get_hash_table) g_hash_table_iter_get_hash_table __attribute((alias("IA__g_hash_table_iter_get_hash_table"), visibility("default")));
+
+#undef g_hash_table_iter_remove
+extern __typeof (g_hash_table_iter_remove) g_hash_table_iter_remove __attribute((alias("IA__g_hash_table_iter_remove"), visibility("default")));
+
+#undef g_hash_table_iter_steal
+extern __typeof (g_hash_table_iter_steal) g_hash_table_iter_steal __attribute((alias("IA__g_hash_table_iter_steal"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_HOOK_H__)
+#if IN_FILE(__G_HOOK_C__)
+#undef g_hook_alloc
+extern __typeof (g_hook_alloc) g_hook_alloc __attribute((alias("IA__g_hook_alloc"), visibility("default")));
+
+#undef g_hook_compare_ids
+extern __typeof (g_hook_compare_ids) g_hook_compare_ids __attribute((alias("IA__g_hook_compare_ids"), visibility("default")));
+
+#undef g_hook_destroy
+extern __typeof (g_hook_destroy) g_hook_destroy __attribute((alias("IA__g_hook_destroy"), visibility("default")));
+
+#undef g_hook_destroy_link
+extern __typeof (g_hook_destroy_link) g_hook_destroy_link __attribute((alias("IA__g_hook_destroy_link"), visibility("default")));
+
+#undef g_hook_find
+extern __typeof (g_hook_find) g_hook_find __attribute((alias("IA__g_hook_find"), visibility("default")));
+
+#undef g_hook_find_data
+extern __typeof (g_hook_find_data) g_hook_find_data __attribute((alias("IA__g_hook_find_data"), visibility("default")));
+
+#undef g_hook_find_func
+extern __typeof (g_hook_find_func) g_hook_find_func __attribute((alias("IA__g_hook_find_func"), visibility("default")));
+
+#undef g_hook_find_func_data
+extern __typeof (g_hook_find_func_data) g_hook_find_func_data __attribute((alias("IA__g_hook_find_func_data"), visibility("default")));
+
+#undef g_hook_first_valid
+extern __typeof (g_hook_first_valid) g_hook_first_valid __attribute((alias("IA__g_hook_first_valid"), visibility("default")));
+
+#undef g_hook_free
+extern __typeof (g_hook_free) g_hook_free __attribute((alias("IA__g_hook_free"), visibility("default")));
+
+#undef g_hook_get
+extern __typeof (g_hook_get) g_hook_get __attribute((alias("IA__g_hook_get"), visibility("default")));
+
+#undef g_hook_insert_before
+extern __typeof (g_hook_insert_before) g_hook_insert_before __attribute((alias("IA__g_hook_insert_before"), visibility("default")));
+
+#undef g_hook_insert_sorted
+extern __typeof (g_hook_insert_sorted) g_hook_insert_sorted __attribute((alias("IA__g_hook_insert_sorted"), visibility("default")));
+
+#undef g_hook_list_clear
+extern __typeof (g_hook_list_clear) g_hook_list_clear __attribute((alias("IA__g_hook_list_clear"), visibility("default")));
+
+#undef g_hook_list_init
+extern __typeof (g_hook_list_init) g_hook_list_init __attribute((alias("IA__g_hook_list_init"), visibility("default")));
+
+#undef g_hook_list_invoke
+extern __typeof (g_hook_list_invoke) g_hook_list_invoke __attribute((alias("IA__g_hook_list_invoke"), visibility("default")));
+
+#undef g_hook_list_invoke_check
+extern __typeof (g_hook_list_invoke_check) g_hook_list_invoke_check __attribute((alias("IA__g_hook_list_invoke_check"), visibility("default")));
+
+#undef g_hook_list_marshal
+extern __typeof (g_hook_list_marshal) g_hook_list_marshal __attribute((alias("IA__g_hook_list_marshal"), visibility("default")));
+
+#undef g_hook_list_marshal_check
+extern __typeof (g_hook_list_marshal_check) g_hook_list_marshal_check __attribute((alias("IA__g_hook_list_marshal_check"), visibility("default")));
+
+#undef g_hook_next_valid
+extern __typeof (g_hook_next_valid) g_hook_next_valid __attribute((alias("IA__g_hook_next_valid"), visibility("default")));
+
+#undef g_hook_prepend
+extern __typeof (g_hook_prepend) g_hook_prepend __attribute((alias("IA__g_hook_prepend"), visibility("default")));
+
+#undef g_hook_ref
+extern __typeof (g_hook_ref) g_hook_ref __attribute((alias("IA__g_hook_ref"), visibility("default")));
+
+#undef g_hook_unref
+extern __typeof (g_hook_unref) g_hook_unref __attribute((alias("IA__g_hook_unref"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IOCHANNEL_C__)
+#undef g_io_add_watch
+extern __typeof (g_io_add_watch) g_io_add_watch __attribute((alias("IA__g_io_add_watch"), visibility("default")));
+
+#undef g_io_add_watch_full
+extern __typeof (g_io_add_watch_full) g_io_add_watch_full __attribute((alias("IA__g_io_add_watch_full"), visibility("default")));
+
+#undef g_io_create_watch
+extern __typeof (g_io_create_watch) g_io_create_watch __attribute((alias("IA__g_io_create_watch"), visibility("default")));
+
+#undef g_io_channel_error_from_errno
+extern __typeof (g_io_channel_error_from_errno) g_io_channel_error_from_errno __attribute((alias("IA__g_io_channel_error_from_errno"), visibility("default")));
+
+#undef g_io_channel_error_quark
+extern __typeof (g_io_channel_error_quark) g_io_channel_error_quark __attribute((alias("IA__g_io_channel_error_quark"), visibility("default")));
+
+#undef g_io_channel_flush
+extern __typeof (g_io_channel_flush) g_io_channel_flush __attribute((alias("IA__g_io_channel_flush"), visibility("default")));
+
+#undef g_io_channel_get_buffer_condition
+extern __typeof (g_io_channel_get_buffer_condition) g_io_channel_get_buffer_condition __attribute((alias("IA__g_io_channel_get_buffer_condition"), visibility("default")));
+
+#undef g_io_channel_get_buffered
+extern __typeof (g_io_channel_get_buffered) g_io_channel_get_buffered __attribute((alias("IA__g_io_channel_get_buffered"), visibility("default")));
+
+#undef g_io_channel_get_buffer_size
+extern __typeof (g_io_channel_get_buffer_size) g_io_channel_get_buffer_size __attribute((alias("IA__g_io_channel_get_buffer_size"), visibility("default")));
+
+#undef g_io_channel_get_close_on_unref
+extern __typeof (g_io_channel_get_close_on_unref) g_io_channel_get_close_on_unref __attribute((alias("IA__g_io_channel_get_close_on_unref"), visibility("default")));
+
+#undef g_io_channel_get_encoding
+extern __typeof (g_io_channel_get_encoding) g_io_channel_get_encoding __attribute((alias("IA__g_io_channel_get_encoding"), visibility("default")));
+
+#undef g_io_channel_get_flags
+extern __typeof (g_io_channel_get_flags) g_io_channel_get_flags __attribute((alias("IA__g_io_channel_get_flags"), visibility("default")));
+
+#undef g_io_channel_get_line_term
+extern __typeof (g_io_channel_get_line_term) g_io_channel_get_line_term __attribute((alias("IA__g_io_channel_get_line_term"), visibility("default")));
+
+#undef g_io_channel_init
+extern __typeof (g_io_channel_init) g_io_channel_init __attribute((alias("IA__g_io_channel_init"), visibility("default")));
+
+#undef g_io_channel_read_chars
+extern __typeof (g_io_channel_read_chars) g_io_channel_read_chars __attribute((alias("IA__g_io_channel_read_chars"), visibility("default")));
+
+#undef g_io_channel_read_line
+extern __typeof (g_io_channel_read_line) g_io_channel_read_line __attribute((alias("IA__g_io_channel_read_line"), visibility("default")));
+
+#undef g_io_channel_read_line_string
+extern __typeof (g_io_channel_read_line_string) g_io_channel_read_line_string __attribute((alias("IA__g_io_channel_read_line_string"), visibility("default")));
+
+#undef g_io_channel_read_to_end
+extern __typeof (g_io_channel_read_to_end) g_io_channel_read_to_end __attribute((alias("IA__g_io_channel_read_to_end"), visibility("default")));
+
+#undef g_io_channel_read_unichar
+extern __typeof (g_io_channel_read_unichar) g_io_channel_read_unichar __attribute((alias("IA__g_io_channel_read_unichar"), visibility("default")));
+
+#undef g_io_channel_ref
+extern __typeof (g_io_channel_ref) g_io_channel_ref __attribute((alias("IA__g_io_channel_ref"), visibility("default")));
+
+#undef g_io_channel_seek_position
+extern __typeof (g_io_channel_seek_position) g_io_channel_seek_position __attribute((alias("IA__g_io_channel_seek_position"), visibility("default")));
+
+#undef g_io_channel_set_buffered
+extern __typeof (g_io_channel_set_buffered) g_io_channel_set_buffered __attribute((alias("IA__g_io_channel_set_buffered"), visibility("default")));
+
+#undef g_io_channel_set_buffer_size
+extern __typeof (g_io_channel_set_buffer_size) g_io_channel_set_buffer_size __attribute((alias("IA__g_io_channel_set_buffer_size"), visibility("default")));
+
+#undef g_io_channel_set_close_on_unref
+extern __typeof (g_io_channel_set_close_on_unref) g_io_channel_set_close_on_unref __attribute((alias("IA__g_io_channel_set_close_on_unref"), visibility("default")));
+
+#undef g_io_channel_set_encoding
+extern __typeof (g_io_channel_set_encoding) g_io_channel_set_encoding __attribute((alias("IA__g_io_channel_set_encoding"), visibility("default")));
+
+#undef g_io_channel_set_flags
+extern __typeof (g_io_channel_set_flags) g_io_channel_set_flags __attribute((alias("IA__g_io_channel_set_flags"), visibility("default")));
+
+#undef g_io_channel_set_line_term
+extern __typeof (g_io_channel_set_line_term) g_io_channel_set_line_term __attribute((alias("IA__g_io_channel_set_line_term"), visibility("default")));
+
+#undef g_io_channel_shutdown
+extern __typeof (g_io_channel_shutdown) g_io_channel_shutdown __attribute((alias("IA__g_io_channel_shutdown"), visibility("default")));
+
+#undef g_io_channel_unref
+extern __typeof (g_io_channel_unref) g_io_channel_unref __attribute((alias("IA__g_io_channel_unref"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_io_channel_close
+extern __typeof (g_io_channel_close) g_io_channel_close __attribute((alias("IA__g_io_channel_close"), visibility("default")));
+
+#undef g_io_channel_read
+extern __typeof (g_io_channel_read) g_io_channel_read __attribute((alias("IA__g_io_channel_read"), visibility("default")));
+
+#undef g_io_channel_seek
+extern __typeof (g_io_channel_seek) g_io_channel_seek __attribute((alias("IA__g_io_channel_seek"), visibility("default")));
+
+#undef g_io_channel_write
+extern __typeof (g_io_channel_write) g_io_channel_write __attribute((alias("IA__g_io_channel_write"), visibility("default")));
+
+#endif
+#undef g_io_channel_write_chars
+extern __typeof (g_io_channel_write_chars) g_io_channel_write_chars __attribute((alias("IA__g_io_channel_write_chars"), visibility("default")));
+
+#undef g_io_channel_write_unichar
+extern __typeof (g_io_channel_write_unichar) g_io_channel_write_unichar __attribute((alias("IA__g_io_channel_write_unichar"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IO_UNIX_C__)
+#ifdef G_OS_UNIX
+#undef g_io_channel_unix_get_fd
+extern __typeof (g_io_channel_unix_get_fd) g_io_channel_unix_get_fd __attribute((alias("IA__g_io_channel_unix_get_fd"), visibility("default")));
+
+#undef g_io_channel_unix_new
+extern __typeof (g_io_channel_unix_new) g_io_channel_unix_new __attribute((alias("IA__g_io_channel_unix_new"), visibility("default")));
+
+#undef g_io_channel_new_file
+extern __typeof (g_io_channel_new_file) g_io_channel_new_file __attribute((alias("IA__g_io_channel_new_file"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IO_WIN32_C__)
+#ifdef G_OS_WIN32
+#undef g_io_channel_unix_get_fd
+extern __typeof (g_io_channel_unix_get_fd) g_io_channel_unix_get_fd __attribute((alias("IA__g_io_channel_unix_get_fd"), visibility("default")));
+
+#undef g_io_channel_unix_new
+extern __typeof (g_io_channel_unix_new) g_io_channel_unix_new __attribute((alias("IA__g_io_channel_unix_new"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_io_channel_new_file
+extern __typeof (g_io_channel_new_file) g_io_channel_new_file __attribute((alias("IA__g_io_channel_new_file"), visibility("default")));
+
+#endif
+#undef g_io_channel_new_file_utf8
+extern __typeof (g_io_channel_new_file_utf8) g_io_channel_new_file_utf8 __attribute((alias("IA__g_io_channel_new_file_utf8"), visibility("default")));
+
+#undef g_io_channel_win32_get_fd
+extern __typeof (g_io_channel_win32_get_fd) g_io_channel_win32_get_fd __attribute((alias("IA__g_io_channel_win32_get_fd"), visibility("default")));
+
+#undef g_io_channel_win32_make_pollfd
+extern __typeof (g_io_channel_win32_make_pollfd) g_io_channel_win32_make_pollfd __attribute((alias("IA__g_io_channel_win32_make_pollfd"), visibility("default")));
+
+#undef g_io_channel_win32_new_fd
+extern __typeof (g_io_channel_win32_new_fd) g_io_channel_win32_new_fd __attribute((alias("IA__g_io_channel_win32_new_fd"), visibility("default")));
+
+#undef g_io_channel_win32_new_messages
+extern __typeof (g_io_channel_win32_new_messages) g_io_channel_win32_new_messages __attribute((alias("IA__g_io_channel_win32_new_messages"), visibility("default")));
+
+#undef g_io_channel_win32_new_socket
+extern __typeof (g_io_channel_win32_new_socket) g_io_channel_win32_new_socket __attribute((alias("IA__g_io_channel_win32_new_socket"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_io_channel_win32_new_stream_socket
+extern __typeof (g_io_channel_win32_new_stream_socket) g_io_channel_win32_new_stream_socket __attribute((alias("IA__g_io_channel_win32_new_stream_socket"), visibility("default")));
+
+#endif
+#undef g_io_channel_win32_poll
+extern __typeof (g_io_channel_win32_poll) g_io_channel_win32_poll __attribute((alias("IA__g_io_channel_win32_poll"), visibility("default")));
+
+#undef g_io_channel_win32_set_debug
+extern __typeof (g_io_channel_win32_set_debug) g_io_channel_win32_set_debug __attribute((alias("IA__g_io_channel_win32_set_debug"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_KEY_FILE_H__)
+#if IN_FILE(__G_KEY_FILE_C__)
+#undef g_key_file_error_quark
+extern __typeof (g_key_file_error_quark) g_key_file_error_quark __attribute((alias("IA__g_key_file_error_quark"), visibility("default")));
+
+#undef g_key_file_free
+extern __typeof (g_key_file_free) g_key_file_free __attribute((alias("IA__g_key_file_free"), visibility("default")));
+
+#undef g_key_file_get_boolean
+extern __typeof (g_key_file_get_boolean) g_key_file_get_boolean __attribute((alias("IA__g_key_file_get_boolean"), visibility("default")));
+
+#undef g_key_file_get_boolean_list
+extern __typeof (g_key_file_get_boolean_list) g_key_file_get_boolean_list __attribute((alias("IA__g_key_file_get_boolean_list"), visibility("default")));
+
+#undef g_key_file_get_comment
+extern __typeof (g_key_file_get_comment) g_key_file_get_comment __attribute((alias("IA__g_key_file_get_comment"), visibility("default")));
+
+#undef g_key_file_get_groups
+extern __typeof (g_key_file_get_groups) g_key_file_get_groups __attribute((alias("IA__g_key_file_get_groups"), visibility("default")));
+
+#undef g_key_file_get_double
+extern __typeof (g_key_file_get_double) g_key_file_get_double __attribute((alias("IA__g_key_file_get_double"), visibility("default")));
+
+#undef g_key_file_get_double_list
+extern __typeof (g_key_file_get_double_list) g_key_file_get_double_list __attribute((alias("IA__g_key_file_get_double_list"), visibility("default")));
+
+#undef g_key_file_get_integer
+extern __typeof (g_key_file_get_integer) g_key_file_get_integer __attribute((alias("IA__g_key_file_get_integer"), visibility("default")));
+
+#undef g_key_file_get_integer_list
+extern __typeof (g_key_file_get_integer_list) g_key_file_get_integer_list __attribute((alias("IA__g_key_file_get_integer_list"), visibility("default")));
+
+#undef g_key_file_get_keys
+extern __typeof (g_key_file_get_keys) g_key_file_get_keys __attribute((alias("IA__g_key_file_get_keys"), visibility("default")));
+
+#undef g_key_file_get_locale_string
+extern __typeof (g_key_file_get_locale_string) g_key_file_get_locale_string __attribute((alias("IA__g_key_file_get_locale_string"), visibility("default")));
+
+#undef g_key_file_get_locale_string_list
+extern __typeof (g_key_file_get_locale_string_list) g_key_file_get_locale_string_list __attribute((alias("IA__g_key_file_get_locale_string_list"), visibility("default")));
+
+#undef g_key_file_get_start_group
+extern __typeof (g_key_file_get_start_group) g_key_file_get_start_group __attribute((alias("IA__g_key_file_get_start_group"), visibility("default")));
+
+#undef g_key_file_get_string
+extern __typeof (g_key_file_get_string) g_key_file_get_string __attribute((alias("IA__g_key_file_get_string"), visibility("default")));
+
+#undef g_key_file_get_string_list
+extern __typeof (g_key_file_get_string_list) g_key_file_get_string_list __attribute((alias("IA__g_key_file_get_string_list"), visibility("default")));
+
+#undef g_key_file_get_value
+extern __typeof (g_key_file_get_value) g_key_file_get_value __attribute((alias("IA__g_key_file_get_value"), visibility("default")));
+
+#undef g_key_file_has_group
+extern __typeof (g_key_file_has_group) g_key_file_has_group __attribute((alias("IA__g_key_file_has_group"), visibility("default")));
+
+#undef g_key_file_has_key
+extern __typeof (g_key_file_has_key) g_key_file_has_key __attribute((alias("IA__g_key_file_has_key"), visibility("default")));
+
+#undef g_key_file_load_from_dirs
+extern __typeof (g_key_file_load_from_dirs) g_key_file_load_from_dirs __attribute((alias("IA__g_key_file_load_from_dirs"), visibility("default")));
+
+#undef g_key_file_load_from_data
+extern __typeof (g_key_file_load_from_data) g_key_file_load_from_data __attribute((alias("IA__g_key_file_load_from_data"), visibility("default")));
+
+#undef g_key_file_load_from_data_dirs
+extern __typeof (g_key_file_load_from_data_dirs) g_key_file_load_from_data_dirs __attribute((alias("IA__g_key_file_load_from_data_dirs"), visibility("default")));
+
+#undef g_key_file_load_from_file
+extern __typeof (g_key_file_load_from_file) g_key_file_load_from_file __attribute((alias("IA__g_key_file_load_from_file"), visibility("default")));
+
+#undef g_key_file_new
+extern __typeof (g_key_file_new) g_key_file_new __attribute((alias("IA__g_key_file_new"), visibility("default")));
+
+#undef g_key_file_remove_comment
+extern __typeof (g_key_file_remove_comment) g_key_file_remove_comment __attribute((alias("IA__g_key_file_remove_comment"), visibility("default")));
+
+#undef g_key_file_remove_group
+extern __typeof (g_key_file_remove_group) g_key_file_remove_group __attribute((alias("IA__g_key_file_remove_group"), visibility("default")));
+
+#undef g_key_file_remove_key
+extern __typeof (g_key_file_remove_key) g_key_file_remove_key __attribute((alias("IA__g_key_file_remove_key"), visibility("default")));
+
+#undef g_key_file_set_boolean
+extern __typeof (g_key_file_set_boolean) g_key_file_set_boolean __attribute((alias("IA__g_key_file_set_boolean"), visibility("default")));
+
+#undef g_key_file_set_boolean_list
+extern __typeof (g_key_file_set_boolean_list) g_key_file_set_boolean_list __attribute((alias("IA__g_key_file_set_boolean_list"), visibility("default")));
+
+#undef g_key_file_set_comment
+extern __typeof (g_key_file_set_comment) g_key_file_set_comment __attribute((alias("IA__g_key_file_set_comment"), visibility("default")));
+
+#undef g_key_file_set_double
+extern __typeof (g_key_file_set_double) g_key_file_set_double __attribute((alias("IA__g_key_file_set_double"), visibility("default")));
+
+#undef g_key_file_set_double_list
+extern __typeof (g_key_file_set_double_list) g_key_file_set_double_list __attribute((alias("IA__g_key_file_set_double_list"), visibility("default")));
+
+#undef g_key_file_set_integer
+extern __typeof (g_key_file_set_integer) g_key_file_set_integer __attribute((alias("IA__g_key_file_set_integer"), visibility("default")));
+
+#undef g_key_file_set_integer_list
+extern __typeof (g_key_file_set_integer_list) g_key_file_set_integer_list __attribute((alias("IA__g_key_file_set_integer_list"), visibility("default")));
+
+#undef g_key_file_set_list_separator
+extern __typeof (g_key_file_set_list_separator) g_key_file_set_list_separator __attribute((alias("IA__g_key_file_set_list_separator"), visibility("default")));
+
+#undef g_key_file_set_locale_string
+extern __typeof (g_key_file_set_locale_string) g_key_file_set_locale_string __attribute((alias("IA__g_key_file_set_locale_string"), visibility("default")));
+
+#undef g_key_file_set_locale_string_list
+extern __typeof (g_key_file_set_locale_string_list) g_key_file_set_locale_string_list __attribute((alias("IA__g_key_file_set_locale_string_list"), visibility("default")));
+
+#undef g_key_file_set_string
+extern __typeof (g_key_file_set_string) g_key_file_set_string __attribute((alias("IA__g_key_file_set_string"), visibility("default")));
+
+#undef g_key_file_set_string_list
+extern __typeof (g_key_file_set_string_list) g_key_file_set_string_list __attribute((alias("IA__g_key_file_set_string_list"), visibility("default")));
+
+#undef g_key_file_set_value
+extern __typeof (g_key_file_set_value) g_key_file_set_value __attribute((alias("IA__g_key_file_set_value"), visibility("default")));
+
+#undef g_key_file_to_data
+extern __typeof (g_key_file_to_data) g_key_file_to_data __attribute((alias("IA__g_key_file_to_data"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_LIST_H__)
+#if IN_FILE(__G_LIST_C__)
+#undef g_list_alloc
+extern __typeof (g_list_alloc) g_list_alloc __attribute((alias("IA__g_list_alloc"), visibility("default")));
+
+#undef g_list_append
+extern __typeof (g_list_append) g_list_append __attribute((alias("IA__g_list_append"), visibility("default")));
+
+#undef g_list_concat
+extern __typeof (g_list_concat) g_list_concat __attribute((alias("IA__g_list_concat"), visibility("default")));
+
+#undef g_list_copy
+extern __typeof (g_list_copy) g_list_copy __attribute((alias("IA__g_list_copy"), visibility("default")));
+
+#undef g_list_delete_link
+extern __typeof (g_list_delete_link) g_list_delete_link __attribute((alias("IA__g_list_delete_link"), visibility("default")));
+
+#undef g_list_find
+extern __typeof (g_list_find) g_list_find __attribute((alias("IA__g_list_find"), visibility("default")));
+
+#undef g_list_find_custom
+extern __typeof (g_list_find_custom) g_list_find_custom __attribute((alias("IA__g_list_find_custom"), visibility("default")));
+
+#undef g_list_first
+extern __typeof (g_list_first) g_list_first __attribute((alias("IA__g_list_first"), visibility("default")));
+
+#undef g_list_foreach
+extern __typeof (g_list_foreach) g_list_foreach __attribute((alias("IA__g_list_foreach"), visibility("default")));
+
+#undef g_list_free
+extern __typeof (g_list_free) g_list_free __attribute((alias("IA__g_list_free"), visibility("default")));
+
+#undef g_list_free_1
+extern __typeof (g_list_free_1) g_list_free_1 __attribute((alias("IA__g_list_free_1"), visibility("default")));
+
+#undef g_list_index
+extern __typeof (g_list_index) g_list_index __attribute((alias("IA__g_list_index"), visibility("default")));
+
+#undef g_list_insert
+extern __typeof (g_list_insert) g_list_insert __attribute((alias("IA__g_list_insert"), visibility("default")));
+
+#undef g_list_insert_before
+extern __typeof (g_list_insert_before) g_list_insert_before __attribute((alias("IA__g_list_insert_before"), visibility("default")));
+
+#undef g_list_insert_sorted
+extern __typeof (g_list_insert_sorted) g_list_insert_sorted __attribute((alias("IA__g_list_insert_sorted"), visibility("default")));
+
+#undef g_list_insert_sorted_with_data
+extern __typeof (g_list_insert_sorted_with_data) g_list_insert_sorted_with_data __attribute((alias("IA__g_list_insert_sorted_with_data"), visibility("default")));
+
+#undef g_list_last
+extern __typeof (g_list_last) g_list_last __attribute((alias("IA__g_list_last"), visibility("default")));
+
+#undef g_list_length
+extern __typeof (g_list_length) g_list_length __attribute((alias("IA__g_list_length"), visibility("default")));
+
+#undef g_list_nth
+extern __typeof (g_list_nth) g_list_nth __attribute((alias("IA__g_list_nth"), visibility("default")));
+
+#undef g_list_nth_data
+extern __typeof (g_list_nth_data) g_list_nth_data __attribute((alias("IA__g_list_nth_data"), visibility("default")));
+
+#undef g_list_nth_prev
+extern __typeof (g_list_nth_prev) g_list_nth_prev __attribute((alias("IA__g_list_nth_prev"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_list_pop_allocator
+extern __typeof (g_list_pop_allocator) g_list_pop_allocator __attribute((alias("IA__g_list_pop_allocator"), visibility("default")));
+
+#endif
+#undef g_list_position
+extern __typeof (g_list_position) g_list_position __attribute((alias("IA__g_list_position"), visibility("default")));
+
+#undef g_list_prepend
+extern __typeof (g_list_prepend) g_list_prepend __attribute((alias("IA__g_list_prepend"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_list_push_allocator
+extern __typeof (g_list_push_allocator) g_list_push_allocator __attribute((alias("IA__g_list_push_allocator"), visibility("default")));
+
+#endif
+#undef g_list_remove
+extern __typeof (g_list_remove) g_list_remove __attribute((alias("IA__g_list_remove"), visibility("default")));
+
+#undef g_list_remove_all
+extern __typeof (g_list_remove_all) g_list_remove_all __attribute((alias("IA__g_list_remove_all"), visibility("default")));
+
+#undef g_list_remove_link
+extern __typeof (g_list_remove_link) g_list_remove_link __attribute((alias("IA__g_list_remove_link"), visibility("default")));
+
+#undef g_list_reverse
+extern __typeof (g_list_reverse) g_list_reverse __attribute((alias("IA__g_list_reverse"), visibility("default")));
+
+#undef g_list_sort
+extern __typeof (g_list_sort) g_list_sort __attribute((alias("IA__g_list_sort"), visibility("default")));
+
+#undef g_list_sort_with_data
+extern __typeof (g_list_sort_with_data) g_list_sort_with_data __attribute((alias("IA__g_list_sort_with_data"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_MAIN_H__)
+#if IN_FILE(__G_MAIN_C__)
+#undef g_child_watch_add
+extern __typeof (g_child_watch_add) g_child_watch_add __attribute((alias("IA__g_child_watch_add"), visibility("default")));
+
+#undef g_child_watch_add_full
+extern __typeof (g_child_watch_add_full) g_child_watch_add_full __attribute((alias("IA__g_child_watch_add_full"), visibility("default")));
+
+#undef g_child_watch_source_new
+extern __typeof (g_child_watch_source_new) g_child_watch_source_new __attribute((alias("IA__g_child_watch_source_new"), visibility("default")));
+
+#undef g_get_current_time
+extern __typeof (g_get_current_time) g_get_current_time __attribute((alias("IA__g_get_current_time"), visibility("default")));
+
+#undef g_main_context_acquire
+extern __typeof (g_main_context_acquire) g_main_context_acquire __attribute((alias("IA__g_main_context_acquire"), visibility("default")));
+
+#undef g_main_context_add_poll
+extern __typeof (g_main_context_add_poll) g_main_context_add_poll __attribute((alias("IA__g_main_context_add_poll"), visibility("default")));
+
+#undef g_main_context_check
+extern __typeof (g_main_context_check) g_main_context_check __attribute((alias("IA__g_main_context_check"), visibility("default")));
+
+#undef g_main_context_default
+extern __typeof (g_main_context_default) g_main_context_default __attribute((alias("IA__g_main_context_default"), visibility("default")));
+
+#undef g_main_context_dispatch
+extern __typeof (g_main_context_dispatch) g_main_context_dispatch __attribute((alias("IA__g_main_context_dispatch"), visibility("default")));
+
+#undef g_main_context_find_source_by_funcs_user_data
+extern __typeof (g_main_context_find_source_by_funcs_user_data) g_main_context_find_source_by_funcs_user_data __attribute((alias("IA__g_main_context_find_source_by_funcs_user_data"), visibility("default")));
+
+#undef g_main_context_find_source_by_id
+extern __typeof (g_main_context_find_source_by_id) g_main_context_find_source_by_id __attribute((alias("IA__g_main_context_find_source_by_id"), visibility("default")));
+
+#undef g_main_context_find_source_by_user_data
+extern __typeof (g_main_context_find_source_by_user_data) g_main_context_find_source_by_user_data __attribute((alias("IA__g_main_context_find_source_by_user_data"), visibility("default")));
+
+#undef g_main_context_get_poll_func
+extern __typeof (g_main_context_get_poll_func) g_main_context_get_poll_func __attribute((alias("IA__g_main_context_get_poll_func"), visibility("default")));
+
+#undef g_main_context_is_owner
+extern __typeof (g_main_context_is_owner) g_main_context_is_owner __attribute((alias("IA__g_main_context_is_owner"), visibility("default")));
+
+#undef g_main_context_iteration
+extern __typeof (g_main_context_iteration) g_main_context_iteration __attribute((alias("IA__g_main_context_iteration"), visibility("default")));
+
+#undef g_main_context_new
+extern __typeof (g_main_context_new) g_main_context_new __attribute((alias("IA__g_main_context_new"), visibility("default")));
+
+#undef g_main_context_pending
+extern __typeof (g_main_context_pending) g_main_context_pending __attribute((alias("IA__g_main_context_pending"), visibility("default")));
+
+#undef g_main_context_prepare
+extern __typeof (g_main_context_prepare) g_main_context_prepare __attribute((alias("IA__g_main_context_prepare"), visibility("default")));
+
+#undef g_main_context_query
+extern __typeof (g_main_context_query) g_main_context_query __attribute((alias("IA__g_main_context_query"), visibility("default")));
+
+#undef g_main_context_ref
+extern __typeof (g_main_context_ref) g_main_context_ref __attribute((alias("IA__g_main_context_ref"), visibility("default")));
+
+#undef g_main_context_release
+extern __typeof (g_main_context_release) g_main_context_release __attribute((alias("IA__g_main_context_release"), visibility("default")));
+
+#undef g_main_context_remove_poll
+extern __typeof (g_main_context_remove_poll) g_main_context_remove_poll __attribute((alias("IA__g_main_context_remove_poll"), visibility("default")));
+
+#undef g_main_context_set_poll_func
+extern __typeof (g_main_context_set_poll_func) g_main_context_set_poll_func __attribute((alias("IA__g_main_context_set_poll_func"), visibility("default")));
+
+#undef g_main_context_unref
+extern __typeof (g_main_context_unref) g_main_context_unref __attribute((alias("IA__g_main_context_unref"), visibility("default")));
+
+#undef g_main_context_wait
+extern __typeof (g_main_context_wait) g_main_context_wait __attribute((alias("IA__g_main_context_wait"), visibility("default")));
+
+#undef g_main_context_wakeup
+extern __typeof (g_main_context_wakeup) g_main_context_wakeup __attribute((alias("IA__g_main_context_wakeup"), visibility("default")));
+
+#undef g_main_depth
+extern __typeof (g_main_depth) g_main_depth __attribute((alias("IA__g_main_depth"), visibility("default")));
+
+#undef g_main_current_source
+extern __typeof (g_main_current_source) g_main_current_source __attribute((alias("IA__g_main_current_source"), visibility("default")));
+
+#undef g_main_loop_get_context
+extern __typeof (g_main_loop_get_context) g_main_loop_get_context __attribute((alias("IA__g_main_loop_get_context"), visibility("default")));
+
+#undef g_main_loop_is_running
+extern __typeof (g_main_loop_is_running) g_main_loop_is_running __attribute((alias("IA__g_main_loop_is_running"), visibility("default")));
+
+#undef g_main_loop_new
+extern __typeof (g_main_loop_new) g_main_loop_new __attribute((alias("IA__g_main_loop_new"), visibility("default")));
+
+#undef g_main_loop_quit
+extern __typeof (g_main_loop_quit) g_main_loop_quit __attribute((alias("IA__g_main_loop_quit"), visibility("default")));
+
+#undef g_main_loop_ref
+extern __typeof (g_main_loop_ref) g_main_loop_ref __attribute((alias("IA__g_main_loop_ref"), visibility("default")));
+
+#undef g_main_loop_run
+extern __typeof (g_main_loop_run) g_main_loop_run __attribute((alias("IA__g_main_loop_run"), visibility("default")));
+
+#undef g_main_loop_unref
+extern __typeof (g_main_loop_unref) g_main_loop_unref __attribute((alias("IA__g_main_loop_unref"), visibility("default")));
+
+#undef g_source_add_poll
+extern __typeof (g_source_add_poll) g_source_add_poll __attribute((alias("IA__g_source_add_poll"), visibility("default")));
+
+#undef g_source_attach
+extern __typeof (g_source_attach) g_source_attach __attribute((alias("IA__g_source_attach"), visibility("default")));
+
+#undef g_source_destroy
+extern __typeof (g_source_destroy) g_source_destroy __attribute((alias("IA__g_source_destroy"), visibility("default")));
+
+#undef g_source_get_can_recurse
+extern __typeof (g_source_get_can_recurse) g_source_get_can_recurse __attribute((alias("IA__g_source_get_can_recurse"), visibility("default")));
+
+#undef g_source_get_context
+extern __typeof (g_source_get_context) g_source_get_context __attribute((alias("IA__g_source_get_context"), visibility("default")));
+
+#undef g_source_get_current_time
+extern __typeof (g_source_get_current_time) g_source_get_current_time __attribute((alias("IA__g_source_get_current_time"), visibility("default")));
+
+#undef g_source_get_id
+extern __typeof (g_source_get_id) g_source_get_id __attribute((alias("IA__g_source_get_id"), visibility("default")));
+
+#undef g_source_get_priority
+extern __typeof (g_source_get_priority) g_source_get_priority __attribute((alias("IA__g_source_get_priority"), visibility("default")));
+
+#undef g_source_new
+extern __typeof (g_source_new) g_source_new __attribute((alias("IA__g_source_new"), visibility("default")));
+
+#undef g_source_ref
+extern __typeof (g_source_ref) g_source_ref __attribute((alias("IA__g_source_ref"), visibility("default")));
+
+#undef g_source_remove
+extern __typeof (g_source_remove) g_source_remove __attribute((alias("IA__g_source_remove"), visibility("default")));
+
+#undef g_source_remove_by_funcs_user_data
+extern __typeof (g_source_remove_by_funcs_user_data) g_source_remove_by_funcs_user_data __attribute((alias("IA__g_source_remove_by_funcs_user_data"), visibility("default")));
+
+#undef g_source_remove_by_user_data
+extern __typeof (g_source_remove_by_user_data) g_source_remove_by_user_data __attribute((alias("IA__g_source_remove_by_user_data"), visibility("default")));
+
+#undef g_source_remove_poll
+extern __typeof (g_source_remove_poll) g_source_remove_poll __attribute((alias("IA__g_source_remove_poll"), visibility("default")));
+
+#undef g_source_set_callback
+extern __typeof (g_source_set_callback) g_source_set_callback __attribute((alias("IA__g_source_set_callback"), visibility("default")));
+
+#undef g_source_set_callback_indirect
+extern __typeof (g_source_set_callback_indirect) g_source_set_callback_indirect __attribute((alias("IA__g_source_set_callback_indirect"), visibility("default")));
+
+#undef g_source_set_can_recurse
+extern __typeof (g_source_set_can_recurse) g_source_set_can_recurse __attribute((alias("IA__g_source_set_can_recurse"), visibility("default")));
+
+#undef g_source_set_funcs
+extern __typeof (g_source_set_funcs) g_source_set_funcs __attribute((alias("IA__g_source_set_funcs"), visibility("default")));
+
+#undef g_source_is_destroyed
+extern __typeof (g_source_is_destroyed) g_source_is_destroyed __attribute((alias("IA__g_source_is_destroyed"), visibility("default")));
+
+#undef g_source_set_priority
+extern __typeof (g_source_set_priority) g_source_set_priority __attribute((alias("IA__g_source_set_priority"), visibility("default")));
+
+#undef g_source_unref
+extern __typeof (g_source_unref) g_source_unref __attribute((alias("IA__g_source_unref"), visibility("default")));
+
+#undef g_idle_add
+extern __typeof (g_idle_add) g_idle_add __attribute((alias("IA__g_idle_add"), visibility("default")));
+
+#undef g_idle_add_full
+extern __typeof (g_idle_add_full) g_idle_add_full __attribute((alias("IA__g_idle_add_full"), visibility("default")));
+
+#undef g_idle_remove_by_data
+extern __typeof (g_idle_remove_by_data) g_idle_remove_by_data __attribute((alias("IA__g_idle_remove_by_data"), visibility("default")));
+
+#undef g_idle_source_new
+extern __typeof (g_idle_source_new) g_idle_source_new __attribute((alias("IA__g_idle_source_new"), visibility("default")));
+
+#undef g_timeout_add
+extern __typeof (g_timeout_add) g_timeout_add __attribute((alias("IA__g_timeout_add"), visibility("default")));
+
+#undef g_timeout_add_seconds
+extern __typeof (g_timeout_add_seconds) g_timeout_add_seconds __attribute((alias("IA__g_timeout_add_seconds"), visibility("default")));
+
+#undef g_timeout_add_full
+extern __typeof (g_timeout_add_full) g_timeout_add_full __attribute((alias("IA__g_timeout_add_full"), visibility("default")));
+
+#undef g_timeout_add_seconds_full
+extern __typeof (g_timeout_add_seconds_full) g_timeout_add_seconds_full __attribute((alias("IA__g_timeout_add_seconds_full"), visibility("default")));
+
+#undef g_timeout_source_new
+extern __typeof (g_timeout_source_new) g_timeout_source_new __attribute((alias("IA__g_timeout_source_new"), visibility("default")));
+
+#undef g_timeout_source_new_seconds
+extern __typeof (g_timeout_source_new_seconds) g_timeout_source_new_seconds __attribute((alias("IA__g_timeout_source_new_seconds"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_MAPPED_FILE_H__)
+#if IN_FILE(__G_MAPPED_FILE_C__)
+#undef g_mapped_file_new
+extern __typeof (g_mapped_file_new) g_mapped_file_new __attribute((alias("IA__g_mapped_file_new"), visibility("default")));
+
+#undef g_mapped_file_get_length
+extern __typeof (g_mapped_file_get_length) g_mapped_file_get_length __attribute((alias("IA__g_mapped_file_get_length"), visibility("default")));
+
+#undef g_mapped_file_get_contents
+extern __typeof (g_mapped_file_get_contents) g_mapped_file_get_contents __attribute((alias("IA__g_mapped_file_get_contents"), visibility("default")));
+
+#undef g_mapped_file_free
+extern __typeof (g_mapped_file_free) g_mapped_file_free __attribute((alias("IA__g_mapped_file_free"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_MARKUP_H__)
+#if IN_FILE(__G_MARKUP_C__)
+#undef g_markup_error_quark
+extern __typeof (g_markup_error_quark) g_markup_error_quark __attribute((alias("IA__g_markup_error_quark"), visibility("default")));
+
+#undef g_markup_escape_text
+extern __typeof (g_markup_escape_text) g_markup_escape_text __attribute((alias("IA__g_markup_escape_text"), visibility("default")));
+
+#undef g_markup_parse_context_end_parse
+extern __typeof (g_markup_parse_context_end_parse) g_markup_parse_context_end_parse __attribute((alias("IA__g_markup_parse_context_end_parse"), visibility("default")));
+
+#undef g_markup_parse_context_free
+extern __typeof (g_markup_parse_context_free) g_markup_parse_context_free __attribute((alias("IA__g_markup_parse_context_free"), visibility("default")));
+
+#undef g_markup_parse_context_get_element
+extern __typeof (g_markup_parse_context_get_element) g_markup_parse_context_get_element __attribute((alias("IA__g_markup_parse_context_get_element"), visibility("default")));
+
+#undef g_markup_parse_context_get_element_stack
+extern __typeof (g_markup_parse_context_get_element_stack) g_markup_parse_context_get_element_stack __attribute((alias("IA__g_markup_parse_context_get_element_stack"), visibility("default")));
+
+#undef g_markup_parse_context_get_position
+extern __typeof (g_markup_parse_context_get_position) g_markup_parse_context_get_position __attribute((alias("IA__g_markup_parse_context_get_position"), visibility("default")));
+
+#undef g_markup_parse_context_get_user_data
+extern __typeof (g_markup_parse_context_get_user_data) g_markup_parse_context_get_user_data __attribute((alias("IA__g_markup_parse_context_get_user_data"), visibility("default")));
+
+#undef g_markup_parse_context_new
+extern __typeof (g_markup_parse_context_new) g_markup_parse_context_new __attribute((alias("IA__g_markup_parse_context_new"), visibility("default")));
+
+#undef g_markup_parse_context_parse
+extern __typeof (g_markup_parse_context_parse) g_markup_parse_context_parse __attribute((alias("IA__g_markup_parse_context_parse"), visibility("default")));
+
+#undef g_markup_parse_context_push
+extern __typeof (g_markup_parse_context_push) g_markup_parse_context_push __attribute((alias("IA__g_markup_parse_context_push"), visibility("default")));
+
+#undef g_markup_parse_context_pop
+extern __typeof (g_markup_parse_context_pop) g_markup_parse_context_pop __attribute((alias("IA__g_markup_parse_context_pop"), visibility("default")));
+
+#undef g_markup_printf_escaped
+extern __typeof (g_markup_printf_escaped) g_markup_printf_escaped __attribute((alias("IA__g_markup_printf_escaped"), visibility("default")));
+
+#undef g_markup_vprintf_escaped
+extern __typeof (g_markup_vprintf_escaped) g_markup_vprintf_escaped __attribute((alias("IA__g_markup_vprintf_escaped"), visibility("default")));
+
+#undef g_markup_collect_attributes
+extern __typeof (g_markup_collect_attributes) g_markup_collect_attributes __attribute((alias("IA__g_markup_collect_attributes"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_MEM_H__)
+#if IN_FILE(__G_MEM_C__)
+#undef g_free
+extern __typeof (g_free) g_free __attribute((alias("IA__g_free"), visibility("default")));
+
+#undef g_malloc
+extern __typeof (g_malloc) g_malloc __attribute((alias("IA__g_malloc"), visibility("default")));
+
+#undef g_malloc0
+extern __typeof (g_malloc0) g_malloc0 __attribute((alias("IA__g_malloc0"), visibility("default")));
+
+#undef g_mem_is_system_malloc
+extern __typeof (g_mem_is_system_malloc) g_mem_is_system_malloc __attribute((alias("IA__g_mem_is_system_malloc"), visibility("default")));
+
+#undef g_mem_profile
+extern __typeof (g_mem_profile) g_mem_profile __attribute((alias("IA__g_mem_profile"), visibility("default")));
+
+#undef g_mem_set_vtable
+extern __typeof (g_mem_set_vtable) g_mem_set_vtable __attribute((alias("IA__g_mem_set_vtable"), visibility("default")));
+
+#undef g_realloc
+extern __typeof (g_realloc) g_realloc __attribute((alias("IA__g_realloc"), visibility("default")));
+
+#undef g_try_malloc
+extern __typeof (g_try_malloc) g_try_malloc __attribute((alias("IA__g_try_malloc"), visibility("default")));
+
+#undef g_try_malloc0
+extern __typeof (g_try_malloc0) g_try_malloc0 __attribute((alias("IA__g_try_malloc0"), visibility("default")));
+
+#undef g_try_realloc
+extern __typeof (g_try_realloc) g_try_realloc __attribute((alias("IA__g_try_realloc"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_allocator_free
+extern __typeof (g_allocator_free) g_allocator_free __attribute((alias("IA__g_allocator_free"), visibility("default")));
+
+#undef g_allocator_new
+extern __typeof (g_allocator_new) g_allocator_new __attribute((alias("IA__g_allocator_new"), visibility("default")));
+
+#undef g_mem_chunk_alloc
+extern __typeof (g_mem_chunk_alloc) g_mem_chunk_alloc __attribute((alias("IA__g_mem_chunk_alloc"), visibility("default")));
+
+#undef g_mem_chunk_alloc0
+extern __typeof (g_mem_chunk_alloc0) g_mem_chunk_alloc0 __attribute((alias("IA__g_mem_chunk_alloc0"), visibility("default")));
+
+#undef g_mem_chunk_clean
+extern __typeof (g_mem_chunk_clean) g_mem_chunk_clean __attribute((alias("IA__g_mem_chunk_clean"), visibility("default")));
+
+#undef g_mem_chunk_destroy
+extern __typeof (g_mem_chunk_destroy) g_mem_chunk_destroy __attribute((alias("IA__g_mem_chunk_destroy"), visibility("default")));
+
+#undef g_mem_chunk_free
+extern __typeof (g_mem_chunk_free) g_mem_chunk_free __attribute((alias("IA__g_mem_chunk_free"), visibility("default")));
+
+#undef g_mem_chunk_info
+extern __typeof (g_mem_chunk_info) g_mem_chunk_info __attribute((alias("IA__g_mem_chunk_info"), visibility("default")));
+
+#undef g_mem_chunk_new
+extern __typeof (g_mem_chunk_new) g_mem_chunk_new __attribute((alias("IA__g_mem_chunk_new"), visibility("default")));
+
+#undef g_mem_chunk_print
+extern __typeof (g_mem_chunk_print) g_mem_chunk_print __attribute((alias("IA__g_mem_chunk_print"), visibility("default")));
+
+#undef g_mem_chunk_reset
+extern __typeof (g_mem_chunk_reset) g_mem_chunk_reset __attribute((alias("IA__g_mem_chunk_reset"), visibility("default")));
+
+#undef g_blow_chunks
+extern __typeof (g_blow_chunks) g_blow_chunks __attribute((alias("IA__g_blow_chunks"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_SLICE_H__)
+#if IN_FILE(__G_SLICE_C__)
+#undef g_slice_alloc
+extern __typeof (g_slice_alloc) g_slice_alloc __attribute((alias("IA__g_slice_alloc"), visibility("default")));
+
+#undef g_slice_alloc0
+extern __typeof (g_slice_alloc0) g_slice_alloc0 __attribute((alias("IA__g_slice_alloc0"), visibility("default")));
+
+#undef g_slice_copy
+extern __typeof (g_slice_copy) g_slice_copy __attribute((alias("IA__g_slice_copy"), visibility("default")));
+
+#undef g_slice_free1
+extern __typeof (g_slice_free1) g_slice_free1 __attribute((alias("IA__g_slice_free1"), visibility("default")));
+
+#undef g_slice_free_chain_with_offset
+extern __typeof (g_slice_free_chain_with_offset) g_slice_free_chain_with_offset __attribute((alias("IA__g_slice_free_chain_with_offset"), visibility("default")));
+
+#undef g_slice_set_config
+extern __typeof (g_slice_set_config) g_slice_set_config __attribute((alias("IA__g_slice_set_config"), visibility("default")));
+
+#undef g_slice_get_config
+extern __typeof (g_slice_get_config) g_slice_get_config __attribute((alias("IA__g_slice_get_config"), visibility("default")));
+
+#undef g_slice_get_config_state
+extern __typeof (g_slice_get_config_state) g_slice_get_config_state __attribute((alias("IA__g_slice_get_config_state"), visibility("default")));
+
+#ifdef G_ENABLE_DEBUG
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_MESSAGES_H__)
+#if IN_FILE(__G_MESSAGES_C__)
+#undef g_printf_string_upper_bound
+extern __typeof (g_printf_string_upper_bound) g_printf_string_upper_bound __attribute((alias("IA__g_printf_string_upper_bound"), visibility("default")));
+
+#undef g_log
+extern __typeof (g_log) g_log __attribute((alias("IA__g_log"), visibility("default")));
+
+#undef g_log_default_handler
+extern __typeof (g_log_default_handler) g_log_default_handler __attribute((alias("IA__g_log_default_handler"), visibility("default")));
+
+#undef g_log_remove_handler
+extern __typeof (g_log_remove_handler) g_log_remove_handler __attribute((alias("IA__g_log_remove_handler"), visibility("default")));
+
+#undef g_log_set_always_fatal
+extern __typeof (g_log_set_always_fatal) g_log_set_always_fatal __attribute((alias("IA__g_log_set_always_fatal"), visibility("default")));
+
+#undef g_log_set_default_handler
+extern __typeof (g_log_set_default_handler) g_log_set_default_handler __attribute((alias("IA__g_log_set_default_handler"), visibility("default")));
+
+#undef g_log_set_fatal_mask
+extern __typeof (g_log_set_fatal_mask) g_log_set_fatal_mask __attribute((alias("IA__g_log_set_fatal_mask"), visibility("default")));
+
+#undef g_log_set_handler
+extern __typeof (g_log_set_handler) g_log_set_handler __attribute((alias("IA__g_log_set_handler"), visibility("default")));
+
+#undef g_logv
+extern __typeof (g_logv) g_logv __attribute((alias("IA__g_logv"), visibility("default")));
+
+#undef g_return_if_fail_warning
+extern __typeof (g_return_if_fail_warning) g_return_if_fail_warning __attribute((alias("IA__g_return_if_fail_warning"), visibility("default")));
+
+#undef g_warn_message
+extern __typeof (g_warn_message) g_warn_message __attribute((alias("IA__g_warn_message"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_assert_warning
+extern __typeof (g_assert_warning) g_assert_warning __attribute((alias("IA__g_assert_warning"), visibility("default")));
+
+#endif
+#undef g_print
+extern __typeof (g_print) g_print __attribute((alias("IA__g_print"), visibility("default")));
+
+#undef g_printerr
+extern __typeof (g_printerr) g_printerr __attribute((alias("IA__g_printerr"), visibility("default")));
+
+#undef g_set_printerr_handler
+extern __typeof (g_set_printerr_handler) g_set_printerr_handler __attribute((alias("IA__g_set_printerr_handler"), visibility("default")));
+
+#undef g_set_print_handler
+extern __typeof (g_set_print_handler) g_set_print_handler __attribute((alias("IA__g_set_print_handler"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_NODE_H__)
+#if IN_FILE(__G_NODE_C__)
+#undef g_node_child_index
+extern __typeof (g_node_child_index) g_node_child_index __attribute((alias("IA__g_node_child_index"), visibility("default")));
+
+#undef g_node_child_position
+extern __typeof (g_node_child_position) g_node_child_position __attribute((alias("IA__g_node_child_position"), visibility("default")));
+
+#undef g_node_children_foreach
+extern __typeof (g_node_children_foreach) g_node_children_foreach __attribute((alias("IA__g_node_children_foreach"), visibility("default")));
+
+#undef g_node_copy
+extern __typeof (g_node_copy) g_node_copy __attribute((alias("IA__g_node_copy"), visibility("default")));
+
+#undef g_node_copy_deep
+extern __typeof (g_node_copy_deep) g_node_copy_deep __attribute((alias("IA__g_node_copy_deep"), visibility("default")));
+
+#undef g_node_depth
+extern __typeof (g_node_depth) g_node_depth __attribute((alias("IA__g_node_depth"), visibility("default")));
+
+#undef g_node_destroy
+extern __typeof (g_node_destroy) g_node_destroy __attribute((alias("IA__g_node_destroy"), visibility("default")));
+
+#undef g_node_find
+extern __typeof (g_node_find) g_node_find __attribute((alias("IA__g_node_find"), visibility("default")));
+
+#undef g_node_find_child
+extern __typeof (g_node_find_child) g_node_find_child __attribute((alias("IA__g_node_find_child"), visibility("default")));
+
+#undef g_node_first_sibling
+extern __typeof (g_node_first_sibling) g_node_first_sibling __attribute((alias("IA__g_node_first_sibling"), visibility("default")));
+
+#undef g_node_get_root
+extern __typeof (g_node_get_root) g_node_get_root __attribute((alias("IA__g_node_get_root"), visibility("default")));
+
+#undef g_node_insert
+extern __typeof (g_node_insert) g_node_insert __attribute((alias("IA__g_node_insert"), visibility("default")));
+
+#undef g_node_insert_after
+extern __typeof (g_node_insert_after) g_node_insert_after __attribute((alias("IA__g_node_insert_after"), visibility("default")));
+
+#undef g_node_insert_before
+extern __typeof (g_node_insert_before) g_node_insert_before __attribute((alias("IA__g_node_insert_before"), visibility("default")));
+
+#undef g_node_is_ancestor
+extern __typeof (g_node_is_ancestor) g_node_is_ancestor __attribute((alias("IA__g_node_is_ancestor"), visibility("default")));
+
+#undef g_node_last_child
+extern __typeof (g_node_last_child) g_node_last_child __attribute((alias("IA__g_node_last_child"), visibility("default")));
+
+#undef g_node_last_sibling
+extern __typeof (g_node_last_sibling) g_node_last_sibling __attribute((alias("IA__g_node_last_sibling"), visibility("default")));
+
+#undef g_node_max_height
+extern __typeof (g_node_max_height) g_node_max_height __attribute((alias("IA__g_node_max_height"), visibility("default")));
+
+#undef g_node_n_children
+extern __typeof (g_node_n_children) g_node_n_children __attribute((alias("IA__g_node_n_children"), visibility("default")));
+
+#undef g_node_new
+extern __typeof (g_node_new) g_node_new __attribute((alias("IA__g_node_new"), visibility("default")));
+
+#undef g_node_n_nodes
+extern __typeof (g_node_n_nodes) g_node_n_nodes __attribute((alias("IA__g_node_n_nodes"), visibility("default")));
+
+#undef g_node_nth_child
+extern __typeof (g_node_nth_child) g_node_nth_child __attribute((alias("IA__g_node_nth_child"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_node_pop_allocator
+extern __typeof (g_node_pop_allocator) g_node_pop_allocator __attribute((alias("IA__g_node_pop_allocator"), visibility("default")));
+
+#endif
+#undef g_node_prepend
+extern __typeof (g_node_prepend) g_node_prepend __attribute((alias("IA__g_node_prepend"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_node_push_allocator
+extern __typeof (g_node_push_allocator) g_node_push_allocator __attribute((alias("IA__g_node_push_allocator"), visibility("default")));
+
+#endif
+#undef g_node_reverse_children
+extern __typeof (g_node_reverse_children) g_node_reverse_children __attribute((alias("IA__g_node_reverse_children"), visibility("default")));
+
+#undef g_node_traverse
+extern __typeof (g_node_traverse) g_node_traverse __attribute((alias("IA__g_node_traverse"), visibility("default")));
+
+#undef g_node_unlink
+extern __typeof (g_node_unlink) g_node_unlink __attribute((alias("IA__g_node_unlink"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_OPTION_H__)
+#if IN_FILE(__G_OPTION_C__)
+#undef g_option_context_add_group
+extern __typeof (g_option_context_add_group) g_option_context_add_group __attribute((alias("IA__g_option_context_add_group"), visibility("default")));
+
+#undef g_option_context_add_main_entries
+extern __typeof (g_option_context_add_main_entries) g_option_context_add_main_entries __attribute((alias("IA__g_option_context_add_main_entries"), visibility("default")));
+
+#undef g_option_error_quark
+extern __typeof (g_option_error_quark) g_option_error_quark __attribute((alias("IA__g_option_error_quark"), visibility("default")));
+
+#undef g_option_context_free
+extern __typeof (g_option_context_free) g_option_context_free __attribute((alias("IA__g_option_context_free"), visibility("default")));
+
+#undef g_option_context_get_description
+extern __typeof (g_option_context_get_description) g_option_context_get_description __attribute((alias("IA__g_option_context_get_description"), visibility("default")));
+
+#undef g_option_context_get_help_enabled
+extern __typeof (g_option_context_get_help_enabled) g_option_context_get_help_enabled __attribute((alias("IA__g_option_context_get_help_enabled"), visibility("default")));
+
+#undef g_option_context_get_ignore_unknown_options
+extern __typeof (g_option_context_get_ignore_unknown_options) g_option_context_get_ignore_unknown_options __attribute((alias("IA__g_option_context_get_ignore_unknown_options"), visibility("default")));
+
+#undef g_option_context_get_main_group
+extern __typeof (g_option_context_get_main_group) g_option_context_get_main_group __attribute((alias("IA__g_option_context_get_main_group"), visibility("default")));
+
+#undef g_option_context_get_summary
+extern __typeof (g_option_context_get_summary) g_option_context_get_summary __attribute((alias("IA__g_option_context_get_summary"), visibility("default")));
+
+#undef g_option_context_new
+extern __typeof (g_option_context_new) g_option_context_new __attribute((alias("IA__g_option_context_new"), visibility("default")));
+
+#undef g_option_context_parse
+extern __typeof (g_option_context_parse) g_option_context_parse __attribute((alias("IA__g_option_context_parse"), visibility("default")));
+
+#undef g_option_context_set_description
+extern __typeof (g_option_context_set_description) g_option_context_set_description __attribute((alias("IA__g_option_context_set_description"), visibility("default")));
+
+#undef g_option_context_set_help_enabled
+extern __typeof (g_option_context_set_help_enabled) g_option_context_set_help_enabled __attribute((alias("IA__g_option_context_set_help_enabled"), visibility("default")));
+
+#undef g_option_context_set_ignore_unknown_options
+extern __typeof (g_option_context_set_ignore_unknown_options) g_option_context_set_ignore_unknown_options __attribute((alias("IA__g_option_context_set_ignore_unknown_options"), visibility("default")));
+
+#undef g_option_context_set_main_group
+extern __typeof (g_option_context_set_main_group) g_option_context_set_main_group __attribute((alias("IA__g_option_context_set_main_group"), visibility("default")));
+
+#undef g_option_context_set_summary
+extern __typeof (g_option_context_set_summary) g_option_context_set_summary __attribute((alias("IA__g_option_context_set_summary"), visibility("default")));
+
+#undef g_option_context_set_translate_func
+extern __typeof (g_option_context_set_translate_func) g_option_context_set_translate_func __attribute((alias("IA__g_option_context_set_translate_func"), visibility("default")));
+
+#undef g_option_context_set_translation_domain
+extern __typeof (g_option_context_set_translation_domain) g_option_context_set_translation_domain __attribute((alias("IA__g_option_context_set_translation_domain"), visibility("default")));
+
+#undef g_option_context_get_help
+extern __typeof (g_option_context_get_help) g_option_context_get_help __attribute((alias("IA__g_option_context_get_help"), visibility("default")));
+
+#undef g_option_group_add_entries
+extern __typeof (g_option_group_add_entries) g_option_group_add_entries __attribute((alias("IA__g_option_group_add_entries"), visibility("default")));
+
+#undef g_option_group_free
+extern __typeof (g_option_group_free) g_option_group_free __attribute((alias("IA__g_option_group_free"), visibility("default")));
+
+#undef g_option_group_new
+extern __typeof (g_option_group_new) g_option_group_new __attribute((alias("IA__g_option_group_new"), visibility("default")));
+
+#undef g_option_group_set_error_hook
+extern __typeof (g_option_group_set_error_hook) g_option_group_set_error_hook __attribute((alias("IA__g_option_group_set_error_hook"), visibility("default")));
+
+#undef g_option_group_set_parse_hooks
+extern __typeof (g_option_group_set_parse_hooks) g_option_group_set_parse_hooks __attribute((alias("IA__g_option_group_set_parse_hooks"), visibility("default")));
+
+#undef g_option_group_set_translate_func
+extern __typeof (g_option_group_set_translate_func) g_option_group_set_translate_func __attribute((alias("IA__g_option_group_set_translate_func"), visibility("default")));
+
+#undef g_option_group_set_translation_domain
+extern __typeof (g_option_group_set_translation_domain) g_option_group_set_translation_domain __attribute((alias("IA__g_option_group_set_translation_domain"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_PATTERN_H__)
+#if IN_FILE(__G_PATTERN_C__)
+#undef g_pattern_match
+extern __typeof (g_pattern_match) g_pattern_match __attribute((alias("IA__g_pattern_match"), visibility("default")));
+
+#undef g_pattern_match_simple
+extern __typeof (g_pattern_match_simple) g_pattern_match_simple __attribute((alias("IA__g_pattern_match_simple"), visibility("default")));
+
+#undef g_pattern_match_string
+extern __typeof (g_pattern_match_string) g_pattern_match_string __attribute((alias("IA__g_pattern_match_string"), visibility("default")));
+
+#undef g_pattern_spec_equal
+extern __typeof (g_pattern_spec_equal) g_pattern_spec_equal __attribute((alias("IA__g_pattern_spec_equal"), visibility("default")));
+
+#undef g_pattern_spec_free
+extern __typeof (g_pattern_spec_free) g_pattern_spec_free __attribute((alias("IA__g_pattern_spec_free"), visibility("default")));
+
+#undef g_pattern_spec_new
+extern __typeof (g_pattern_spec_new) g_pattern_spec_new __attribute((alias("IA__g_pattern_spec_new"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_POLL_H__)
+#if IN_FILE(__G_POLL_C__)
+#undef g_poll
+extern __typeof (g_poll) g_poll __attribute((alias("IA__g_poll"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_PRIMES_H__)
+#if IN_FILE(__G_PRIMES_C__)
+#undef g_spaced_primes_closest
+extern __typeof (g_spaced_primes_closest) g_spaced_primes_closest __attribute((alias("IA__g_spaced_primes_closest"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_PRINTF_H__)
+#if IN_FILE(__G_PRINTF_C__)
+#undef g_fprintf
+extern __typeof (g_fprintf) g_fprintf __attribute((alias("IA__g_fprintf"), visibility("default")));
+
+#undef g_printf
+extern __typeof (g_printf) g_printf __attribute((alias("IA__g_printf"), visibility("default")));
+
+#undef g_sprintf
+extern __typeof (g_sprintf) g_sprintf __attribute((alias("IA__g_sprintf"), visibility("default")));
+
+#undef g_vasprintf
+extern __typeof (g_vasprintf) g_vasprintf __attribute((alias("IA__g_vasprintf"), visibility("default")));
+
+#undef g_vfprintf
+extern __typeof (g_vfprintf) g_vfprintf __attribute((alias("IA__g_vfprintf"), visibility("default")));
+
+#undef g_vprintf
+extern __typeof (g_vprintf) g_vprintf __attribute((alias("IA__g_vprintf"), visibility("default")));
+
+#undef g_vsprintf
+extern __typeof (g_vsprintf) g_vsprintf __attribute((alias("IA__g_vsprintf"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_UTILS_H__)
+#if IN_FILE(__G_PRINTF_C__)
+#undef g_snprintf
+extern __typeof (g_snprintf) g_snprintf __attribute((alias("IA__g_snprintf"), visibility("default")));
+
+#undef g_vsnprintf
+extern __typeof (g_vsnprintf) g_vsnprintf __attribute((alias("IA__g_vsnprintf"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_QSORT_H__)
+#if IN_FILE(__G_QSORT_C__)
+#undef g_qsort_with_data
+extern __typeof (g_qsort_with_data) g_qsort_with_data __attribute((alias("IA__g_qsort_with_data"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_QUEUE_H__)
+#if IN_FILE(__G_QUEUE_C__)
+#undef g_queue_clear
+extern __typeof (g_queue_clear) g_queue_clear __attribute((alias("IA__g_queue_clear"), visibility("default")));
+
+#undef g_queue_copy
+extern __typeof (g_queue_copy) g_queue_copy __attribute((alias("IA__g_queue_copy"), visibility("default")));
+
+#undef g_queue_delete_link
+extern __typeof (g_queue_delete_link) g_queue_delete_link __attribute((alias("IA__g_queue_delete_link"), visibility("default")));
+
+#undef g_queue_find
+extern __typeof (g_queue_find) g_queue_find __attribute((alias("IA__g_queue_find"), visibility("default")));
+
+#undef g_queue_find_custom
+extern __typeof (g_queue_find_custom) g_queue_find_custom __attribute((alias("IA__g_queue_find_custom"), visibility("default")));
+
+#undef g_queue_foreach
+extern __typeof (g_queue_foreach) g_queue_foreach __attribute((alias("IA__g_queue_foreach"), visibility("default")));
+
+#undef g_queue_free
+extern __typeof (g_queue_free) g_queue_free __attribute((alias("IA__g_queue_free"), visibility("default")));
+
+#undef g_queue_get_length
+extern __typeof (g_queue_get_length) g_queue_get_length __attribute((alias("IA__g_queue_get_length"), visibility("default")));
+
+#undef g_queue_index
+extern __typeof (g_queue_index) g_queue_index __attribute((alias("IA__g_queue_index"), visibility("default")));
+
+#undef g_queue_init
+extern __typeof (g_queue_init) g_queue_init __attribute((alias("IA__g_queue_init"), visibility("default")));
+
+#undef g_queue_insert_after
+extern __typeof (g_queue_insert_after) g_queue_insert_after __attribute((alias("IA__g_queue_insert_after"), visibility("default")));
+
+#undef g_queue_insert_before
+extern __typeof (g_queue_insert_before) g_queue_insert_before __attribute((alias("IA__g_queue_insert_before"), visibility("default")));
+
+#undef g_queue_insert_sorted
+extern __typeof (g_queue_insert_sorted) g_queue_insert_sorted __attribute((alias("IA__g_queue_insert_sorted"), visibility("default")));
+
+#undef g_queue_is_empty
+extern __typeof (g_queue_is_empty) g_queue_is_empty __attribute((alias("IA__g_queue_is_empty"), visibility("default")));
+
+#undef g_queue_link_index
+extern __typeof (g_queue_link_index) g_queue_link_index __attribute((alias("IA__g_queue_link_index"), visibility("default")));
+
+#undef g_queue_new
+extern __typeof (g_queue_new) g_queue_new __attribute((alias("IA__g_queue_new"), visibility("default")));
+
+#undef g_queue_peek_head
+extern __typeof (g_queue_peek_head) g_queue_peek_head __attribute((alias("IA__g_queue_peek_head"), visibility("default")));
+
+#undef g_queue_peek_head_link
+extern __typeof (g_queue_peek_head_link) g_queue_peek_head_link __attribute((alias("IA__g_queue_peek_head_link"), visibility("default")));
+
+#undef g_queue_peek_nth
+extern __typeof (g_queue_peek_nth) g_queue_peek_nth __attribute((alias("IA__g_queue_peek_nth"), visibility("default")));
+
+#undef g_queue_peek_nth_link
+extern __typeof (g_queue_peek_nth_link) g_queue_peek_nth_link __attribute((alias("IA__g_queue_peek_nth_link"), visibility("default")));
+
+#undef g_queue_peek_tail
+extern __typeof (g_queue_peek_tail) g_queue_peek_tail __attribute((alias("IA__g_queue_peek_tail"), visibility("default")));
+
+#undef g_queue_peek_tail_link
+extern __typeof (g_queue_peek_tail_link) g_queue_peek_tail_link __attribute((alias("IA__g_queue_peek_tail_link"), visibility("default")));
+
+#undef g_queue_pop_head
+extern __typeof (g_queue_pop_head) g_queue_pop_head __attribute((alias("IA__g_queue_pop_head"), visibility("default")));
+
+#undef g_queue_pop_head_link
+extern __typeof (g_queue_pop_head_link) g_queue_pop_head_link __attribute((alias("IA__g_queue_pop_head_link"), visibility("default")));
+
+#undef g_queue_pop_nth
+extern __typeof (g_queue_pop_nth) g_queue_pop_nth __attribute((alias("IA__g_queue_pop_nth"), visibility("default")));
+
+#undef g_queue_pop_nth_link
+extern __typeof (g_queue_pop_nth_link) g_queue_pop_nth_link __attribute((alias("IA__g_queue_pop_nth_link"), visibility("default")));
+
+#undef g_queue_pop_tail
+extern __typeof (g_queue_pop_tail) g_queue_pop_tail __attribute((alias("IA__g_queue_pop_tail"), visibility("default")));
+
+#undef g_queue_pop_tail_link
+extern __typeof (g_queue_pop_tail_link) g_queue_pop_tail_link __attribute((alias("IA__g_queue_pop_tail_link"), visibility("default")));
+
+#undef g_queue_push_head
+extern __typeof (g_queue_push_head) g_queue_push_head __attribute((alias("IA__g_queue_push_head"), visibility("default")));
+
+#undef g_queue_push_head_link
+extern __typeof (g_queue_push_head_link) g_queue_push_head_link __attribute((alias("IA__g_queue_push_head_link"), visibility("default")));
+
+#undef g_queue_push_nth
+extern __typeof (g_queue_push_nth) g_queue_push_nth __attribute((alias("IA__g_queue_push_nth"), visibility("default")));
+
+#undef g_queue_push_nth_link
+extern __typeof (g_queue_push_nth_link) g_queue_push_nth_link __attribute((alias("IA__g_queue_push_nth_link"), visibility("default")));
+
+#undef g_queue_push_tail
+extern __typeof (g_queue_push_tail) g_queue_push_tail __attribute((alias("IA__g_queue_push_tail"), visibility("default")));
+
+#undef g_queue_push_tail_link
+extern __typeof (g_queue_push_tail_link) g_queue_push_tail_link __attribute((alias("IA__g_queue_push_tail_link"), visibility("default")));
+
+#undef g_queue_remove
+extern __typeof (g_queue_remove) g_queue_remove __attribute((alias("IA__g_queue_remove"), visibility("default")));
+
+#undef g_queue_remove_all
+extern __typeof (g_queue_remove_all) g_queue_remove_all __attribute((alias("IA__g_queue_remove_all"), visibility("default")));
+
+#undef g_queue_reverse
+extern __typeof (g_queue_reverse) g_queue_reverse __attribute((alias("IA__g_queue_reverse"), visibility("default")));
+
+#undef g_queue_sort
+extern __typeof (g_queue_sort) g_queue_sort __attribute((alias("IA__g_queue_sort"), visibility("default")));
+
+#undef g_queue_unlink
+extern __typeof (g_queue_unlink) g_queue_unlink __attribute((alias("IA__g_queue_unlink"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_RAND_H__)
+#if IN_FILE(__G_RAND_C__)
+#undef g_rand_copy
+extern __typeof (g_rand_copy) g_rand_copy __attribute((alias("IA__g_rand_copy"), visibility("default")));
+
+#undef g_rand_double
+extern __typeof (g_rand_double) g_rand_double __attribute((alias("IA__g_rand_double"), visibility("default")));
+
+#undef g_rand_double_range
+extern __typeof (g_rand_double_range) g_rand_double_range __attribute((alias("IA__g_rand_double_range"), visibility("default")));
+
+#undef g_rand_free
+extern __typeof (g_rand_free) g_rand_free __attribute((alias("IA__g_rand_free"), visibility("default")));
+
+#undef g_rand_int
+extern __typeof (g_rand_int) g_rand_int __attribute((alias("IA__g_rand_int"), visibility("default")));
+
+#undef g_rand_int_range
+extern __typeof (g_rand_int_range) g_rand_int_range __attribute((alias("IA__g_rand_int_range"), visibility("default")));
+
+#undef g_rand_new
+extern __typeof (g_rand_new) g_rand_new __attribute((alias("IA__g_rand_new"), visibility("default")));
+
+#undef g_rand_new_with_seed
+extern __typeof (g_rand_new_with_seed) g_rand_new_with_seed __attribute((alias("IA__g_rand_new_with_seed"), visibility("default")));
+
+#undef g_rand_new_with_seed_array
+extern __typeof (g_rand_new_with_seed_array) g_rand_new_with_seed_array __attribute((alias("IA__g_rand_new_with_seed_array"), visibility("default")));
+
+#undef g_random_double
+extern __typeof (g_random_double) g_random_double __attribute((alias("IA__g_random_double"), visibility("default")));
+
+#undef g_random_double_range
+extern __typeof (g_random_double_range) g_random_double_range __attribute((alias("IA__g_random_double_range"), visibility("default")));
+
+#undef g_random_int
+extern __typeof (g_random_int) g_random_int __attribute((alias("IA__g_random_int"), visibility("default")));
+
+#undef g_random_int_range
+extern __typeof (g_random_int_range) g_random_int_range __attribute((alias("IA__g_random_int_range"), visibility("default")));
+
+#undef g_random_set_seed
+extern __typeof (g_random_set_seed) g_random_set_seed __attribute((alias("IA__g_random_set_seed"), visibility("default")));
+
+#undef g_rand_set_seed
+extern __typeof (g_rand_set_seed) g_rand_set_seed __attribute((alias("IA__g_rand_set_seed"), visibility("default")));
+
+#undef g_rand_set_seed_array
+extern __typeof (g_rand_set_seed_array) g_rand_set_seed_array __attribute((alias("IA__g_rand_set_seed_array"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_REL_H__)
+#if IN_FILE(__G_REL_C__)
+#undef g_relation_count
+extern __typeof (g_relation_count) g_relation_count __attribute((alias("IA__g_relation_count"), visibility("default")));
+
+#undef g_relation_delete
+extern __typeof (g_relation_delete) g_relation_delete __attribute((alias("IA__g_relation_delete"), visibility("default")));
+
+#undef g_relation_destroy
+extern __typeof (g_relation_destroy) g_relation_destroy __attribute((alias("IA__g_relation_destroy"), visibility("default")));
+
+#undef g_relation_exists
+extern __typeof (g_relation_exists) g_relation_exists __attribute((alias("IA__g_relation_exists"), visibility("default")));
+
+#undef g_relation_index
+extern __typeof (g_relation_index) g_relation_index __attribute((alias("IA__g_relation_index"), visibility("default")));
+
+#undef g_relation_insert
+extern __typeof (g_relation_insert) g_relation_insert __attribute((alias("IA__g_relation_insert"), visibility("default")));
+
+#undef g_relation_new
+extern __typeof (g_relation_new) g_relation_new __attribute((alias("IA__g_relation_new"), visibility("default")));
+
+#undef g_relation_print
+extern __typeof (g_relation_print) g_relation_print __attribute((alias("IA__g_relation_print"), visibility("default")));
+
+#undef g_relation_select
+extern __typeof (g_relation_select) g_relation_select __attribute((alias("IA__g_relation_select"), visibility("default")));
+
+#undef g_tuples_destroy
+extern __typeof (g_tuples_destroy) g_tuples_destroy __attribute((alias("IA__g_tuples_destroy"), visibility("default")));
+
+#undef g_tuples_index
+extern __typeof (g_tuples_index) g_tuples_index __attribute((alias("IA__g_tuples_index"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_SCANNER_H__)
+#if IN_FILE(__G_SCANNER_C__)
+#undef g_scanner_cur_line
+extern __typeof (g_scanner_cur_line) g_scanner_cur_line __attribute((alias("IA__g_scanner_cur_line"), visibility("default")));
+
+#undef g_scanner_cur_position
+extern __typeof (g_scanner_cur_position) g_scanner_cur_position __attribute((alias("IA__g_scanner_cur_position"), visibility("default")));
+
+#undef g_scanner_cur_token
+extern __typeof (g_scanner_cur_token) g_scanner_cur_token __attribute((alias("IA__g_scanner_cur_token"), visibility("default")));
+
+#undef g_scanner_cur_value
+extern __typeof (g_scanner_cur_value) g_scanner_cur_value __attribute((alias("IA__g_scanner_cur_value"), visibility("default")));
+
+#undef g_scanner_destroy
+extern __typeof (g_scanner_destroy) g_scanner_destroy __attribute((alias("IA__g_scanner_destroy"), visibility("default")));
+
+#undef g_scanner_eof
+extern __typeof (g_scanner_eof) g_scanner_eof __attribute((alias("IA__g_scanner_eof"), visibility("default")));
+
+#undef g_scanner_error
+extern __typeof (g_scanner_error) g_scanner_error __attribute((alias("IA__g_scanner_error"), visibility("default")));
+
+#undef g_scanner_get_next_token
+extern __typeof (g_scanner_get_next_token) g_scanner_get_next_token __attribute((alias("IA__g_scanner_get_next_token"), visibility("default")));
+
+#undef g_scanner_input_file
+extern __typeof (g_scanner_input_file) g_scanner_input_file __attribute((alias("IA__g_scanner_input_file"), visibility("default")));
+
+#undef g_scanner_input_text
+extern __typeof (g_scanner_input_text) g_scanner_input_text __attribute((alias("IA__g_scanner_input_text"), visibility("default")));
+
+#undef g_scanner_lookup_symbol
+extern __typeof (g_scanner_lookup_symbol) g_scanner_lookup_symbol __attribute((alias("IA__g_scanner_lookup_symbol"), visibility("default")));
+
+#undef g_scanner_new
+extern __typeof (g_scanner_new) g_scanner_new __attribute((alias("IA__g_scanner_new"), visibility("default")));
+
+#undef g_scanner_peek_next_token
+extern __typeof (g_scanner_peek_next_token) g_scanner_peek_next_token __attribute((alias("IA__g_scanner_peek_next_token"), visibility("default")));
+
+#undef g_scanner_scope_add_symbol
+extern __typeof (g_scanner_scope_add_symbol) g_scanner_scope_add_symbol __attribute((alias("IA__g_scanner_scope_add_symbol"), visibility("default")));
+
+#undef g_scanner_scope_foreach_symbol
+extern __typeof (g_scanner_scope_foreach_symbol) g_scanner_scope_foreach_symbol __attribute((alias("IA__g_scanner_scope_foreach_symbol"), visibility("default")));
+
+#undef g_scanner_scope_lookup_symbol
+extern __typeof (g_scanner_scope_lookup_symbol) g_scanner_scope_lookup_symbol __attribute((alias("IA__g_scanner_scope_lookup_symbol"), visibility("default")));
+
+#undef g_scanner_scope_remove_symbol
+extern __typeof (g_scanner_scope_remove_symbol) g_scanner_scope_remove_symbol __attribute((alias("IA__g_scanner_scope_remove_symbol"), visibility("default")));
+
+#undef g_scanner_set_scope
+extern __typeof (g_scanner_set_scope) g_scanner_set_scope __attribute((alias("IA__g_scanner_set_scope"), visibility("default")));
+
+#undef g_scanner_sync_file_offset
+extern __typeof (g_scanner_sync_file_offset) g_scanner_sync_file_offset __attribute((alias("IA__g_scanner_sync_file_offset"), visibility("default")));
+
+#undef g_scanner_unexp_token
+extern __typeof (g_scanner_unexp_token) g_scanner_unexp_token __attribute((alias("IA__g_scanner_unexp_token"), visibility("default")));
+
+#undef g_scanner_warn
+extern __typeof (g_scanner_warn) g_scanner_warn __attribute((alias("IA__g_scanner_warn"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_SEQUENCE_H__)
+#if IN_FILE(__G_SEQUENCE_C__)
+#undef g_sequence_new
+extern __typeof (g_sequence_new) g_sequence_new __attribute((alias("IA__g_sequence_new"), visibility("default")));
+
+#undef g_sequence_free
+extern __typeof (g_sequence_free) g_sequence_free __attribute((alias("IA__g_sequence_free"), visibility("default")));
+
+#undef g_sequence_get_length
+extern __typeof (g_sequence_get_length) g_sequence_get_length __attribute((alias("IA__g_sequence_get_length"), visibility("default")));
+
+#undef g_sequence_foreach
+extern __typeof (g_sequence_foreach) g_sequence_foreach __attribute((alias("IA__g_sequence_foreach"), visibility("default")));
+
+#undef g_sequence_foreach_range
+extern __typeof (g_sequence_foreach_range) g_sequence_foreach_range __attribute((alias("IA__g_sequence_foreach_range"), visibility("default")));
+
+#undef g_sequence_sort
+extern __typeof (g_sequence_sort) g_sequence_sort __attribute((alias("IA__g_sequence_sort"), visibility("default")));
+
+#undef g_sequence_sort_iter
+extern __typeof (g_sequence_sort_iter) g_sequence_sort_iter __attribute((alias("IA__g_sequence_sort_iter"), visibility("default")));
+
+#undef g_sequence_get_begin_iter
+extern __typeof (g_sequence_get_begin_iter) g_sequence_get_begin_iter __attribute((alias("IA__g_sequence_get_begin_iter"), visibility("default")));
+
+#undef g_sequence_get_end_iter
+extern __typeof (g_sequence_get_end_iter) g_sequence_get_end_iter __attribute((alias("IA__g_sequence_get_end_iter"), visibility("default")));
+
+#undef g_sequence_get_iter_at_pos
+extern __typeof (g_sequence_get_iter_at_pos) g_sequence_get_iter_at_pos __attribute((alias("IA__g_sequence_get_iter_at_pos"), visibility("default")));
+
+#undef g_sequence_append
+extern __typeof (g_sequence_append) g_sequence_append __attribute((alias("IA__g_sequence_append"), visibility("default")));
+
+#undef g_sequence_prepend
+extern __typeof (g_sequence_prepend) g_sequence_prepend __attribute((alias("IA__g_sequence_prepend"), visibility("default")));
+
+#undef g_sequence_insert_before
+extern __typeof (g_sequence_insert_before) g_sequence_insert_before __attribute((alias("IA__g_sequence_insert_before"), visibility("default")));
+
+#undef g_sequence_move
+extern __typeof (g_sequence_move) g_sequence_move __attribute((alias("IA__g_sequence_move"), visibility("default")));
+
+#undef g_sequence_swap
+extern __typeof (g_sequence_swap) g_sequence_swap __attribute((alias("IA__g_sequence_swap"), visibility("default")));
+
+#undef g_sequence_insert_sorted
+extern __typeof (g_sequence_insert_sorted) g_sequence_insert_sorted __attribute((alias("IA__g_sequence_insert_sorted"), visibility("default")));
+
+#undef g_sequence_insert_sorted_iter
+extern __typeof (g_sequence_insert_sorted_iter) g_sequence_insert_sorted_iter __attribute((alias("IA__g_sequence_insert_sorted_iter"), visibility("default")));
+
+#undef g_sequence_sort_changed
+extern __typeof (g_sequence_sort_changed) g_sequence_sort_changed __attribute((alias("IA__g_sequence_sort_changed"), visibility("default")));
+
+#undef g_sequence_sort_changed_iter
+extern __typeof (g_sequence_sort_changed_iter) g_sequence_sort_changed_iter __attribute((alias("IA__g_sequence_sort_changed_iter"), visibility("default")));
+
+#undef g_sequence_remove
+extern __typeof (g_sequence_remove) g_sequence_remove __attribute((alias("IA__g_sequence_remove"), visibility("default")));
+
+#undef g_sequence_remove_range
+extern __typeof (g_sequence_remove_range) g_sequence_remove_range __attribute((alias("IA__g_sequence_remove_range"), visibility("default")));
+
+#undef g_sequence_move_range
+extern __typeof (g_sequence_move_range) g_sequence_move_range __attribute((alias("IA__g_sequence_move_range"), visibility("default")));
+
+#undef g_sequence_search
+extern __typeof (g_sequence_search) g_sequence_search __attribute((alias("IA__g_sequence_search"), visibility("default")));
+
+#undef g_sequence_search_iter
+extern __typeof (g_sequence_search_iter) g_sequence_search_iter __attribute((alias("IA__g_sequence_search_iter"), visibility("default")));
+
+#undef g_sequence_get
+extern __typeof (g_sequence_get) g_sequence_get __attribute((alias("IA__g_sequence_get"), visibility("default")));
+
+#undef g_sequence_set
+extern __typeof (g_sequence_set) g_sequence_set __attribute((alias("IA__g_sequence_set"), visibility("default")));
+
+#undef g_sequence_iter_is_begin
+extern __typeof (g_sequence_iter_is_begin) g_sequence_iter_is_begin __attribute((alias("IA__g_sequence_iter_is_begin"), visibility("default")));
+
+#undef g_sequence_iter_is_end
+extern __typeof (g_sequence_iter_is_end) g_sequence_iter_is_end __attribute((alias("IA__g_sequence_iter_is_end"), visibility("default")));
+
+#undef g_sequence_iter_next
+extern __typeof (g_sequence_iter_next) g_sequence_iter_next __attribute((alias("IA__g_sequence_iter_next"), visibility("default")));
+
+#undef g_sequence_iter_prev
+extern __typeof (g_sequence_iter_prev) g_sequence_iter_prev __attribute((alias("IA__g_sequence_iter_prev"), visibility("default")));
+
+#undef g_sequence_iter_get_position
+extern __typeof (g_sequence_iter_get_position) g_sequence_iter_get_position __attribute((alias("IA__g_sequence_iter_get_position"), visibility("default")));
+
+#undef g_sequence_iter_move
+extern __typeof (g_sequence_iter_move) g_sequence_iter_move __attribute((alias("IA__g_sequence_iter_move"), visibility("default")));
+
+#undef g_sequence_iter_get_sequence
+extern __typeof (g_sequence_iter_get_sequence) g_sequence_iter_get_sequence __attribute((alias("IA__g_sequence_iter_get_sequence"), visibility("default")));
+
+#undef g_sequence_iter_compare
+extern __typeof (g_sequence_iter_compare) g_sequence_iter_compare __attribute((alias("IA__g_sequence_iter_compare"), visibility("default")));
+
+#undef g_sequence_range_get_midpoint
+extern __typeof (g_sequence_range_get_midpoint) g_sequence_range_get_midpoint __attribute((alias("IA__g_sequence_range_get_midpoint"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_SHELL_H__)
+#if IN_FILE(__G_SHELL_C__)
+#undef g_shell_error_quark
+extern __typeof (g_shell_error_quark) g_shell_error_quark __attribute((alias("IA__g_shell_error_quark"), visibility("default")));
+
+#undef g_shell_parse_argv
+extern __typeof (g_shell_parse_argv) g_shell_parse_argv __attribute((alias("IA__g_shell_parse_argv"), visibility("default")));
+
+#undef g_shell_quote
+extern __typeof (g_shell_quote) g_shell_quote __attribute((alias("IA__g_shell_quote"), visibility("default")));
+
+#undef g_shell_unquote
+extern __typeof (g_shell_unquote) g_shell_unquote __attribute((alias("IA__g_shell_unquote"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_SLIST_H__)
+#if IN_FILE(__G_SLIST_C__)
+#undef g_slist_alloc
+extern __typeof (g_slist_alloc) g_slist_alloc __attribute((alias("IA__g_slist_alloc"), visibility("default")));
+
+#undef g_slist_append
+extern __typeof (g_slist_append) g_slist_append __attribute((alias("IA__g_slist_append"), visibility("default")));
+
+#undef g_slist_concat
+extern __typeof (g_slist_concat) g_slist_concat __attribute((alias("IA__g_slist_concat"), visibility("default")));
+
+#undef g_slist_copy
+extern __typeof (g_slist_copy) g_slist_copy __attribute((alias("IA__g_slist_copy"), visibility("default")));
+
+#undef g_slist_delete_link
+extern __typeof (g_slist_delete_link) g_slist_delete_link __attribute((alias("IA__g_slist_delete_link"), visibility("default")));
+
+#undef g_slist_find
+extern __typeof (g_slist_find) g_slist_find __attribute((alias("IA__g_slist_find"), visibility("default")));
+
+#undef g_slist_find_custom
+extern __typeof (g_slist_find_custom) g_slist_find_custom __attribute((alias("IA__g_slist_find_custom"), visibility("default")));
+
+#undef g_slist_foreach
+extern __typeof (g_slist_foreach) g_slist_foreach __attribute((alias("IA__g_slist_foreach"), visibility("default")));
+
+#undef g_slist_free
+extern __typeof (g_slist_free) g_slist_free __attribute((alias("IA__g_slist_free"), visibility("default")));
+
+#undef g_slist_free_1
+extern __typeof (g_slist_free_1) g_slist_free_1 __attribute((alias("IA__g_slist_free_1"), visibility("default")));
+
+#undef g_slist_index
+extern __typeof (g_slist_index) g_slist_index __attribute((alias("IA__g_slist_index"), visibility("default")));
+
+#undef g_slist_insert
+extern __typeof (g_slist_insert) g_slist_insert __attribute((alias("IA__g_slist_insert"), visibility("default")));
+
+#undef g_slist_insert_before
+extern __typeof (g_slist_insert_before) g_slist_insert_before __attribute((alias("IA__g_slist_insert_before"), visibility("default")));
+
+#undef g_slist_insert_sorted
+extern __typeof (g_slist_insert_sorted) g_slist_insert_sorted __attribute((alias("IA__g_slist_insert_sorted"), visibility("default")));
+
+#undef g_slist_insert_sorted_with_data
+extern __typeof (g_slist_insert_sorted_with_data) g_slist_insert_sorted_with_data __attribute((alias("IA__g_slist_insert_sorted_with_data"), visibility("default")));
+
+#undef g_slist_last
+extern __typeof (g_slist_last) g_slist_last __attribute((alias("IA__g_slist_last"), visibility("default")));
+
+#undef g_slist_length
+extern __typeof (g_slist_length) g_slist_length __attribute((alias("IA__g_slist_length"), visibility("default")));
+
+#undef g_slist_nth
+extern __typeof (g_slist_nth) g_slist_nth __attribute((alias("IA__g_slist_nth"), visibility("default")));
+
+#undef g_slist_nth_data
+extern __typeof (g_slist_nth_data) g_slist_nth_data __attribute((alias("IA__g_slist_nth_data"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_slist_pop_allocator
+extern __typeof (g_slist_pop_allocator) g_slist_pop_allocator __attribute((alias("IA__g_slist_pop_allocator"), visibility("default")));
+
+#endif
+#undef g_slist_position
+extern __typeof (g_slist_position) g_slist_position __attribute((alias("IA__g_slist_position"), visibility("default")));
+
+#undef g_slist_prepend
+extern __typeof (g_slist_prepend) g_slist_prepend __attribute((alias("IA__g_slist_prepend"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_slist_push_allocator
+extern __typeof (g_slist_push_allocator) g_slist_push_allocator __attribute((alias("IA__g_slist_push_allocator"), visibility("default")));
+
+#endif
+#undef g_slist_remove
+extern __typeof (g_slist_remove) g_slist_remove __attribute((alias("IA__g_slist_remove"), visibility("default")));
+
+#undef g_slist_remove_all
+extern __typeof (g_slist_remove_all) g_slist_remove_all __attribute((alias("IA__g_slist_remove_all"), visibility("default")));
+
+#undef g_slist_remove_link
+extern __typeof (g_slist_remove_link) g_slist_remove_link __attribute((alias("IA__g_slist_remove_link"), visibility("default")));
+
+#undef g_slist_reverse
+extern __typeof (g_slist_reverse) g_slist_reverse __attribute((alias("IA__g_slist_reverse"), visibility("default")));
+
+#undef g_slist_sort
+extern __typeof (g_slist_sort) g_slist_sort __attribute((alias("IA__g_slist_sort"), visibility("default")));
+
+#undef g_slist_sort_with_data
+extern __typeof (g_slist_sort_with_data) g_slist_sort_with_data __attribute((alias("IA__g_slist_sort_with_data"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_SPAWN_H__)
+#if IN_FILE(__G_SPAWN_C__)
+#ifndef _WIN64
+#undef g_spawn_async
+extern __typeof (g_spawn_async) g_spawn_async __attribute((alias("IA__g_spawn_async"), visibility("default")));
+
+#undef g_spawn_async_with_pipes
+extern __typeof (g_spawn_async_with_pipes) g_spawn_async_with_pipes __attribute((alias("IA__g_spawn_async_with_pipes"), visibility("default")));
+
+#endif
+#undef g_spawn_close_pid
+extern __typeof (g_spawn_close_pid) g_spawn_close_pid __attribute((alias("IA__g_spawn_close_pid"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_spawn_command_line_async
+extern __typeof (g_spawn_command_line_async) g_spawn_command_line_async __attribute((alias("IA__g_spawn_command_line_async"), visibility("default")));
+
+#undef g_spawn_command_line_sync
+extern __typeof (g_spawn_command_line_sync) g_spawn_command_line_sync __attribute((alias("IA__g_spawn_command_line_sync"), visibility("default")));
+
+#endif
+#undef g_spawn_error_quark
+extern __typeof (g_spawn_error_quark) g_spawn_error_quark __attribute((alias("IA__g_spawn_error_quark"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_spawn_sync
+extern __typeof (g_spawn_sync) g_spawn_sync __attribute((alias("IA__g_spawn_sync"), visibility("default")));
+
+#endif
+#ifdef G_OS_WIN32
+#undef g_spawn_async_utf8
+extern __typeof (g_spawn_async_utf8) g_spawn_async_utf8 __attribute((alias("IA__g_spawn_async_utf8"), visibility("default")));
+
+#undef g_spawn_async_with_pipes_utf8
+extern __typeof (g_spawn_async_with_pipes_utf8) g_spawn_async_with_pipes_utf8 __attribute((alias("IA__g_spawn_async_with_pipes_utf8"), visibility("default")));
+
+#undef g_spawn_command_line_async_utf8
+extern __typeof (g_spawn_command_line_async_utf8) g_spawn_command_line_async_utf8 __attribute((alias("IA__g_spawn_command_line_async_utf8"), visibility("default")));
+
+#undef g_spawn_command_line_sync_utf8
+extern __typeof (g_spawn_command_line_sync_utf8) g_spawn_command_line_sync_utf8 __attribute((alias("IA__g_spawn_command_line_sync_utf8"), visibility("default")));
+
+#undef g_spawn_sync_utf8
+extern __typeof (g_spawn_sync_utf8) g_spawn_sync_utf8 __attribute((alias("IA__g_spawn_sync_utf8"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_STDIO_H__)
+#if IN_FILE(__G_STDIO_C__)
+#if !defined(G_OS_UNIX) || defined(G_STDIO_NO_WRAP_ON_UNIX)
+#undef g_chmod
+extern __typeof (g_chmod) g_chmod __attribute((alias("IA__g_chmod"), visibility("default")));
+
+#undef g_open
+extern __typeof (g_open) g_open __attribute((alias("IA__g_open"), visibility("default")));
+
+#undef g_creat
+extern __typeof (g_creat) g_creat __attribute((alias("IA__g_creat"), visibility("default")));
+
+#undef g_rename
+extern __typeof (g_rename) g_rename __attribute((alias("IA__g_rename"), visibility("default")));
+
+#undef g_mkdir
+extern __typeof (g_mkdir) g_mkdir __attribute((alias("IA__g_mkdir"), visibility("default")));
+
+#undef g_stat
+extern __typeof (g_stat) g_stat __attribute((alias("IA__g_stat"), visibility("default")));
+
+#undef g_lstat
+extern __typeof (g_lstat) g_lstat __attribute((alias("IA__g_lstat"), visibility("default")));
+
+#undef g_remove
+extern __typeof (g_remove) g_remove __attribute((alias("IA__g_remove"), visibility("default")));
+
+#undef g_fopen
+extern __typeof (g_fopen) g_fopen __attribute((alias("IA__g_fopen"), visibility("default")));
+
+#undef g_freopen
+extern __typeof (g_freopen) g_freopen __attribute((alias("IA__g_freopen"), visibility("default")));
+
+#undef g_utime
+extern __typeof (g_utime) g_utime __attribute((alias("IA__g_utime"), visibility("default")));
+
+#endif
+#undef g_access
+extern __typeof (g_access) g_access __attribute((alias("IA__g_access"), visibility("default")));
+
+#undef g_chdir
+extern __typeof (g_chdir) g_chdir __attribute((alias("IA__g_chdir"), visibility("default")));
+
+#undef g_unlink
+extern __typeof (g_unlink) g_unlink __attribute((alias("IA__g_unlink"), visibility("default")));
+
+#undef g_rmdir
+extern __typeof (g_rmdir) g_rmdir __attribute((alias("IA__g_rmdir"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_STRFUNCS_H__)
+#if IN_FILE(__G_STRFUNCS_C__)
+#undef g_ascii_digit_value
+extern __typeof (g_ascii_digit_value) g_ascii_digit_value __attribute((alias("IA__g_ascii_digit_value"), visibility("default")));
+
+#undef g_ascii_dtostr
+extern __typeof (g_ascii_dtostr) g_ascii_dtostr __attribute((alias("IA__g_ascii_dtostr"), visibility("default")));
+
+#undef g_ascii_formatd
+extern __typeof (g_ascii_formatd) g_ascii_formatd __attribute((alias("IA__g_ascii_formatd"), visibility("default")));
+
+#undef g_ascii_strdown
+extern __typeof (g_ascii_strdown) g_ascii_strdown __attribute((alias("IA__g_ascii_strdown"), visibility("default")));
+
+#undef g_ascii_strtod
+extern __typeof (g_ascii_strtod) g_ascii_strtod __attribute((alias("IA__g_ascii_strtod"), visibility("default")));
+
+#undef g_ascii_strtoull
+extern __typeof (g_ascii_strtoull) g_ascii_strtoull __attribute((alias("IA__g_ascii_strtoull"), visibility("default")));
+
+#undef g_ascii_strtoll
+extern __typeof (g_ascii_strtoll) g_ascii_strtoll __attribute((alias("IA__g_ascii_strtoll"), visibility("default")));
+
+#undef g_ascii_strup
+extern __typeof (g_ascii_strup) g_ascii_strup __attribute((alias("IA__g_ascii_strup"), visibility("default")));
+
+#undef g_ascii_tolower
+extern __typeof (g_ascii_tolower) g_ascii_tolower __attribute((alias("IA__g_ascii_tolower"), visibility("default")));
+
+#undef g_ascii_toupper
+extern __typeof (g_ascii_toupper) g_ascii_toupper __attribute((alias("IA__g_ascii_toupper"), visibility("default")));
+
+#undef g_ascii_xdigit_value
+extern __typeof (g_ascii_xdigit_value) g_ascii_xdigit_value __attribute((alias("IA__g_ascii_xdigit_value"), visibility("default")));
+
+#undef g_ascii_strcasecmp
+extern __typeof (g_ascii_strcasecmp) g_ascii_strcasecmp __attribute((alias("IA__g_ascii_strcasecmp"), visibility("default")));
+
+#undef g_ascii_strncasecmp
+extern __typeof (g_ascii_strncasecmp) g_ascii_strncasecmp __attribute((alias("IA__g_ascii_strncasecmp"), visibility("default")));
+
+#undef g_memdup
+extern __typeof (g_memdup) g_memdup __attribute((alias("IA__g_memdup"), visibility("default")));
+
+#undef g_stpcpy
+extern __typeof (g_stpcpy) g_stpcpy __attribute((alias("IA__g_stpcpy"), visibility("default")));
+
+#undef g_strcanon
+extern __typeof (g_strcanon) g_strcanon __attribute((alias("IA__g_strcanon"), visibility("default")));
+
+#undef g_strchomp
+extern __typeof (g_strchomp) g_strchomp __attribute((alias("IA__g_strchomp"), visibility("default")));
+
+#undef g_strchug
+extern __typeof (g_strchug) g_strchug __attribute((alias("IA__g_strchug"), visibility("default")));
+
+#undef g_strcompress
+extern __typeof (g_strcompress) g_strcompress __attribute((alias("IA__g_strcompress"), visibility("default")));
+
+#undef g_strconcat
+extern __typeof (g_strconcat) g_strconcat __attribute((alias("IA__g_strconcat"), visibility("default")));
+
+#undef g_strdelimit
+extern __typeof (g_strdelimit) g_strdelimit __attribute((alias("IA__g_strdelimit"), visibility("default")));
+
+#undef g_strdup
+extern __typeof (g_strdup) g_strdup __attribute((alias("IA__g_strdup"), visibility("default")));
+
+#undef g_strdup_printf
+extern __typeof (g_strdup_printf) g_strdup_printf __attribute((alias("IA__g_strdup_printf"), visibility("default")));
+
+#undef g_strdupv
+extern __typeof (g_strdupv) g_strdupv __attribute((alias("IA__g_strdupv"), visibility("default")));
+
+#undef g_strdup_vprintf
+extern __typeof (g_strdup_vprintf) g_strdup_vprintf __attribute((alias("IA__g_strdup_vprintf"), visibility("default")));
+
+#undef g_strerror
+extern __typeof (g_strerror) g_strerror __attribute((alias("IA__g_strerror"), visibility("default")));
+
+#undef g_strescape
+extern __typeof (g_strescape) g_strescape __attribute((alias("IA__g_strescape"), visibility("default")));
+
+#undef g_strfreev
+extern __typeof (g_strfreev) g_strfreev __attribute((alias("IA__g_strfreev"), visibility("default")));
+
+#undef g_str_has_prefix
+extern __typeof (g_str_has_prefix) g_str_has_prefix __attribute((alias("IA__g_str_has_prefix"), visibility("default")));
+
+#undef g_str_has_suffix
+extern __typeof (g_str_has_suffix) g_str_has_suffix __attribute((alias("IA__g_str_has_suffix"), visibility("default")));
+
+#undef g_strjoin
+extern __typeof (g_strjoin) g_strjoin __attribute((alias("IA__g_strjoin"), visibility("default")));
+
+#undef g_strjoinv
+extern __typeof (g_strjoinv) g_strjoinv __attribute((alias("IA__g_strjoinv"), visibility("default")));
+
+#undef g_strlcat
+extern __typeof (g_strlcat) g_strlcat __attribute((alias("IA__g_strlcat"), visibility("default")));
+
+#undef g_strlcpy
+extern __typeof (g_strlcpy) g_strlcpy __attribute((alias("IA__g_strlcpy"), visibility("default")));
+
+#undef g_strndup
+extern __typeof (g_strndup) g_strndup __attribute((alias("IA__g_strndup"), visibility("default")));
+
+#undef g_strnfill
+extern __typeof (g_strnfill) g_strnfill __attribute((alias("IA__g_strnfill"), visibility("default")));
+
+#undef g_strreverse
+extern __typeof (g_strreverse) g_strreverse __attribute((alias("IA__g_strreverse"), visibility("default")));
+
+#undef g_strrstr
+extern __typeof (g_strrstr) g_strrstr __attribute((alias("IA__g_strrstr"), visibility("default")));
+
+#undef g_strrstr_len
+extern __typeof (g_strrstr_len) g_strrstr_len __attribute((alias("IA__g_strrstr_len"), visibility("default")));
+
+#undef g_strsignal
+extern __typeof (g_strsignal) g_strsignal __attribute((alias("IA__g_strsignal"), visibility("default")));
+
+#undef g_strsplit
+extern __typeof (g_strsplit) g_strsplit __attribute((alias("IA__g_strsplit"), visibility("default")));
+
+#undef g_strsplit_set
+extern __typeof (g_strsplit_set) g_strsplit_set __attribute((alias("IA__g_strsplit_set"), visibility("default")));
+
+#undef g_strstr_len
+extern __typeof (g_strstr_len) g_strstr_len __attribute((alias("IA__g_strstr_len"), visibility("default")));
+
+#undef g_strtod
+extern __typeof (g_strtod) g_strtod __attribute((alias("IA__g_strtod"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_strcasecmp
+extern __typeof (g_strcasecmp) g_strcasecmp __attribute((alias("IA__g_strcasecmp"), visibility("default")));
+
+#undef g_strncasecmp
+extern __typeof (g_strncasecmp) g_strncasecmp __attribute((alias("IA__g_strncasecmp"), visibility("default")));
+
+#undef g_strup
+extern __typeof (g_strup) g_strup __attribute((alias("IA__g_strup"), visibility("default")));
+
+#undef g_strdown
+extern __typeof (g_strdown) g_strdown __attribute((alias("IA__g_strdown"), visibility("default")));
+
+#endif
+#undef g_strv_length
+extern __typeof (g_strv_length) g_strv_length __attribute((alias("IA__g_strv_length"), visibility("default")));
+
+#undef g_strip_context
+extern __typeof (g_strip_context) g_strip_context __attribute((alias("IA__g_strip_context"), visibility("default")));
+
+#undef g_dgettext
+extern __typeof (g_dgettext) g_dgettext __attribute((alias("IA__g_dgettext"), visibility("default")));
+
+#undef g_dngettext
+extern __typeof (g_dngettext) g_dngettext __attribute((alias("IA__g_dngettext"), visibility("default")));
+
+#undef g_dpgettext
+extern __typeof (g_dpgettext) g_dpgettext __attribute((alias("IA__g_dpgettext"), visibility("default")));
+
+#undef g_dpgettext2
+extern __typeof (g_dpgettext2) g_dpgettext2 __attribute((alias("IA__g_dpgettext2"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_URI_FUNCS_H__)
+#if IN_FILE(__G_URI_FUNCS_C__)
+#undef g_uri_unescape_string
+extern __typeof (g_uri_unescape_string) g_uri_unescape_string __attribute((alias("IA__g_uri_unescape_string"), visibility("default")));
+
+#undef g_uri_unescape_segment
+extern __typeof (g_uri_unescape_segment) g_uri_unescape_segment __attribute((alias("IA__g_uri_unescape_segment"), visibility("default")));
+
+#undef g_uri_parse_scheme
+extern __typeof (g_uri_parse_scheme) g_uri_parse_scheme __attribute((alias("IA__g_uri_parse_scheme"), visibility("default")));
+
+#undef g_uri_escape_string
+extern __typeof (g_uri_escape_string) g_uri_escape_string __attribute((alias("IA__g_uri_escape_string"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_STRING_H__)
+#if IN_FILE(__G_STRING_C__)
+#undef g_string_append
+extern __typeof (g_string_append) g_string_append __attribute((alias("IA__g_string_append"), visibility("default")));
+
+#undef g_string_append_len
+extern __typeof (g_string_append_len) g_string_append_len __attribute((alias("IA__g_string_append_len"), visibility("default")));
+
+#undef g_string_append_printf
+extern __typeof (g_string_append_printf) g_string_append_printf __attribute((alias("IA__g_string_append_printf"), visibility("default")));
+
+#undef g_string_append_unichar
+extern __typeof (g_string_append_unichar) g_string_append_unichar __attribute((alias("IA__g_string_append_unichar"), visibility("default")));
+
+#undef g_string_append_vprintf
+extern __typeof (g_string_append_vprintf) g_string_append_vprintf __attribute((alias("IA__g_string_append_vprintf"), visibility("default")));
+
+#undef g_string_ascii_down
+extern __typeof (g_string_ascii_down) g_string_ascii_down __attribute((alias("IA__g_string_ascii_down"), visibility("default")));
+
+#undef g_string_ascii_up
+extern __typeof (g_string_ascii_up) g_string_ascii_up __attribute((alias("IA__g_string_ascii_up"), visibility("default")));
+
+#undef g_string_assign
+extern __typeof (g_string_assign) g_string_assign __attribute((alias("IA__g_string_assign"), visibility("default")));
+
+#undef g_string_chunk_free
+extern __typeof (g_string_chunk_free) g_string_chunk_free __attribute((alias("IA__g_string_chunk_free"), visibility("default")));
+
+#undef g_string_chunk_clear
+extern __typeof (g_string_chunk_clear) g_string_chunk_clear __attribute((alias("IA__g_string_chunk_clear"), visibility("default")));
+
+#undef g_string_chunk_insert
+extern __typeof (g_string_chunk_insert) g_string_chunk_insert __attribute((alias("IA__g_string_chunk_insert"), visibility("default")));
+
+#undef g_string_chunk_insert_const
+extern __typeof (g_string_chunk_insert_const) g_string_chunk_insert_const __attribute((alias("IA__g_string_chunk_insert_const"), visibility("default")));
+
+#undef g_string_chunk_insert_len
+extern __typeof (g_string_chunk_insert_len) g_string_chunk_insert_len __attribute((alias("IA__g_string_chunk_insert_len"), visibility("default")));
+
+#undef g_string_chunk_new
+extern __typeof (g_string_chunk_new) g_string_chunk_new __attribute((alias("IA__g_string_chunk_new"), visibility("default")));
+
+#undef g_string_equal
+extern __typeof (g_string_equal) g_string_equal __attribute((alias("IA__g_string_equal"), visibility("default")));
+
+#undef g_string_erase
+extern __typeof (g_string_erase) g_string_erase __attribute((alias("IA__g_string_erase"), visibility("default")));
+
+#undef g_string_free
+extern __typeof (g_string_free) g_string_free __attribute((alias("IA__g_string_free"), visibility("default")));
+
+#undef g_string_hash
+extern __typeof (g_string_hash) g_string_hash __attribute((alias("IA__g_string_hash"), visibility("default")));
+
+#undef g_string_insert
+extern __typeof (g_string_insert) g_string_insert __attribute((alias("IA__g_string_insert"), visibility("default")));
+
+#undef g_string_insert_c
+extern __typeof (g_string_insert_c) g_string_insert_c __attribute((alias("IA__g_string_insert_c"), visibility("default")));
+
+#undef g_string_insert_len
+extern __typeof (g_string_insert_len) g_string_insert_len __attribute((alias("IA__g_string_insert_len"), visibility("default")));
+
+#undef g_string_insert_unichar
+extern __typeof (g_string_insert_unichar) g_string_insert_unichar __attribute((alias("IA__g_string_insert_unichar"), visibility("default")));
+
+#undef g_string_new
+extern __typeof (g_string_new) g_string_new __attribute((alias("IA__g_string_new"), visibility("default")));
+
+#undef g_string_new_len
+extern __typeof (g_string_new_len) g_string_new_len __attribute((alias("IA__g_string_new_len"), visibility("default")));
+
+#undef g_string_overwrite
+extern __typeof (g_string_overwrite) g_string_overwrite __attribute((alias("IA__g_string_overwrite"), visibility("default")));
+
+#undef g_string_overwrite_len
+extern __typeof (g_string_overwrite_len) g_string_overwrite_len __attribute((alias("IA__g_string_overwrite_len"), visibility("default")));
+
+#undef g_string_prepend
+extern __typeof (g_string_prepend) g_string_prepend __attribute((alias("IA__g_string_prepend"), visibility("default")));
+
+#undef g_string_prepend_c
+extern __typeof (g_string_prepend_c) g_string_prepend_c __attribute((alias("IA__g_string_prepend_c"), visibility("default")));
+
+#undef g_string_prepend_len
+extern __typeof (g_string_prepend_len) g_string_prepend_len __attribute((alias("IA__g_string_prepend_len"), visibility("default")));
+
+#undef g_string_prepend_unichar
+extern __typeof (g_string_prepend_unichar) g_string_prepend_unichar __attribute((alias("IA__g_string_prepend_unichar"), visibility("default")));
+
+#undef g_string_printf
+extern __typeof (g_string_printf) g_string_printf __attribute((alias("IA__g_string_printf"), visibility("default")));
+
+#undef g_string_set_size
+extern __typeof (g_string_set_size) g_string_set_size __attribute((alias("IA__g_string_set_size"), visibility("default")));
+
+#undef g_string_sized_new
+extern __typeof (g_string_sized_new) g_string_sized_new __attribute((alias("IA__g_string_sized_new"), visibility("default")));
+
+#undef g_string_truncate
+extern __typeof (g_string_truncate) g_string_truncate __attribute((alias("IA__g_string_truncate"), visibility("default")));
+
+#undef g_string_append_uri_escaped
+extern __typeof (g_string_append_uri_escaped) g_string_append_uri_escaped __attribute((alias("IA__g_string_append_uri_escaped"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_string_down
+extern __typeof (g_string_down) g_string_down __attribute((alias("IA__g_string_down"), visibility("default")));
+
+#undef g_string_up
+extern __typeof (g_string_up) g_string_up __attribute((alias("IA__g_string_up"), visibility("default")));
+
+#endif
+#undef g_string_vprintf
+extern __typeof (g_string_vprintf) g_string_vprintf __attribute((alias("IA__g_string_vprintf"), visibility("default")));
+
+#undef g_str_equal
+extern __typeof (g_str_equal) g_str_equal __attribute((alias("IA__g_str_equal"), visibility("default")));
+
+#undef g_str_hash
+extern __typeof (g_str_hash) g_str_hash __attribute((alias("IA__g_str_hash"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_THREAD_H__)
+#if IN_FILE(__G_THREAD_C__)
+#undef g_once_impl
+extern __typeof (g_once_impl) g_once_impl __attribute((alias("IA__g_once_impl"), visibility("default")));
+
+#undef g_once_init_enter_impl
+extern __typeof (g_once_init_enter_impl) g_once_init_enter_impl __attribute((alias("IA__g_once_init_enter_impl"), visibility("default")));
+
+#undef g_once_init_leave
+extern __typeof (g_once_init_leave) g_once_init_leave __attribute((alias("IA__g_once_init_leave"), visibility("default")));
+
+#undef g_thread_create_full
+extern __typeof (g_thread_create_full) g_thread_create_full __attribute((alias("IA__g_thread_create_full"), visibility("default")));
+
+#undef g_thread_error_quark
+extern __typeof (g_thread_error_quark) g_thread_error_quark __attribute((alias("IA__g_thread_error_quark"), visibility("default")));
+
+#undef g_thread_exit
+extern __typeof (g_thread_exit) g_thread_exit __attribute((alias("IA__g_thread_exit"), visibility("default")));
+
+#undef g_thread_join
+extern __typeof (g_thread_join) g_thread_join __attribute((alias("IA__g_thread_join"), visibility("default")));
+
+#undef g_thread_self
+extern __typeof (g_thread_self) g_thread_self __attribute((alias("IA__g_thread_self"), visibility("default")));
+
+#undef g_thread_set_priority
+extern __typeof (g_thread_set_priority) g_thread_set_priority __attribute((alias("IA__g_thread_set_priority"), visibility("default")));
+
+#undef g_static_mutex_free
+extern __typeof (g_static_mutex_free) g_static_mutex_free __attribute((alias("IA__g_static_mutex_free"), visibility("default")));
+
+#undef g_static_mutex_get_mutex_impl
+extern __typeof (g_static_mutex_get_mutex_impl) g_static_mutex_get_mutex_impl __attribute((alias("IA__g_static_mutex_get_mutex_impl"), visibility("default")));
+
+#undef g_static_mutex_init
+extern __typeof (g_static_mutex_init) g_static_mutex_init __attribute((alias("IA__g_static_mutex_init"), visibility("default")));
+
+#undef g_static_private_free
+extern __typeof (g_static_private_free) g_static_private_free __attribute((alias("IA__g_static_private_free"), visibility("default")));
+
+#undef g_static_private_get
+extern __typeof (g_static_private_get) g_static_private_get __attribute((alias("IA__g_static_private_get"), visibility("default")));
+
+#undef g_static_private_init
+extern __typeof (g_static_private_init) g_static_private_init __attribute((alias("IA__g_static_private_init"), visibility("default")));
+
+#undef g_static_private_set
+extern __typeof (g_static_private_set) g_static_private_set __attribute((alias("IA__g_static_private_set"), visibility("default")));
+
+#undef g_static_rec_mutex_free
+extern __typeof (g_static_rec_mutex_free) g_static_rec_mutex_free __attribute((alias("IA__g_static_rec_mutex_free"), visibility("default")));
+
+#undef g_static_rec_mutex_init
+extern __typeof (g_static_rec_mutex_init) g_static_rec_mutex_init __attribute((alias("IA__g_static_rec_mutex_init"), visibility("default")));
+
+#undef g_static_rec_mutex_lock
+extern __typeof (g_static_rec_mutex_lock) g_static_rec_mutex_lock __attribute((alias("IA__g_static_rec_mutex_lock"), visibility("default")));
+
+#undef g_static_rec_mutex_lock_full
+extern __typeof (g_static_rec_mutex_lock_full) g_static_rec_mutex_lock_full __attribute((alias("IA__g_static_rec_mutex_lock_full"), visibility("default")));
+
+#undef g_static_rec_mutex_trylock
+extern __typeof (g_static_rec_mutex_trylock) g_static_rec_mutex_trylock __attribute((alias("IA__g_static_rec_mutex_trylock"), visibility("default")));
+
+#undef g_static_rec_mutex_unlock
+extern __typeof (g_static_rec_mutex_unlock) g_static_rec_mutex_unlock __attribute((alias("IA__g_static_rec_mutex_unlock"), visibility("default")));
+
+#undef g_static_rec_mutex_unlock_full
+extern __typeof (g_static_rec_mutex_unlock_full) g_static_rec_mutex_unlock_full __attribute((alias("IA__g_static_rec_mutex_unlock_full"), visibility("default")));
+
+#undef g_static_rw_lock_free
+extern __typeof (g_static_rw_lock_free) g_static_rw_lock_free __attribute((alias("IA__g_static_rw_lock_free"), visibility("default")));
+
+#undef g_static_rw_lock_init
+extern __typeof (g_static_rw_lock_init) g_static_rw_lock_init __attribute((alias("IA__g_static_rw_lock_init"), visibility("default")));
+
+#undef g_static_rw_lock_reader_lock
+extern __typeof (g_static_rw_lock_reader_lock) g_static_rw_lock_reader_lock __attribute((alias("IA__g_static_rw_lock_reader_lock"), visibility("default")));
+
+#undef g_static_rw_lock_reader_trylock
+extern __typeof (g_static_rw_lock_reader_trylock) g_static_rw_lock_reader_trylock __attribute((alias("IA__g_static_rw_lock_reader_trylock"), visibility("default")));
+
+#undef g_static_rw_lock_reader_unlock
+extern __typeof (g_static_rw_lock_reader_unlock) g_static_rw_lock_reader_unlock __attribute((alias("IA__g_static_rw_lock_reader_unlock"), visibility("default")));
+
+#undef g_static_rw_lock_writer_lock
+extern __typeof (g_static_rw_lock_writer_lock) g_static_rw_lock_writer_lock __attribute((alias("IA__g_static_rw_lock_writer_lock"), visibility("default")));
+
+#undef g_static_rw_lock_writer_trylock
+extern __typeof (g_static_rw_lock_writer_trylock) g_static_rw_lock_writer_trylock __attribute((alias("IA__g_static_rw_lock_writer_trylock"), visibility("default")));
+
+#undef g_static_rw_lock_writer_unlock
+extern __typeof (g_static_rw_lock_writer_unlock) g_static_rw_lock_writer_unlock __attribute((alias("IA__g_static_rw_lock_writer_unlock"), visibility("default")));
+
+#undef g_thread_foreach
+extern __typeof (g_thread_foreach) g_thread_foreach __attribute((alias("IA__g_thread_foreach"), visibility("default")));
+
+#undef g_thread_get_initialized
+extern __typeof (g_thread_get_initialized) g_thread_get_initialized __attribute((alias("IA__g_thread_get_initialized"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_THREADPOOL_H__)
+#if IN_FILE(__G_THREADPOOL_C__)
+#undef g_thread_pool_free
+extern __typeof (g_thread_pool_free) g_thread_pool_free __attribute((alias("IA__g_thread_pool_free"), visibility("default")));
+
+#undef g_thread_pool_get_max_threads
+extern __typeof (g_thread_pool_get_max_threads) g_thread_pool_get_max_threads __attribute((alias("IA__g_thread_pool_get_max_threads"), visibility("default")));
+
+#undef g_thread_pool_get_max_unused_threads
+extern __typeof (g_thread_pool_get_max_unused_threads) g_thread_pool_get_max_unused_threads __attribute((alias("IA__g_thread_pool_get_max_unused_threads"), visibility("default")));
+
+#undef g_thread_pool_get_max_idle_time
+extern __typeof (g_thread_pool_get_max_idle_time) g_thread_pool_get_max_idle_time __attribute((alias("IA__g_thread_pool_get_max_idle_time"), visibility("default")));
+
+#undef g_thread_pool_get_num_threads
+extern __typeof (g_thread_pool_get_num_threads) g_thread_pool_get_num_threads __attribute((alias("IA__g_thread_pool_get_num_threads"), visibility("default")));
+
+#undef g_thread_pool_get_num_unused_threads
+extern __typeof (g_thread_pool_get_num_unused_threads) g_thread_pool_get_num_unused_threads __attribute((alias("IA__g_thread_pool_get_num_unused_threads"), visibility("default")));
+
+#undef g_thread_pool_new
+extern __typeof (g_thread_pool_new) g_thread_pool_new __attribute((alias("IA__g_thread_pool_new"), visibility("default")));
+
+#undef g_thread_pool_push
+extern __typeof (g_thread_pool_push) g_thread_pool_push __attribute((alias("IA__g_thread_pool_push"), visibility("default")));
+
+#undef g_thread_pool_set_max_threads
+extern __typeof (g_thread_pool_set_max_threads) g_thread_pool_set_max_threads __attribute((alias("IA__g_thread_pool_set_max_threads"), visibility("default")));
+
+#undef g_thread_pool_set_max_unused_threads
+extern __typeof (g_thread_pool_set_max_unused_threads) g_thread_pool_set_max_unused_threads __attribute((alias("IA__g_thread_pool_set_max_unused_threads"), visibility("default")));
+
+#undef g_thread_pool_set_max_idle_time
+extern __typeof (g_thread_pool_set_max_idle_time) g_thread_pool_set_max_idle_time __attribute((alias("IA__g_thread_pool_set_max_idle_time"), visibility("default")));
+
+#undef g_thread_pool_stop_unused_threads
+extern __typeof (g_thread_pool_stop_unused_threads) g_thread_pool_stop_unused_threads __attribute((alias("IA__g_thread_pool_stop_unused_threads"), visibility("default")));
+
+#undef g_thread_pool_unprocessed
+extern __typeof (g_thread_pool_unprocessed) g_thread_pool_unprocessed __attribute((alias("IA__g_thread_pool_unprocessed"), visibility("default")));
+
+#undef g_thread_pool_set_sort_function
+extern __typeof (g_thread_pool_set_sort_function) g_thread_pool_set_sort_function __attribute((alias("IA__g_thread_pool_set_sort_function"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_TEST_UTILS_H__)
+#if IN_FILE(__G_TEST_UTILS_C__)
+#undef g_assertion_message
+extern __typeof (g_assertion_message) g_assertion_message __attribute((alias("IA__g_assertion_message"), visibility("default")));
+
+#undef g_assertion_message_cmpnum
+extern __typeof (g_assertion_message_cmpnum) g_assertion_message_cmpnum __attribute((alias("IA__g_assertion_message_cmpnum"), visibility("default")));
+
+#undef g_assertion_message_cmpstr
+extern __typeof (g_assertion_message_cmpstr) g_assertion_message_cmpstr __attribute((alias("IA__g_assertion_message_cmpstr"), visibility("default")));
+
+#undef g_assertion_message_expr
+extern __typeof (g_assertion_message_expr) g_assertion_message_expr __attribute((alias("IA__g_assertion_message_expr"), visibility("default")));
+
+#undef g_assertion_message_error
+extern __typeof (g_assertion_message_error) g_assertion_message_error __attribute((alias("IA__g_assertion_message_error"), visibility("default")));
+
+#undef g_strcmp0
+extern __typeof (g_strcmp0) g_strcmp0 __attribute((alias("IA__g_strcmp0"), visibility("default")));
+
+#undef g_test_add_data_func
+extern __typeof (g_test_add_data_func) g_test_add_data_func __attribute((alias("IA__g_test_add_data_func"), visibility("default")));
+
+#undef g_test_add_func
+extern __typeof (g_test_add_func) g_test_add_func __attribute((alias("IA__g_test_add_func"), visibility("default")));
+
+#undef g_test_add_vtable
+extern __typeof (g_test_add_vtable) g_test_add_vtable __attribute((alias("IA__g_test_add_vtable"), visibility("default")));
+
+#undef g_test_bug
+extern __typeof (g_test_bug) g_test_bug __attribute((alias("IA__g_test_bug"), visibility("default")));
+
+#undef g_test_bug_base
+extern __typeof (g_test_bug_base) g_test_bug_base __attribute((alias("IA__g_test_bug_base"), visibility("default")));
+
+#undef g_test_create_case
+extern __typeof (g_test_create_case) g_test_create_case __attribute((alias("IA__g_test_create_case"), visibility("default")));
+
+#undef g_test_create_suite
+extern __typeof (g_test_create_suite) g_test_create_suite __attribute((alias("IA__g_test_create_suite"), visibility("default")));
+
+#undef g_test_get_root
+extern __typeof (g_test_get_root) g_test_get_root __attribute((alias("IA__g_test_get_root"), visibility("default")));
+
+#undef g_test_init
+extern __typeof (g_test_init) g_test_init __attribute((alias("IA__g_test_init"), visibility("default")));
+
+#undef g_test_log_buffer_free
+extern __typeof (g_test_log_buffer_free) g_test_log_buffer_free __attribute((alias("IA__g_test_log_buffer_free"), visibility("default")));
+
+#undef g_test_log_buffer_new
+extern __typeof (g_test_log_buffer_new) g_test_log_buffer_new __attribute((alias("IA__g_test_log_buffer_new"), visibility("default")));
+
+#undef g_test_log_buffer_pop
+extern __typeof (g_test_log_buffer_pop) g_test_log_buffer_pop __attribute((alias("IA__g_test_log_buffer_pop"), visibility("default")));
+
+#undef g_test_log_buffer_push
+extern __typeof (g_test_log_buffer_push) g_test_log_buffer_push __attribute((alias("IA__g_test_log_buffer_push"), visibility("default")));
+
+#undef g_test_log_msg_free
+extern __typeof (g_test_log_msg_free) g_test_log_msg_free __attribute((alias("IA__g_test_log_msg_free"), visibility("default")));
+
+#undef g_test_log_type_name
+extern __typeof (g_test_log_type_name) g_test_log_type_name __attribute((alias("IA__g_test_log_type_name"), visibility("default")));
+
+#undef g_test_maximized_result
+extern __typeof (g_test_maximized_result) g_test_maximized_result __attribute((alias("IA__g_test_maximized_result"), visibility("default")));
+
+#undef g_test_message
+extern __typeof (g_test_message) g_test_message __attribute((alias("IA__g_test_message"), visibility("default")));
+
+#undef g_test_minimized_result
+extern __typeof (g_test_minimized_result) g_test_minimized_result __attribute((alias("IA__g_test_minimized_result"), visibility("default")));
+
+#undef g_test_queue_destroy
+extern __typeof (g_test_queue_destroy) g_test_queue_destroy __attribute((alias("IA__g_test_queue_destroy"), visibility("default")));
+
+#undef g_test_queue_free
+extern __typeof (g_test_queue_free) g_test_queue_free __attribute((alias("IA__g_test_queue_free"), visibility("default")));
+
+#undef g_test_rand_double
+extern __typeof (g_test_rand_double) g_test_rand_double __attribute((alias("IA__g_test_rand_double"), visibility("default")));
+
+#undef g_test_rand_double_range
+extern __typeof (g_test_rand_double_range) g_test_rand_double_range __attribute((alias("IA__g_test_rand_double_range"), visibility("default")));
+
+#undef g_test_rand_int
+extern __typeof (g_test_rand_int) g_test_rand_int __attribute((alias("IA__g_test_rand_int"), visibility("default")));
+
+#undef g_test_rand_int_range
+extern __typeof (g_test_rand_int_range) g_test_rand_int_range __attribute((alias("IA__g_test_rand_int_range"), visibility("default")));
+
+#undef g_test_run
+extern __typeof (g_test_run) g_test_run __attribute((alias("IA__g_test_run"), visibility("default")));
+
+#undef g_test_run_suite
+extern __typeof (g_test_run_suite) g_test_run_suite __attribute((alias("IA__g_test_run_suite"), visibility("default")));
+
+#undef g_test_suite_add
+extern __typeof (g_test_suite_add) g_test_suite_add __attribute((alias("IA__g_test_suite_add"), visibility("default")));
+
+#undef g_test_suite_add_suite
+extern __typeof (g_test_suite_add_suite) g_test_suite_add_suite __attribute((alias("IA__g_test_suite_add_suite"), visibility("default")));
+
+#undef g_test_timer_elapsed
+extern __typeof (g_test_timer_elapsed) g_test_timer_elapsed __attribute((alias("IA__g_test_timer_elapsed"), visibility("default")));
+
+#undef g_test_timer_last
+extern __typeof (g_test_timer_last) g_test_timer_last __attribute((alias("IA__g_test_timer_last"), visibility("default")));
+
+#undef g_test_timer_start
+extern __typeof (g_test_timer_start) g_test_timer_start __attribute((alias("IA__g_test_timer_start"), visibility("default")));
+
+#undef g_test_trap_assertions
+extern __typeof (g_test_trap_assertions) g_test_trap_assertions __attribute((alias("IA__g_test_trap_assertions"), visibility("default")));
+
+#undef g_test_trap_fork
+extern __typeof (g_test_trap_fork) g_test_trap_fork __attribute((alias("IA__g_test_trap_fork"), visibility("default")));
+
+#undef g_test_trap_has_passed
+extern __typeof (g_test_trap_has_passed) g_test_trap_has_passed __attribute((alias("IA__g_test_trap_has_passed"), visibility("default")));
+
+#undef g_test_trap_reached_timeout
+extern __typeof (g_test_trap_reached_timeout) g_test_trap_reached_timeout __attribute((alias("IA__g_test_trap_reached_timeout"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_TIMER_H__)
+#if IN_FILE(__G_TIMER_C__)
+#undef g_timer_continue
+extern __typeof (g_timer_continue) g_timer_continue __attribute((alias("IA__g_timer_continue"), visibility("default")));
+
+#undef g_timer_destroy
+extern __typeof (g_timer_destroy) g_timer_destroy __attribute((alias("IA__g_timer_destroy"), visibility("default")));
+
+#undef g_timer_elapsed
+extern __typeof (g_timer_elapsed) g_timer_elapsed __attribute((alias("IA__g_timer_elapsed"), visibility("default")));
+
+#undef g_timer_new
+extern __typeof (g_timer_new) g_timer_new __attribute((alias("IA__g_timer_new"), visibility("default")));
+
+#undef g_timer_reset
+extern __typeof (g_timer_reset) g_timer_reset __attribute((alias("IA__g_timer_reset"), visibility("default")));
+
+#undef g_timer_start
+extern __typeof (g_timer_start) g_timer_start __attribute((alias("IA__g_timer_start"), visibility("default")));
+
+#undef g_timer_stop
+extern __typeof (g_timer_stop) g_timer_stop __attribute((alias("IA__g_timer_stop"), visibility("default")));
+
+#undef g_time_val_add
+extern __typeof (g_time_val_add) g_time_val_add __attribute((alias("IA__g_time_val_add"), visibility("default")));
+
+#undef g_time_val_from_iso8601
+extern __typeof (g_time_val_from_iso8601) g_time_val_from_iso8601 __attribute((alias("IA__g_time_val_from_iso8601"), visibility("default")));
+
+#undef g_time_val_to_iso8601
+extern __typeof (g_time_val_to_iso8601) g_time_val_to_iso8601 __attribute((alias("IA__g_time_val_to_iso8601"), visibility("default")));
+
+#undef g_usleep
+extern __typeof (g_usleep) g_usleep __attribute((alias("IA__g_usleep"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_TREE_H__)
+#if IN_FILE(__G_TREE_C__)
+#undef g_tree_destroy
+extern __typeof (g_tree_destroy) g_tree_destroy __attribute((alias("IA__g_tree_destroy"), visibility("default")));
+
+#undef g_tree_foreach
+extern __typeof (g_tree_foreach) g_tree_foreach __attribute((alias("IA__g_tree_foreach"), visibility("default")));
+
+#undef g_tree_height
+extern __typeof (g_tree_height) g_tree_height __attribute((alias("IA__g_tree_height"), visibility("default")));
+
+#undef g_tree_insert
+extern __typeof (g_tree_insert) g_tree_insert __attribute((alias("IA__g_tree_insert"), visibility("default")));
+
+#undef g_tree_lookup
+extern __typeof (g_tree_lookup) g_tree_lookup __attribute((alias("IA__g_tree_lookup"), visibility("default")));
+
+#undef g_tree_lookup_extended
+extern __typeof (g_tree_lookup_extended) g_tree_lookup_extended __attribute((alias("IA__g_tree_lookup_extended"), visibility("default")));
+
+#undef g_tree_new
+extern __typeof (g_tree_new) g_tree_new __attribute((alias("IA__g_tree_new"), visibility("default")));
+
+#undef g_tree_new_full
+extern __typeof (g_tree_new_full) g_tree_new_full __attribute((alias("IA__g_tree_new_full"), visibility("default")));
+
+#undef g_tree_new_with_data
+extern __typeof (g_tree_new_with_data) g_tree_new_with_data __attribute((alias("IA__g_tree_new_with_data"), visibility("default")));
+
+#undef g_tree_nnodes
+extern __typeof (g_tree_nnodes) g_tree_nnodes __attribute((alias("IA__g_tree_nnodes"), visibility("default")));
+
+#undef g_tree_remove
+extern __typeof (g_tree_remove) g_tree_remove __attribute((alias("IA__g_tree_remove"), visibility("default")));
+
+#undef g_tree_replace
+extern __typeof (g_tree_replace) g_tree_replace __attribute((alias("IA__g_tree_replace"), visibility("default")));
+
+#undef g_tree_search
+extern __typeof (g_tree_search) g_tree_search __attribute((alias("IA__g_tree_search"), visibility("default")));
+
+#undef g_tree_steal
+extern __typeof (g_tree_steal) g_tree_steal __attribute((alias("IA__g_tree_steal"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_tree_traverse
+extern __typeof (g_tree_traverse) g_tree_traverse __attribute((alias("IA__g_tree_traverse"), visibility("default")));
+
+#endif
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIBREAK_C__)
+#undef g_unichar_break_type
+extern __typeof (g_unichar_break_type) g_unichar_break_type __attribute((alias("IA__g_unichar_break_type"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNICOLLATE_C__)
+#undef g_utf8_collate
+extern __typeof (g_utf8_collate) g_utf8_collate __attribute((alias("IA__g_utf8_collate"), visibility("default")));
+
+#undef g_utf8_collate_key
+extern __typeof (g_utf8_collate_key) g_utf8_collate_key __attribute((alias("IA__g_utf8_collate_key"), visibility("default")));
+
+#undef g_utf8_collate_key_for_filename
+extern __typeof (g_utf8_collate_key_for_filename) g_utf8_collate_key_for_filename __attribute((alias("IA__g_utf8_collate_key_for_filename"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIDECOMP_C__)
+#undef g_unicode_canonical_decomposition
+extern __typeof (g_unicode_canonical_decomposition) g_unicode_canonical_decomposition __attribute((alias("IA__g_unicode_canonical_decomposition"), visibility("default")));
+
+#undef g_unicode_canonical_ordering
+extern __typeof (g_unicode_canonical_ordering) g_unicode_canonical_ordering __attribute((alias("IA__g_unicode_canonical_ordering"), visibility("default")));
+
+#undef g_unichar_combining_class
+extern __typeof (g_unichar_combining_class) g_unichar_combining_class __attribute((alias("IA__g_unichar_combining_class"), visibility("default")));
+
+#undef g_utf8_normalize
+extern __typeof (g_utf8_normalize) g_utf8_normalize __attribute((alias("IA__g_utf8_normalize"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIPROP_C__)
+#undef g_unichar_isalnum
+extern __typeof (g_unichar_isalnum) g_unichar_isalnum __attribute((alias("IA__g_unichar_isalnum"), visibility("default")));
+
+#undef g_unichar_isalpha
+extern __typeof (g_unichar_isalpha) g_unichar_isalpha __attribute((alias("IA__g_unichar_isalpha"), visibility("default")));
+
+#undef g_unichar_iscntrl
+extern __typeof (g_unichar_iscntrl) g_unichar_iscntrl __attribute((alias("IA__g_unichar_iscntrl"), visibility("default")));
+
+#undef g_unichar_isdefined
+extern __typeof (g_unichar_isdefined) g_unichar_isdefined __attribute((alias("IA__g_unichar_isdefined"), visibility("default")));
+
+#undef g_unichar_isdigit
+extern __typeof (g_unichar_isdigit) g_unichar_isdigit __attribute((alias("IA__g_unichar_isdigit"), visibility("default")));
+
+#undef g_unichar_isgraph
+extern __typeof (g_unichar_isgraph) g_unichar_isgraph __attribute((alias("IA__g_unichar_isgraph"), visibility("default")));
+
+#undef g_unichar_islower
+extern __typeof (g_unichar_islower) g_unichar_islower __attribute((alias("IA__g_unichar_islower"), visibility("default")));
+
+#undef g_unichar_isprint
+extern __typeof (g_unichar_isprint) g_unichar_isprint __attribute((alias("IA__g_unichar_isprint"), visibility("default")));
+
+#undef g_unichar_ispunct
+extern __typeof (g_unichar_ispunct) g_unichar_ispunct __attribute((alias("IA__g_unichar_ispunct"), visibility("default")));
+
+#undef g_unichar_isspace
+extern __typeof (g_unichar_isspace) g_unichar_isspace __attribute((alias("IA__g_unichar_isspace"), visibility("default")));
+
+#undef g_unichar_istitle
+extern __typeof (g_unichar_istitle) g_unichar_istitle __attribute((alias("IA__g_unichar_istitle"), visibility("default")));
+
+#undef g_unichar_isupper
+extern __typeof (g_unichar_isupper) g_unichar_isupper __attribute((alias("IA__g_unichar_isupper"), visibility("default")));
+
+#undef g_unichar_iswide
+extern __typeof (g_unichar_iswide) g_unichar_iswide __attribute((alias("IA__g_unichar_iswide"), visibility("default")));
+
+#undef g_unichar_iswide_cjk
+extern __typeof (g_unichar_iswide_cjk) g_unichar_iswide_cjk __attribute((alias("IA__g_unichar_iswide_cjk"), visibility("default")));
+
+#undef g_unichar_isxdigit
+extern __typeof (g_unichar_isxdigit) g_unichar_isxdigit __attribute((alias("IA__g_unichar_isxdigit"), visibility("default")));
+
+#undef g_unichar_iszerowidth
+extern __typeof (g_unichar_iszerowidth) g_unichar_iszerowidth __attribute((alias("IA__g_unichar_iszerowidth"), visibility("default")));
+
+#undef g_unichar_tolower
+extern __typeof (g_unichar_tolower) g_unichar_tolower __attribute((alias("IA__g_unichar_tolower"), visibility("default")));
+
+#undef g_unichar_totitle
+extern __typeof (g_unichar_totitle) g_unichar_totitle __attribute((alias("IA__g_unichar_totitle"), visibility("default")));
+
+#undef g_unichar_toupper
+extern __typeof (g_unichar_toupper) g_unichar_toupper __attribute((alias("IA__g_unichar_toupper"), visibility("default")));
+
+#undef g_unichar_ismark
+extern __typeof (g_unichar_ismark) g_unichar_ismark __attribute((alias("IA__g_unichar_ismark"), visibility("default")));
+
+#undef g_unichar_get_mirror_char
+extern __typeof (g_unichar_get_mirror_char) g_unichar_get_mirror_char __attribute((alias("IA__g_unichar_get_mirror_char"), visibility("default")));
+
+#undef g_unichar_get_script
+extern __typeof (g_unichar_get_script) g_unichar_get_script __attribute((alias("IA__g_unichar_get_script"), visibility("default")));
+
+#undef g_unichar_digit_value
+extern __typeof (g_unichar_digit_value) g_unichar_digit_value __attribute((alias("IA__g_unichar_digit_value"), visibility("default")));
+
+#undef g_unichar_xdigit_value
+extern __typeof (g_unichar_xdigit_value) g_unichar_xdigit_value __attribute((alias("IA__g_unichar_xdigit_value"), visibility("default")));
+
+#undef g_unichar_type
+extern __typeof (g_unichar_type) g_unichar_type __attribute((alias("IA__g_unichar_type"), visibility("default")));
+
+#undef g_utf8_casefold
+extern __typeof (g_utf8_casefold) g_utf8_casefold __attribute((alias("IA__g_utf8_casefold"), visibility("default")));
+
+#undef g_utf8_strup
+extern __typeof (g_utf8_strup) g_utf8_strup __attribute((alias("IA__g_utf8_strup"), visibility("default")));
+
+#undef g_utf8_strdown
+extern __typeof (g_utf8_strdown) g_utf8_strdown __attribute((alias("IA__g_utf8_strdown"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UTF8_C__)
+#undef g_get_charset
+extern __typeof (g_get_charset) g_get_charset __attribute((alias("IA__g_get_charset"), visibility("default")));
+
+#undef g_ucs4_to_utf16
+extern __typeof (g_ucs4_to_utf16) g_ucs4_to_utf16 __attribute((alias("IA__g_ucs4_to_utf16"), visibility("default")));
+
+#undef g_ucs4_to_utf8
+extern __typeof (g_ucs4_to_utf8) g_ucs4_to_utf8 __attribute((alias("IA__g_ucs4_to_utf8"), visibility("default")));
+
+#undef g_utf16_to_ucs4
+extern __typeof (g_utf16_to_ucs4) g_utf16_to_ucs4 __attribute((alias("IA__g_utf16_to_ucs4"), visibility("default")));
+
+#undef g_utf16_to_utf8
+extern __typeof (g_utf16_to_utf8) g_utf16_to_utf8 __attribute((alias("IA__g_utf16_to_utf8"), visibility("default")));
+
+#undef g_utf8_find_next_char
+extern __typeof (g_utf8_find_next_char) g_utf8_find_next_char __attribute((alias("IA__g_utf8_find_next_char"), visibility("default")));
+
+#undef g_utf8_find_prev_char
+extern __typeof (g_utf8_find_prev_char) g_utf8_find_prev_char __attribute((alias("IA__g_utf8_find_prev_char"), visibility("default")));
+
+#undef g_utf8_get_char
+extern __typeof (g_utf8_get_char) g_utf8_get_char __attribute((alias("IA__g_utf8_get_char"), visibility("default")));
+
+#undef g_utf8_get_char_validated
+extern __typeof (g_utf8_get_char_validated) g_utf8_get_char_validated __attribute((alias("IA__g_utf8_get_char_validated"), visibility("default")));
+
+#undef g_utf8_offset_to_pointer
+extern __typeof (g_utf8_offset_to_pointer) g_utf8_offset_to_pointer __attribute((alias("IA__g_utf8_offset_to_pointer"), visibility("default")));
+
+#undef g_utf8_pointer_to_offset
+extern __typeof (g_utf8_pointer_to_offset) g_utf8_pointer_to_offset __attribute((alias("IA__g_utf8_pointer_to_offset"), visibility("default")));
+
+#undef g_utf8_prev_char
+extern __typeof (g_utf8_prev_char) g_utf8_prev_char __attribute((alias("IA__g_utf8_prev_char"), visibility("default")));
+
+#undef g_utf8_strchr
+extern __typeof (g_utf8_strchr) g_utf8_strchr __attribute((alias("IA__g_utf8_strchr"), visibility("default")));
+
+#undef g_utf8_strlen
+extern __typeof (g_utf8_strlen) g_utf8_strlen __attribute((alias("IA__g_utf8_strlen"), visibility("default")));
+
+#undef g_utf8_strncpy
+extern __typeof (g_utf8_strncpy) g_utf8_strncpy __attribute((alias("IA__g_utf8_strncpy"), visibility("default")));
+
+#undef g_utf8_strrchr
+extern __typeof (g_utf8_strrchr) g_utf8_strrchr __attribute((alias("IA__g_utf8_strrchr"), visibility("default")));
+
+#undef g_utf8_strreverse
+extern __typeof (g_utf8_strreverse) g_utf8_strreverse __attribute((alias("IA__g_utf8_strreverse"), visibility("default")));
+
+#undef g_utf8_to_ucs4
+extern __typeof (g_utf8_to_ucs4) g_utf8_to_ucs4 __attribute((alias("IA__g_utf8_to_ucs4"), visibility("default")));
+
+#undef g_utf8_to_ucs4_fast
+extern __typeof (g_utf8_to_ucs4_fast) g_utf8_to_ucs4_fast __attribute((alias("IA__g_utf8_to_ucs4_fast"), visibility("default")));
+
+#undef g_utf8_to_utf16
+extern __typeof (g_utf8_to_utf16) g_utf8_to_utf16 __attribute((alias("IA__g_utf8_to_utf16"), visibility("default")));
+
+#undef g_utf8_validate
+extern __typeof (g_utf8_validate) g_utf8_validate __attribute((alias("IA__g_utf8_validate"), visibility("default")));
+
+#undef g_unichar_to_utf8
+extern __typeof (g_unichar_to_utf8) g_unichar_to_utf8 __attribute((alias("IA__g_unichar_to_utf8"), visibility("default")));
+
+#undef g_unichar_validate
+extern __typeof (g_unichar_validate) g_unichar_validate __attribute((alias("IA__g_unichar_validate"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__GLIBINTL_H__)
+#if IN_FILE(__G_UTILS_C__)
+#undef glib_gettext
+extern __typeof (glib_gettext) glib_gettext __attribute((alias("IA__glib_gettext"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_HASH_H__)
+#if IN_FILE(__G_UTILS_C__)
+#undef g_int_equal
+extern __typeof (g_int_equal) g_int_equal __attribute((alias("IA__g_int_equal"), visibility("default")));
+
+#undef g_int_hash
+extern __typeof (g_int_hash) g_int_hash __attribute((alias("IA__g_int_hash"), visibility("default")));
+
+#undef g_direct_equal
+extern __typeof (g_direct_equal) g_direct_equal __attribute((alias("IA__g_direct_equal"), visibility("default")));
+
+#undef g_direct_hash
+extern __typeof (g_direct_hash) g_direct_hash __attribute((alias("IA__g_direct_hash"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_UTILS_H__)
+#if IN_FILE(__G_UTILS_C__)
+#undef g_atexit
+extern __typeof (g_atexit) g_atexit __attribute((alias("IA__g_atexit"), visibility("default")));
+
+#ifndef G_DISABLE_DEPRECATED
+#undef g_basename
+extern __typeof (g_basename) g_basename __attribute((alias("IA__g_basename"), visibility("default")));
+
+#endif
+#undef g_get_application_name
+extern __typeof (g_get_application_name) g_get_application_name __attribute((alias("IA__g_get_application_name"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_find_program_in_path
+extern __typeof (g_find_program_in_path) g_find_program_in_path __attribute((alias("IA__g_find_program_in_path"), visibility("default")));
+
+#undef g_get_current_dir
+extern __typeof (g_get_current_dir) g_get_current_dir __attribute((alias("IA__g_get_current_dir"), visibility("default")));
+
+#undef g_getenv
+extern __typeof (g_getenv) g_getenv __attribute((alias("IA__g_getenv"), visibility("default")));
+
+#undef g_unsetenv
+extern __typeof (g_unsetenv) g_unsetenv __attribute((alias("IA__g_unsetenv"), visibility("default")));
+
+#undef g_get_home_dir
+extern __typeof (g_get_home_dir) g_get_home_dir __attribute((alias("IA__g_get_home_dir"), visibility("default")));
+
+#endif
+#undef g_get_host_name
+extern __typeof (g_get_host_name) g_get_host_name __attribute((alias("IA__g_get_host_name"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_setenv
+extern __typeof (g_setenv) g_setenv __attribute((alias("IA__g_setenv"), visibility("default")));
+
+#endif
+#undef g_listenv
+extern __typeof (g_listenv) g_listenv __attribute((alias("IA__g_listenv"), visibility("default")));
+
+#ifdef G_OS_WIN32
+#undef g_find_program_in_path_utf8
+extern __typeof (g_find_program_in_path_utf8) g_find_program_in_path_utf8 __attribute((alias("IA__g_find_program_in_path_utf8"), visibility("default")));
+
+#undef g_get_current_dir_utf8
+extern __typeof (g_get_current_dir_utf8) g_get_current_dir_utf8 __attribute((alias("IA__g_get_current_dir_utf8"), visibility("default")));
+
+#undef g_getenv_utf8
+extern __typeof (g_getenv_utf8) g_getenv_utf8 __attribute((alias("IA__g_getenv_utf8"), visibility("default")));
+
+#undef g_unsetenv_utf8
+extern __typeof (g_unsetenv_utf8) g_unsetenv_utf8 __attribute((alias("IA__g_unsetenv_utf8"), visibility("default")));
+
+#undef g_setenv_utf8
+extern __typeof (g_setenv_utf8) g_setenv_utf8 __attribute((alias("IA__g_setenv_utf8"), visibility("default")));
+
+#undef g_get_home_dir_utf8
+extern __typeof (g_get_home_dir_utf8) g_get_home_dir_utf8 __attribute((alias("IA__g_get_home_dir_utf8"), visibility("default")));
+
+#endif
+#undef g_get_language_names
+extern __typeof (g_get_language_names) g_get_language_names __attribute((alias("IA__g_get_language_names"), visibility("default")));
+
+#undef g_get_prgname
+extern __typeof (g_get_prgname) g_get_prgname __attribute((alias("IA__g_get_prgname"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_get_real_name
+extern __typeof (g_get_real_name) g_get_real_name __attribute((alias("IA__g_get_real_name"), visibility("default")));
+
+#endif
+#ifdef G_OS_WIN32
+#undef g_get_real_name_utf8
+extern __typeof (g_get_real_name_utf8) g_get_real_name_utf8 __attribute((alias("IA__g_get_real_name_utf8"), visibility("default")));
+
+#endif
+#undef g_get_system_config_dirs
+extern __typeof (g_get_system_config_dirs) g_get_system_config_dirs __attribute((alias("IA__g_get_system_config_dirs"), visibility("default")));
+
+#undef g_get_system_data_dirs
+extern __typeof (g_get_system_data_dirs) g_get_system_data_dirs __attribute((alias("IA__g_get_system_data_dirs"), visibility("default")));
+
+#ifdef G_OS_WIN32
+#undef g_win32_get_system_data_dirs_for_module
+extern __typeof (g_win32_get_system_data_dirs_for_module) g_win32_get_system_data_dirs_for_module __attribute((alias("IA__g_win32_get_system_data_dirs_for_module"), visibility("default")));
+
+#endif
+#ifndef _WIN64
+#undef g_get_tmp_dir
+extern __typeof (g_get_tmp_dir) g_get_tmp_dir __attribute((alias("IA__g_get_tmp_dir"), visibility("default")));
+
+#endif
+#ifdef G_OS_WIN32
+#undef g_get_tmp_dir_utf8
+extern __typeof (g_get_tmp_dir_utf8) g_get_tmp_dir_utf8 __attribute((alias("IA__g_get_tmp_dir_utf8"), visibility("default")));
+
+#endif
+#undef g_get_user_cache_dir
+extern __typeof (g_get_user_cache_dir) g_get_user_cache_dir __attribute((alias("IA__g_get_user_cache_dir"), visibility("default")));
+
+#undef g_get_user_config_dir
+extern __typeof (g_get_user_config_dir) g_get_user_config_dir __attribute((alias("IA__g_get_user_config_dir"), visibility("default")));
+
+#undef g_get_user_data_dir
+extern __typeof (g_get_user_data_dir) g_get_user_data_dir __attribute((alias("IA__g_get_user_data_dir"), visibility("default")));
+
+#undef g_get_user_special_dir
+extern __typeof (g_get_user_special_dir) g_get_user_special_dir __attribute((alias("IA__g_get_user_special_dir"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_get_user_name
+extern __typeof (g_get_user_name) g_get_user_name __attribute((alias("IA__g_get_user_name"), visibility("default")));
+
+#endif
+#ifdef G_OS_WIN32
+#undef g_get_user_name_utf8
+extern __typeof (g_get_user_name_utf8) g_get_user_name_utf8 __attribute((alias("IA__g_get_user_name_utf8"), visibility("default")));
+
+#endif
+#undef glib_check_version
+extern __typeof (glib_check_version) glib_check_version __attribute((alias("IA__glib_check_version"), visibility("default")));
+
+#undef g_nullify_pointer
+extern __typeof (g_nullify_pointer) g_nullify_pointer __attribute((alias("IA__g_nullify_pointer"), visibility("default")));
+
+#undef g_parse_debug_string
+extern __typeof (g_parse_debug_string) g_parse_debug_string __attribute((alias("IA__g_parse_debug_string"), visibility("default")));
+
+#undef g_path_get_basename
+extern __typeof (g_path_get_basename) g_path_get_basename __attribute((alias("IA__g_path_get_basename"), visibility("default")));
+
+#undef g_path_get_dirname
+extern __typeof (g_path_get_dirname) g_path_get_dirname __attribute((alias("IA__g_path_get_dirname"), visibility("default")));
+
+#undef g_path_is_absolute
+extern __typeof (g_path_is_absolute) g_path_is_absolute __attribute((alias("IA__g_path_is_absolute"), visibility("default")));
+
+#undef g_path_skip_root
+extern __typeof (g_path_skip_root) g_path_skip_root __attribute((alias("IA__g_path_skip_root"), visibility("default")));
+
+#undef g_set_application_name
+extern __typeof (g_set_application_name) g_set_application_name __attribute((alias("IA__g_set_application_name"), visibility("default")));
+
+#undef g_set_prgname
+extern __typeof (g_set_prgname) g_set_prgname __attribute((alias("IA__g_set_prgname"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_REGEX_H__)
+#if IN_FILE(__G_REGEX_C__)
+#undef g_regex_error_quark
+extern __typeof (g_regex_error_quark) g_regex_error_quark __attribute((alias("IA__g_regex_error_quark"), visibility("default")));
+
+#undef g_regex_new
+extern __typeof (g_regex_new) g_regex_new __attribute((alias("IA__g_regex_new"), visibility("default")));
+
+#undef g_regex_ref
+extern __typeof (g_regex_ref) g_regex_ref __attribute((alias("IA__g_regex_ref"), visibility("default")));
+
+#undef g_regex_unref
+extern __typeof (g_regex_unref) g_regex_unref __attribute((alias("IA__g_regex_unref"), visibility("default")));
+
+#undef g_regex_get_pattern
+extern __typeof (g_regex_get_pattern) g_regex_get_pattern __attribute((alias("IA__g_regex_get_pattern"), visibility("default")));
+
+#undef g_regex_get_max_backref
+extern __typeof (g_regex_get_max_backref) g_regex_get_max_backref __attribute((alias("IA__g_regex_get_max_backref"), visibility("default")));
+
+#undef g_regex_get_capture_count
+extern __typeof (g_regex_get_capture_count) g_regex_get_capture_count __attribute((alias("IA__g_regex_get_capture_count"), visibility("default")));
+
+#undef g_regex_get_string_number
+extern __typeof (g_regex_get_string_number) g_regex_get_string_number __attribute((alias("IA__g_regex_get_string_number"), visibility("default")));
+
+#undef g_regex_escape_string
+extern __typeof (g_regex_escape_string) g_regex_escape_string __attribute((alias("IA__g_regex_escape_string"), visibility("default")));
+
+#undef g_regex_match_simple
+extern __typeof (g_regex_match_simple) g_regex_match_simple __attribute((alias("IA__g_regex_match_simple"), visibility("default")));
+
+#undef g_regex_match
+extern __typeof (g_regex_match) g_regex_match __attribute((alias("IA__g_regex_match"), visibility("default")));
+
+#undef g_regex_match_full
+extern __typeof (g_regex_match_full) g_regex_match_full __attribute((alias("IA__g_regex_match_full"), visibility("default")));
+
+#undef g_regex_match_all
+extern __typeof (g_regex_match_all) g_regex_match_all __attribute((alias("IA__g_regex_match_all"), visibility("default")));
+
+#undef g_regex_match_all_full
+extern __typeof (g_regex_match_all_full) g_regex_match_all_full __attribute((alias("IA__g_regex_match_all_full"), visibility("default")));
+
+#undef g_regex_split_simple
+extern __typeof (g_regex_split_simple) g_regex_split_simple __attribute((alias("IA__g_regex_split_simple"), visibility("default")));
+
+#undef g_regex_split
+extern __typeof (g_regex_split) g_regex_split __attribute((alias("IA__g_regex_split"), visibility("default")));
+
+#undef g_regex_split_full
+extern __typeof (g_regex_split_full) g_regex_split_full __attribute((alias("IA__g_regex_split_full"), visibility("default")));
+
+#undef g_regex_replace
+extern __typeof (g_regex_replace) g_regex_replace __attribute((alias("IA__g_regex_replace"), visibility("default")));
+
+#undef g_regex_replace_literal
+extern __typeof (g_regex_replace_literal) g_regex_replace_literal __attribute((alias("IA__g_regex_replace_literal"), visibility("default")));
+
+#undef g_regex_replace_eval
+extern __typeof (g_regex_replace_eval) g_regex_replace_eval __attribute((alias("IA__g_regex_replace_eval"), visibility("default")));
+
+#undef g_regex_check_replacement
+extern __typeof (g_regex_check_replacement) g_regex_check_replacement __attribute((alias("IA__g_regex_check_replacement"), visibility("default")));
+
+#undef g_match_info_get_regex
+extern __typeof (g_match_info_get_regex) g_match_info_get_regex __attribute((alias("IA__g_match_info_get_regex"), visibility("default")));
+
+#undef g_match_info_get_string
+extern __typeof (g_match_info_get_string) g_match_info_get_string __attribute((alias("IA__g_match_info_get_string"), visibility("default")));
+
+#undef g_match_info_free
+extern __typeof (g_match_info_free) g_match_info_free __attribute((alias("IA__g_match_info_free"), visibility("default")));
+
+#undef g_match_info_next
+extern __typeof (g_match_info_next) g_match_info_next __attribute((alias("IA__g_match_info_next"), visibility("default")));
+
+#undef g_match_info_matches
+extern __typeof (g_match_info_matches) g_match_info_matches __attribute((alias("IA__g_match_info_matches"), visibility("default")));
+
+#undef g_match_info_get_match_count
+extern __typeof (g_match_info_get_match_count) g_match_info_get_match_count __attribute((alias("IA__g_match_info_get_match_count"), visibility("default")));
+
+#undef g_match_info_is_partial_match
+extern __typeof (g_match_info_is_partial_match) g_match_info_is_partial_match __attribute((alias("IA__g_match_info_is_partial_match"), visibility("default")));
+
+#undef g_match_info_expand_references
+extern __typeof (g_match_info_expand_references) g_match_info_expand_references __attribute((alias("IA__g_match_info_expand_references"), visibility("default")));
+
+#undef g_match_info_fetch
+extern __typeof (g_match_info_fetch) g_match_info_fetch __attribute((alias("IA__g_match_info_fetch"), visibility("default")));
+
+#undef g_match_info_fetch_pos
+extern __typeof (g_match_info_fetch_pos) g_match_info_fetch_pos __attribute((alias("IA__g_match_info_fetch_pos"), visibility("default")));
+
+#undef g_match_info_fetch_named
+extern __typeof (g_match_info_fetch_named) g_match_info_fetch_named __attribute((alias("IA__g_match_info_fetch_named"), visibility("default")));
+
+#undef g_match_info_fetch_named_pos
+extern __typeof (g_match_info_fetch_named_pos) g_match_info_fetch_named_pos __attribute((alias("IA__g_match_info_fetch_named_pos"), visibility("default")));
+
+#undef g_match_info_fetch_all
+extern __typeof (g_match_info_fetch_all) g_match_info_fetch_all __attribute((alias("IA__g_match_info_fetch_all"), visibility("default")));
+
+#endif
+#endif
+#if IN_HEADER(__G_WIN32_H__)
+#if IN_FILE(__G_WIN32_H__)
+#ifdef G_OS_WIN32
+#undef g_win32_error_message
+extern __typeof (g_win32_error_message) g_win32_error_message __attribute((alias("IA__g_win32_error_message"), visibility("default")));
+
+#undef g_win32_ftruncate
+extern __typeof (g_win32_ftruncate) g_win32_ftruncate __attribute((alias("IA__g_win32_ftruncate"), visibility("default")));
+
+#undef g_win32_get_package_installation_directory_of_module
+extern __typeof (g_win32_get_package_installation_directory_of_module) g_win32_get_package_installation_directory_of_module __attribute((alias("IA__g_win32_get_package_installation_directory_of_module"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_win32_get_package_installation_directory
+extern __typeof (g_win32_get_package_installation_directory) g_win32_get_package_installation_directory __attribute((alias("IA__g_win32_get_package_installation_directory"), visibility("default")));
+
+#endif
+#undef g_win32_get_package_installation_directory_utf8
+extern __typeof (g_win32_get_package_installation_directory_utf8) g_win32_get_package_installation_directory_utf8 __attribute((alias("IA__g_win32_get_package_installation_directory_utf8"), visibility("default")));
+
+#ifndef _WIN64
+#undef g_win32_get_package_installation_subdirectory
+extern __typeof (g_win32_get_package_installation_subdirectory) g_win32_get_package_installation_subdirectory __attribute((alias("IA__g_win32_get_package_installation_subdirectory"), visibility("default")));
+
+#endif
+#undef g_win32_get_package_installation_subdirectory_utf8
+extern __typeof (g_win32_get_package_installation_subdirectory_utf8) g_win32_get_package_installation_subdirectory_utf8 __attribute((alias("IA__g_win32_get_package_installation_subdirectory_utf8"), visibility("default")));
+
+#undef g_win32_get_windows_version
+extern __typeof (g_win32_get_windows_version) g_win32_get_windows_version __attribute((alias("IA__g_win32_get_windows_version"), visibility("default")));
+
+#undef g_win32_getlocale
+extern __typeof (g_win32_getlocale) g_win32_getlocale __attribute((alias("IA__g_win32_getlocale"), visibility("default")));
+
+#undef g_win32_locale_filename_from_utf8
+extern __typeof (g_win32_locale_filename_from_utf8) g_win32_locale_filename_from_utf8 __attribute((alias("IA__g_win32_locale_filename_from_utf8"), visibility("default")));
+
+#endif
+#endif
+#endif
+
+#endif /* G_HAVE_GNUC_VISIBILITY */
+#endif /* DISABLE_VISIBILITY */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/galloca.h b/desmume/src/windows/glib-2.20.1/build/glib/galloca.h
new file mode 100644
index 000000000..356587ff6
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/galloca.h
@@ -0,0 +1,63 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_ALLOCA_H__
+#define __G_ALLOCA_H__
+
+#include
+
+#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
+#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
+# if defined(_MSC_VER) || defined(__DMC__)
+# include
+# 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 */
+
+#define g_alloca(size) alloca (size)
+#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs)))
+
+#endif /* __G_ALLOCA_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/garray.c b/desmume/src/windows/glib-2.20.1/build/glib/garray.c
new file mode 100644
index 000000000..b05ded6b2
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/garray.c
@@ -0,0 +1,719 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#include "garray.h"
+
+#include "gmem.h"
+#include "gthread.h"
+#include "gmessages.h"
+#include "gqsort.h"
+
+#include "galias.h"
+
+
+#define MIN_ARRAY_SIZE 16
+
+typedef struct _GRealArray GRealArray;
+
+struct _GRealArray
+{
+ guint8 *data;
+ guint len;
+ guint alloc;
+ guint elt_size;
+ guint zero_terminated : 1;
+ guint clear : 1;
+};
+
+#define g_array_elt_len(array,i) ((array)->elt_size * (i))
+#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
+#define g_array_elt_zero(array, pos, len) \
+ (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len)))
+#define g_array_zero_terminate(array) G_STMT_START{ \
+ if ((array)->zero_terminated) \
+ g_array_elt_zero ((array), (array)->len, 1); \
+}G_STMT_END
+
+static gint g_nearest_pow (gint num) G_GNUC_CONST;
+static void g_array_maybe_expand (GRealArray *array,
+ gint len);
+
+GArray*
+g_array_new (gboolean zero_terminated,
+ gboolean clear,
+ guint elt_size)
+{
+ return (GArray*) g_array_sized_new (zero_terminated, clear, elt_size, 0);
+}
+
+GArray* g_array_sized_new (gboolean zero_terminated,
+ gboolean clear,
+ guint elt_size,
+ guint reserved_size)
+{
+ GRealArray *array = g_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;
+
+ if (array->zero_terminated || reserved_size != 0)
+ {
+ g_array_maybe_expand (array, reserved_size);
+ g_array_zero_terminate(array);
+ }
+
+ return (GArray*) array;
+}
+
+gchar*
+g_array_free (GArray *array,
+ gboolean free_segment)
+{
+ gchar* segment;
+
+ g_return_val_if_fail (array, NULL);
+
+ if (free_segment)
+ {
+ g_free (array->data);
+ segment = NULL;
+ }
+ else
+ segment = array->data;
+
+ g_slice_free1 (sizeof (GRealArray), array);
+
+ return segment;
+}
+
+GArray*
+g_array_append_vals (GArray *farray,
+ gconstpointer data,
+ guint len)
+{
+ GRealArray *array = (GRealArray*) farray;
+
+ g_array_maybe_expand (array, len);
+
+ memcpy (g_array_elt_pos (array, array->len), data,
+ g_array_elt_len (array, len));
+
+ array->len += len;
+
+ g_array_zero_terminate (array);
+
+ return farray;
+}
+
+GArray*
+g_array_prepend_vals (GArray *farray,
+ gconstpointer data,
+ guint len)
+{
+ GRealArray *array = (GRealArray*) farray;
+
+ g_array_maybe_expand (array, len);
+
+ g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
+ g_array_elt_len (array, array->len));
+
+ memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
+
+ array->len += len;
+
+ g_array_zero_terminate (array);
+
+ return farray;
+}
+
+GArray*
+g_array_insert_vals (GArray *farray,
+ guint index_,
+ gconstpointer data,
+ guint len)
+{
+ GRealArray *array = (GRealArray*) farray;
+
+ g_array_maybe_expand (array, len);
+
+ g_memmove (g_array_elt_pos (array, len + index_),
+ g_array_elt_pos (array, index_),
+ g_array_elt_len (array, array->len - index_));
+
+ memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
+
+ array->len += len;
+
+ g_array_zero_terminate (array);
+
+ return farray;
+}
+
+GArray*
+g_array_set_size (GArray *farray,
+ guint length)
+{
+ GRealArray *array = (GRealArray*) farray;
+ if (length > array->len)
+ {
+ g_array_maybe_expand (array, length - array->len);
+
+ if (array->clear)
+ g_array_elt_zero (array, array->len, length - array->len);
+ }
+ 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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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);
+}
+
+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);
+}
+
+
+static gint
+g_nearest_pow (gint num)
+{
+ gint n = 1;
+
+ while (n < num)
+ n <<= 1;
+
+ return n;
+}
+
+static void
+g_array_maybe_expand (GRealArray *array,
+ gint len)
+{
+ guint want_alloc = g_array_elt_len (array, array->len + len +
+ array->zero_terminated);
+
+ if (want_alloc > array->alloc)
+ {
+ want_alloc = g_nearest_pow (want_alloc);
+ want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
+
+ array->data = g_realloc (array->data, want_alloc);
+
+ if (G_UNLIKELY (g_mem_gc_friendly))
+ memset (array->data + array->alloc, 0, want_alloc - array->alloc);
+
+ array->alloc = want_alloc;
+ }
+}
+
+/* Pointer Array
+ */
+
+typedef struct _GRealPtrArray GRealPtrArray;
+
+struct _GRealPtrArray
+{
+ gpointer *pdata;
+ guint len;
+ guint alloc;
+};
+
+static void g_ptr_array_maybe_expand (GRealPtrArray *array,
+ gint len);
+
+GPtrArray*
+g_ptr_array_new (void)
+{
+ return g_ptr_array_sized_new (0);
+}
+
+GPtrArray*
+g_ptr_array_sized_new (guint reserved_size)
+{
+ GRealPtrArray *array = g_slice_new (GRealPtrArray);
+
+ array->pdata = NULL;
+ array->len = 0;
+ array->alloc = 0;
+
+ if (reserved_size != 0)
+ g_ptr_array_maybe_expand (array, reserved_size);
+
+ return (GPtrArray*) array;
+}
+
+gpointer*
+g_ptr_array_free (GPtrArray *array,
+ gboolean free_segment)
+{
+ gpointer* segment;
+
+ g_return_val_if_fail (array, NULL);
+
+ if (free_segment)
+ {
+ g_free (array->pdata);
+ segment = NULL;
+ }
+ else
+ segment = array->pdata;
+
+ g_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;
+ }
+}
+
+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;
+ }
+ if (G_UNLIKELY (g_mem_gc_friendly) && length < array->len)
+ {
+ int i;
+ for (i = length; i < array->len; i++)
+ array->pdata[i] = NULL;
+ }
+
+ array->len = length;
+}
+
+gpointer
+g_ptr_array_remove_index (GPtrArray *farray,
+ guint index_)
+{
+ GRealPtrArray* array = (GRealPtrArray*) farray;
+ gpointer result;
+
+ g_return_val_if_fail (array, NULL);
+
+ g_return_val_if_fail (index_ < array->len, NULL);
+
+ result = array->pdata[index_];
+
+ if (index_ != array->len - 1)
+ g_memmove (array->pdata + index_, array->pdata + index_ + 1,
+ sizeof (gpointer) * (array->len - index_ - 1));
+
+ array->len -= 1;
+
+ if (G_UNLIKELY (g_mem_gc_friendly))
+ array->pdata[array->len] = NULL;
+
+ return result;
+}
+
+gpointer
+g_ptr_array_remove_index_fast (GPtrArray *farray,
+ guint index_)
+{
+ GRealPtrArray* array = (GRealPtrArray*) farray;
+ gpointer result;
+
+ g_return_val_if_fail (array, NULL);
+
+ g_return_val_if_fail (index_ < array->len, NULL);
+
+ result = array->pdata[index_];
+
+ if (index_ != array->len - 1)
+ array->pdata[index_] = array->pdata[array->len - 1];
+
+ array->len -= 1;
+
+ if (G_UNLIKELY (g_mem_gc_friendly))
+ array->pdata[array->len] = NULL;
+
+ return result;
+}
+
+void
+g_ptr_array_remove_range (GPtrArray *farray,
+ guint index_,
+ guint length)
+{
+ GRealPtrArray* array = (GRealPtrArray*) farray;
+
+ g_return_if_fail (array);
+ g_return_if_fail (index_ < array->len);
+ g_return_if_fail (index_ + length <= array->len);
+
+ 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;
+ }
+}
+
+gboolean
+g_ptr_array_remove (GPtrArray *farray,
+ gpointer data)
+{
+ GRealPtrArray* array = (GRealPtrArray*) farray;
+ guint i;
+
+ g_return_val_if_fail (array, FALSE);
+
+ for (i = 0; i < array->len; i += 1)
+ {
+ if (array->pdata[i] == data)
+ {
+ g_ptr_array_remove_index (farray, i);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+gboolean
+g_ptr_array_remove_fast (GPtrArray *farray,
+ gpointer data)
+{
+ GRealPtrArray* array = (GRealPtrArray*) farray;
+ guint i;
+
+ g_return_val_if_fail (array, FALSE);
+
+ for (i = 0; i < array->len; i += 1)
+ {
+ if (array->pdata[i] == data)
+ {
+ g_ptr_array_remove_index_fast (farray, i);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+void
+g_ptr_array_add (GPtrArray *farray,
+ gpointer data)
+{
+ GRealPtrArray* array = (GRealPtrArray*) farray;
+
+ g_return_if_fail (array);
+
+ g_ptr_array_maybe_expand (array, 1);
+
+ array->pdata[array->len++] = data;
+}
+
+void
+g_ptr_array_sort (GPtrArray *array,
+ GCompareFunc compare_func)
+{
+ g_return_if_fail (array != NULL);
+
+ qsort (array->pdata,
+ array->len,
+ sizeof (gpointer),
+ compare_func);
+}
+
+void
+g_ptr_array_sort_with_data (GPtrArray *array,
+ GCompareDataFunc compare_func,
+ gpointer user_data)
+{
+ g_return_if_fail (array != NULL);
+
+ g_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);
+}
+
+/* Byte arrays
+ */
+
+GByteArray* g_byte_array_new (void)
+{
+ return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0);
+}
+
+GByteArray* g_byte_array_sized_new (guint reserved_size)
+{
+ return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size);
+}
+
+guint8* g_byte_array_free (GByteArray *array,
+ gboolean free_segment)
+{
+ return (guint8*) g_array_free ((GArray*) array, free_segment);
+}
+
+GByteArray* g_byte_array_append (GByteArray *array,
+ const guint8 *data,
+ guint len)
+{
+ g_array_append_vals ((GArray*) array, (guint8*)data, len);
+
+ return array;
+}
+
+GByteArray* g_byte_array_prepend (GByteArray *array,
+ const guint8 *data,
+ guint len)
+{
+ g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
+
+ return array;
+}
+
+GByteArray* g_byte_array_set_size (GByteArray *array,
+ guint length)
+{
+ g_array_set_size ((GArray*) array, length);
+
+ return array;
+}
+
+GByteArray* g_byte_array_remove_index (GByteArray *array,
+ guint index_)
+{
+ g_array_remove_index ((GArray*) array, index_);
+
+ return array;
+}
+
+GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
+ guint index_)
+{
+ g_array_remove_index_fast ((GArray*) array, index_);
+
+ return array;
+}
+
+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);
+}
+
+void
+g_byte_array_sort (GByteArray *array,
+ GCompareFunc compare_func)
+{
+ g_array_sort ((GArray *) array, compare_func);
+}
+
+void
+g_byte_array_sort_with_data (GByteArray *array,
+ GCompareDataFunc compare_func,
+ gpointer user_data)
+{
+ g_array_sort_with_data ((GArray *) array, compare_func, user_data);
+}
+
+#define __G_ARRAY_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/garray.h b/desmume/src/windows/glib-2.20.1/build/glib/garray.h
new file mode 100644
index 000000000..db001370a
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/garray.h
@@ -0,0 +1,169 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_ARRAY_H__
+#define __G_ARRAY_H__
+
+#include
+
+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_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_sized_new (guint reserved_size);
+gpointer* g_ptr_array_free (GPtrArray *array,
+ gboolean free_seg);
+void g_ptr_array_set_size (GPtrArray *array,
+ gint length);
+gpointer g_ptr_array_remove_index (GPtrArray *array,
+ guint index_);
+gpointer g_ptr_array_remove_index_fast (GPtrArray *array,
+ guint index_);
+gboolean g_ptr_array_remove (GPtrArray *array,
+ gpointer data);
+gboolean g_ptr_array_remove_fast (GPtrArray *array,
+ gpointer data);
+void g_ptr_array_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_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/desmume/src/windows/glib-2.20.1/build/glib/gasyncqueue.c b/desmume/src/windows/glib-2.20.1/build/glib/gasyncqueue.c
new file mode 100644
index 000000000..65e95a8de
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gasyncqueue.c
@@ -0,0 +1,666 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GAsyncQueue: asynchronous queue implementation, based on Gqueue.
+ * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "galias.h"
+
+
+struct _GAsyncQueue
+{
+ GMutex *mutex;
+ GCond *cond;
+ GQueue *queue;
+ GDestroyNotify item_free_func;
+ guint waiting_threads;
+ gint32 ref_count;
+};
+
+typedef struct {
+ GCompareDataFunc func;
+ gpointer user_data;
+} SortData;
+
+/**
+ * g_async_queue_new:
+ *
+ * Creates a new asynchronous queue with the initial reference count of 1.
+ *
+ * Return value: the new #GAsyncQueue.
+ **/
+GAsyncQueue*
+g_async_queue_new (void)
+{
+ GAsyncQueue* retval = g_new (GAsyncQueue, 1);
+ retval->mutex = g_mutex_new ();
+ retval->cond = NULL;
+ retval->queue = g_queue_new ();
+ retval->waiting_threads = 0;
+ retval->ref_count = 1;
+ retval->item_free_func = NULL;
+ return retval;
+}
+
+/**
+ * g_async_queue_new_full:
+ * @item_free_func: function to free queue elements
+ *
+ * Creates a new asynchronous queue with an initial reference count of 1 and
+ * sets up a destroy notify function that is used to free any remaining
+ * queue items when the queue is destroyed after the final unref.
+ *
+ * Return value: the new #GAsyncQueue.
+ *
+ * Since: 2.16
+ **/
+GAsyncQueue*
+g_async_queue_new_full (GDestroyNotify item_free_func)
+{
+ GAsyncQueue *async_queue = g_async_queue_new ();
+ async_queue->item_free_func = item_free_func;
+ return async_queue;
+}
+
+/**
+ * g_async_queue_ref:
+ * @queue: a #GAsyncQueue.
+ *
+ * Increases the reference count of the asynchronous @queue by 1. You
+ * do not need to hold the lock to call this function.
+ *
+ * Returns: the @queue that was passed in (since 2.6)
+ **/
+GAsyncQueue *
+g_async_queue_ref (GAsyncQueue *queue)
+{
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ g_atomic_int_inc (&queue->ref_count);
+
+ return queue;
+}
+
+/**
+ * g_async_queue_ref_unlocked:
+ * @queue: a #GAsyncQueue.
+ *
+ * Increases the reference count of the asynchronous @queue by 1.
+ *
+ * @Deprecated: Since 2.8, reference counting is done atomically
+ * so g_async_queue_ref() can be used regardless of the @queue's
+ * lock.
+ **/
+void
+g_async_queue_ref_unlocked (GAsyncQueue *queue)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+ g_atomic_int_inc (&queue->ref_count);
+}
+
+/**
+ * g_async_queue_unref_and_unlock:
+ * @queue: a #GAsyncQueue.
+ *
+ * Decreases the reference count of the asynchronous @queue by 1 and
+ * releases the lock. This function must be called while holding the
+ * @queue's lock. If the reference count went to 0, the @queue will be
+ * destroyed and the memory allocated will be freed.
+ *
+ * @Deprecated: Since 2.8, reference counting is done atomically
+ * so g_async_queue_unref() can be used regardless of the @queue's
+ * lock.
+ **/
+void
+g_async_queue_unref_and_unlock (GAsyncQueue *queue)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+ g_mutex_unlock (queue->mutex);
+ g_async_queue_unref (queue);
+}
+
+/**
+ * g_async_queue_unref:
+ * @queue: a #GAsyncQueue.
+ *
+ * Decreases the reference count of the asynchronous @queue by 1. If
+ * the reference count went to 0, the @queue will be destroyed and the
+ * memory allocated will be freed. So you are not allowed to use the
+ * @queue afterwards, as it might have disappeared. You do not need to
+ * hold the lock to call this function.
+ **/
+void
+g_async_queue_unref (GAsyncQueue *queue)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+ if (g_atomic_int_dec_and_test (&queue->ref_count))
+ {
+ g_return_if_fail (queue->waiting_threads == 0);
+ g_mutex_free (queue->mutex);
+ if (queue->cond)
+ g_cond_free (queue->cond);
+ if (queue->item_free_func)
+ g_queue_foreach (queue->queue, (GFunc) queue->item_free_func, NULL);
+ g_queue_free (queue->queue);
+ g_free (queue);
+ }
+}
+
+/**
+ * g_async_queue_lock:
+ * @queue: a #GAsyncQueue.
+ *
+ * Acquires the @queue's lock. After that you can only call the
+ * g_async_queue_*_unlocked() function variants on that
+ * @queue. Otherwise it will deadlock.
+ **/
+void
+g_async_queue_lock (GAsyncQueue *queue)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+ g_mutex_lock (queue->mutex);
+}
+
+/**
+ * g_async_queue_unlock:
+ * @queue: a #GAsyncQueue.
+ *
+ * Releases the queue's lock.
+ **/
+void
+g_async_queue_unlock (GAsyncQueue *queue)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+ g_mutex_unlock (queue->mutex);
+}
+
+/**
+ * g_async_queue_push:
+ * @queue: a #GAsyncQueue.
+ * @data: @data to push into the @queue.
+ *
+ * Pushes the @data into the @queue. @data must not be %NULL.
+ **/
+void
+g_async_queue_push (GAsyncQueue* queue, gpointer data)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+ g_return_if_fail (data);
+
+ g_mutex_lock (queue->mutex);
+ g_async_queue_push_unlocked (queue, data);
+ g_mutex_unlock (queue->mutex);
+}
+
+/**
+ * g_async_queue_push_unlocked:
+ * @queue: a #GAsyncQueue.
+ * @data: @data to push into the @queue.
+ *
+ * Pushes the @data into the @queue. @data must not be %NULL. This
+ * function must be called while holding the @queue's lock.
+ **/
+void
+g_async_queue_push_unlocked (GAsyncQueue* queue, gpointer data)
+{
+ g_return_if_fail (queue);
+ g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+ g_return_if_fail (data);
+
+ g_queue_push_head (queue->queue, data);
+ if (queue->waiting_threads > 0)
+ g_cond_signal (queue->cond);
+}
+
+/**
+ * g_async_queue_push_sorted:
+ * @queue: a #GAsyncQueue
+ * @data: the @data to push into the @queue
+ * @func: the #GCompareDataFunc is used to sort @queue. This function
+ * is passed two elements of the @queue. The function should return
+ * 0 if they are equal, a negative value if the first element
+ * should be higher in the @queue or a positive value if the first
+ * element should be lower in the @queue than the second element.
+ * @user_data: user data passed to @func.
+ *
+ * Inserts @data into @queue using @func to determine the new
+ * position.
+ *
+ * This function requires that the @queue is sorted before pushing on
+ * new elements.
+ *
+ * This function will lock @queue before it sorts the queue and unlock
+ * it when it is finished.
+ *
+ * For an example of @func see g_async_queue_sort().
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_push_sorted (GAsyncQueue *queue,
+ gpointer data,
+ GCompareDataFunc func,
+ gpointer user_data)
+{
+ g_return_if_fail (queue != NULL);
+
+ g_mutex_lock (queue->mutex);
+ g_async_queue_push_sorted_unlocked (queue, data, func, user_data);
+ g_mutex_unlock (queue->mutex);
+}
+
+static gint
+g_async_queue_invert_compare (gpointer v1,
+ gpointer v2,
+ SortData *sd)
+{
+ return -sd->func (v1, v2, sd->user_data);
+}
+
+/**
+ * g_async_queue_push_sorted_unlocked:
+ * @queue: a #GAsyncQueue
+ * @data: the @data to push into the @queue
+ * @func: the #GCompareDataFunc is used to sort @queue. This function
+ * is passed two elements of the @queue. The function should return
+ * 0 if they are equal, a negative value if the first element
+ * should be higher in the @queue or a positive value if the first
+ * element should be lower in the @queue than the second element.
+ * @user_data: user data passed to @func.
+ *
+ * Inserts @data into @queue using @func to determine the new
+ * position.
+ *
+ * This function requires that the @queue is sorted before pushing on
+ * new elements.
+ *
+ * This function is called while holding the @queue's lock.
+ *
+ * For an example of @func see g_async_queue_sort().
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_push_sorted_unlocked (GAsyncQueue *queue,
+ gpointer data,
+ GCompareDataFunc func,
+ gpointer user_data)
+{
+ SortData sd;
+
+ g_return_if_fail (queue != NULL);
+
+ sd.func = func;
+ sd.user_data = user_data;
+
+ g_queue_insert_sorted (queue->queue,
+ data,
+ (GCompareDataFunc)g_async_queue_invert_compare,
+ &sd);
+ if (queue->waiting_threads > 0)
+ g_cond_signal (queue->cond);
+}
+
+static gpointer
+g_async_queue_pop_intern_unlocked (GAsyncQueue *queue,
+ gboolean try,
+ GTimeVal *end_time)
+{
+ gpointer retval;
+
+ if (!g_queue_peek_tail_link (queue->queue))
+ {
+ if (try)
+ return NULL;
+
+ if (!queue->cond)
+ queue->cond = g_cond_new ();
+
+ if (!end_time)
+ {
+ queue->waiting_threads++;
+ while (!g_queue_peek_tail_link (queue->queue))
+ g_cond_wait (queue->cond, queue->mutex);
+ queue->waiting_threads--;
+ }
+ else
+ {
+ queue->waiting_threads++;
+ while (!g_queue_peek_tail_link (queue->queue))
+ if (!g_cond_timed_wait (queue->cond, queue->mutex, end_time))
+ break;
+ queue->waiting_threads--;
+ if (!g_queue_peek_tail_link (queue->queue))
+ return NULL;
+ }
+ }
+
+ retval = g_queue_pop_tail (queue->queue);
+
+ g_assert (retval);
+
+ return retval;
+}
+
+/**
+ * g_async_queue_pop:
+ * @queue: a #GAsyncQueue.
+ *
+ * Pops data from the @queue. This function blocks until data become
+ * available.
+ *
+ * Return value: data from the queue.
+ **/
+gpointer
+g_async_queue_pop (GAsyncQueue* queue)
+{
+ gpointer retval;
+
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ g_mutex_lock (queue->mutex);
+ retval = g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
+ g_mutex_unlock (queue->mutex);
+
+ return retval;
+}
+
+/**
+ * g_async_queue_pop_unlocked:
+ * @queue: a #GAsyncQueue.
+ *
+ * Pops data from the @queue. This function blocks until data become
+ * available. This function must be called while holding the @queue's
+ * lock.
+ *
+ * Return value: data from the queue.
+ **/
+gpointer
+g_async_queue_pop_unlocked (GAsyncQueue* queue)
+{
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
+}
+
+/**
+ * g_async_queue_try_pop:
+ * @queue: a #GAsyncQueue.
+ *
+ * Tries to pop data from the @queue. If no data is available, %NULL is
+ * returned.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * available immediately.
+ **/
+gpointer
+g_async_queue_try_pop (GAsyncQueue* queue)
+{
+ gpointer retval;
+
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ g_mutex_lock (queue->mutex);
+ retval = g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
+ g_mutex_unlock (queue->mutex);
+
+ return retval;
+}
+
+/**
+ * g_async_queue_try_pop_unlocked:
+ * @queue: a #GAsyncQueue.
+ *
+ * Tries to pop data from the @queue. If no data is available, %NULL is
+ * returned. This function must be called while holding the @queue's
+ * lock.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * available immediately.
+ **/
+gpointer
+g_async_queue_try_pop_unlocked (GAsyncQueue* queue)
+{
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
+}
+
+/**
+ * g_async_queue_timed_pop:
+ * @queue: a #GAsyncQueue.
+ * @end_time: a #GTimeVal, determining the final time.
+ *
+ * Pops data from the @queue. If no data is received before @end_time,
+ * %NULL is returned.
+ *
+ * To easily calculate @end_time a combination of g_get_current_time()
+ * and g_time_val_add() can be used.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * received before @end_time.
+ **/
+gpointer
+g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time)
+{
+ gpointer retval;
+
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ g_mutex_lock (queue->mutex);
+ retval = g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
+ g_mutex_unlock (queue->mutex);
+
+ return retval;
+}
+
+/**
+ * g_async_queue_timed_pop_unlocked:
+ * @queue: a #GAsyncQueue.
+ * @end_time: a #GTimeVal, determining the final time.
+ *
+ * Pops data from the @queue. If no data is received before @end_time,
+ * %NULL is returned. This function must be called while holding the
+ * @queue's lock.
+ *
+ * To easily calculate @end_time a combination of g_get_current_time()
+ * and g_time_val_add() can be used.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * received before @end_time.
+ **/
+gpointer
+g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time)
+{
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ return g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
+}
+
+/**
+ * g_async_queue_length:
+ * @queue: a #GAsyncQueue.
+ *
+ * Returns the length of the queue, negative values mean waiting
+ * threads, positive values mean available entries in the
+ * @queue. Actually this function returns the number of data items in
+ * the queue minus the number of waiting threads. Thus a return value
+ * of 0 could mean 'n' entries in the queue and 'n' thread waiting.
+ * That can happen due to locking of the queue or due to
+ * scheduling.
+ *
+ * Return value: the length of the @queue.
+ **/
+gint
+g_async_queue_length (GAsyncQueue* queue)
+{
+ gint retval;
+
+ g_return_val_if_fail (queue, 0);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, 0);
+
+ g_mutex_lock (queue->mutex);
+ retval = queue->queue->length - queue->waiting_threads;
+ g_mutex_unlock (queue->mutex);
+
+ return retval;
+}
+
+/**
+ * g_async_queue_length_unlocked:
+ * @queue: a #GAsyncQueue.
+ *
+ * Returns the length of the queue, negative values mean waiting
+ * threads, positive values mean available entries in the
+ * @queue. Actually this function returns the number of data items in
+ * the queue minus the number of waiting threads. Thus a return value
+ * of 0 could mean 'n' entries in the queue and 'n' thread waiting.
+ * That can happen due to locking of the queue or due to
+ * scheduling. This function must be called while holding the @queue's
+ * lock.
+ *
+ * Return value: the length of the @queue.
+ **/
+gint
+g_async_queue_length_unlocked (GAsyncQueue* queue)
+{
+ g_return_val_if_fail (queue, 0);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, 0);
+
+ return queue->queue->length - queue->waiting_threads;
+}
+
+/**
+ * g_async_queue_sort:
+ * @queue: a #GAsyncQueue
+ * @func: the #GCompareDataFunc is used to sort @queue. This
+ * function is passed two elements of the @queue. The function
+ * should return 0 if they are equal, a negative value if the
+ * first element should be higher in the @queue or a positive
+ * value if the first element should be lower in the @queue than
+ * the second element.
+ * @user_data: user data passed to @func
+ *
+ * Sorts @queue using @func.
+ *
+ * This function will lock @queue before it sorts the queue and unlock
+ * it when it is finished.
+ *
+ * If you were sorting a list of priority numbers to make sure the
+ * lowest priority would be at the top of the queue, you could use:
+ * |[
+ * gint32 id1;
+ * gint32 id2;
+ *
+ * id1 = GPOINTER_TO_INT (element1);
+ * id2 = GPOINTER_TO_INT (element2);
+ *
+ * return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1);
+ * ]|
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_sort (GAsyncQueue *queue,
+ GCompareDataFunc func,
+ gpointer user_data)
+{
+ g_return_if_fail (queue != NULL);
+ g_return_if_fail (func != NULL);
+
+ g_mutex_lock (queue->mutex);
+ g_async_queue_sort_unlocked (queue, func, user_data);
+ g_mutex_unlock (queue->mutex);
+}
+
+/**
+ * g_async_queue_sort_unlocked:
+ * @queue: a #GAsyncQueue
+ * @func: the #GCompareDataFunc is used to sort @queue. This
+ * function is passed two elements of the @queue. The function
+ * should return 0 if they are equal, a negative value if the
+ * first element should be higher in the @queue or a positive
+ * value if the first element should be lower in the @queue than
+ * the second element.
+ * @user_data: user data passed to @func
+ *
+ * Sorts @queue using @func.
+ *
+ * This function is called while holding the @queue's lock.
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_sort_unlocked (GAsyncQueue *queue,
+ GCompareDataFunc func,
+ gpointer user_data)
+{
+ SortData sd;
+
+ g_return_if_fail (queue != NULL);
+ g_return_if_fail (func != NULL);
+
+ sd.func = func;
+ sd.user_data = user_data;
+
+ g_queue_sort (queue->queue,
+ (GCompareDataFunc)g_async_queue_invert_compare,
+ &sd);
+}
+
+/*
+ * Private API
+ */
+
+GMutex*
+_g_async_queue_get_mutex (GAsyncQueue* queue)
+{
+ g_return_val_if_fail (queue, NULL);
+ g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+ return queue->mutex;
+}
+
+#define __G_ASYNCQUEUE_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gasyncqueue.h b/desmume/src/windows/glib-2.20.1/build/glib/gasyncqueue.h
new file mode 100644
index 000000000..9da43e36d
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gasyncqueue.h
@@ -0,0 +1,120 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_ASYNCQUEUE_H__
+#define __G_ASYNCQUEUE_H__
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct _GAsyncQueue GAsyncQueue;
+
+/* Asyncronous Queues, can be used to communicate between threads */
+
+/* Get a new GAsyncQueue with the ref_count 1 */
+GAsyncQueue* g_async_queue_new (void);
+
+GAsyncQueue* g_async_queue_new_full (GDestroyNotify item_free_func);
+
+/* Lock and unlock a GAsyncQueue. All functions lock the queue for
+ * themselves, but in certain cirumstances you want to hold the lock longer,
+ * thus you lock the queue, call the *_unlocked functions and unlock it again.
+ */
+void g_async_queue_lock (GAsyncQueue *queue);
+void g_async_queue_unlock (GAsyncQueue *queue);
+
+/* Ref and unref the GAsyncQueue. */
+GAsyncQueue* g_async_queue_ref (GAsyncQueue *queue);
+void g_async_queue_unref (GAsyncQueue *queue);
+
+#ifndef G_DISABLE_DEPRECATED
+/* You don't have to hold the lock for calling *_ref and *_unref anymore. */
+void g_async_queue_ref_unlocked (GAsyncQueue *queue);
+void g_async_queue_unref_and_unlock (GAsyncQueue *queue);
+#endif /* !G_DISABLE_DEPRECATED */
+
+/* Push data into the async queue. Must not be NULL. */
+void g_async_queue_push (GAsyncQueue *queue,
+ gpointer data);
+void g_async_queue_push_unlocked (GAsyncQueue *queue,
+ gpointer data);
+
+void g_async_queue_push_sorted (GAsyncQueue *queue,
+ gpointer data,
+ GCompareDataFunc func,
+ gpointer user_data);
+void g_async_queue_push_sorted_unlocked (GAsyncQueue *queue,
+ gpointer data,
+ GCompareDataFunc func,
+ gpointer user_data);
+
+/* Pop data from the async queue. When no data is there, the thread is blocked
+ * until data arrives.
+ */
+gpointer g_async_queue_pop (GAsyncQueue *queue);
+gpointer g_async_queue_pop_unlocked (GAsyncQueue *queue);
+
+/* Try to pop data. NULL is returned in case of empty queue. */
+gpointer g_async_queue_try_pop (GAsyncQueue *queue);
+gpointer g_async_queue_try_pop_unlocked (GAsyncQueue *queue);
+
+
+
+/* Wait for data until at maximum until end_time is reached. NULL is returned
+ * in case of empty queue.
+ */
+gpointer g_async_queue_timed_pop (GAsyncQueue *queue,
+ GTimeVal *end_time);
+gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue *queue,
+ GTimeVal *end_time);
+
+/* Return the length of the queue. Negative values mean that threads
+ * are waiting, positve values mean that there are entries in the
+ * queue. Actually this function returns the length of the queue minus
+ * the number of waiting threads, g_async_queue_length == 0 could also
+ * mean 'n' entries in the queue and 'n' thread waiting. Such can
+ * happen due to locking of the queue or due to scheduling.
+ */
+gint g_async_queue_length (GAsyncQueue *queue);
+gint g_async_queue_length_unlocked (GAsyncQueue *queue);
+void g_async_queue_sort (GAsyncQueue *queue,
+ GCompareDataFunc func,
+ gpointer user_data);
+void g_async_queue_sort_unlocked (GAsyncQueue *queue,
+ GCompareDataFunc func,
+ gpointer user_data);
+
+/* Private API */
+GMutex* _g_async_queue_get_mutex (GAsyncQueue *queue);
+
+G_END_DECLS
+
+#endif /* __G_ASYNCQUEUE_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gatomic.c b/desmume/src/windows/glib-2.20.1/build/glib/gatomic.c
new file mode 100644
index 000000000..baa73e7ac
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gatomic.c
@@ -0,0 +1,1058 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * g_atomic_*: atomic operations.
+ * Copyright (C) 2003 Sebastian Wilhelmi
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#if defined (G_ATOMIC_ARM)
+#include
+#endif
+
+#include "glib.h"
+#include "gthreadprivate.h"
+#include "galias.h"
+
+#if defined (__GNUC__)
+# if defined (G_ATOMIC_I486)
+/* Adapted from CVS version 1.10 of glibc's sysdeps/i386/i486/bits/atomic.h
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+
+ __asm__ __volatile__ ("lock; xaddl %0,%1"
+ : "=r" (result), "=m" (*atomic)
+ : "0" (val), "m" (*atomic));
+ return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ __asm__ __volatile__ ("lock; addl %1,%0"
+ : "=m" (*atomic)
+ : "ir" (val), "m" (*atomic));
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ gint result;
+
+ __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+ : "=a" (result), "=m" (*atomic)
+ : "r" (newval), "m" (*atomic), "0" (oldval));
+
+ return result == oldval;
+}
+
+/* The same code as above, as on i386 gpointer is 32 bit as well.
+ * Duplicating the code here seems more natural than casting the
+ * arguments and calling the former function */
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result;
+
+ __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+ : "=a" (result), "=m" (*atomic)
+ : "r" (newval), "m" (*atomic), "0" (oldval));
+
+ return result == oldval;
+}
+
+# elif defined (G_ATOMIC_SPARCV9)
+/* Adapted from CVS version 1.3 of glibc's sysdeps/sparc/sparc64/bits/atomic.h
+ */
+# define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
+ ({ \
+ gint __result; \
+ __asm__ __volatile__ ("cas [%4], %2, %0" \
+ : "=r" (__result), "=m" (*(atomic)) \
+ : "r" (oldval), "m" (*(atomic)), "r" (atomic),\
+ "0" (newval)); \
+ __result == oldval; \
+ })
+
+# if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result;
+ __asm__ __volatile__ ("cas [%4], %2, %0"
+ : "=r" (result), "=m" (*atomic)
+ : "r" (oldval), "m" (*atomic), "r" (atomic),
+ "0" (newval));
+ return result == oldval;
+}
+# elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result;
+ gpointer *a = atomic;
+ __asm__ __volatile__ ("casx [%4], %2, %0"
+ : "=r" (result), "=m" (*a)
+ : "r" (oldval), "m" (*a), "r" (a),
+ "0" (newval));
+ return result == oldval;
+}
+# else /* What's that */
+# error "Your system has an unsupported pointer size"
+# endif /* GLIB_SIZEOF_VOID_P */
+# define G_ATOMIC_MEMORY_BARRIER \
+ __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" \
+ " | #StoreLoad | #StoreStore" : : : "memory")
+
+# elif defined (G_ATOMIC_ALPHA)
+/* Adapted from CVS version 1.3 of glibc's sysdeps/alpha/bits/atomic.h
+ */
+# define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
+ ({ \
+ gint __result; \
+ gint __prev; \
+ __asm__ __volatile__ ( \
+ " mb\n" \
+ "1: ldl_l %0,%2\n" \
+ " cmpeq %0,%3,%1\n" \
+ " beq %1,2f\n" \
+ " mov %4,%1\n" \
+ " stl_c %1,%2\n" \
+ " beq %1,1b\n" \
+ " mb\n" \
+ "2:" \
+ : "=&r" (__prev), \
+ "=&r" (__result) \
+ : "m" (*(atomic)), \
+ "Ir" (oldval), \
+ "Ir" (newval) \
+ : "memory"); \
+ __result != 0; \
+ })
+# if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gint result;
+ gpointer prev;
+ __asm__ __volatile__ (
+ " mb\n"
+ "1: ldl_l %0,%2\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stl_c %1,%2\n"
+ " beq %1,1b\n"
+ " mb\n"
+ "2:"
+ : "=&r" (prev),
+ "=&r" (result)
+ : "m" (*atomic),
+ "Ir" (oldval),
+ "Ir" (newval)
+ : "memory");
+ return result != 0;
+}
+# elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gint result;
+ gpointer prev;
+ __asm__ __volatile__ (
+ " mb\n"
+ "1: ldq_l %0,%2\n"
+ " cmpeq %0,%3,%1\n"
+ " beq %1,2f\n"
+ " mov %4,%1\n"
+ " stq_c %1,%2\n"
+ " beq %1,1b\n"
+ " mb\n"
+ "2:"
+ : "=&r" (prev),
+ "=&r" (result)
+ : "m" (*atomic),
+ "Ir" (oldval),
+ "Ir" (newval)
+ : "memory");
+ return result != 0;
+}
+# else /* What's that */
+# error "Your system has an unsupported pointer size"
+# endif /* GLIB_SIZEOF_VOID_P */
+# define G_ATOMIC_MEMORY_BARRIER __asm__ ("mb" : : : "memory")
+# elif defined (G_ATOMIC_X86_64)
+/* Adapted from CVS version 1.9 of glibc's sysdeps/x86_64/bits/atomic.h
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+
+ __asm__ __volatile__ ("lock; xaddl %0,%1"
+ : "=r" (result), "=m" (*atomic)
+ : "0" (val), "m" (*atomic));
+ return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ __asm__ __volatile__ ("lock; addl %1,%0"
+ : "=m" (*atomic)
+ : "ir" (val), "m" (*atomic));
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ gint result;
+
+ __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+ : "=a" (result), "=m" (*atomic)
+ : "r" (newval), "m" (*atomic), "0" (oldval));
+
+ return result == oldval;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result;
+
+ __asm__ __volatile__ ("lock; cmpxchgq %q2, %1"
+ : "=a" (result), "=m" (*atomic)
+ : "r" (newval), "m" (*atomic), "0" (oldval));
+
+ return result == oldval;
+}
+
+# elif defined (G_ATOMIC_POWERPC)
+/* Adapted from CVS version 1.16 of glibc's sysdeps/powerpc/bits/atomic.h
+ * and CVS version 1.4 of glibc's sysdeps/powerpc/powerpc32/bits/atomic.h
+ * and CVS version 1.7 of glibc's sysdeps/powerpc/powerpc64/bits/atomic.h
+ */
+# ifdef __OPTIMIZE__
+/* Non-optimizing compile bails on the following two asm statements
+ * for reasons unknown to the author */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result, temp;
+#if ASM_NUMERIC_LABELS
+ __asm__ __volatile__ ("1: lwarx %0,0,%3\n"
+ " add %1,%0,%4\n"
+ " stwcx. %1,0,%3\n"
+ " bne- 1b"
+ : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+ : "b" (atomic), "r" (val), "m" (*atomic)
+ : "cr0", "memory");
+#else
+ __asm__ __volatile__ (".Lieaa%=: lwarx %0,0,%3\n"
+ " add %1,%0,%4\n"
+ " stwcx. %1,0,%3\n"
+ " bne- .Lieaa%="
+ : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+ : "b" (atomic), "r" (val), "m" (*atomic)
+ : "cr0", "memory");
+#endif
+ return result;
+}
+
+/* The same as above, to save a function call repeated here */
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result, temp;
+#if ASM_NUMERIC_LABELS
+ __asm__ __volatile__ ("1: lwarx %0,0,%3\n"
+ " add %1,%0,%4\n"
+ " stwcx. %1,0,%3\n"
+ " bne- 1b"
+ : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+ : "b" (atomic), "r" (val), "m" (*atomic)
+ : "cr0", "memory");
+#else
+ __asm__ __volatile__ (".Lia%=: lwarx %0,0,%3\n"
+ " add %1,%0,%4\n"
+ " stwcx. %1,0,%3\n"
+ " bne- .Lia%="
+ : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+ : "b" (atomic), "r" (val), "m" (*atomic)
+ : "cr0", "memory");
+#endif
+}
+# else /* !__OPTIMIZE__ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+ do
+ result = *atomic;
+ while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
+
+ return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+ do
+ result = *atomic;
+ while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
+}
+# endif /* !__OPTIMIZE__ */
+
+# if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ gint result;
+#if ASM_NUMERIC_LABELS
+ __asm__ __volatile__ ("sync\n"
+ "1: lwarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne 2f\n"
+ " stwcx. %3,0,%1\n"
+ " bne- 1b\n"
+ "2: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#else
+ __asm__ __volatile__ ("sync\n"
+ ".L1icae%=: lwarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne .L2icae%=\n"
+ " stwcx. %3,0,%1\n"
+ " bne- .L1icae%=\n"
+ ".L2icae%=: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#endif
+ return result == 0;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result;
+#if ASM_NUMERIC_LABELS
+ __asm__ __volatile__ ("sync\n"
+ "1: lwarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne 2f\n"
+ " stwcx. %3,0,%1\n"
+ " bne- 1b\n"
+ "2: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#else
+ __asm__ __volatile__ ("sync\n"
+ ".L1pcae%=: lwarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne .L2pcae%=\n"
+ " stwcx. %3,0,%1\n"
+ " bne- .L1pcae%=\n"
+ ".L2pcae%=: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#endif
+ return result == 0;
+}
+# elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ gpointer result;
+#if ASM_NUMERIC_LABELS
+ __asm__ __volatile__ ("sync\n"
+ "1: lwarx %0,0,%1\n"
+ " extsw %0,%0\n"
+ " subf. %0,%2,%0\n"
+ " bne 2f\n"
+ " stwcx. %3,0,%1\n"
+ " bne- 1b\n"
+ "2: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#else
+ __asm__ __volatile__ ("sync\n"
+ ".L1icae%=: lwarx %0,0,%1\n"
+ " extsw %0,%0\n"
+ " subf. %0,%2,%0\n"
+ " bne .L2icae%=\n"
+ " stwcx. %3,0,%1\n"
+ " bne- .L1icae%=\n"
+ ".L2icae%=: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#endif
+ return result == 0;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result;
+#if ASM_NUMERIC_LABELS
+ __asm__ __volatile__ ("sync\n"
+ "1: ldarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne 2f\n"
+ " stdcx. %3,0,%1\n"
+ " bne- 1b\n"
+ "2: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#else
+ __asm__ __volatile__ ("sync\n"
+ ".L1pcae%=: ldarx %0,0,%1\n"
+ " subf. %0,%2,%0\n"
+ " bne .L2pcae%=\n"
+ " stdcx. %3,0,%1\n"
+ " bne- .L1pcae%=\n"
+ ".L2pcae%=: isync"
+ : "=&r" (result)
+ : "b" (atomic), "r" (oldval), "r" (newval)
+ : "cr0", "memory");
+#endif
+ return result == 0;
+}
+# else /* What's that */
+# error "Your system has an unsupported pointer size"
+# endif /* GLIB_SIZEOF_VOID_P */
+
+# define G_ATOMIC_MEMORY_BARRIER __asm__ ("sync" : : : "memory")
+
+# elif defined (G_ATOMIC_IA64)
+/* Adapted from CVS version 1.8 of glibc's sysdeps/ia64/bits/atomic.h
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ return __sync_fetch_and_add (atomic, val);
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ __sync_fetch_and_add (atomic, val);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ return __sync_bool_compare_and_swap (atomic, oldval, newval);
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ return __sync_bool_compare_and_swap ((long *)atomic,
+ (long)oldval, (long)newval);
+}
+
+# define G_ATOMIC_MEMORY_BARRIER __sync_synchronize ()
+# elif defined (G_ATOMIC_S390)
+/* Adapted from glibc's sysdeps/s390/bits/atomic.h
+ */
+# define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
+ ({ \
+ gint __result = oldval; \
+ __asm__ __volatile__ ("cs %0, %2, %1" \
+ : "+d" (__result), "=Q" (*(atomic)) \
+ : "d" (newval), "m" (*(atomic)) : "cc" ); \
+ __result == oldval; \
+ })
+
+# if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result = oldval;
+ __asm__ __volatile__ ("cs %0, %2, %1"
+ : "+d" (result), "=Q" (*(atomic))
+ : "d" (newval), "m" (*(atomic)) : "cc" );
+ return result == oldval;
+}
+# elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gpointer result = oldval;
+ gpointer *a = atomic;
+ __asm__ __volatile__ ("csg %0, %2, %1"
+ : "+d" (result), "=Q" (*a)
+ : "d" ((long)(newval)), "m" (*a) : "cc" );
+ return result == oldval;
+}
+# else /* What's that */
+# error "Your system has an unsupported pointer size"
+# endif /* GLIB_SIZEOF_VOID_P */
+# elif defined (G_ATOMIC_ARM)
+static volatile int atomic_spin = 0;
+
+static int atomic_spin_trylock (void)
+{
+ int result;
+
+ asm volatile (
+ "swp %0, %1, [%2]\n"
+ : "=&r,&r" (result)
+ : "r,0" (1), "r,r" (&atomic_spin)
+ : "memory");
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+}
+
+static void atomic_spin_lock (void)
+{
+ while (atomic_spin_trylock())
+ sched_yield();
+}
+
+static void atomic_spin_unlock (void)
+{
+ atomic_spin = 0;
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+
+ atomic_spin_lock();
+ result = *atomic;
+ *atomic += val;
+ atomic_spin_unlock();
+
+ return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ atomic_spin_lock();
+ *atomic += val;
+ atomic_spin_unlock();
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ gboolean result;
+
+ atomic_spin_lock();
+ if (*atomic == oldval)
+ {
+ result = TRUE;
+ *atomic = newval;
+ }
+ else
+ result = FALSE;
+ atomic_spin_unlock();
+
+ return result;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gboolean result;
+
+ atomic_spin_lock();
+ if (*atomic == oldval)
+ {
+ result = TRUE;
+ *atomic = newval;
+ }
+ else
+ result = FALSE;
+ atomic_spin_unlock();
+
+ return result;
+}
+# elif defined (G_ATOMIC_CRIS) || defined (G_ATOMIC_CRISV32)
+# ifdef G_ATOMIC_CRIS
+# define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
+ ({ \
+ gboolean __result; \
+ __asm__ __volatile__ ("\n" \
+ "0:\tclearf\n\t" \
+ "cmp.d [%[Atomic]], %[OldVal]\n\t" \
+ "bne 1f\n\t" \
+ "ax\n\t" \
+ "move.d %[NewVal], [%[Atomic]]\n\t" \
+ "bwf 0b\n" \
+ "1:\tseq %[Result]" \
+ : [Result] "=&r" (__result), \
+ "=m" (*(atomic)) \
+ : [Atomic] "r" (atomic), \
+ [OldVal] "r" (oldval), \
+ [NewVal] "r" (newval), \
+ "g" (*(gpointer*) (atomic)) \
+ : "memory"); \
+ __result; \
+ })
+# else
+# define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
+ ({ \
+ gboolean __result; \
+ __asm__ __volatile__ ("\n" \
+ "0:\tclearf p\n\t" \
+ "cmp.d [%[Atomic]], %[OldVal]\n\t" \
+ "bne 1f\n\t" \
+ "ax\n\t" \
+ "move.d %[NewVal], [%[Atomic]]\n\t" \
+ "bcs 0b\n" \
+ "1:\tseq %[Result]" \
+ : [Result] "=&r" (__result), \
+ "=m" (*(atomic)) \
+ : [Atomic] "r" (atomic), \
+ [OldVal] "r" (oldval), \
+ [NewVal] "r" (newval), \
+ "g" (*(gpointer*) (atomic)) \
+ : "memory"); \
+ __result; \
+ })
+# endif
+
+#define CRIS_CACHELINE_SIZE 32
+#define CRIS_ATOMIC_BREAKS_CACHELINE(atomic) \
+ (((gulong)(atomic) & (CRIS_CACHELINE_SIZE - 1)) > (CRIS_CACHELINE_SIZE - sizeof (atomic)))
+
+gint __g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val);
+void __g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val);
+gboolean __g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval);
+gboolean __g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval);
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+ return __g_atomic_pointer_compare_and_exchange (atomic, oldval, newval);
+
+ return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+ return __g_atomic_int_compare_and_exchange (atomic, oldval, newval);
+
+ return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+
+ if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+ return __g_atomic_int_exchange_and_add (atomic, val);
+
+ do
+ result = *atomic;
+ while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+
+ return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+
+ if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+ return __g_atomic_int_add (atomic, val);
+
+ do
+ result = *atomic;
+ while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+}
+
+/* We need the atomic mutex for atomic operations where the atomic variable
+ * breaks the 32 byte cache line since the CRIS architecture does not support
+ * atomic operations on such variables. Fortunately this should be rare.
+ */
+# define DEFINE_WITH_MUTEXES
+# define g_atomic_int_exchange_and_add __g_atomic_int_exchange_and_add
+# define g_atomic_int_add __g_atomic_int_add
+# define g_atomic_int_compare_and_exchange __g_atomic_int_compare_and_exchange
+# define g_atomic_pointer_compare_and_exchange __g_atomic_pointer_compare_and_exchange
+
+# else /* !G_ATOMIC_* */
+# define DEFINE_WITH_MUTEXES
+# endif /* G_ATOMIC_* */
+#else /* !__GNUC__ */
+# ifdef G_PLATFORM_WIN32
+# define DEFINE_WITH_WIN32_INTERLOCKED
+# else
+# define DEFINE_WITH_MUTEXES
+# endif
+#endif /* __GNUC__ */
+
+#ifdef DEFINE_WITH_WIN32_INTERLOCKED
+# include
+/* Following indicates that InterlockedCompareExchangePointer is
+ * declared in winbase.h (included by windows.h) and needs to be
+ * commented out if not true. It is defined iff WINVER > 0x0400,
+ * which is usually correct but can be wrong if WINVER is set before
+ * windows.h is included.
+ */
+# if WINVER > 0x0400
+# define HAVE_INTERLOCKED_COMPARE_EXCHANGE_POINTER
+# endif
+
+gint32
+g_atomic_int_exchange_and_add (volatile gint32 G_GNUC_MAY_ALIAS *atomic,
+ gint32 val)
+{
+ return InterlockedExchangeAdd (atomic, val);
+}
+
+void
+g_atomic_int_add (volatile gint32 G_GNUC_MAY_ALIAS *atomic,
+ gint32 val)
+{
+ InterlockedExchangeAdd (atomic, val);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint32 G_GNUC_MAY_ALIAS *atomic,
+ gint32 oldval,
+ gint32 newval)
+{
+#ifndef HAVE_INTERLOCKED_COMPARE_EXCHANGE_POINTER
+ return (guint32) InterlockedCompareExchange ((PVOID*)atomic,
+ (PVOID)newval,
+ (PVOID)oldval) == oldval;
+#else
+ return InterlockedCompareExchange (atomic,
+ newval,
+ oldval) == oldval;
+#endif
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+# ifdef HAVE_INTERLOCKED_COMPARE_EXCHANGE_POINTER
+ return InterlockedCompareExchangePointer (atomic, newval, oldval) == oldval;
+# else
+# if GLIB_SIZEOF_VOID_P != 4 /* no 32-bit system */
+# error "InterlockedCompareExchangePointer needed"
+# else
+ return InterlockedCompareExchange (atomic, newval, oldval) == oldval;
+# endif
+# endif
+}
+#endif /* DEFINE_WITH_WIN32_INTERLOCKED */
+
+#ifdef DEFINE_WITH_MUTEXES
+/* We have to use the slow, but safe locking method */
+static GMutex *g_atomic_mutex;
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+
+ g_mutex_lock (g_atomic_mutex);
+ result = *atomic;
+ *atomic += val;
+ g_mutex_unlock (g_atomic_mutex);
+
+ return result;
+}
+
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ g_mutex_lock (g_atomic_mutex);
+ *atomic += val;
+ g_mutex_unlock (g_atomic_mutex);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ gboolean result;
+
+ g_mutex_lock (g_atomic_mutex);
+ if (*atomic == oldval)
+ {
+ result = TRUE;
+ *atomic = newval;
+ }
+ else
+ result = FALSE;
+ g_mutex_unlock (g_atomic_mutex);
+
+ return result;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval)
+{
+ gboolean result;
+
+ g_mutex_lock (g_atomic_mutex);
+ if (*atomic == oldval)
+ {
+ result = TRUE;
+ *atomic = newval;
+ }
+ else
+ result = FALSE;
+ g_mutex_unlock (g_atomic_mutex);
+
+ return result;
+}
+
+#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+ gint result;
+
+ g_mutex_lock (g_atomic_mutex);
+ result = *atomic;
+ g_mutex_unlock (g_atomic_mutex);
+
+ return result;
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint newval)
+{
+ g_mutex_lock (g_atomic_mutex);
+ *atomic = newval;
+ g_mutex_unlock (g_atomic_mutex);
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+ gpointer result;
+
+ g_mutex_lock (g_atomic_mutex);
+ result = *atomic;
+ g_mutex_unlock (g_atomic_mutex);
+
+ return result;
+}
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer newval)
+{
+ g_mutex_lock (g_atomic_mutex);
+ *atomic = newval;
+ g_mutex_unlock (g_atomic_mutex);
+}
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+#elif defined (G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+ G_ATOMIC_MEMORY_BARRIER;
+ return *atomic;
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint newval)
+{
+ *atomic = newval;
+ G_ATOMIC_MEMORY_BARRIER;
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+ G_ATOMIC_MEMORY_BARRIER;
+ return *atomic;
+}
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer newval)
+{
+ *atomic = newval;
+ G_ATOMIC_MEMORY_BARRIER;
+}
+#endif /* DEFINE_WITH_MUTEXES || G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+#ifdef ATOMIC_INT_CMP_XCHG
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval)
+{
+ return ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+ do
+ result = *atomic;
+ while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+
+ return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val)
+{
+ gint result;
+ do
+ result = *atomic;
+ while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+}
+#endif /* ATOMIC_INT_CMP_XCHG */
+
+void
+_g_atomic_thread_init (void)
+{
+#ifdef DEFINE_WITH_MUTEXES
+ g_atomic_mutex = g_mutex_new ();
+#endif /* DEFINE_WITH_MUTEXES */
+}
+
+#ifndef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+ return g_atomic_int_get (atomic);
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint newval)
+{
+ g_atomic_int_set (atomic, newval);
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+ return g_atomic_pointer_get (atomic);
+}
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer newval)
+{
+ g_atomic_pointer_set (atomic, newval);
+}
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+#define __G_ATOMIC_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gatomic.h b/desmume/src/windows/glib-2.20.1/build/glib/gatomic.h
new file mode 100644
index 000000000..7d9c318cc
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gatomic.h
@@ -0,0 +1,85 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * g_atomic_*: atomic operations.
+ * Copyright (C) 2003 Sebastian Wilhelmi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_ATOMIC_H__
+#define __G_ATOMIC_H__
+
+#include
+
+G_BEGIN_DECLS
+
+gint g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val);
+void g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint val);
+gboolean g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint oldval,
+ gint newval);
+gboolean g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer oldval,
+ gpointer newval);
+
+gint g_atomic_int_get (volatile gint G_GNUC_MAY_ALIAS *atomic);
+void g_atomic_int_set (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint newval);
+gpointer g_atomic_pointer_get (volatile gpointer G_GNUC_MAY_ALIAS *atomic);
+void g_atomic_pointer_set (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer newval);
+
+#ifndef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+# define g_atomic_int_get(atomic) ((gint)*(atomic))
+# define g_atomic_int_set(atomic, newval) ((void) (*(atomic) = (newval)))
+# define g_atomic_pointer_get(atomic) ((gpointer)*(atomic))
+# define g_atomic_pointer_set(atomic, newval) ((void) (*(atomic) = (newval)))
+#else
+# define g_atomic_int_get(atomic) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gint) ? 1 : -1]), \
+ (g_atomic_int_get) ((volatile gint G_GNUC_MAY_ALIAS *) (void *) (atomic)))
+# define g_atomic_int_set(atomic, newval) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gint) ? 1 : -1]), \
+ (g_atomic_int_set) ((volatile gint G_GNUC_MAY_ALIAS *) (void *) (atomic), (newval)))
+# define g_atomic_pointer_get(atomic) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gpointer) ? 1 : -1]), \
+ (g_atomic_pointer_get) ((volatile gpointer G_GNUC_MAY_ALIAS *) (void *) (atomic)))
+# define g_atomic_pointer_set(atomic, newval) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gpointer) ? 1 : -1]), \
+ (g_atomic_pointer_set) ((volatile gpointer G_GNUC_MAY_ALIAS *) (void *) (atomic), (newval)))
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+#define g_atomic_int_inc(atomic) (g_atomic_int_add ((atomic), 1))
+#define g_atomic_int_dec_and_test(atomic) \
+ (g_atomic_int_exchange_and_add ((atomic), -1) == 1)
+
+G_END_DECLS
+
+#endif /* __G_ATOMIC_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gbacktrace.c b/desmume/src/windows/glib-2.20.1/build/glib/gbacktrace.c
new file mode 100644
index 000000000..238d9cf97
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbacktrace.c
@@ -0,0 +1,308 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe ; except for g_on_error_stack_trace, but who wants thread safety
+ * then
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include "glib.h"
+#include "gprintfint.h"
+
+#ifdef HAVE_SYS_TIME_H
+#include
+#endif
+#ifdef HAVE_SYS_TIMES_H
+#include
+#endif
+#include
+#ifdef HAVE_SYS_WAIT_H
+#include
+#endif
+
+#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include
+#endif /* HAVE_SYS_SELECT_H */
+
+#include /* for bzero on BSD systems */
+
+#ifdef G_OS_WIN32
+# define STRICT /* Strict typing, please */
+# define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */
+# include
+# undef STRICT
+#endif
+
+#ifndef NO_FD_SET
+# define SELECT_MASK fd_set
+#else
+# if defined(_IBMR2)
+# define SELECT_MASK void
+# else
+# define SELECT_MASK int
+# endif
+#endif
+
+#include "galias.h"
+
+#ifndef G_OS_WIN32
+static void stack_trace (char **args);
+#endif
+
+extern volatile gboolean glib_on_error_halt;
+volatile gboolean glib_on_error_halt = TRUE;
+
+void
+g_on_error_query (const gchar *prg_name)
+{
+#ifndef G_OS_WIN32
+ static const gchar * const query1 = "[E]xit, [H]alt";
+ static const gchar * const query2 = ", show [S]tack trace";
+ static const gchar * const query3 = " or [P]roceed";
+ gchar buf[16];
+
+ if (!prg_name)
+ prg_name = g_get_prgname ();
+
+ retry:
+
+ if (prg_name)
+ _g_fprintf (stdout,
+ "%s (pid:%u): %s%s%s: ",
+ prg_name,
+ (guint) getpid (),
+ query1,
+ query2,
+ query3);
+ else
+ _g_fprintf (stdout,
+ "(process:%u): %s%s: ",
+ (guint) getpid (),
+ query1,
+ query3);
+ fflush (stdout);
+
+ if (isatty(0) && isatty(1))
+ fgets (buf, 8, stdin);
+ else
+ strcpy (buf, "E\n");
+
+ if ((buf[0] == 'E' || buf[0] == 'e')
+ && buf[1] == '\n')
+ _exit (0);
+ else if ((buf[0] == 'P' || buf[0] == 'p')
+ && buf[1] == '\n')
+ return;
+ else if (prg_name
+ && (buf[0] == 'S' || buf[0] == 's')
+ && buf[1] == '\n')
+ {
+ g_on_error_stack_trace (prg_name);
+ goto retry;
+ }
+ else if ((buf[0] == 'H' || buf[0] == 'h')
+ && buf[1] == '\n')
+ {
+ while (glib_on_error_halt)
+ ;
+ glib_on_error_halt = TRUE;
+ return;
+ }
+ else
+ goto retry;
+#else
+ if (!prg_name)
+ prg_name = g_get_prgname ();
+
+ MessageBox (NULL, "g_on_error_query called, program terminating",
+ (prg_name && *prg_name) ? prg_name : NULL,
+ MB_OK|MB_ICONERROR);
+ _exit(0);
+#endif
+}
+
+void
+g_on_error_stack_trace (const gchar *prg_name)
+{
+#if defined(G_OS_UNIX) || defined(G_OS_BEOS)
+ pid_t pid;
+ gchar buf[16];
+ gchar *args[4] = { "gdb", NULL, NULL, NULL };
+ int status;
+
+ if (!prg_name)
+ return;
+
+ _g_sprintf (buf, "%u", (guint) getpid ());
+
+ args[1] = (gchar*) prg_name;
+ args[2] = buf;
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ stack_trace (args);
+ _exit (0);
+ }
+ else if (pid == (pid_t) -1)
+ {
+ perror ("unable to fork gdb");
+ return;
+ }
+
+ waitpid (pid, &status, 0);
+#else
+ if (IsDebuggerPresent ())
+ G_BREAKPOINT ();
+ else
+ abort ();
+#endif
+}
+
+#ifndef G_OS_WIN32
+
+static gboolean stack_trace_done = FALSE;
+
+static void
+stack_trace_sigchld (int signum)
+{
+ stack_trace_done = TRUE;
+}
+
+static void
+stack_trace (char **args)
+{
+ pid_t pid;
+ int in_fd[2];
+ int out_fd[2];
+ SELECT_MASK fdset;
+ SELECT_MASK readset;
+ struct timeval tv;
+ int sel, idx, state;
+ char buffer[256];
+ char c;
+
+ stack_trace_done = FALSE;
+ signal (SIGCHLD, stack_trace_sigchld);
+
+ if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+ {
+ perror ("unable to open pipe");
+ _exit (0);
+ }
+
+ pid = fork ();
+ if (pid == 0)
+ {
+ close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
+ close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
+ close (2); dup (out_fd[1]); /* set the stderr to the out pipe */
+
+ execvp (args[0], args); /* exec gdb */
+ perror ("exec failed");
+ _exit (0);
+ }
+ else if (pid == (pid_t) -1)
+ {
+ perror ("unable to fork");
+ _exit (0);
+ }
+
+ FD_ZERO (&fdset);
+ FD_SET (out_fd[0], &fdset);
+
+ write (in_fd[1], "backtrace\n", 10);
+ write (in_fd[1], "p x = 0\n", 8);
+ write (in_fd[1], "quit\n", 5);
+
+ idx = 0;
+ state = 0;
+
+ while (1)
+ {
+ readset = fdset;
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
+ if (sel == -1)
+ break;
+
+ if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
+ {
+ if (read (out_fd[0], &c, 1))
+ {
+ switch (state)
+ {
+ case 0:
+ if (c == '#')
+ {
+ state = 1;
+ idx = 0;
+ buffer[idx++] = c;
+ }
+ break;
+ case 1:
+ buffer[idx++] = c;
+ if ((c == '\n') || (c == '\r'))
+ {
+ buffer[idx] = 0;
+ _g_fprintf (stdout, "%s", buffer);
+ state = 0;
+ idx = 0;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if (stack_trace_done)
+ break;
+ }
+
+ close (in_fd[0]);
+ close (in_fd[1]);
+ close (out_fd[0]);
+ close (out_fd[1]);
+ _exit (0);
+}
+
+#endif /* !G_OS_WIN32 */
+
+#define __G_BACKTRACE_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gbacktrace.h b/desmume/src/windows/glib-2.20.1/build/glib/gbacktrace.h
new file mode 100644
index 000000000..2e74b49a3
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbacktrace.h
@@ -0,0 +1,68 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_BACKTRACE_H__
+#define __G_BACKTRACE_H__
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+/* Fatal error handlers.
+ * g_on_error_query() will prompt the user to either
+ * [E]xit, [H]alt, [P]roceed or show [S]tack trace.
+ * g_on_error_stack_trace() invokes gdb, which attaches to the current
+ * process and shows a stack trace.
+ * These function may cause different actions on non-unix platforms.
+ * The prg_name arg is required by gdb to find the executable, if it is
+ * passed as NULL, g_on_error_query() will try g_get_prgname().
+ */
+void g_on_error_query (const gchar *prg_name);
+void g_on_error_stack_trace (const gchar *prg_name);
+
+/* Hacker macro to place breakpoints for selected machines.
+ * Actual use is strongly discouraged of course ;)
+ */
+#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/desmume/src/windows/glib-2.20.1/build/glib/gbase64.c b/desmume/src/windows/glib-2.20.1/build/glib/gbase64.c
new file mode 100644
index 000000000..bfdc76aa5
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbase64.c
@@ -0,0 +1,423 @@
+/* gbase64.c - Base64 encoding/decoding
+ *
+ * Copyright (C) 2006 Alexander Larsson
+ * Copyright (C) 2000-2003 Ximian Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * This is based on code in camel, written by:
+ * Michael Zucchi
+ * Jeffrey Stedfast
+ */
+
+#include "config.h"
+
+#include
+
+#include "gbase64.h"
+#include "glib.h"
+#include "glibintl.h"
+
+#include "galias.h"
+
+static const char base64_alphabet[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * g_base64_encode_step:
+ * @in: the binary data to encode
+ * @len: the length of @in
+ * @break_lines: whether to break long lines
+ * @out: pointer to destination buffer
+ * @state: Saved state between steps, initialize to 0
+ * @save: Saved state between steps, initialize to 0
+ *
+ * Incrementally encode a sequence of binary data into its Base-64 stringified
+ * representation. By calling this function multiple times you can convert
+ * data in chunks to avoid having to have the full encoded data in memory.
+ *
+ * When all of the data has been converted you must call
+ * g_base64_encode_close() to flush the saved state.
+ *
+ * The output buffer must be large enough to fit all the data that will
+ * be written to it. Due to the way base64 encodes you will need
+ * at least: (@len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of
+ * non-zero state). If you enable line-breaking you will need at least:
+ * ((@len / 3 + 1) * 4 + 4) / 72 + 1 bytes of extra space.
+ *
+ * @break_lines is typically used when putting base64-encoded data in emails.
+ * It breaks the lines at 72 columns instead of putting all of the text on
+ * the same line. This avoids problems with long lines in the email system.
+ *
+ * Return value: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ */
+gsize
+g_base64_encode_step (const guchar *in,
+ gsize len,
+ gboolean break_lines,
+ gchar *out,
+ gint *state,
+ gint *save)
+{
+ char *outptr;
+ const guchar *inptr;
+
+ g_return_val_if_fail (in != NULL, 0);
+ g_return_val_if_fail (out != NULL, 0);
+ g_return_val_if_fail (state != NULL, 0);
+ g_return_val_if_fail (save != NULL, 0);
+
+ if (len <= 0)
+ return 0;
+
+ inptr = in;
+ outptr = out;
+
+ if (len + ((char *) save) [0] > 2)
+ {
+ const guchar *inend = in+len-2;
+ int c1, c2, c3;
+ int already;
+
+ already = *state;
+
+ switch (((char *) save) [0])
+ {
+ case 1:
+ c1 = ((unsigned char *) save) [1];
+ goto skip1;
+ case 2:
+ c1 = ((unsigned char *) save) [1];
+ c2 = ((unsigned char *) save) [2];
+ goto skip2;
+ }
+
+ /*
+ * yes, we jump into the loop, no i'm not going to change it,
+ * it's beautiful!
+ */
+ while (inptr < inend)
+ {
+ c1 = *inptr++;
+ skip1:
+ c2 = *inptr++;
+ skip2:
+ c3 = *inptr++;
+ *outptr++ = base64_alphabet [ c1 >> 2 ];
+ *outptr++ = base64_alphabet [ c2 >> 4 |
+ ((c1&0x3) << 4) ];
+ *outptr++ = base64_alphabet [ ((c2 &0x0f) << 2) |
+ (c3 >> 6) ];
+ *outptr++ = base64_alphabet [ c3 & 0x3f ];
+ /* this is a bit ugly ... */
+ if (break_lines && (++already) >= 19)
+ {
+ *outptr++ = '\n';
+ already = 0;
+ }
+ }
+
+ ((char *)save)[0] = 0;
+ len = 2 - (inptr - inend);
+ *state = already;
+ }
+
+ if (len>0)
+ {
+ char *saveout;
+
+ /* points to the slot for the next char to save */
+ saveout = & (((char *)save)[1]) + ((char *)save)[0];
+
+ /* len can only be 0 1 or 2 */
+ switch(len)
+ {
+ case 2: *saveout++ = *inptr++;
+ case 1: *saveout++ = *inptr++;
+ }
+ ((char *)save)[0] += len;
+ }
+
+ return outptr - out;
+}
+
+/**
+ * g_base64_encode_close:
+ * @break_lines: whether to break long lines
+ * @out: pointer to destination buffer
+ * @state: Saved state from g_base64_encode_step()
+ * @save: Saved state from g_base64_encode_step()
+ *
+ * Flush the status from a sequence of calls to g_base64_encode_step().
+ *
+ * Return value: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ */
+gsize
+g_base64_encode_close (gboolean break_lines,
+ gchar *out,
+ gint *state,
+ gint *save)
+{
+ int c1, c2;
+ char *outptr = out;
+
+ g_return_val_if_fail (out != NULL, 0);
+ g_return_val_if_fail (state != NULL, 0);
+ g_return_val_if_fail (save != NULL, 0);
+
+ c1 = ((unsigned char *) save) [1];
+ c2 = ((unsigned char *) save) [2];
+
+ switch (((char *) save) [0])
+ {
+ case 2:
+ outptr [2] = base64_alphabet[ ( (c2 &0x0f) << 2 ) ];
+ g_assert (outptr [2] != 0);
+ goto skip;
+ case 1:
+ outptr[2] = '=';
+ skip:
+ outptr [0] = base64_alphabet [ c1 >> 2 ];
+ outptr [1] = base64_alphabet [ c2 >> 4 | ( (c1&0x3) << 4 )];
+ outptr [3] = '=';
+ outptr += 4;
+ break;
+ }
+ if (break_lines)
+ *outptr++ = '\n';
+
+ *save = 0;
+ *state = 0;
+
+ return outptr - out;
+}
+
+/**
+ * g_base64_encode:
+ * @data: the binary data to encode
+ * @len: the length of @data
+ *
+ * Encode a sequence of binary data into its Base-64 stringified
+ * representation.
+ *
+ * Return value: a newly allocated, zero-terminated Base-64 encoded
+ * string representing @data. The returned string must
+ * be freed with g_free().
+ *
+ * Since: 2.12
+ */
+gchar *
+g_base64_encode (const guchar *data,
+ gsize len)
+{
+ gchar *out;
+ gint state = 0, outlen;
+ gint save = 0;
+
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+
+ /* We can use a smaller limit here, since we know the saved state is 0,
+ +1 is needed for trailing \0, also check for unlikely integer overflow */
+ if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
+ g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
+ G_STRLOC, len);
+
+ out = g_malloc ((len / 3 + 1) * 4 + 1);
+
+ outlen = g_base64_encode_step (data, len, FALSE, out, &state, &save);
+ outlen += g_base64_encode_close (FALSE, out + outlen, &state, &save);
+ out[outlen] = '\0';
+
+ return (gchar *) out;
+}
+
+static const unsigned char mime_base64_rank[256] = {
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+
+/**
+ * g_base64_decode_step:
+ * @in: binary input data
+ * @len: max length of @in data to decode
+ * @out: output buffer
+ * @state: Saved state between steps, initialize to 0
+ * @save: Saved state between steps, initialize to 0
+ *
+ * Incrementally decode a sequence of binary data from its Base-64 stringified
+ * representation. By calling this function multiple times you can convert
+ * data in chunks to avoid having to have the full encoded data in memory.
+ *
+ * The output buffer must be large enough to fit all the data that will
+ * be written to it. Since base64 encodes 3 bytes in 4 chars you need
+ * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero
+ * state).
+ *
+ * Return value: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ **/
+gsize
+g_base64_decode_step (const gchar *in,
+ gsize len,
+ guchar *out,
+ gint *state,
+ guint *save)
+{
+ const guchar *inptr;
+ guchar *outptr;
+ const guchar *inend;
+ guchar c, rank;
+ guchar last[2];
+ unsigned int v;
+ int i;
+
+ g_return_val_if_fail (in != NULL, 0);
+ g_return_val_if_fail (out != NULL, 0);
+ g_return_val_if_fail (state != NULL, 0);
+ g_return_val_if_fail (save != NULL, 0);
+
+ if (len <= 0)
+ return 0;
+
+ inend = (const guchar *)in+len;
+ outptr = out;
+
+ /* convert 4 base64 bytes to 3 normal bytes */
+ v=*save;
+ i=*state;
+ inptr = (const guchar *)in;
+ last[0] = last[1] = 0;
+ while (inptr < inend)
+ {
+ c = *inptr++;
+ rank = mime_base64_rank [c];
+ if (rank != 0xff)
+ {
+ last[1] = last[0];
+ last[0] = c;
+ v = (v<<6) | rank;
+ i++;
+ if (i==4)
+ {
+ *outptr++ = v>>16;
+ if (last[1] != '=')
+ *outptr++ = v>>8;
+ if (last[0] != '=')
+ *outptr++ = v;
+ i=0;
+ }
+ }
+ }
+
+ *save = v;
+ *state = i;
+
+ return outptr - out;
+}
+
+/**
+ * g_base64_decode:
+ * @text: zero-terminated string with base64 text to decode
+ * @out_len: The length of the decoded data is written here
+ *
+ * Decode a sequence of Base-64 encoded text into binary data
+ *
+ * Return value: a newly allocated buffer containing the binary data
+ * that @text represents. The returned buffer must
+ * be freed with g_free().
+ *
+ * Since: 2.12
+ */
+guchar *
+g_base64_decode (const gchar *text,
+ gsize *out_len)
+{
+ guchar *ret;
+ gsize input_length;
+ gint state = 0;
+ guint save = 0;
+
+ g_return_val_if_fail (text != NULL, NULL);
+ g_return_val_if_fail (out_len != NULL, NULL);
+
+ input_length = strlen (text);
+
+ g_return_val_if_fail (input_length > 1, NULL);
+
+ /* We can use a smaller limit here, since we know the saved state is 0,
+ +1 used to avoid calling g_malloc0(0), and hence retruning NULL */
+ ret = g_malloc0 ((input_length / 4) * 3 + 1);
+
+ *out_len = g_base64_decode_step (text, input_length, ret, &state, &save);
+
+ return ret;
+}
+
+/**
+ * g_base64_decode_inplace:
+ * @text: zero-terminated string with base64 text to decode
+ * @out_len: The length of the decoded data is written here
+ *
+ * Decode a sequence of Base-64 encoded text into binary data
+ * by overwriting the input data.
+ *
+ * Return value: The binary data that @text responds. This pointer
+ * is the same as the input @text.
+ *
+ * Since: 2.20
+ */
+guchar *
+g_base64_decode_inplace (gchar *text,
+ gsize *out_len)
+{
+ gint input_length, state = 0;
+ guint save = 0;
+
+ g_return_val_if_fail (text != NULL, NULL);
+ g_return_val_if_fail (out_len != NULL, NULL);
+
+ input_length = strlen (text);
+
+ g_return_val_if_fail (input_length > 1, NULL);
+
+ *out_len = g_base64_decode_step (text, input_length, (guchar *) text, &state, &save);
+
+ return text;
+}
+
+
+#define __G_BASE64_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gbase64.h b/desmume/src/windows/glib-2.20.1/build/glib/gbase64.h
new file mode 100644
index 000000000..2f7c49fdd
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbase64.h
@@ -0,0 +1,57 @@
+/* gbase64.h - Base64 coding functions
+ *
+ * Copyright (C) 2005 Alexander Larsson
+ *
+ * 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.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_BASE64_H__
+#define __G_BASE64_H__
+
+#include
+
+G_BEGIN_DECLS
+
+gsize g_base64_encode_step (const guchar *in,
+ gsize len,
+ gboolean break_lines,
+ gchar *out,
+ gint *state,
+ gint *save);
+gsize g_base64_encode_close (gboolean break_lines,
+ gchar *out,
+ gint *state,
+ gint *save);
+gchar* g_base64_encode (const guchar *data,
+ gsize len) G_GNUC_MALLOC;
+gsize g_base64_decode_step (const gchar *in,
+ gsize len,
+ guchar *out,
+ gint *state,
+ guint *save);
+guchar *g_base64_decode (const gchar *text,
+ gsize *out_len) G_GNUC_MALLOC;
+guchar *g_base64_decode_inplace (gchar *text,
+ gsize *out_len);
+
+
+G_END_DECLS
+
+#endif /* __G_BASE64_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gbookmarkfile.c b/desmume/src/windows/glib-2.20.1/build/glib/gbookmarkfile.c
new file mode 100644
index 000000000..01c7e639e
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbookmarkfile.c
@@ -0,0 +1,3709 @@
+/* gbookmarkfile.c: parsing and building desktop bookmarks
+ *
+ * Copyright (C) 2005-2006 Emmanuele Bassi
+ *
+ * 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,
+ */
+
+#include "config.h"
+
+#include "gbookmarkfile.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+
+#include "gconvert.h"
+#include "gdataset.h"
+#include "gerror.h"
+#include "gfileutils.h"
+#include "ghash.h"
+#include "glibintl.h"
+#include "glist.h"
+#include "gslist.h"
+#include "gmain.h"
+#include "gmarkup.h"
+#include "gmem.h"
+#include "gmessages.h"
+#include "gshell.h"
+#include "gslice.h"
+#include "gstdio.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gtimer.h"
+#include "gutils.h"
+
+#include "galias.h"
+
+/* XBEL 1.0 standard entities */
+#define XBEL_VERSION "1.0"
+#define XBEL_DTD_NICK "xbel"
+#define XBEL_DTD_SYSTEM "+//IDN python.org//DTD XML Bookmark " \
+ "Exchange Language 1.0//EN//XML"
+
+#define XBEL_DTD_URI "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"
+
+#define XBEL_ROOT_ELEMENT "xbel"
+#define XBEL_FOLDER_ELEMENT "folder" /* unused */
+#define XBEL_BOOKMARK_ELEMENT "bookmark"
+#define XBEL_ALIAS_ELEMENT "alias" /* unused */
+#define XBEL_SEPARATOR_ELEMENT "separator" /* unused */
+#define XBEL_TITLE_ELEMENT "title"
+#define XBEL_DESC_ELEMENT "desc"
+#define XBEL_INFO_ELEMENT "info"
+#define XBEL_METADATA_ELEMENT "metadata"
+
+#define XBEL_VERSION_ATTRIBUTE "version"
+#define XBEL_FOLDED_ATTRIBUTE "folded" /* unused */
+#define XBEL_OWNER_ATTRIBUTE "owner"
+#define XBEL_ADDED_ATTRIBUTE "added"
+#define XBEL_VISITED_ATTRIBUTE "visited"
+#define XBEL_MODIFIED_ATTRIBUTE "modified"
+#define XBEL_ID_ATTRIBUTE "id"
+#define XBEL_HREF_ATTRIBUTE "href"
+#define XBEL_REF_ATTRIBUTE "ref" /* unused */
+
+#define XBEL_YES_VALUE "yes"
+#define XBEL_NO_VALUE "no"
+
+/* Desktop bookmark spec entities */
+#define BOOKMARK_METADATA_OWNER "http://freedesktop.org"
+
+#define BOOKMARK_NAMESPACE_NAME "bookmark"
+#define BOOKMARK_NAMESPACE_URI "http://www.freedesktop.org/standards/desktop-bookmarks"
+
+#define BOOKMARK_GROUPS_ELEMENT "groups"
+#define BOOKMARK_GROUP_ELEMENT "group"
+#define BOOKMARK_APPLICATIONS_ELEMENT "applications"
+#define BOOKMARK_APPLICATION_ELEMENT "application"
+#define BOOKMARK_ICON_ELEMENT "icon"
+#define BOOKMARK_PRIVATE_ELEMENT "private"
+
+#define BOOKMARK_NAME_ATTRIBUTE "name"
+#define BOOKMARK_EXEC_ATTRIBUTE "exec"
+#define BOOKMARK_COUNT_ATTRIBUTE "count"
+#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp" /* deprecated by "modified" */
+#define BOOKMARK_MODIFIED_ATTRIBUTE "modified"
+#define BOOKMARK_HREF_ATTRIBUTE "href"
+#define BOOKMARK_TYPE_ATTRIBUTE "type"
+
+/* Shared MIME Info entities */
+#define MIME_NAMESPACE_NAME "mime"
+#define MIME_NAMESPACE_URI "http://www.freedesktop.org/standards/shared-mime-info"
+#define MIME_TYPE_ELEMENT "mime-type"
+#define MIME_TYPE_ATTRIBUTE "type"
+
+
+typedef struct _BookmarkAppInfo BookmarkAppInfo;
+typedef struct _BookmarkMetadata BookmarkMetadata;
+typedef struct _BookmarkItem BookmarkItem;
+typedef struct _ParseData ParseData;
+
+struct _BookmarkAppInfo
+{
+ gchar *name;
+ gchar *exec;
+
+ guint count;
+
+ time_t stamp;
+};
+
+struct _BookmarkMetadata
+{
+ gchar *mime_type;
+
+ GList *groups;
+
+ GList *applications;
+ GHashTable *apps_by_name;
+
+ gchar *icon_href;
+ gchar *icon_mime;
+
+ guint is_private : 1;
+};
+
+struct _BookmarkItem
+{
+ gchar *uri;
+
+ gchar *title;
+ gchar *description;
+
+ time_t added;
+ time_t modified;
+ time_t visited;
+
+ BookmarkMetadata *metadata;
+};
+
+struct _GBookmarkFile
+{
+ gchar *title;
+ gchar *description;
+
+ /* we store our items in a list and keep a copy inside
+ * an hash table for faster lookup performances
+ */
+ GList *items;
+ GHashTable *items_by_uri;
+};
+
+/* parser state machine */
+enum
+{
+ STATE_STARTED = 0,
+
+ STATE_ROOT,
+ STATE_BOOKMARK,
+ STATE_TITLE,
+ STATE_DESC,
+ STATE_INFO,
+ STATE_METADATA,
+ STATE_APPLICATIONS,
+ STATE_APPLICATION,
+ STATE_GROUPS,
+ STATE_GROUP,
+ STATE_MIME,
+ STATE_ICON,
+
+ STATE_FINISHED
+};
+
+static void g_bookmark_file_init (GBookmarkFile *bookmark);
+static void g_bookmark_file_clear (GBookmarkFile *bookmark);
+static gboolean g_bookmark_file_parse (GBookmarkFile *bookmark,
+ const gchar *buffer,
+ gsize length,
+ GError **error);
+static gchar * g_bookmark_file_dump (GBookmarkFile *bookmark,
+ gsize *length,
+ GError **error);
+static BookmarkItem *g_bookmark_file_lookup_item (GBookmarkFile *bookmark,
+ const gchar *uri);
+static void g_bookmark_file_add_item (GBookmarkFile *bookmark,
+ BookmarkItem *item,
+ GError **error);
+
+static time_t timestamp_from_iso8601 (const gchar *iso_date);
+static gchar * timestamp_to_iso8601 (time_t timestamp);
+
+/********************************
+ * BookmarkAppInfo *
+ * *
+ * Application metadata storage *
+ ********************************/
+static BookmarkAppInfo *
+bookmark_app_info_new (const gchar *name)
+{
+ BookmarkAppInfo *retval;
+
+ g_warn_if_fail (name != NULL);
+
+ retval = g_slice_new (BookmarkAppInfo);
+
+ retval->name = g_strdup (name);
+ retval->exec = NULL;
+ retval->count = 0;
+ retval->stamp = 0;
+
+ return retval;
+}
+
+static void
+bookmark_app_info_free (BookmarkAppInfo *app_info)
+{
+ if (!app_info)
+ return;
+
+ g_free (app_info->name);
+ g_free (app_info->exec);
+
+ g_slice_free (BookmarkAppInfo, app_info);
+}
+
+static gchar *
+bookmark_app_info_dump (BookmarkAppInfo *app_info)
+{
+ gchar *retval;
+ gchar *name, *exec, *modified, *count;
+
+ g_warn_if_fail (app_info != NULL);
+
+ if (app_info->count == 0)
+ return NULL;
+
+ name = g_markup_escape_text (app_info->name, -1);
+ exec = g_markup_escape_text (app_info->exec, -1);
+ modified = timestamp_to_iso8601 (app_info->stamp);
+ count = g_strdup_printf ("%u", app_info->count);
+
+ retval = g_strconcat (" "
+ "<" BOOKMARK_NAMESPACE_NAME ":" BOOKMARK_APPLICATION_ELEMENT
+ " " BOOKMARK_NAME_ATTRIBUTE "=\"", name, "\""
+ " " BOOKMARK_EXEC_ATTRIBUTE "=\"", exec, "\""
+ " " BOOKMARK_MODIFIED_ATTRIBUTE "=\"", modified, "\""
+ " " BOOKMARK_COUNT_ATTRIBUTE "=\"", count, "\"/>\n",
+ NULL);
+
+ g_free (name);
+ g_free (exec);
+ g_free (modified);
+ g_free (count);
+
+ return retval;
+}
+
+
+/***********************
+ * BookmarkMetadata *
+ * *
+ * Metadata storage *
+ ***********************/
+static BookmarkMetadata *
+bookmark_metadata_new (void)
+{
+ BookmarkMetadata *retval;
+
+ retval = g_slice_new (BookmarkMetadata);
+
+ retval->mime_type = NULL;
+
+ retval->groups = NULL;
+
+ retval->applications = NULL;
+ retval->apps_by_name = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ NULL);
+
+ retval->is_private = FALSE;
+
+ retval->icon_href = NULL;
+ retval->icon_mime = NULL;
+
+ return retval;
+}
+
+static void
+bookmark_metadata_free (BookmarkMetadata *metadata)
+{
+ if (!metadata)
+ return;
+
+ g_free (metadata->mime_type);
+
+ if (metadata->groups)
+ {
+ g_list_foreach (metadata->groups,
+ (GFunc) g_free,
+ NULL);
+ g_list_free (metadata->groups);
+ }
+
+ if (metadata->applications)
+ {
+ g_list_foreach (metadata->applications,
+ (GFunc) bookmark_app_info_free,
+ NULL);
+ g_list_free (metadata->applications);
+ }
+
+ g_hash_table_destroy (metadata->apps_by_name);
+
+ g_free (metadata->icon_href);
+ g_free (metadata->icon_mime);
+
+ g_slice_free (BookmarkMetadata, metadata);
+}
+
+static gchar *
+bookmark_metadata_dump (BookmarkMetadata *metadata)
+{
+ GString *retval;
+ gchar *buffer;
+
+ if (!metadata->applications)
+ return NULL;
+
+ retval = g_string_sized_new (1024);
+
+ /* metadata container */
+ g_string_append (retval,
+ " "
+ "<" XBEL_METADATA_ELEMENT
+ " " XBEL_OWNER_ATTRIBUTE "=\"" BOOKMARK_METADATA_OWNER
+ "\">\n");
+
+ /* mime type */
+ if (metadata->mime_type) {
+ buffer = g_strconcat (" "
+ "<" MIME_NAMESPACE_NAME ":" MIME_TYPE_ELEMENT " "
+ MIME_TYPE_ATTRIBUTE "=\"", metadata->mime_type, "\"/>\n",
+ NULL);
+ g_string_append (retval, buffer);
+ g_free (buffer);
+ }
+
+ if (metadata->groups)
+ {
+ GList *l;
+
+ /* open groups container */
+ g_string_append (retval,
+ " "
+ "<" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_GROUPS_ELEMENT ">\n");
+
+ for (l = g_list_last (metadata->groups); l != NULL; l = l->prev)
+ {
+ gchar *group_name;
+
+ group_name = g_markup_escape_text ((gchar *) l->data, -1);
+ buffer = g_strconcat (" "
+ "<" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_GROUP_ELEMENT ">",
+ group_name,
+ "" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_GROUP_ELEMENT ">\n", NULL);
+ g_string_append (retval, buffer);
+
+ g_free (buffer);
+ g_free (group_name);
+ }
+
+ /* close groups container */
+ g_string_append (retval,
+ " "
+ "" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_GROUPS_ELEMENT ">\n");
+ }
+
+ if (metadata->applications)
+ {
+ GList *l;
+
+ /* open applications container */
+ g_string_append (retval,
+ " "
+ "<" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n");
+
+ for (l = g_list_last (metadata->applications); l != NULL; l = l->prev)
+ {
+ BookmarkAppInfo *app_info = (BookmarkAppInfo *) l->data;
+ gchar *app_data;
+
+ g_warn_if_fail (app_info != NULL);
+
+ app_data = bookmark_app_info_dump (app_info);
+
+ if (app_data)
+ {
+ retval = g_string_append (retval, app_data);
+
+ g_free (app_data);
+ }
+ }
+
+ /* close applications container */
+ g_string_append (retval,
+ " "
+ "" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n");
+ }
+
+ /* icon */
+ if (metadata->icon_href)
+ {
+ if (!metadata->icon_mime)
+ metadata->icon_mime = g_strdup ("application/octet-stream");
+
+ buffer = g_strconcat (" "
+ "<" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_ICON_ELEMENT
+ " " BOOKMARK_HREF_ATTRIBUTE "=\"", metadata->icon_href,
+ "\" " BOOKMARK_TYPE_ATTRIBUTE "=\"", metadata->icon_mime, "\"/>\n", NULL);
+ g_string_append (retval, buffer);
+
+ g_free (buffer);
+ }
+
+ /* private hint */
+ if (metadata->is_private)
+ g_string_append (retval,
+ " "
+ "<" BOOKMARK_NAMESPACE_NAME
+ ":" BOOKMARK_PRIVATE_ELEMENT "/>\n");
+
+ /* close metadata container */
+ g_string_append (retval,
+ " "
+ "" XBEL_METADATA_ELEMENT ">\n");
+
+ return g_string_free (retval, FALSE);
+}
+
+/******************************************************
+ * BookmarkItem *
+ * *
+ * Storage for a single bookmark item inside the list *
+ ******************************************************/
+static BookmarkItem *
+bookmark_item_new (const gchar *uri)
+{
+ BookmarkItem *item;
+
+ g_warn_if_fail (uri != NULL);
+
+ item = g_slice_new (BookmarkItem);
+ item->uri = g_strdup (uri);
+
+ item->title = NULL;
+ item->description = NULL;
+
+ item->added = (time_t) -1;
+ item->modified = (time_t) -1;
+ item->visited = (time_t) -1;
+
+ item->metadata = NULL;
+
+ return item;
+}
+
+static void
+bookmark_item_free (BookmarkItem *item)
+{
+ if (!item)
+ return;
+
+ g_free (item->uri);
+ g_free (item->title);
+ g_free (item->description);
+
+ if (item->metadata)
+ bookmark_metadata_free (item->metadata);
+
+ g_slice_free (BookmarkItem, item);
+}
+
+static gchar *
+bookmark_item_dump (BookmarkItem *item)
+{
+ GString *retval;
+ gchar *added, *visited, *modified;
+ gchar *escaped_uri;
+ gchar *buffer;
+
+ /* at this point, we must have at least a registered application; if we don't
+ * we don't screw up the bookmark file, and just skip this item
+ */
+ if (!item->metadata || !item->metadata->applications)
+ {
+ g_warning ("Item for URI '%s' has no registered applications: skipping.\n", item->uri);
+ return NULL;
+ }
+
+ retval = g_string_sized_new (4096);
+
+ added = timestamp_to_iso8601 (item->added);
+ modified = timestamp_to_iso8601 (item->modified);
+ visited = timestamp_to_iso8601 (item->visited);
+
+ escaped_uri = g_markup_escape_text (item->uri, -1);
+
+ buffer = g_strconcat (" <"
+ XBEL_BOOKMARK_ELEMENT
+ " "
+ XBEL_HREF_ATTRIBUTE "=\"", escaped_uri, "\" "
+ XBEL_ADDED_ATTRIBUTE "=\"", added, "\" "
+ XBEL_MODIFIED_ATTRIBUTE "=\"", modified, "\" "
+ XBEL_VISITED_ATTRIBUTE "=\"", visited, "\">\n",
+ NULL);
+
+ g_string_append (retval, buffer);
+
+ g_free (escaped_uri);
+ g_free (visited);
+ g_free (modified);
+ g_free (added);
+ g_free (buffer);
+
+ if (item->title)
+ {
+ gchar *escaped_title;
+
+ escaped_title = g_markup_escape_text (item->title, -1);
+ buffer = g_strconcat (" "
+ "<" XBEL_TITLE_ELEMENT ">",
+ escaped_title,
+ "" XBEL_TITLE_ELEMENT ">\n",
+ NULL);
+ g_string_append (retval, buffer);
+
+ g_free (escaped_title);
+ g_free (buffer);
+ }
+
+ if (item->description)
+ {
+ gchar *escaped_desc;
+
+ escaped_desc = g_markup_escape_text (item->description, -1);
+ buffer = g_strconcat (" "
+ "<" XBEL_DESC_ELEMENT ">",
+ escaped_desc,
+ "" XBEL_DESC_ELEMENT ">\n",
+ NULL);
+ g_string_append (retval, buffer);
+
+ g_free (escaped_desc);
+ g_free (buffer);
+ }
+
+ if (item->metadata)
+ {
+ gchar *metadata;
+
+ metadata = bookmark_metadata_dump (item->metadata);
+ if (metadata)
+ {
+ buffer = g_strconcat (" "
+ "<" XBEL_INFO_ELEMENT ">\n",
+ metadata,
+ " "
+ "" XBEL_INFO_ELEMENT ">\n",
+ NULL);
+ retval = g_string_append (retval, buffer);
+
+ g_free (buffer);
+ g_free (metadata);
+ }
+ }
+
+ g_string_append (retval, " " XBEL_BOOKMARK_ELEMENT ">\n");
+
+ return g_string_free (retval, FALSE);
+}
+
+static BookmarkAppInfo *
+bookmark_item_lookup_app_info (BookmarkItem *item,
+ const gchar *app_name)
+{
+ g_warn_if_fail (item != NULL && app_name != NULL);
+
+ if (!item->metadata)
+ return NULL;
+
+ return g_hash_table_lookup (item->metadata->apps_by_name, app_name);
+}
+
+/*************************
+ * GBookmarkFile *
+ *************************/
+
+static void
+g_bookmark_file_init (GBookmarkFile *bookmark)
+{
+ bookmark->title = NULL;
+ bookmark->description = NULL;
+
+ bookmark->items = NULL;
+ bookmark->items_by_uri = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ NULL);
+}
+
+static void
+g_bookmark_file_clear (GBookmarkFile *bookmark)
+{
+ g_free (bookmark->title);
+ g_free (bookmark->description);
+
+ if (bookmark->items)
+ {
+ g_list_foreach (bookmark->items,
+ (GFunc) bookmark_item_free,
+ NULL);
+ g_list_free (bookmark->items);
+
+ bookmark->items = NULL;
+ }
+
+ if (bookmark->items_by_uri)
+ {
+ g_hash_table_destroy (bookmark->items_by_uri);
+
+ bookmark->items_by_uri = NULL;
+ }
+}
+
+struct _ParseData
+{
+ gint state;
+
+ GHashTable *namespaces;
+
+ GBookmarkFile *bookmark_file;
+ BookmarkItem *current_item;
+};
+
+static ParseData *
+parse_data_new (void)
+{
+ ParseData *retval;
+
+ retval = g_new (ParseData, 1);
+
+ retval->state = STATE_STARTED;
+ retval->namespaces = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
+ retval->bookmark_file = NULL;
+ retval->current_item = NULL;
+
+ return retval;
+}
+
+static void
+parse_data_free (ParseData *parse_data)
+{
+ g_hash_table_destroy (parse_data->namespaces);
+
+ g_free (parse_data);
+}
+
+#define IS_ATTRIBUTE(s,a) ((0 == strcmp ((s), (a))))
+
+static void
+parse_bookmark_element (GMarkupParseContext *context,
+ ParseData *parse_data,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ GError **error)
+{
+ const gchar *uri, *added, *modified, *visited;
+ const gchar *attr;
+ gint i;
+ BookmarkItem *item;
+ GError *add_error;
+
+ g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_BOOKMARK));
+
+ i = 0;
+ uri = added = modified = visited = NULL;
+ for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+ {
+ if (IS_ATTRIBUTE (attr, XBEL_HREF_ATTRIBUTE))
+ uri = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, XBEL_ADDED_ATTRIBUTE))
+ added = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, XBEL_MODIFIED_ATTRIBUTE))
+ modified = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, XBEL_VISITED_ATTRIBUTE))
+ visited = attribute_values[i];
+ else
+ {
+ /* bookmark is defined by the XBEL spec, so we need
+ * to error out if the element has different or
+ * missing attributes
+ */
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+ _("Unexpected attribute '%s' for element '%s'"),
+ attr,
+ XBEL_BOOKMARK_ELEMENT);
+ return;
+ }
+ }
+
+ if (!uri)
+ {
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Attribute '%s' of element '%s' not found"),
+ XBEL_HREF_ATTRIBUTE,
+ XBEL_BOOKMARK_ELEMENT);
+ return;
+ }
+
+ g_warn_if_fail (parse_data->current_item == NULL);
+
+ item = bookmark_item_new (uri);
+
+ if (added)
+ item->added = timestamp_from_iso8601 (added);
+
+ if (modified)
+ item->modified = timestamp_from_iso8601 (modified);
+
+ if (visited)
+ item->visited = timestamp_from_iso8601 (visited);
+
+ add_error = NULL;
+ g_bookmark_file_add_item (parse_data->bookmark_file,
+ item,
+ &add_error);
+ if (add_error)
+ {
+ bookmark_item_free (item);
+
+ g_propagate_error (error, add_error);
+
+ return;
+ }
+
+ parse_data->current_item = item;
+}
+
+static void
+parse_application_element (GMarkupParseContext *context,
+ ParseData *parse_data,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ GError **error)
+{
+ const gchar *name, *exec, *count, *stamp, *modified;
+ const gchar *attr;
+ gint i;
+ BookmarkItem *item;
+ BookmarkAppInfo *ai;
+
+ g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION));
+
+ i = 0;
+ name = exec = count = stamp = modified = NULL;
+ for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+ {
+ if (IS_ATTRIBUTE (attr, BOOKMARK_NAME_ATTRIBUTE))
+ name = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, BOOKMARK_EXEC_ATTRIBUTE))
+ exec = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, BOOKMARK_COUNT_ATTRIBUTE))
+ count = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, BOOKMARK_TIMESTAMP_ATTRIBUTE))
+ stamp = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, BOOKMARK_MODIFIED_ATTRIBUTE))
+ modified = attribute_values[i];
+ }
+
+ /* the "name" and "exec" attributes are mandatory */
+ if (!name)
+ {
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Attribute '%s' of element '%s' not found"),
+ BOOKMARK_NAME_ATTRIBUTE,
+ BOOKMARK_APPLICATION_ELEMENT);
+ return;
+ }
+
+ if (!exec)
+ {
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Attribute '%s' of element '%s' not found"),
+ BOOKMARK_EXEC_ATTRIBUTE,
+ BOOKMARK_APPLICATION_ELEMENT);
+ return;
+ }
+
+ g_warn_if_fail (parse_data->current_item != NULL);
+ item = parse_data->current_item;
+
+ ai = bookmark_item_lookup_app_info (item, name);
+ if (!ai)
+ {
+ ai = bookmark_app_info_new (name);
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ item->metadata->applications = g_list_prepend (item->metadata->applications, ai);
+ g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai);
+ }
+
+ ai->exec = g_strdup (exec);
+
+ if (count)
+ ai->count = atoi (count);
+ else
+ ai->count = 1;
+
+ if (modified)
+ ai->stamp = timestamp_from_iso8601 (modified);
+ else
+ {
+ /* the timestamp attribute has been deprecated but we still parse
+ * it for backward compatibility
+ */
+ if (stamp)
+ ai->stamp = (time_t) atol (stamp);
+ else
+ ai->stamp = time (NULL);
+ }
+}
+
+static void
+parse_mime_type_element (GMarkupParseContext *context,
+ ParseData *parse_data,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ GError **error)
+{
+ const gchar *type;
+ const gchar *attr;
+ gint i;
+ BookmarkItem *item;
+
+ g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_MIME));
+
+ i = 0;
+ type = NULL;
+ for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+ {
+ if (IS_ATTRIBUTE (attr, MIME_TYPE_ATTRIBUTE))
+ type = attribute_values[i];
+ }
+
+ if (!type)
+ type = "application/octet-stream";
+
+ g_warn_if_fail (parse_data->current_item != NULL);
+ item = parse_data->current_item;
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ item->metadata->mime_type = g_strdup (type);
+}
+
+static void
+parse_icon_element (GMarkupParseContext *context,
+ ParseData *parse_data,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ GError **error)
+{
+ const gchar *href;
+ const gchar *type;
+ const gchar *attr;
+ gint i;
+ BookmarkItem *item;
+
+ g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_ICON));
+
+ i = 0;
+ href = NULL;
+ type = NULL;
+ for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+ {
+ if (IS_ATTRIBUTE (attr, BOOKMARK_HREF_ATTRIBUTE))
+ href = attribute_values[i];
+ else if (IS_ATTRIBUTE (attr, BOOKMARK_TYPE_ATTRIBUTE))
+ type = attribute_values[i];
+ }
+
+ /* the "href" attribute is mandatory */
+ if (!href)
+ {
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Attribute '%s' of element '%s' not found"),
+ BOOKMARK_HREF_ATTRIBUTE,
+ BOOKMARK_ICON_ELEMENT);
+ return;
+ }
+
+ if (!type)
+ type = "application/octet-stream";
+
+ g_warn_if_fail (parse_data->current_item != NULL);
+ item = parse_data->current_item;
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ item->metadata->icon_href = g_strdup (href);
+ item->metadata->icon_mime = g_strdup (type);
+}
+
+/* scans through the attributes of an element for the "xmlns" pragma, and
+ * adds any resulting namespace declaration to a per-parser hashtable, using
+ * the namespace name as a key for the namespace URI; if no key was found,
+ * the namespace is considered as default, and stored under the "default" key.
+ *
+ * FIXME: this works on the assumption that the generator of the XBEL file
+ * is either this code or is smart enough to place the namespace declarations
+ * inside the main root node or inside the metadata node and does not redefine
+ * a namespace inside an inner node; this does *not* conform to the
+ * XML-NS standard, although is a close approximation. In order to make this
+ * conformant to the XML-NS specification we should use a per-element
+ * namespace table inside GMarkup and ask it to resolve the namespaces for us.
+ */
+static void
+map_namespace_to_name (ParseData *parse_data,
+ const gchar **attribute_names,
+ const gchar **attribute_values)
+{
+ const gchar *attr;
+ gint i;
+
+ g_warn_if_fail (parse_data != NULL);
+
+ if (!attribute_names || !attribute_names[0])
+ return;
+
+ i = 0;
+ for (attr = attribute_names[i]; attr; attr = attribute_names[++i])
+ {
+ if (g_str_has_prefix (attr, "xmlns"))
+ {
+ gchar *namespace_name, *namespace_uri;
+ gchar *p;
+
+ p = g_utf8_strchr (attr, -1, ':');
+ if (p)
+ p = g_utf8_next_char (p);
+ else
+ p = "default";
+
+ namespace_name = g_strdup (p);
+ namespace_uri = g_strdup (attribute_values[i]);
+
+ g_hash_table_replace (parse_data->namespaces,
+ namespace_name,
+ namespace_uri);
+ }
+ }
+}
+
+/* checks whether @element_full is equal to @element.
+ *
+ * if @namespace is set, it tries to resolve the namespace to a known URI,
+ * and if found is prepended to the element name, from which is separated
+ * using the character specified in the @sep parameter.
+ */
+static gboolean
+is_element_full (ParseData *parse_data,
+ const gchar *element_full,
+ const gchar *namespace,
+ const gchar *element,
+ const gchar sep)
+{
+ gchar *ns_uri, *ns_name;
+ const gchar *p, *element_name;
+ gboolean retval;
+
+ g_warn_if_fail (parse_data != NULL);
+ g_warn_if_fail (element_full != NULL);
+
+ if (!element)
+ return FALSE;
+
+ /* no namespace requested: dumb element compare */
+ if (!namespace)
+ return (0 == strcmp (element_full, element));
+
+ /* search for namespace separator; if none found, assume we are under the
+ * default namespace, and set ns_name to our "default" marker; if no default
+ * namespace has been set, just do a plain comparison between @full_element
+ * and @element.
+ */
+ p = g_utf8_strchr (element_full, -1, ':');
+ if (p)
+ {
+ ns_name = g_strndup (element_full, p - element_full);
+ element_name = g_utf8_next_char (p);
+ }
+ else
+ {
+ ns_name = g_strdup ("default");
+ element_name = element_full;
+ }
+
+ ns_uri = g_hash_table_lookup (parse_data->namespaces, ns_name);
+ if (!ns_uri)
+ {
+ /* no default namespace found */
+ g_free (ns_name);
+
+ return (0 == strcmp (element_full, element));
+ }
+
+ retval = (0 == strcmp (ns_uri, namespace) &&
+ 0 == strcmp (element_name, element));
+
+ g_free (ns_name);
+
+ return retval;
+}
+
+#define IS_ELEMENT(p,s,e) (is_element_full ((p), (s), NULL, (e), '\0'))
+#define IS_ELEMENT_NS(p,s,n,e) (is_element_full ((p), (s), (n), (e), '|'))
+
+static void
+start_element_raw_cb (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ ParseData *parse_data = (ParseData *) user_data;
+
+ /* we must check for namespace declarations first
+ *
+ * XXX - we could speed up things by checking for namespace declarations
+ * only on the root node, where they usually are; this would probably break
+ * on streams not produced by us or by "smart" generators
+ */
+ map_namespace_to_name (parse_data, attribute_names, attribute_values);
+
+ switch (parse_data->state)
+ {
+ case STATE_STARTED:
+ if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT))
+ {
+ const gchar *attr;
+ gint i;
+
+ i = 0;
+ for (attr = attribute_names[i]; attr; attr = attribute_names[++i])
+ {
+ if ((IS_ATTRIBUTE (attr, XBEL_VERSION_ATTRIBUTE)) &&
+ (0 == strcmp (attribute_values[i], XBEL_VERSION)))
+ parse_data->state = STATE_ROOT;
+ }
+ }
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Unexpected tag '%s', tag '%s' expected"),
+ element_name, XBEL_ROOT_ELEMENT);
+ break;
+ case STATE_ROOT:
+ if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT))
+ parse_data->state = STATE_TITLE;
+ else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT))
+ parse_data->state = STATE_DESC;
+ else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT))
+ {
+ GError *inner_error = NULL;
+
+ parse_data->state = STATE_BOOKMARK;
+
+ parse_bookmark_element (context,
+ parse_data,
+ attribute_names,
+ attribute_values,
+ &inner_error);
+ if (inner_error)
+ g_propagate_error (error, inner_error);
+ }
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Unexpected tag '%s' inside '%s'"),
+ element_name,
+ XBEL_ROOT_ELEMENT);
+ break;
+ case STATE_BOOKMARK:
+ if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT))
+ parse_data->state = STATE_TITLE;
+ else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT))
+ parse_data->state = STATE_DESC;
+ else if (IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT))
+ parse_data->state = STATE_INFO;
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Unexpected tag '%s' inside '%s'"),
+ element_name,
+ XBEL_BOOKMARK_ELEMENT);
+ break;
+ case STATE_INFO:
+ if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT))
+ {
+ const gchar *attr;
+ gint i;
+
+ i = 0;
+ for (attr = attribute_names[i]; attr; attr = attribute_names[++i])
+ {
+ if ((IS_ATTRIBUTE (attr, XBEL_OWNER_ATTRIBUTE)) &&
+ (0 == strcmp (attribute_values[i], BOOKMARK_METADATA_OWNER)))
+ {
+ parse_data->state = STATE_METADATA;
+
+ if (!parse_data->current_item->metadata)
+ parse_data->current_item->metadata = bookmark_metadata_new ();
+ }
+ }
+ }
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Unexpected tag '%s', tag '%s' expected"),
+ element_name,
+ XBEL_METADATA_ELEMENT);
+ break;
+ case STATE_METADATA:
+ if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT))
+ parse_data->state = STATE_APPLICATIONS;
+ else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT))
+ parse_data->state = STATE_GROUPS;
+ else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT))
+ parse_data->current_item->metadata->is_private = TRUE;
+ else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT))
+ {
+ GError *inner_error = NULL;
+
+ parse_data->state = STATE_ICON;
+
+ parse_icon_element (context,
+ parse_data,
+ attribute_names,
+ attribute_values,
+ &inner_error);
+ if (inner_error)
+ g_propagate_error (error, inner_error);
+ }
+ else if (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT))
+ {
+ GError *inner_error = NULL;
+
+ parse_data->state = STATE_MIME;
+
+ parse_mime_type_element (context,
+ parse_data,
+ attribute_names,
+ attribute_values,
+ &inner_error);
+ if (inner_error)
+ g_propagate_error (error, inner_error);
+ }
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ _("Unexpected tag '%s' inside '%s'"),
+ element_name,
+ XBEL_METADATA_ELEMENT);
+ break;
+ case STATE_APPLICATIONS:
+ if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATION_ELEMENT))
+ {
+ GError *inner_error = NULL;
+
+ parse_data->state = STATE_APPLICATION;
+
+ parse_application_element (context,
+ parse_data,
+ attribute_names,
+ attribute_values,
+ &inner_error);
+ if (inner_error)
+ g_propagate_error (error, inner_error);
+ }
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Unexpected tag '%s', tag '%s' expected"),
+ element_name,
+ BOOKMARK_APPLICATION_ELEMENT);
+ break;
+ case STATE_GROUPS:
+ if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUP_ELEMENT))
+ parse_data->state = STATE_GROUP;
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Unexpected tag '%s', tag '%s' expected"),
+ element_name,
+ BOOKMARK_GROUP_ELEMENT);
+ break;
+ case STATE_ICON:
+ if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT))
+ {
+ GError *inner_error = NULL;
+
+ parse_icon_element (context,
+ parse_data,
+ attribute_names,
+ attribute_values,
+ &inner_error);
+ if (inner_error)
+ g_propagate_error (error, inner_error);
+ }
+ else
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ _("Unexpected tag '%s' inside '%s'"),
+ element_name,
+ XBEL_METADATA_ELEMENT);
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
+}
+
+static void
+end_element_raw_cb (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParseData *parse_data = (ParseData *) user_data;
+
+ if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT))
+ parse_data->state = STATE_FINISHED;
+ else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT))
+ {
+ parse_data->current_item = NULL;
+
+ parse_data->state = STATE_ROOT;
+ }
+ else if ((IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT)) ||
+ (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) ||
+ (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT)))
+ {
+ if (parse_data->current_item)
+ parse_data->state = STATE_BOOKMARK;
+ else
+ parse_data->state = STATE_ROOT;
+ }
+ else if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT))
+ parse_data->state = STATE_INFO;
+ else if (IS_ELEMENT_NS (parse_data, element_name,
+ BOOKMARK_NAMESPACE_URI,
+ BOOKMARK_APPLICATION_ELEMENT))
+ parse_data->state = STATE_APPLICATIONS;
+ else if (IS_ELEMENT_NS (parse_data, element_name,
+ BOOKMARK_NAMESPACE_URI,
+ BOOKMARK_GROUP_ELEMENT))
+ parse_data->state = STATE_GROUPS;
+ else if ((IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT)) ||
+ (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT)) ||
+ (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT)) ||
+ (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) ||
+ (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT)))
+ parse_data->state = STATE_METADATA;
+}
+
+static void
+text_raw_cb (GMarkupParseContext *context,
+ const gchar *text,
+ gsize length,
+ gpointer user_data,
+ GError **error)
+{
+ ParseData *parse_data = (ParseData *) user_data;
+ gchar *payload;
+
+ payload = g_strndup (text, length);
+
+ switch (parse_data->state)
+ {
+ case STATE_TITLE:
+ if (parse_data->current_item)
+ {
+ g_free (parse_data->current_item->title);
+ parse_data->current_item->title = g_strdup (payload);
+ }
+ else
+ {
+ g_free (parse_data->bookmark_file->title);
+ parse_data->bookmark_file->title = g_strdup (payload);
+ }
+ break;
+ case STATE_DESC:
+ if (parse_data->current_item)
+ {
+ g_free (parse_data->current_item->description);
+ parse_data->current_item->description = g_strdup (payload);
+ }
+ else
+ {
+ g_free (parse_data->bookmark_file->description);
+ parse_data->bookmark_file->description = g_strdup (payload);
+ }
+ break;
+ case STATE_GROUP:
+ {
+ GList *groups;
+
+ g_warn_if_fail (parse_data->current_item != NULL);
+
+ if (!parse_data->current_item->metadata)
+ parse_data->current_item->metadata = bookmark_metadata_new ();
+
+ groups = parse_data->current_item->metadata->groups;
+ parse_data->current_item->metadata->groups = g_list_prepend (groups, g_strdup (payload));
+ }
+ break;
+ case STATE_ROOT:
+ case STATE_BOOKMARK:
+ case STATE_INFO:
+ case STATE_METADATA:
+ case STATE_APPLICATIONS:
+ case STATE_APPLICATION:
+ case STATE_GROUPS:
+ case STATE_MIME:
+ case STATE_ICON:
+ break;
+ default:
+ g_warn_if_reached ();
+ break;
+ }
+
+ g_free (payload);
+}
+
+static const GMarkupParser markup_parser =
+{
+ start_element_raw_cb, /* start_element */
+ end_element_raw_cb, /* end_element */
+ text_raw_cb, /* text */
+ NULL, /* passthrough */
+ NULL
+};
+
+static gboolean
+g_bookmark_file_parse (GBookmarkFile *bookmark,
+ const gchar *buffer,
+ gsize length,
+ GError **error)
+{
+ GMarkupParseContext *context;
+ ParseData *parse_data;
+ GError *parse_error, *end_error;
+ gboolean retval;
+
+ g_warn_if_fail (bookmark != NULL);
+
+ if (!buffer)
+ return FALSE;
+
+ if (length == (gsize) -1)
+ length = strlen (buffer);
+
+ parse_data = parse_data_new ();
+ parse_data->bookmark_file = bookmark;
+
+ context = g_markup_parse_context_new (&markup_parser,
+ 0,
+ parse_data,
+ (GDestroyNotify) parse_data_free);
+
+ parse_error = NULL;
+ retval = g_markup_parse_context_parse (context,
+ buffer,
+ length,
+ &parse_error);
+ if (!retval)
+ {
+ g_propagate_error (error, parse_error);
+
+ return FALSE;
+ }
+
+ end_error = NULL;
+ retval = g_markup_parse_context_end_parse (context, &end_error);
+ if (!retval)
+ {
+ g_propagate_error (error, end_error);
+
+ return FALSE;
+ }
+
+ g_markup_parse_context_free (context);
+
+ return TRUE;
+}
+
+static gchar *
+g_bookmark_file_dump (GBookmarkFile *bookmark,
+ gsize *length,
+ GError **error)
+{
+ GString *retval;
+ gchar *buffer;
+ GList *l;
+
+ retval = g_string_sized_new (4096);
+
+ g_string_append (retval,
+ "\n"
+#if 0
+ /* XXX - do we really need the doctype? */
+ "\n"
+#endif
+ "<" XBEL_ROOT_ELEMENT " " XBEL_VERSION_ATTRIBUTE "=\"" XBEL_VERSION "\"\n"
+ " xmlns:" BOOKMARK_NAMESPACE_NAME "=\"" BOOKMARK_NAMESPACE_URI "\"\n"
+ " xmlns:" MIME_NAMESPACE_NAME "=\"" MIME_NAMESPACE_URI "\"\n>");
+
+ if (bookmark->title)
+ {
+ gchar *escaped_title;
+
+ escaped_title = g_markup_escape_text (bookmark->title, -1);
+
+ buffer = g_strconcat (" "
+ "<" XBEL_TITLE_ELEMENT ">",
+ escaped_title,
+ "" XBEL_TITLE_ELEMENT ">\n", NULL);
+
+ g_string_append (retval, buffer);
+
+ g_free (buffer);
+ g_free (escaped_title);
+ }
+
+ if (bookmark->description)
+ {
+ gchar *escaped_desc;
+
+ escaped_desc = g_markup_escape_text (bookmark->description, -1);
+
+ buffer = g_strconcat (" "
+ "<" XBEL_DESC_ELEMENT ">",
+ escaped_desc,
+ "" XBEL_DESC_ELEMENT ">\n", NULL);
+ g_string_append (retval, buffer);
+
+ g_free (buffer);
+ g_free (escaped_desc);
+ }
+
+ if (!bookmark->items)
+ goto out;
+ else
+ retval = g_string_append (retval, "\n");
+
+ /* the items are stored in reverse order */
+ for (l = g_list_last (bookmark->items);
+ l != NULL;
+ l = l->prev)
+ {
+ BookmarkItem *item = (BookmarkItem *) l->data;
+ gchar *item_dump;
+
+ item_dump = bookmark_item_dump (item);
+ if (!item_dump)
+ continue;
+
+ retval = g_string_append (retval, item_dump);
+
+ g_free (item_dump);
+ }
+
+out:
+ g_string_append (retval, "" XBEL_ROOT_ELEMENT ">");
+
+ if (length)
+ *length = retval->len;
+
+ return g_string_free (retval, FALSE);
+}
+
+/**************
+ * Misc *
+ **************/
+
+/* converts a Unix timestamp in a ISO 8601 compliant string; you
+ * should free the returned string.
+ */
+static gchar *
+timestamp_to_iso8601 (time_t timestamp)
+{
+ GTimeVal stamp;
+
+ if (timestamp == (time_t) -1)
+ g_get_current_time (&stamp);
+ else
+ {
+ stamp.tv_sec = timestamp;
+ stamp.tv_usec = 0;
+ }
+
+ return g_time_val_to_iso8601 (&stamp);
+}
+
+static time_t
+timestamp_from_iso8601 (const gchar *iso_date)
+{
+ GTimeVal stamp;
+
+ if (!g_time_val_from_iso8601 (iso_date, &stamp))
+ return (time_t) -1;
+
+ return (time_t) stamp.tv_sec;
+}
+
+
+
+GQuark
+g_bookmark_file_error_quark (void)
+{
+ return g_quark_from_static_string ("g-bookmark-file-error-quark");
+}
+
+
+
+/********************
+ * Public API *
+ ********************/
+
+/**
+ * g_bookmark_file_new:
+ *
+ * Creates a new empty #GBookmarkFile object.
+ *
+ * Use g_bookmark_file_load_from_file(), g_bookmark_file_load_from_data()
+ * or g_bookmark_file_load_from_data_dirs() to read an existing bookmark
+ * file.
+ *
+ * Return value: an empty #GBookmarkFile
+ *
+ * Since: 2.12
+ */
+GBookmarkFile *
+g_bookmark_file_new (void)
+{
+ GBookmarkFile *bookmark;
+
+ bookmark = g_new (GBookmarkFile, 1);
+
+ g_bookmark_file_init (bookmark);
+
+ return bookmark;
+}
+
+/**
+ * g_bookmark_file_free:
+ * @bookmark: a #GBookmarkFile
+ *
+ * Frees a #GBookmarkFile.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_free (GBookmarkFile *bookmark)
+{
+ if (!bookmark)
+ return;
+
+ g_bookmark_file_clear (bookmark);
+
+ g_free (bookmark);
+}
+
+/**
+ * g_bookmark_file_load_from_data:
+ * @bookmark: an empty #GBookmarkFile struct
+ * @data: desktop bookmarks loaded in memory
+ * @length: the length of @data in bytes
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a bookmark file from memory into an empty #GBookmarkFile
+ * structure. If the object cannot be created then @error is set to a
+ * #GBookmarkFileError.
+ *
+ * Return value: %TRUE if a desktop bookmark could be loaded.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_load_from_data (GBookmarkFile *bookmark,
+ const gchar *data,
+ gsize length,
+ GError **error)
+{
+ GError *parse_error;
+ gboolean retval;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (length != 0, FALSE);
+
+ if (length == (gsize) -1)
+ length = strlen (data);
+
+ if (bookmark->items)
+ {
+ g_bookmark_file_clear (bookmark);
+ g_bookmark_file_init (bookmark);
+ }
+
+ parse_error = NULL;
+ retval = g_bookmark_file_parse (bookmark, data, length, &parse_error);
+ if (!retval)
+ {
+ g_propagate_error (error, parse_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * g_bookmark_file_load_from_file:
+ * @bookmark: an empty #GBookmarkFile struct
+ * @filename: the path of a filename to load, in the GLib file name encoding
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a desktop bookmark file into an empty #GBookmarkFile structure.
+ * If the file could not be loaded then @error is set to either a #GFileError
+ * or #GBookmarkFileError.
+ *
+ * Return value: %TRUE if a desktop bookmark file could be loaded
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_load_from_file (GBookmarkFile *bookmark,
+ const gchar *filename,
+ GError **error)
+{
+ gchar *buffer;
+ gsize len;
+ GError *read_error;
+ gboolean retval;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ read_error = NULL;
+ g_file_get_contents (filename, &buffer, &len, &read_error);
+ if (read_error)
+ {
+ g_propagate_error (error, read_error);
+
+ return FALSE;
+ }
+
+ read_error = NULL;
+ retval = g_bookmark_file_load_from_data (bookmark,
+ buffer,
+ len,
+ &read_error);
+ if (read_error)
+ {
+ g_propagate_error (error, read_error);
+
+ g_free (buffer);
+
+ return FALSE;
+ }
+
+ g_free (buffer);
+
+ return retval;
+}
+
+
+/* Iterates through all the directories in *dirs trying to
+ * find file. When it successfully locates file, returns a
+ * string its absolute path. It also leaves the unchecked
+ * directories in *dirs. You should free the returned string
+ *
+ * Adapted from gkeyfile.c
+ */
+static gchar *
+find_file_in_data_dirs (const gchar *file,
+ gchar ***dirs,
+ GError **error)
+{
+ gchar **data_dirs, *data_dir, *path;
+
+ path = NULL;
+
+ if (dirs == NULL)
+ return NULL;
+
+ data_dirs = *dirs;
+ path = NULL;
+ while (data_dirs && (data_dir = *data_dirs) && !path)
+ {
+ gchar *candidate_file, *sub_dir;
+
+ candidate_file = (gchar *) file;
+ sub_dir = g_strdup ("");
+ while (candidate_file != NULL && !path)
+ {
+ gchar *p;
+
+ path = g_build_filename (data_dir, sub_dir,
+ candidate_file, NULL);
+
+ candidate_file = strchr (candidate_file, '-');
+
+ if (candidate_file == NULL)
+ break;
+
+ candidate_file++;
+
+ g_free (sub_dir);
+ sub_dir = g_strndup (file, candidate_file - file - 1);
+
+ for (p = sub_dir; *p != '\0'; p++)
+ {
+ if (*p == '-')
+ *p = G_DIR_SEPARATOR;
+ }
+ }
+ g_free (sub_dir);
+ data_dirs++;
+ }
+
+ *dirs = data_dirs;
+
+ if (!path)
+ {
+ g_set_error_literal (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND,
+ _("No valid bookmark file found in data dirs"));
+
+ return NULL;
+ }
+
+ return path;
+}
+
+
+/**
+ * g_bookmark_file_load_from_data_dirs:
+ * @bookmark: a #GBookmarkFile
+ * @file: a relative path to a filename to open and parse
+ * @full_path: return location for a string containing the full path
+ * of the file, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function looks for a desktop bookmark file named @file in the
+ * paths returned from g_get_user_data_dir() and g_get_system_data_dirs(),
+ * loads the file into @bookmark and returns the file's full path in
+ * @full_path. If the file could not be loaded then an %error is
+ * set to either a #GFileError or #GBookmarkFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE othewise
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark,
+ const gchar *file,
+ gchar **full_path,
+ GError **error)
+{
+ GError *file_error = NULL;
+ gchar **all_data_dirs, **data_dirs;
+ const gchar *user_data_dir;
+ const gchar * const * system_data_dirs;
+ gsize i, j;
+ gchar *output_path;
+ gboolean found_file;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
+
+ user_data_dir = g_get_user_data_dir ();
+ system_data_dirs = g_get_system_data_dirs ();
+ all_data_dirs = g_new0 (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);
+
+ i = 0;
+ all_data_dirs[i++] = g_strdup (user_data_dir);
+
+ j = 0;
+ while (system_data_dirs[j] != NULL)
+ all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
+
+ found_file = FALSE;
+ data_dirs = all_data_dirs;
+ output_path = NULL;
+ while (*data_dirs != NULL && !found_file)
+ {
+ g_free (output_path);
+
+ output_path = find_file_in_data_dirs (file, &data_dirs, &file_error);
+
+ if (file_error)
+ {
+ g_propagate_error (error, file_error);
+ break;
+ }
+
+ found_file = g_bookmark_file_load_from_file (bookmark,
+ output_path,
+ &file_error);
+ if (file_error)
+ {
+ g_propagate_error (error, file_error);
+ break;
+ }
+ }
+
+ if (found_file && full_path)
+ *full_path = output_path;
+ else
+ g_free (output_path);
+
+ g_strfreev (all_data_dirs);
+
+ return found_file;
+}
+
+
+/**
+ * g_bookmark_file_to_data:
+ * @bookmark: a #GBookmarkFile
+ * @length: return location for the length of the returned string, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function outputs @bookmark as a string.
+ *
+ * Return value: a newly allocated string holding
+ * the contents of the #GBookmarkFile
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_to_data (GBookmarkFile *bookmark,
+ gsize *length,
+ GError **error)
+{
+ GError *write_error = NULL;
+ gchar *retval;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+
+ retval = g_bookmark_file_dump (bookmark, length, &write_error);
+ if (write_error)
+ {
+ g_propagate_error (error, write_error);
+
+ return NULL;
+ }
+
+ return retval;
+}
+
+/**
+ * g_bookmark_file_to_file:
+ * @bookmark: a #GBookmarkFile
+ * @filename: path of the output file
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function outputs @bookmark into a file. The write process is
+ * guaranteed to be atomic by using g_file_set_contents() internally.
+ *
+ * Return value: %TRUE if the file was successfully written.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_to_file (GBookmarkFile *bookmark,
+ const gchar *filename,
+ GError **error)
+{
+ gchar *data;
+ GError *data_error, *write_error;
+ gsize len;
+ gboolean retval;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+
+ data_error = NULL;
+ data = g_bookmark_file_to_data (bookmark, &len, &data_error);
+ if (data_error)
+ {
+ g_propagate_error (error, data_error);
+
+ return FALSE;
+ }
+
+ write_error = NULL;
+ g_file_set_contents (filename, data, len, &write_error);
+ if (write_error)
+ {
+ g_propagate_error (error, write_error);
+
+ retval = FALSE;
+ }
+ else
+ retval = TRUE;
+
+ g_free (data);
+
+ return retval;
+}
+
+static BookmarkItem *
+g_bookmark_file_lookup_item (GBookmarkFile *bookmark,
+ const gchar *uri)
+{
+ g_warn_if_fail (bookmark != NULL && uri != NULL);
+
+ return g_hash_table_lookup (bookmark->items_by_uri, uri);
+}
+
+/* this function adds a new item to the list */
+static void
+g_bookmark_file_add_item (GBookmarkFile *bookmark,
+ BookmarkItem *item,
+ GError **error)
+{
+ g_warn_if_fail (bookmark != NULL);
+ g_warn_if_fail (item != NULL);
+
+ /* this should never happen; and if it does, then we are
+ * screwing up something big time.
+ */
+ if (G_UNLIKELY (g_bookmark_file_has_item (bookmark, item->uri)))
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_INVALID_URI,
+ _("A bookmark for URI '%s' already exists"),
+ item->uri);
+ return;
+ }
+
+ bookmark->items = g_list_prepend (bookmark->items, item);
+
+ g_hash_table_replace (bookmark->items_by_uri,
+ item->uri,
+ item);
+
+ if (item->added == (time_t) -1)
+ item->added = time (NULL);
+
+ if (item->modified == (time_t) -1)
+ item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_remove_item:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Removes the bookmark for @uri from the bookmark file @bookmark.
+ *
+ * Return value: %TRUE if the bookmark was removed successfully.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_remove_item (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ bookmark->items = g_list_remove (bookmark->items, item);
+ g_hash_table_remove (bookmark->items_by_uri, item->uri);
+
+ bookmark_item_free (item);
+
+ return TRUE;
+}
+
+/**
+ * g_bookmark_file_has_item:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ *
+ * Looks whether the desktop bookmark has an item with its URI set to @uri.
+ *
+ * Return value: %TRUE if @uri is inside @bookmark, %FALSE otherwise
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_has_item (GBookmarkFile *bookmark,
+ const gchar *uri)
+{
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ return (NULL != g_hash_table_lookup (bookmark->items_by_uri, uri));
+}
+
+/**
+ * g_bookmark_file_get_uris:
+ * @bookmark: a #GBookmarkFile
+ * @length: return location for the number of returned URIs, or %NULL
+ *
+ * Returns all URIs of the bookmarks in the bookmark file @bookmark.
+ * The array of returned URIs will be %NULL-terminated, so @length may
+ * optionally be %NULL.
+ *
+ * Return value: a newly allocated %NULL-terminated array of strings.
+ * Use g_strfreev() to free it.
+ *
+ * Since: 2.12
+ */
+gchar **
+g_bookmark_file_get_uris (GBookmarkFile *bookmark,
+ gsize *length)
+{
+ GList *l;
+ gchar **uris;
+ gsize i, n_items;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+
+ n_items = g_list_length (bookmark->items);
+ uris = g_new0 (gchar *, n_items + 1);
+
+ /* the items are stored in reverse order, so we walk the list backward */
+ for (l = g_list_last (bookmark->items), i = 0; l != NULL; l = l->prev)
+ {
+ BookmarkItem *item = (BookmarkItem *) l->data;
+
+ g_warn_if_fail (item != NULL);
+
+ uris[i++] = g_strdup (item->uri);
+ }
+ uris[i] = NULL;
+
+ if (length)
+ *length = i;
+
+ return uris;
+}
+
+/**
+ * g_bookmark_file_set_title:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI or %NULL
+ * @title: a UTF-8 encoded string
+ *
+ * Sets @title as the title of the bookmark for @uri inside the
+ * bookmark file @bookmark.
+ *
+ * If @uri is %NULL, the title of @bookmark is set.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_title (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *title)
+{
+ g_return_if_fail (bookmark != NULL);
+
+ if (!uri)
+ {
+ g_free (bookmark->title);
+ bookmark->title = g_strdup (title);
+ }
+ else
+ {
+ BookmarkItem *item;
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ g_free (item->title);
+ item->title = g_strdup (title);
+
+ item->modified = time (NULL);
+ }
+}
+
+/**
+ * g_bookmark_file_get_title:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the title of the bookmark for @uri.
+ *
+ * If @uri is %NULL, the title of @bookmark is returned.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ * URI cannot be found.
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_get_title (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+
+ if (!uri)
+ return g_strdup (bookmark->title);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return NULL;
+ }
+
+ return g_strdup (item->title);
+}
+
+/**
+ * g_bookmark_file_set_description:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI or %NULL
+ * @description: a string
+ *
+ * Sets @description as the description of the bookmark for @uri.
+ *
+ * If @uri is %NULL, the description of @bookmark is set.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_description (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *description)
+{
+ g_return_if_fail (bookmark != NULL);
+
+ if (!uri)
+ {
+ g_free (bookmark->description);
+ bookmark->description = g_strdup (description);
+ }
+ else
+ {
+ BookmarkItem *item;
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ g_free (item->description);
+ item->description = g_strdup (description);
+
+ item->modified = time (NULL);
+ }
+}
+
+/**
+ * g_bookmark_file_get_description:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the description of the bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ * URI cannot be found.
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_get_description (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+
+ if (!uri)
+ return g_strdup (bookmark->description);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return NULL;
+ }
+
+ return g_strdup (item->description);
+}
+
+/**
+ * g_bookmark_file_set_mime_type:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @mime_type: a MIME type
+ *
+ * Sets @mime_type as the MIME type of the bookmark for @uri.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_mime_type (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *mime_type)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (mime_type != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ g_free (item->metadata->mime_type);
+
+ item->metadata->mime_type = g_strdup (mime_type);
+ item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_mime_type:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the MIME type of the resource pointed by @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the
+ * event that the MIME type cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ * URI cannot be found.
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_get_mime_type (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return NULL;
+ }
+
+ if (!item->metadata)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+ _("No MIME type defined in the bookmark for URI '%s'"),
+ uri);
+ return NULL;
+ }
+
+ return g_strdup (item->metadata->mime_type);
+}
+
+/**
+ * g_bookmark_file_set_is_private:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @is_private: %TRUE if the bookmark should be marked as private
+ *
+ * Sets the private flag of the bookmark for @uri.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_is_private (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gboolean is_private)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ item->metadata->is_private = (is_private == TRUE);
+ item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_is_private:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets whether the private flag of the bookmark for @uri is set.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the
+ * event that the private flag cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: %TRUE if the private flag is set, %FALSE otherwise.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_get_is_private (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ if (!item->metadata)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+ _("No private flag has been defined in bookmark for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ return item->metadata->is_private;
+}
+
+/**
+ * g_bookmark_file_set_added:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @added: a timestamp or -1 to use the current time
+ *
+ * Sets the time the bookmark for @uri was added into @bookmark.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_added (GBookmarkFile *bookmark,
+ const gchar *uri,
+ time_t added)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (added == (time_t) -1)
+ time (&added);
+
+ item->added = added;
+ item->modified = added;
+}
+
+/**
+ * g_bookmark_file_get_added:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the time the bookmark for @uri was added to @bookmark
+ *
+ * In the event the URI cannot be found, -1 is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a timestamp
+ *
+ * Since: 2.12
+ */
+time_t
+g_bookmark_file_get_added (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, (time_t) -1);
+ g_return_val_if_fail (uri != NULL, (time_t) -1);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return (time_t) -1;
+ }
+
+ return item->added;
+}
+
+/**
+ * g_bookmark_file_set_modified:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @modified: a timestamp or -1 to use the current time
+ *
+ * Sets the last time the bookmark for @uri was last modified.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * The "modified" time should only be set when the bookmark's meta-data
+ * was actually changed. Every function of #GBookmarkFile that
+ * modifies a bookmark also changes the modification time, except for
+ * g_bookmark_file_set_visited().
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_modified (GBookmarkFile *bookmark,
+ const gchar *uri,
+ time_t modified)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (modified == (time_t) -1)
+ time (&modified);
+
+ item->modified = modified;
+}
+
+/**
+ * g_bookmark_file_get_modified:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the time when the bookmark for @uri was last modified.
+ *
+ * In the event the URI cannot be found, -1 is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a timestamp
+ *
+ * Since: 2.12
+ */
+time_t
+g_bookmark_file_get_modified (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, (time_t) -1);
+ g_return_val_if_fail (uri != NULL, (time_t) -1);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return (time_t) -1;
+ }
+
+ return item->modified;
+}
+
+/**
+ * g_bookmark_file_set_visited:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @visited: a timestamp or -1 to use the current time
+ *
+ * Sets the time the bookmark for @uri was last visited.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * The "visited" time should only be set if the bookmark was launched,
+ * either using the command line retrieved by g_bookmark_file_get_app_info()
+ * or by the default application for the bookmark's MIME type, retrieved
+ * using g_bookmark_file_get_mime_type(). Changing the "visited" time
+ * does not affect the "modified" time.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_visited (GBookmarkFile *bookmark,
+ const gchar *uri,
+ time_t visited)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (visited == (time_t) -1)
+ time (&visited);
+
+ item->visited = visited;
+}
+
+/**
+ * g_bookmark_file_get_visited:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the time the bookmark for @uri was last visited.
+ *
+ * In the event the URI cannot be found, -1 is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a timestamp.
+ *
+ * Since: 2.12
+ */
+time_t
+g_bookmark_file_get_visited (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, (time_t) -1);
+ g_return_val_if_fail (uri != NULL, (time_t) -1);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return (time_t) -1;
+ }
+
+ return item->visited;
+}
+
+/**
+ * g_bookmark_file_has_group:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @group: the group name to be searched
+ * @error: return location for a #GError, or %NULL
+ *
+ * Checks whether @group appears in the list of groups to which
+ * the bookmark for @uri belongs to.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if @group was found.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_has_group (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *group,
+ GError **error)
+{
+ BookmarkItem *item;
+ GList *l;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ if (!item->metadata)
+ return FALSE;
+
+ for (l = item->metadata->groups; l != NULL; l = l->next)
+ {
+ if (strcmp (l->data, group) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+/**
+ * g_bookmark_file_add_group:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @group: the group name to be added
+ *
+ * Adds @group to the list of groups to which the bookmark for @uri
+ * belongs to.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_add_group (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *group)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (group != NULL && group[0] != '\0');
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ if (!g_bookmark_file_has_group (bookmark, uri, group, NULL))
+ {
+ item->metadata->groups = g_list_prepend (item->metadata->groups,
+ g_strdup (group));
+
+ item->modified = time (NULL);
+ }
+}
+
+/**
+ * g_bookmark_file_remove_group:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @group: the group name to be removed
+ * @error: return location for a #GError, or %NULL
+ *
+ * Removes @group from the list of groups to which the bookmark
+ * for @uri belongs to.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ * In the event no group was defined, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: %TRUE if @group was successfully removed.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_remove_group (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *group,
+ GError **error)
+{
+ BookmarkItem *item;
+ GList *l;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ if (!item->metadata)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+ _("No groups set in bookmark for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ for (l = item->metadata->groups; l != NULL; l = l->next)
+ {
+ if (strcmp (l->data, group) == 0)
+ {
+ item->metadata->groups = g_list_remove_link (item->metadata->groups, l);
+ g_free (l->data);
+ g_list_free_1 (l);
+
+ item->modified = time (NULL);
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * g_bookmark_file_set_groups:
+ * @bookmark: a #GBookmarkFile
+ * @uri: an item's URI
+ * @groups: an array of group names, or %NULL to remove all groups
+ * @length: number of group name values in @groups
+ *
+ * Sets a list of group names for the item with URI @uri. Each previously
+ * set group name list is removed.
+ *
+ * If @uri cannot be found then an item for it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_groups (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar **groups,
+ gsize length)
+{
+ BookmarkItem *item;
+ gsize i;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (groups != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ if (item->metadata->groups != NULL)
+ {
+ g_list_foreach (item->metadata->groups,
+ (GFunc) g_free,
+ NULL);
+ g_list_free (item->metadata->groups);
+ item->metadata->groups = NULL;
+ }
+
+ if (groups)
+ {
+ for (i = 0; groups[i] != NULL && i < length; i++)
+ item->metadata->groups = g_list_append (item->metadata->groups,
+ g_strdup (groups[i]));
+ }
+
+ item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_groups:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @length: return location for the length of the returned string, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the list of group names of the bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * The returned array is %NULL terminated, so @length may optionally
+ * be %NULL.
+ *
+ * Return value: a newly allocated %NULL-terminated array of group names.
+ * Use g_strfreev() to free it.
+ *
+ * Since: 2.12
+ */
+gchar **
+g_bookmark_file_get_groups (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gsize *length,
+ GError **error)
+{
+ BookmarkItem *item;
+ GList *l;
+ gsize len, i;
+ gchar **retval;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return NULL;
+ }
+
+ if (!item->metadata)
+ {
+ if (length)
+ *length = 0;
+
+ return NULL;
+ }
+
+ len = g_list_length (item->metadata->groups);
+ retval = g_new0 (gchar *, len + 1);
+ for (l = g_list_last (item->metadata->groups), i = 0;
+ l != NULL;
+ l = l->prev)
+ {
+ gchar *group_name = (gchar *) l->data;
+
+ g_warn_if_fail (group_name != NULL);
+
+ retval[i++] = g_strdup (group_name);
+ }
+ retval[i] = NULL;
+
+ if (length)
+ *length = len;
+
+ return retval;
+}
+
+/**
+ * g_bookmark_file_add_application:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: the name of the application registering the bookmark
+ * or %NULL
+ * @exec: command line to be used to launch the bookmark or %NULL
+ *
+ * Adds the application with @name and @exec to the list of
+ * applications that have registered a bookmark for @uri into
+ * @bookmark.
+ *
+ * Every bookmark inside a #GBookmarkFile must have at least an
+ * application registered. Each application must provide a name, a
+ * command line useful for launching the bookmark, the number of times
+ * the bookmark has been registered by the application and the last
+ * time the application registered this bookmark.
+ *
+ * If @name is %NULL, the name of the application will be the
+ * same returned by g_get_application_name(); if @exec is %NULL, the
+ * command line will be a composition of the program name as
+ * returned by g_get_prgname() and the "%u" modifier, which will be
+ * expanded to the bookmark's URI.
+ *
+ * This function will automatically take care of updating the
+ * registrations count and timestamping in case an application
+ * with the same @name had already registered a bookmark for
+ * @uri inside @bookmark.
+ *
+ * If no bookmark for @uri is found, one is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_add_application (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ const gchar *exec)
+{
+ BookmarkItem *item;
+ gchar *app_name, *app_exec;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (name && name[0] != '\0')
+ app_name = g_strdup (name);
+ else
+ app_name = g_strdup (g_get_application_name ());
+
+ if (exec && exec[0] != '\0')
+ app_exec = g_strdup (exec);
+ else
+ app_exec = g_strjoin (" ", g_get_prgname(), "%u", NULL);
+
+ g_bookmark_file_set_app_info (bookmark, uri,
+ app_name,
+ app_exec,
+ -1,
+ (time_t) -1,
+ NULL);
+
+ g_free (app_exec);
+ g_free (app_name);
+}
+
+/**
+ * g_bookmark_file_remove_application:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: the name of the application
+ * @error: return location for a #GError or %NULL
+ *
+ * Removes application registered with @name from the list of applications
+ * that have registered a bookmark for @uri inside @bookmark.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ * In the event that no application with name @app_name has registered
+ * a bookmark for @uri, %FALSE is returned and error is set to
+ * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED.
+ *
+ * Return value: %TRUE if the application was successfully removed.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_remove_application (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ GError **error)
+{
+ GError *set_error;
+ gboolean retval;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ set_error = NULL;
+ retval = g_bookmark_file_set_app_info (bookmark, uri,
+ name,
+ "",
+ 0,
+ (time_t) -1,
+ &set_error);
+ if (set_error)
+ {
+ g_propagate_error (error, set_error);
+
+ return FALSE;
+ }
+
+ return retval;
+}
+
+/**
+ * g_bookmark_file_has_application:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: the name of the application
+ * @error: return location for a #GError or %NULL
+ *
+ * Checks whether the bookmark for @uri inside @bookmark has been
+ * registered by application @name.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if the application @name was found
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_has_application (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ return (NULL != bookmark_item_lookup_app_info (item, name));
+}
+
+/**
+ * g_bookmark_file_set_app_info:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: an application's name
+ * @exec: an application's command line
+ * @count: the number of registrations done for this application
+ * @stamp: the time of the last registration for this application
+ * @error: return location for a #GError or %NULL
+ *
+ * Sets the meta-data of application @name inside the list of
+ * applications that have registered a bookmark for @uri inside
+ * @bookmark.
+ *
+ * You should rarely use this function; use g_bookmark_file_add_application()
+ * and g_bookmark_file_remove_application() instead.
+ *
+ * @name can be any UTF-8 encoded string used to identify an
+ * application.
+ * @exec can have one of these two modifiers: "%f", which will
+ * be expanded as the local file name retrieved from the bookmark's
+ * URI; "%u", which will be expanded as the bookmark's URI.
+ * The expansion is done automatically when retrieving the stored
+ * command line using the g_bookmark_file_get_app_info() function.
+ * @count is the number of times the application has registered the
+ * bookmark; if is < 0, the current registration count will be increased
+ * by one, if is 0, the application with @name will be removed from
+ * the list of registered applications.
+ * @stamp is the Unix time of the last registration; if it is -1, the
+ * current time will be used.
+ *
+ * If you try to remove an application by setting its registration count to
+ * zero, and no bookmark for @uri is found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND; similarly,
+ * in the event that no application @name has registered a bookmark
+ * for @uri, %FALSE is returned and error is set to
+ * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. Otherwise, if no bookmark
+ * for @uri is found, one is created.
+ *
+ * Return value: %TRUE if the application's meta-data was successfully
+ * changed.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_set_app_info (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ const gchar *exec,
+ gint count,
+ time_t stamp,
+ GError **error)
+{
+ BookmarkItem *item;
+ BookmarkAppInfo *ai;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (exec != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ if (count == 0)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+ else
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+ }
+
+ ai = bookmark_item_lookup_app_info (item, name);
+ if (!ai)
+ {
+ if (count == 0)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED,
+ _("No application with name '%s' registered a bookmark for '%s'"),
+ name,
+ uri);
+ return FALSE;
+ }
+ else
+ {
+ ai = bookmark_app_info_new (name);
+
+ item->metadata->applications = g_list_prepend (item->metadata->applications, ai);
+ g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai);
+ }
+ }
+
+ if (count == 0)
+ {
+ item->metadata->applications = g_list_remove (item->metadata->applications, ai);
+ g_hash_table_remove (item->metadata->apps_by_name, ai->name);
+ bookmark_app_info_free (ai);
+
+ item->modified = time (NULL);
+
+ return TRUE;
+ }
+ else if (count > 0)
+ ai->count = count;
+ else
+ ai->count += 1;
+
+ if (stamp != (time_t) -1)
+ ai->stamp = stamp;
+ else
+ ai->stamp = time (NULL);
+
+ if (exec && exec[0] != '\0')
+ {
+ g_free (ai->exec);
+ ai->exec = g_shell_quote (exec);
+ }
+
+ item->modified = time (NULL);
+
+ return TRUE;
+}
+
+/* expands the application's command line */
+static gchar *
+expand_exec_line (const gchar *exec_fmt,
+ const gchar *uri)
+{
+ GString *exec;
+ gchar ch;
+
+ exec = g_string_sized_new (512);
+ while ((ch = *exec_fmt++) != '\0')
+ {
+ if (ch != '%')
+ {
+ exec = g_string_append_c (exec, ch);
+ continue;
+ }
+
+ ch = *exec_fmt++;
+ switch (ch)
+ {
+ case '\0':
+ goto out;
+ case 'U':
+ case 'u':
+ g_string_append (exec, uri);
+ break;
+ case 'F':
+ case 'f':
+ {
+ gchar *file = g_filename_from_uri (uri, NULL, NULL);
+ if (file)
+ {
+ g_string_append (exec, file);
+ g_free (file);
+ }
+ else
+ {
+ g_string_free (exec, TRUE);
+ return NULL;
+ }
+ }
+ break;
+ case '%':
+ default:
+ exec = g_string_append_c (exec, ch);
+ break;
+ }
+ }
+
+ out:
+ return g_string_free (exec, FALSE);
+}
+
+/**
+ * g_bookmark_file_get_app_info:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: an application's name
+ * @exec: location for the command line of the application, or %NULL
+ * @count: return location for the registration count, or %NULL
+ * @stamp: return location for the last registration time, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the registration informations of @app_name for the bookmark for
+ * @uri. See g_bookmark_file_set_app_info() for more informations about
+ * the returned data.
+ *
+ * The string returned in @app_exec must be freed.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the
+ * event that no application with name @app_name has registered a bookmark
+ * for @uri, %FALSE is returned and error is set to
+ * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. In the event that unquoting
+ * the command line fails, an error of the #G_SHELL_ERROR domain is
+ * set and %FALSE is returned.
+ *
+ * Return value: %TRUE on success.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_get_app_info (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ gchar **exec,
+ guint *count,
+ time_t *stamp,
+ GError **error)
+{
+ BookmarkItem *item;
+ BookmarkAppInfo *ai;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ ai = bookmark_item_lookup_app_info (item, name);
+ if (!ai)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED,
+ _("No application with name '%s' registered a bookmark for '%s'"),
+ name,
+ uri);
+ return FALSE;
+ }
+
+ if (exec)
+ {
+ GError *unquote_error = NULL;
+ gchar *command_line;
+
+ command_line = g_shell_unquote (ai->exec, &unquote_error);
+ if (unquote_error)
+ {
+ g_propagate_error (error, unquote_error);
+ return FALSE;
+ }
+
+ *exec = expand_exec_line (command_line, uri);
+ if (!*exec)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_INVALID_URI,
+ _("Failed to expand exec line '%s' with URI '%s'"),
+ ai->exec, uri);
+ g_free (command_line);
+
+ return FALSE;
+ }
+ else
+ g_free (command_line);
+ }
+
+ if (count)
+ *count = ai->count;
+
+ if (stamp)
+ *stamp = ai->stamp;
+
+ return TRUE;
+}
+
+/**
+ * g_bookmark_file_get_applications:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @length: return location of the length of the returned list, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the names of the applications that have registered the
+ * bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a newly allocated %NULL-terminated array of strings.
+ * Use g_strfreev() to free it.
+ *
+ * Since: 2.12
+ */
+gchar **
+g_bookmark_file_get_applications (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gsize *length,
+ GError **error)
+{
+ BookmarkItem *item;
+ GList *l;
+ gchar **apps;
+ gsize i, n_apps;
+
+ g_return_val_if_fail (bookmark != NULL, NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return NULL;
+ }
+
+ if (!item->metadata)
+ {
+ if (length)
+ *length = 0;
+
+ return NULL;
+ }
+
+ n_apps = g_list_length (item->metadata->applications);
+ apps = g_new0 (gchar *, n_apps + 1);
+
+ for (l = g_list_last (item->metadata->applications), i = 0;
+ l != NULL;
+ l = l->prev)
+ {
+ BookmarkAppInfo *ai;
+
+ ai = (BookmarkAppInfo *) l->data;
+
+ g_warn_if_fail (ai != NULL);
+ g_warn_if_fail (ai->name != NULL);
+
+ apps[i++] = g_strdup (ai->name);
+ }
+ apps[i] = NULL;
+
+ if (length)
+ *length = i;
+
+ return apps;
+}
+
+/**
+ * g_bookmark_file_get_size:
+ * @bookmark: a #GBookmarkFile
+ *
+ * Gets the number of bookmarks inside @bookmark.
+ *
+ * Return value: the number of bookmarks
+ *
+ * Since: 2.12
+ */
+gint
+g_bookmark_file_get_size (GBookmarkFile *bookmark)
+{
+ g_return_val_if_fail (bookmark != NULL, 0);
+
+ return g_list_length (bookmark->items);
+}
+
+/**
+ * g_bookmark_file_move_item:
+ * @bookmark: a #GBookmarkFile
+ * @old_uri: a valid URI
+ * @new_uri: a valid URI, or %NULL
+ * @error: return location for a #GError or %NULL
+ *
+ * Changes the URI of a bookmark item from @old_uri to @new_uri. Any
+ * existing bookmark for @new_uri will be overwritten. If @new_uri is
+ * %NULL, then the bookmark is removed.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if the URI was successfully changed
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_move_item (GBookmarkFile *bookmark,
+ const gchar *old_uri,
+ const gchar *new_uri,
+ GError **error)
+{
+ BookmarkItem *item;
+ GError *remove_error;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (old_uri != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, old_uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ old_uri);
+ return FALSE;
+ }
+
+ if (new_uri && new_uri[0] != '\0')
+ {
+ if (g_bookmark_file_has_item (bookmark, new_uri))
+ {
+ remove_error = NULL;
+ g_bookmark_file_remove_item (bookmark, new_uri, &remove_error);
+ if (remove_error)
+ {
+ g_propagate_error (error, remove_error);
+
+ return FALSE;
+ }
+ }
+
+ g_hash_table_steal (bookmark->items_by_uri, item->uri);
+
+ g_free (item->uri);
+ item->uri = g_strdup (new_uri);
+ item->modified = time (NULL);
+
+ g_hash_table_replace (bookmark->items_by_uri, item->uri, item);
+
+ return TRUE;
+ }
+ else
+ {
+ remove_error = NULL;
+ g_bookmark_file_remove_item (bookmark, old_uri, &remove_error);
+ if (remove_error)
+ {
+ g_propagate_error (error, remove_error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+}
+
+/**
+ * g_bookmark_file_set_icon:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @href: the URI of the icon for the bookmark, or %NULL
+ * @mime_type: the MIME type of the icon for the bookmark
+ *
+ * Sets the icon for the bookmark for @uri. If @href is %NULL, unsets
+ * the currently set icon. @href can either be a full URL for the icon
+ * file or the icon name following the Icon Naming specification.
+ *
+ * If no bookmark for @uri is found one is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_icon (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *href,
+ const gchar *mime_type)
+{
+ BookmarkItem *item;
+
+ g_return_if_fail (bookmark != NULL);
+ g_return_if_fail (uri != NULL);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ item = bookmark_item_new (uri);
+ g_bookmark_file_add_item (bookmark, item, NULL);
+ }
+
+ if (!item->metadata)
+ item->metadata = bookmark_metadata_new ();
+
+ g_free (item->metadata->icon_href);
+ g_free (item->metadata->icon_mime);
+
+ item->metadata->icon_href = g_strdup (href);
+
+ if (mime_type && mime_type[0] != '\0')
+ item->metadata->icon_mime = g_strdup (mime_type);
+ else
+ item->metadata->icon_mime = g_strdup ("application/octet-stream");
+
+ item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_icon:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @href: return location for the icon's location or %NULL
+ * @mime_type: return location for the icon's MIME type or %NULL
+ * @error: return location for a #GError or %NULL
+ *
+ * Gets the icon of the bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if the icon for the bookmark for the URI was found.
+ * You should free the returned strings.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_get_icon (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gchar **href,
+ gchar **mime_type,
+ GError **error)
+{
+ BookmarkItem *item;
+
+ g_return_val_if_fail (bookmark != NULL, FALSE);
+ g_return_val_if_fail (uri != NULL, FALSE);
+
+ item = g_bookmark_file_lookup_item (bookmark, uri);
+ if (!item)
+ {
+ g_set_error (error, G_BOOKMARK_FILE_ERROR,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ _("No bookmark found for URI '%s'"),
+ uri);
+ return FALSE;
+ }
+
+ if ((!item->metadata) || (!item->metadata->icon_href))
+ return FALSE;
+
+ if (href)
+ *href = g_strdup (item->metadata->icon_href);
+
+ if (mime_type)
+ *mime_type = g_strdup (item->metadata->icon_mime);
+
+ return TRUE;
+}
+
+#define __G_BOOKMARK_FILE_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gbookmarkfile.h b/desmume/src/windows/glib-2.20.1/build/glib/gbookmarkfile.h
new file mode 100644
index 000000000..bdf97c09f
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbookmarkfile.h
@@ -0,0 +1,191 @@
+/* gbookmarkfile.h: parsing and building desktop bookmarks
+ *
+ * Copyright (C) 2005-2006 Emmanuele Bassi
+ *
+ * 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,
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_BOOKMARK_FILE_H__
+#define __G_BOOKMARK_FILE_H__
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+/* GError enumeration
+ */
+#define G_BOOKMARK_FILE_ERROR (g_bookmark_file_error_quark ())
+
+typedef enum
+{
+ G_BOOKMARK_FILE_ERROR_INVALID_URI,
+ G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+ G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED,
+ G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+ G_BOOKMARK_FILE_ERROR_READ,
+ G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING,
+ G_BOOKMARK_FILE_ERROR_WRITE,
+ G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND
+} GBookmarkFileError;
+
+GQuark g_bookmark_file_error_quark (void);
+
+/*
+ * GBookmarkFile
+ */
+typedef struct _GBookmarkFile GBookmarkFile;
+
+GBookmarkFile *g_bookmark_file_new (void);
+void g_bookmark_file_free (GBookmarkFile *bookmark);
+
+gboolean g_bookmark_file_load_from_file (GBookmarkFile *bookmark,
+ const gchar *filename,
+ GError **error);
+gboolean g_bookmark_file_load_from_data (GBookmarkFile *bookmark,
+ const gchar *data,
+ gsize length,
+ GError **error);
+gboolean g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark,
+ const gchar *file,
+ gchar **full_path,
+ GError **error);
+gchar * g_bookmark_file_to_data (GBookmarkFile *bookmark,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+gboolean g_bookmark_file_to_file (GBookmarkFile *bookmark,
+ const gchar *filename,
+ GError **error);
+
+void g_bookmark_file_set_title (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *title);
+gchar * g_bookmark_file_get_title (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error) G_GNUC_MALLOC;
+void g_bookmark_file_set_description (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *description);
+gchar * g_bookmark_file_get_description (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error) G_GNUC_MALLOC;
+void g_bookmark_file_set_mime_type (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *mime_type);
+gchar * g_bookmark_file_get_mime_type (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error) G_GNUC_MALLOC;
+void g_bookmark_file_set_groups (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar **groups,
+ gsize length);
+void g_bookmark_file_add_group (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *group);
+gboolean g_bookmark_file_has_group (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *group,
+ GError **error);
+gchar ** g_bookmark_file_get_groups (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+void g_bookmark_file_add_application (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ const gchar *exec);
+gboolean g_bookmark_file_has_application (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ GError **error);
+gchar ** g_bookmark_file_get_applications (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+gboolean g_bookmark_file_set_app_info (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ const gchar *exec,
+ gint count,
+ time_t stamp,
+ GError **error);
+gboolean g_bookmark_file_get_app_info (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ gchar **exec,
+ guint *count,
+ time_t *stamp,
+ GError **error);
+void g_bookmark_file_set_is_private (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gboolean is_private);
+gboolean g_bookmark_file_get_is_private (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error);
+void g_bookmark_file_set_icon (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *href,
+ const gchar *mime_type);
+gboolean g_bookmark_file_get_icon (GBookmarkFile *bookmark,
+ const gchar *uri,
+ gchar **href,
+ gchar **mime_type,
+ GError **error);
+void g_bookmark_file_set_added (GBookmarkFile *bookmark,
+ const gchar *uri,
+ time_t added);
+time_t g_bookmark_file_get_added (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error);
+void g_bookmark_file_set_modified (GBookmarkFile *bookmark,
+ const gchar *uri,
+ time_t modified);
+time_t g_bookmark_file_get_modified (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error);
+void g_bookmark_file_set_visited (GBookmarkFile *bookmark,
+ const gchar *uri,
+ time_t visited);
+time_t g_bookmark_file_get_visited (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error);
+gboolean g_bookmark_file_has_item (GBookmarkFile *bookmark,
+ const gchar *uri);
+gint g_bookmark_file_get_size (GBookmarkFile *bookmark);
+gchar ** g_bookmark_file_get_uris (GBookmarkFile *bookmark,
+ gsize *length) G_GNUC_MALLOC;
+gboolean g_bookmark_file_remove_group (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *group,
+ GError **error);
+gboolean g_bookmark_file_remove_application (GBookmarkFile *bookmark,
+ const gchar *uri,
+ const gchar *name,
+ GError **error);
+gboolean g_bookmark_file_remove_item (GBookmarkFile *bookmark,
+ const gchar *uri,
+ GError **error);
+gboolean g_bookmark_file_move_item (GBookmarkFile *bookmark,
+ const gchar *old_uri,
+ const gchar *new_uri,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __G_BOOKMARK_FILE_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gbsearcharray.h b/desmume/src/windows/glib-2.20.1/build/glib/gbsearcharray.h
new file mode 100644
index 000000000..8e6875893
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gbsearcharray.h
@@ -0,0 +1,303 @@
+/* GBSearchArray - Binary Searchable Array implementation
+ * Copyright (C) 2000-2003 Tim Janik
+ *
+ * This software is provided "as is"; redistribution and modification
+ * is permitted, provided that the following disclaimer is retained.
+ *
+ * This software 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.
+ * In no event shall the authors or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even
+ * if advised of the possibility of such damage.
+ */
+#ifndef __G_BSEARCH_ARRAY_H__
+#define __G_BSEARCH_ARRAY_H__
+
+#include
+#include
+
+
+G_BEGIN_DECLS /* c++ guards */
+
+/* this implementation is intended to be usable in third-party code
+ * simply by pasting the contents of this file. as such, the
+ * implementation needs to be self-contained within this file.
+ */
+
+/* convenience macro to avoid signed overflow for value comparisions */
+#define G_BSEARCH_ARRAY_CMP(v1,v2) ((v1) > (v2) ? +1 : (v1) == (v2) ? 0 : -1)
+
+
+/* --- typedefs --- */
+typedef gint (*GBSearchCompareFunc) (gconstpointer bsearch_node1, /* key */
+ gconstpointer bsearch_node2);
+typedef enum
+{
+ G_BSEARCH_ARRAY_ALIGN_POWER2 = 1 << 0, /* align memory to power2 sizes */
+ G_BSEARCH_ARRAY_AUTO_SHRINK = 1 << 1 /* shrink array upon removal */
+} GBSearchArrayFlags;
+
+
+/* --- structures --- */
+typedef struct
+{
+ guint sizeof_node;
+ GBSearchCompareFunc cmp_nodes;
+ guint flags;
+} GBSearchConfig;
+typedef union
+{
+ guint n_nodes;
+ /*< private >*/
+ gpointer alignment_dummy1;
+ glong alignment_dummy2;
+ gdouble alignment_dummy3;
+} GBSearchArray;
+
+
+/* --- public API --- */
+static inline GBSearchArray* g_bsearch_array_create (const GBSearchConfig *bconfig);
+static inline gpointer g_bsearch_array_get_nth (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint nth);
+static inline guint g_bsearch_array_get_index (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer node_in_array);
+static inline GBSearchArray* g_bsearch_array_remove (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index_);
+/* provide uninitialized space at index for node insertion */
+static inline GBSearchArray* g_bsearch_array_grow (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index);
+/* insert key_node into array if it does not exist, otherwise do nothing */
+static inline GBSearchArray* g_bsearch_array_insert (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node);
+/* insert key_node into array if it does not exist,
+ * otherwise replace the existing node's contents with key_node
+ */
+static inline GBSearchArray* g_bsearch_array_replace (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node);
+static inline void g_bsearch_array_free (GBSearchArray *barray,
+ const GBSearchConfig *bconfig);
+#define g_bsearch_array_get_n_nodes(barray) (((GBSearchArray*) (barray))->n_nodes)
+
+/* g_bsearch_array_lookup():
+ * return NULL or exact match node
+ */
+#define g_bsearch_array_lookup(barray, bconfig, key_node) \
+ g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 0)
+
+/* g_bsearch_array_lookup_sibling():
+ * return NULL for barray->n_nodes==0, otherwise return the
+ * exact match node, or, if there's no such node, return the
+ * node last visited, which is pretty close to an exact match
+ * (will be one off into either direction).
+ */
+#define g_bsearch_array_lookup_sibling(barray, bconfig, key_node) \
+ g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 1)
+
+/* g_bsearch_array_lookup_insertion():
+ * return NULL for barray->n_nodes==0 or exact match, otherwise
+ * return the node where key_node should be inserted (may be one
+ * after end, i.e. g_bsearch_array_get_index(result) <= barray->n_nodes).
+ */
+#define g_bsearch_array_lookup_insertion(barray, bconfig, key_node) \
+ g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 2)
+
+
+/* --- implementation --- */
+/* helper macro to cut down realloc()s */
+#ifdef DISABLE_MEM_POOLS
+#define G_BSEARCH_UPPER_POWER2(n) (n)
+#else /* !DISABLE_MEM_POOLS */
+#define G_BSEARCH_UPPER_POWER2(n) ((n) ? 1 << g_bit_storage ((n) - 1) : 0)
+#endif /* !DISABLE_MEM_POOLS */
+#define G_BSEARCH_ARRAY_NODES(barray) (((guint8*) (barray)) + sizeof (GBSearchArray))
+static inline GBSearchArray*
+g_bsearch_array_create (const GBSearchConfig *bconfig)
+{
+ GBSearchArray *barray;
+ guint size;
+
+ g_return_val_if_fail (bconfig != NULL, NULL);
+
+ size = sizeof (GBSearchArray) + bconfig->sizeof_node;
+ if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
+ size = G_BSEARCH_UPPER_POWER2 (size);
+ barray = (GBSearchArray *) g_realloc (NULL, size);
+ memset (barray, 0, sizeof (GBSearchArray));
+
+ return barray;
+}
+static inline gpointer
+g_bsearch_array_lookup_fuzzy (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node,
+ const guint sibling_or_after);
+static inline gpointer
+g_bsearch_array_lookup_fuzzy (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node,
+ const guint sibling_or_after)
+{
+ GBSearchCompareFunc cmp_nodes = bconfig->cmp_nodes;
+ guint8 *check = NULL, *nodes = G_BSEARCH_ARRAY_NODES (barray);
+ guint n_nodes = barray->n_nodes, offs = 0;
+ guint sizeof_node = bconfig->sizeof_node;
+ gint cmp = 0;
+
+ while (offs < n_nodes)
+ {
+ guint i = (offs + n_nodes) >> 1;
+
+ check = nodes + i * sizeof_node;
+ cmp = cmp_nodes (key_node, check);
+ if (cmp == 0)
+ return sibling_or_after > 1 ? NULL : check;
+ else if (cmp < 0)
+ n_nodes = i;
+ else /* (cmp > 0) */
+ offs = i + 1;
+ }
+
+ /* check is last mismatch, cmp > 0 indicates greater key */
+ return G_LIKELY (!sibling_or_after) ? NULL : (sibling_or_after > 1 && cmp > 0) ? check + sizeof_node : check;
+}
+static inline gpointer
+g_bsearch_array_get_nth (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint nth)
+{
+ return (G_LIKELY (nth < barray->n_nodes) ?
+ G_BSEARCH_ARRAY_NODES (barray) + nth * bconfig->sizeof_node :
+ NULL);
+}
+static inline guint
+g_bsearch_array_get_index (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer node_in_array)
+{
+ guint distance = ((guint8*) node_in_array) - G_BSEARCH_ARRAY_NODES (barray);
+
+ g_return_val_if_fail (node_in_array != NULL, barray->n_nodes);
+
+ distance /= bconfig->sizeof_node;
+
+ return MIN (distance, barray->n_nodes + 1); /* may return one after end */
+}
+static inline GBSearchArray*
+g_bsearch_array_grow (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index_)
+{
+ guint old_size = barray->n_nodes * bconfig->sizeof_node;
+ guint new_size = old_size + bconfig->sizeof_node;
+ guint8 *node;
+
+ g_return_val_if_fail (index_ <= barray->n_nodes, NULL);
+
+ if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2))
+ {
+ new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size);
+ old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size);
+ if (old_size != new_size)
+ barray = (GBSearchArray *) g_realloc (barray, new_size);
+ }
+ else
+ barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size);
+ node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node;
+ g_memmove (node + bconfig->sizeof_node, node, (barray->n_nodes - index_) * bconfig->sizeof_node);
+ barray->n_nodes += 1;
+ return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_insert (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node)
+{
+ guint8 *node;
+
+ if (G_UNLIKELY (!barray->n_nodes))
+ {
+ barray = g_bsearch_array_grow (barray, bconfig, 0);
+ node = G_BSEARCH_ARRAY_NODES (barray);
+ }
+ else
+ {
+ node = (guint8 *) g_bsearch_array_lookup_insertion (barray, bconfig, key_node);
+ if (G_LIKELY (node))
+ {
+ guint index_ = g_bsearch_array_get_index (barray, bconfig, node);
+
+ /* grow and insert */
+ barray = g_bsearch_array_grow (barray, bconfig, index_);
+ node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node;
+ }
+ else /* no insertion needed, node already there */
+ return barray;
+ }
+ memcpy (node, key_node, bconfig->sizeof_node);
+ return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_replace (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node)
+{
+ guint8 *node = (guint8 *) g_bsearch_array_lookup (barray, bconfig, key_node);
+ if (G_LIKELY (node)) /* expected path */
+ memcpy (node, key_node, bconfig->sizeof_node);
+ else /* revert to insertion */
+ barray = g_bsearch_array_insert (barray, bconfig, key_node);
+ return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_remove (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index_)
+{
+ guint8 *node;
+
+ g_return_val_if_fail (index_ < barray->n_nodes, NULL);
+
+ barray->n_nodes -= 1;
+ node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node;
+ g_memmove (node, node + bconfig->sizeof_node, (barray->n_nodes - index_) * bconfig->sizeof_node);
+ if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_AUTO_SHRINK))
+ {
+ guint new_size = barray->n_nodes * bconfig->sizeof_node;
+ guint old_size = new_size + bconfig->sizeof_node;
+
+ if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2))
+ {
+ new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size);
+ old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size);
+ if (old_size != new_size)
+ barray = (GBSearchArray *) g_realloc (barray, new_size);
+ }
+ else
+ barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size);
+ }
+ return barray;
+}
+static inline void
+g_bsearch_array_free (GBSearchArray *barray,
+ const GBSearchConfig *bconfig)
+{
+ g_return_if_fail (barray != NULL);
+
+ g_free (barray);
+}
+
+G_END_DECLS /* c++ guards */
+
+#endif /* !__G_BSEARCH_ARRAY_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gcache.c b/desmume/src/windows/glib-2.20.1/build/glib/gcache.c
new file mode 100644
index 000000000..a5b02974c
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gcache.c
@@ -0,0 +1,197 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "galias.h"
+
+
+typedef struct _GCacheNode GCacheNode;
+
+struct _GCacheNode
+{
+ /* A reference counted node */
+ gpointer value;
+ gint ref_count;
+};
+
+struct _GCache
+{
+ /* Called to create a value from a key */
+ GCacheNewFunc value_new_func;
+
+ /* Called to destroy a value */
+ GCacheDestroyFunc value_destroy_func;
+
+ /* Called to duplicate a key */
+ GCacheDupFunc key_dup_func;
+
+ /* Called to destroy a key */
+ GCacheDestroyFunc key_destroy_func;
+
+ /* Associates keys with nodes */
+ GHashTable *key_table;
+
+ /* Associates nodes with keys */
+ GHashTable *value_table;
+};
+
+static inline GCacheNode*
+g_cache_node_new (gpointer value)
+{
+ GCacheNode *node = g_slice_new (GCacheNode);
+ node->value = value;
+ node->ref_count = 1;
+ return node;
+}
+
+static inline void
+g_cache_node_destroy (GCacheNode *node)
+{
+ g_slice_free (GCacheNode, node);
+}
+
+GCache*
+g_cache_new (GCacheNewFunc value_new_func,
+ GCacheDestroyFunc value_destroy_func,
+ GCacheDupFunc key_dup_func,
+ GCacheDestroyFunc key_destroy_func,
+ GHashFunc hash_key_func,
+ GHashFunc hash_value_func,
+ GEqualFunc key_equal_func)
+{
+ GCache *cache;
+
+ g_return_val_if_fail (value_new_func != NULL, NULL);
+ g_return_val_if_fail (value_destroy_func != NULL, NULL);
+ g_return_val_if_fail (key_dup_func != NULL, NULL);
+ g_return_val_if_fail (key_destroy_func != NULL, NULL);
+ g_return_val_if_fail (hash_key_func != NULL, NULL);
+ g_return_val_if_fail (hash_value_func != NULL, NULL);
+ g_return_val_if_fail (key_equal_func != NULL, NULL);
+
+ cache = g_slice_new (GCache);
+ cache->value_new_func = value_new_func;
+ cache->value_destroy_func = value_destroy_func;
+ cache->key_dup_func = key_dup_func;
+ cache->key_destroy_func = key_destroy_func;
+ cache->key_table = g_hash_table_new (hash_key_func, key_equal_func);
+ cache->value_table = g_hash_table_new (hash_value_func, NULL);
+
+ return cache;
+}
+
+void
+g_cache_destroy (GCache *cache)
+{
+ g_return_if_fail (cache != NULL);
+
+ g_hash_table_destroy (cache->key_table);
+ g_hash_table_destroy (cache->value_table);
+ g_slice_free (GCache, cache);
+}
+
+gpointer
+g_cache_insert (GCache *cache,
+ gpointer key)
+{
+ GCacheNode *node;
+ gpointer value;
+
+ g_return_val_if_fail (cache != NULL, NULL);
+
+ node = g_hash_table_lookup (cache->key_table, key);
+ if (node)
+ {
+ node->ref_count += 1;
+ return node->value;
+ }
+
+ key = (* cache->key_dup_func) (key);
+ value = (* cache->value_new_func) (key);
+ node = g_cache_node_new (value);
+
+ g_hash_table_insert (cache->key_table, key, node);
+ g_hash_table_insert (cache->value_table, value, key);
+
+ return node->value;
+}
+
+void
+g_cache_remove (GCache *cache,
+ gconstpointer value)
+{
+ GCacheNode *node;
+ gpointer key;
+
+ g_return_if_fail (cache != NULL);
+
+ key = g_hash_table_lookup (cache->value_table, value);
+ node = g_hash_table_lookup (cache->key_table, key);
+
+ g_return_if_fail (node != NULL);
+
+ node->ref_count -= 1;
+ if (node->ref_count == 0)
+ {
+ g_hash_table_remove (cache->value_table, value);
+ g_hash_table_remove (cache->key_table, key);
+
+ (* cache->key_destroy_func) (key);
+ (* cache->value_destroy_func) (node->value);
+ g_cache_node_destroy (node);
+ }
+}
+
+void
+g_cache_key_foreach (GCache *cache,
+ GHFunc func,
+ gpointer user_data)
+{
+ g_return_if_fail (cache != NULL);
+ g_return_if_fail (func != NULL);
+
+ g_hash_table_foreach (cache->value_table, func, user_data);
+}
+
+void
+g_cache_value_foreach (GCache *cache,
+ GHFunc func,
+ gpointer user_data)
+{
+ g_return_if_fail (cache != NULL);
+ g_return_if_fail (func != NULL);
+
+ g_hash_table_foreach (cache->key_table, func, user_data);
+}
+
+#define __G_CACHE_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gcache.h b/desmume/src/windows/glib-2.20.1/build/glib/gcache.h
new file mode 100644
index 000000000..283783dbb
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gcache.h
@@ -0,0 +1,69 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_CACHE_H__
+#define __G_CACHE_H__
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct _GCache GCache;
+
+typedef gpointer (*GCacheNewFunc) (gpointer key);
+typedef gpointer (*GCacheDupFunc) (gpointer value);
+typedef void (*GCacheDestroyFunc) (gpointer value);
+
+/* Caches
+ */
+GCache* g_cache_new (GCacheNewFunc value_new_func,
+ GCacheDestroyFunc value_destroy_func,
+ GCacheDupFunc key_dup_func,
+ GCacheDestroyFunc key_destroy_func,
+ GHashFunc hash_key_func,
+ GHashFunc hash_value_func,
+ GEqualFunc key_equal_func);
+void g_cache_destroy (GCache *cache);
+gpointer g_cache_insert (GCache *cache,
+ gpointer key);
+void g_cache_remove (GCache *cache,
+ gconstpointer value);
+void g_cache_key_foreach (GCache *cache,
+ GHFunc func,
+ gpointer user_data);
+#ifndef G_DISABLE_DEPRECATED
+void g_cache_value_foreach (GCache *cache,
+ GHFunc func,
+ gpointer user_data);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_CACHE_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gchecksum.c b/desmume/src/windows/glib-2.20.1/build/glib/gchecksum.c
new file mode 100644
index 000000000..1611193d4
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gchecksum.c
@@ -0,0 +1,1439 @@
+/* gchecksum.h - data hashing functions
+ *
+ * Copyright (C) 2007 Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include
+
+#include "glibconfig.h"
+#include "gchecksum.h"
+#include "glib.h"
+#include "glibintl.h"
+
+#include "galias.h"
+
+#define IS_VALID_TYPE(type) ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA256)
+
+/* The fact that these are lower case characters is part of the ABI */
+static const gchar hex_digits[] = "0123456789abcdef";
+
+#define MD5_DATASIZE 64
+#define MD5_DIGEST_LEN 16
+
+typedef struct
+{
+ guint32 buf[4];
+ guint32 bits[2];
+
+ guchar data[MD5_DATASIZE];
+
+ guchar digest[MD5_DIGEST_LEN];
+} Md5sum;
+
+#define SHA1_DATASIZE 64
+#define SHA1_DIGEST_LEN 20
+
+typedef struct
+{
+ guint32 buf[5];
+ guint32 bits[2];
+
+ /* we pack 64 unsigned chars into 16 32-bit unsigned integers */
+ guint32 data[16];
+
+ guchar digest[SHA1_DIGEST_LEN];
+} Sha1sum;
+
+#define SHA256_DATASIZE 64
+#define SHA256_DIGEST_LEN 32
+
+typedef struct
+{
+ guint32 buf[8];
+ guint32 bits[2];
+
+ guint8 data[SHA256_DATASIZE];
+
+ guchar digest[SHA256_DIGEST_LEN];
+} Sha256sum;
+
+struct _GChecksum
+{
+ GChecksumType type;
+
+ gchar *digest_str;
+
+ union {
+ Md5sum md5;
+ Sha1sum sha1;
+ Sha256sum sha256;
+ } sum;
+};
+
+/* we need different byte swapping functions because MD5 expects buffers
+ * to be little-endian, while SHA1 and SHA256 expect them in big-endian
+ * form.
+ */
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define md5_byte_reverse(buffer,length)
+#else
+/* assume that the passed buffer is integer aligned */
+static inline void
+md5_byte_reverse (guchar *buffer,
+ gulong length)
+{
+ guint32 bit;
+
+ do
+ {
+ bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 |
+ ((unsigned) buffer[1] << 8 | buffer[0]);
+ * (guint32 *) buffer = bit;
+ buffer += 4;
+ }
+ while (--length);
+}
+#endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define sha_byte_reverse(buffer,length)
+#else
+static inline void
+sha_byte_reverse (guint32 *buffer,
+ gint length)
+{
+ length /= sizeof (guint32);
+ while (length--)
+ {
+ *buffer = GUINT32_SWAP_LE_BE (*buffer);
+ ++buffer;
+ }
+}
+#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
+
+static gchar *
+digest_to_string (guint8 *digest,
+ gsize digest_len)
+{
+ gint len = digest_len * 2;
+ gint i;
+ gchar *retval;
+
+ retval = g_new (gchar, len + 1);
+
+ for (i = 0; i < digest_len; i++)
+ {
+ guint8 byte = digest[i];
+
+ retval[2 * i] = hex_digits[byte >> 4];
+ retval[2 * i + 1] = hex_digits[byte & 0xf];
+ }
+
+ retval[len] = 0;
+
+ return retval;
+}
+
+/*
+ * MD5 Checksum
+ */
+
+/* This MD5 digest computation is based on the equivalent code
+ * written by Colin Plumb. It came with this notice:
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+static void
+md5_sum_init (Md5sum *md5)
+{
+ /* arbitrary constants */
+ md5->buf[0] = 0x67452301;
+ md5->buf[1] = 0xefcdab89;
+ md5->buf[2] = 0x98badcfe;
+ md5->buf[3] = 0x10325476;
+
+ md5->bits[0] = md5->bits[1] = 0;
+}
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. md5_sum_update()
+ * blocks the data and converts bytes into longwords for this routine.
+ */
+static void
+md5_transform (guint32 buf[4],
+ guint32 const in[16])
+{
+ register guint32 a, b, c, d;
+
+/* The four core functions - F1 is optimized somewhat */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1 (z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define md5_step(f, w, x, y, z, data, s) \
+ ( w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x )
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ md5_step (F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ md5_step (F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ md5_step (F1, c, d, a, b, in[2] + 0x242070db, 17);
+ md5_step (F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ md5_step (F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ md5_step (F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ md5_step (F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ md5_step (F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ md5_step (F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ md5_step (F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ md5_step (F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ md5_step (F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ md5_step (F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ md5_step (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ md5_step (F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ md5_step (F2, d, a, b, c, in[10] + 0x02441453, 9);
+ md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ md5_step (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ md5_step (F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ md5_step (F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ md5_step (F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ md5_step (F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ md5_step (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ md5_step (F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ md5_step (F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ md5_step (F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ md5_step (F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ md5_step (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ md5_step (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ md5_step (F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ md5_step (F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ md5_step (F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ md5_step (F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ md5_step (F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ md5_step (F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ md5_step (F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ md5_step (F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ md5_step (F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ md5_step (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ md5_step (F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ md5_step (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ md5_step (F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ md5_step (F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ md5_step (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ md5_step (F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+
+#undef F1
+#undef F2
+#undef F3
+#undef F4
+#undef md5_step
+}
+
+static void
+md5_sum_update (Md5sum *md5,
+ const guchar *data,
+ gsize length)
+{
+ guint32 bit;
+
+ bit = md5->bits[0];
+ md5->bits[0] = bit + ((guint32) length << 3);
+
+ /* carry from low to high */
+ if (md5->bits[0] < bit)
+ md5->bits[1] += 1;
+
+ md5->bits[1] += length >> 29;
+
+ /* bytes already in Md5sum->data */
+ bit = (bit >> 3) & 0x3f;
+
+ /* handle any leading odd-sized chunks */
+ if (bit)
+ {
+ guchar *p = (guchar *) md5->data + bit;
+
+ bit = MD5_DATASIZE - bit;
+ if (length < bit)
+ {
+ memcpy (p, data, length);
+ return;
+ }
+
+ memcpy (p, data, bit);
+
+ md5_byte_reverse (md5->data, 16);
+ md5_transform (md5->buf, (guint32 *) md5->data);
+
+ data += bit;
+ length -= bit;
+ }
+
+ /* process data in 64-byte chunks */
+ while (length >= MD5_DATASIZE)
+ {
+ memcpy (md5->data, data, MD5_DATASIZE);
+
+ md5_byte_reverse (md5->data, 16);
+ md5_transform (md5->buf, (guint32 *) md5->data);
+
+ data += MD5_DATASIZE;
+ length -= MD5_DATASIZE;
+ }
+
+ /* handle any remaining bytes of data */
+ memcpy (md5->data, data, length);
+}
+
+/* closes a checksum */
+static void
+md5_sum_close (Md5sum *md5)
+{
+ guint count;
+ guchar *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (md5->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80.
+ * This is safe since there is always at least one byte free
+ */
+ p = md5->data + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = MD5_DATASIZE - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8)
+ {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset (p, 0, count);
+
+ md5_byte_reverse (md5->data, 16);
+ md5_transform (md5->buf, (guint32 *) md5->data);
+
+ /* Now fill the next block with 56 bytes */
+ memset (md5->data, 0, MD5_DATASIZE - 8);
+ }
+ else
+ {
+ /* Pad block to 56 bytes */
+ memset (p, 0, count - 8);
+ }
+
+ md5_byte_reverse (md5->data, 14);
+
+ /* Append length in bits and transform */
+ ((guint32 *) md5->data)[14] = md5->bits[0];
+ ((guint32 *) md5->data)[15] = md5->bits[1];
+
+ md5_transform (md5->buf, (guint32 *) md5->data);
+ md5_byte_reverse ((guchar *) md5->buf, 4);
+
+ memcpy (md5->digest, md5->buf, 16);
+
+ /* Reset buffers in case they contain sensitive data */
+ memset (md5->buf, 0, sizeof (md5->buf));
+ memset (md5->data, 0, sizeof (md5->data));
+}
+
+static gchar *
+md5_sum_to_string (Md5sum *md5)
+{
+ return digest_to_string (md5->digest, MD5_DIGEST_LEN);
+}
+
+static void
+md5_sum_digest (Md5sum *md5,
+ guint8 *digest)
+{
+ gint i;
+
+ for (i = 0; i < MD5_DIGEST_LEN; i++)
+ digest[i] = md5->digest[i];
+}
+
+/*
+ * SHA-1 Checksum
+ */
+
+/* The following implementation comes from D-Bus dbus-sha.c. I've changed
+ * it to use GLib types and to work more like the MD5 implementation above.
+ * I left the comments to have an history of this code.
+ * -- Emmanuele Bassi, ebassi@gnome.org
+ */
+
+/* The following comments have the history of where this code
+ * comes from. I actually copied it from GNet in GNOME CVS.
+ * - hp@redhat.com
+ */
+
+/*
+ * sha.h : Implementation of the Secure Hash Algorithm
+ *
+ * Part of the Python Cryptography Toolkit, version 1.0.0
+ *
+ * Copyright (C) 1995, A.M. Kuchling
+ *
+ * Distribute and use freely; there are no restrictions on further
+ * dissemination and usage except those imposed by the laws of your
+ * country of residence.
+ *
+ */
+
+/* SHA: NIST's Secure Hash Algorithm */
+
+/* Based on SHA code originally posted to sci.crypt by Peter Gutmann
+ in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
+ Modified to test for endianness on creation of SHA objects by AMK.
+ Also, the original specification of SHA was found to have a weakness
+ by NSA/NIST. This code implements the fixed version of SHA.
+*/
+
+/* Here's the first paragraph of Peter Gutmann's posting:
+
+The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
+SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
+what's changed in the new version. The fix is a simple change which involves
+adding a single rotate in the initial expansion function. It is unknown
+whether this is an optimal solution to the problem which was discovered in the
+SHA or whether it's simply a bandaid which fixes the problem with a minimum of
+effort (for example the reengineering of a great many Capstone chips).
+*/
+
+static void
+sha1_sum_init (Sha1sum *sha1)
+{
+ /* initialize constants */
+ sha1->buf[0] = 0x67452301L;
+ sha1->buf[1] = 0xEFCDAB89L;
+ sha1->buf[2] = 0x98BADCFEL;
+ sha1->buf[3] = 0x10325476L;
+ sha1->buf[4] = 0xC3D2E1F0L;
+
+ /* initialize bits */
+ sha1->bits[0] = sha1->bits[1] = 0;
+}
+
+/* The SHA f()-functions. */
+
+#define f1(x,y,z) (z ^ (x & (y ^ z))) /* Rounds 0-19 */
+#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39 */
+#define f3(x,y,z) (( x & y) | (z & (x | y))) /* Rounds 40-59 */
+#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79 */
+
+/* The SHA Mysterious Constants */
+#define K1 0x5A827999L /* Rounds 0-19 */
+#define K2 0x6ED9EBA1L /* Rounds 20-39 */
+#define K3 0x8F1BBCDCL /* Rounds 40-59 */
+#define K4 0xCA62C1D6L /* Rounds 60-79 */
+
+/* 32-bit rotate left - kludged with shifts */
+#define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n)))
+
+/* The initial expanding function. The hash function is defined over an
+ 80-word expanded input array W, where the first 16 are copies of the input
+ data, and the remaining 64 are defined by
+
+ W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+ This implementation generates these values on the fly in a circular
+ buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+ optimization.
+
+ The updated SHA changes the expanding function by adding a rotate of 1
+ bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+ for this information */
+
+#define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i & 15] ^ \
+ W[(i - 14) & 15] ^ \
+ W[(i - 8) & 15] ^ \
+ W[(i - 3) & 15])))
+
+
+/* The prototype SHA sub-round. The fundamental sub-round is:
+
+ a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+ b' = a;
+ c' = ROTL( 30, b );
+ d' = c;
+ e' = d;
+
+ but this is implemented by unrolling the loop 5 times and renaming the
+ variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+ This code is then replicated 20 times for each of the 4 functions, using
+ the next 20 values from the W[] array each time */
+
+#define subRound(a, b, c, d, e, f, k, data) \
+ (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b))
+
+static void
+sha1_transform (guint32 buf[5],
+ guint32 in[16])
+{
+ guint32 A, B, C, D, E;
+
+ A = buf[0];
+ B = buf[1];
+ C = buf[2];
+ D = buf[3];
+ E = buf[4];
+
+ /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+ subRound (A, B, C, D, E, f1, K1, in[0]);
+ subRound (E, A, B, C, D, f1, K1, in[1]);
+ subRound (D, E, A, B, C, f1, K1, in[2]);
+ subRound (C, D, E, A, B, f1, K1, in[3]);
+ subRound (B, C, D, E, A, f1, K1, in[4]);
+ subRound (A, B, C, D, E, f1, K1, in[5]);
+ subRound (E, A, B, C, D, f1, K1, in[6]);
+ subRound (D, E, A, B, C, f1, K1, in[7]);
+ subRound (C, D, E, A, B, f1, K1, in[8]);
+ subRound (B, C, D, E, A, f1, K1, in[9]);
+ subRound (A, B, C, D, E, f1, K1, in[10]);
+ subRound (E, A, B, C, D, f1, K1, in[11]);
+ subRound (D, E, A, B, C, f1, K1, in[12]);
+ subRound (C, D, E, A, B, f1, K1, in[13]);
+ subRound (B, C, D, E, A, f1, K1, in[14]);
+ subRound (A, B, C, D, E, f1, K1, in[15]);
+ subRound (E, A, B, C, D, f1, K1, expand (in, 16));
+ subRound (D, E, A, B, C, f1, K1, expand (in, 17));
+ subRound (C, D, E, A, B, f1, K1, expand (in, 18));
+ subRound (B, C, D, E, A, f1, K1, expand (in, 19));
+
+ subRound (A, B, C, D, E, f2, K2, expand (in, 20));
+ subRound (E, A, B, C, D, f2, K2, expand (in, 21));
+ subRound (D, E, A, B, C, f2, K2, expand (in, 22));
+ subRound (C, D, E, A, B, f2, K2, expand (in, 23));
+ subRound (B, C, D, E, A, f2, K2, expand (in, 24));
+ subRound (A, B, C, D, E, f2, K2, expand (in, 25));
+ subRound (E, A, B, C, D, f2, K2, expand (in, 26));
+ subRound (D, E, A, B, C, f2, K2, expand (in, 27));
+ subRound (C, D, E, A, B, f2, K2, expand (in, 28));
+ subRound (B, C, D, E, A, f2, K2, expand (in, 29));
+ subRound (A, B, C, D, E, f2, K2, expand (in, 30));
+ subRound (E, A, B, C, D, f2, K2, expand (in, 31));
+ subRound (D, E, A, B, C, f2, K2, expand (in, 32));
+ subRound (C, D, E, A, B, f2, K2, expand (in, 33));
+ subRound (B, C, D, E, A, f2, K2, expand (in, 34));
+ subRound (A, B, C, D, E, f2, K2, expand (in, 35));
+ subRound (E, A, B, C, D, f2, K2, expand (in, 36));
+ subRound (D, E, A, B, C, f2, K2, expand (in, 37));
+ subRound (C, D, E, A, B, f2, K2, expand (in, 38));
+ subRound (B, C, D, E, A, f2, K2, expand (in, 39));
+
+ subRound (A, B, C, D, E, f3, K3, expand (in, 40));
+ subRound (E, A, B, C, D, f3, K3, expand (in, 41));
+ subRound (D, E, A, B, C, f3, K3, expand (in, 42));
+ subRound (C, D, E, A, B, f3, K3, expand (in, 43));
+ subRound (B, C, D, E, A, f3, K3, expand (in, 44));
+ subRound (A, B, C, D, E, f3, K3, expand (in, 45));
+ subRound (E, A, B, C, D, f3, K3, expand (in, 46));
+ subRound (D, E, A, B, C, f3, K3, expand (in, 47));
+ subRound (C, D, E, A, B, f3, K3, expand (in, 48));
+ subRound (B, C, D, E, A, f3, K3, expand (in, 49));
+ subRound (A, B, C, D, E, f3, K3, expand (in, 50));
+ subRound (E, A, B, C, D, f3, K3, expand (in, 51));
+ subRound (D, E, A, B, C, f3, K3, expand (in, 52));
+ subRound (C, D, E, A, B, f3, K3, expand (in, 53));
+ subRound (B, C, D, E, A, f3, K3, expand (in, 54));
+ subRound (A, B, C, D, E, f3, K3, expand (in, 55));
+ subRound (E, A, B, C, D, f3, K3, expand (in, 56));
+ subRound (D, E, A, B, C, f3, K3, expand (in, 57));
+ subRound (C, D, E, A, B, f3, K3, expand (in, 58));
+ subRound (B, C, D, E, A, f3, K3, expand (in, 59));
+
+ subRound (A, B, C, D, E, f4, K4, expand (in, 60));
+ subRound (E, A, B, C, D, f4, K4, expand (in, 61));
+ subRound (D, E, A, B, C, f4, K4, expand (in, 62));
+ subRound (C, D, E, A, B, f4, K4, expand (in, 63));
+ subRound (B, C, D, E, A, f4, K4, expand (in, 64));
+ subRound (A, B, C, D, E, f4, K4, expand (in, 65));
+ subRound (E, A, B, C, D, f4, K4, expand (in, 66));
+ subRound (D, E, A, B, C, f4, K4, expand (in, 67));
+ subRound (C, D, E, A, B, f4, K4, expand (in, 68));
+ subRound (B, C, D, E, A, f4, K4, expand (in, 69));
+ subRound (A, B, C, D, E, f4, K4, expand (in, 70));
+ subRound (E, A, B, C, D, f4, K4, expand (in, 71));
+ subRound (D, E, A, B, C, f4, K4, expand (in, 72));
+ subRound (C, D, E, A, B, f4, K4, expand (in, 73));
+ subRound (B, C, D, E, A, f4, K4, expand (in, 74));
+ subRound (A, B, C, D, E, f4, K4, expand (in, 75));
+ subRound (E, A, B, C, D, f4, K4, expand (in, 76));
+ subRound (D, E, A, B, C, f4, K4, expand (in, 77));
+ subRound (C, D, E, A, B, f4, K4, expand (in, 78));
+ subRound (B, C, D, E, A, f4, K4, expand (in, 79));
+
+ /* Build message digest */
+ buf[0] += A;
+ buf[1] += B;
+ buf[2] += C;
+ buf[3] += D;
+ buf[4] += E;
+}
+
+#undef K1
+#undef K2
+#undef K3
+#undef K4
+#undef f1
+#undef f2
+#undef f3
+#undef f4
+#undef ROTL
+#undef expand
+#undef subRound
+
+static void
+sha1_sum_update (Sha1sum *sha1,
+ const guchar *buffer,
+ gsize count)
+{
+ guint32 tmp;
+ guint dataCount;
+
+ /* Update bitcount */
+ tmp = sha1->bits[0];
+ if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp)
+ sha1->bits[1] += 1; /* Carry from low to high */
+ sha1->bits[1] += count >> 29;
+
+ /* Get count of bytes already in data */
+ dataCount = (guint) (tmp >> 3) & 0x3F;
+
+ /* Handle any leading odd-sized chunks */
+ if (dataCount)
+ {
+ guchar *p = (guchar *) sha1->data + dataCount;
+
+ dataCount = SHA1_DATASIZE - dataCount;
+ if (count < dataCount)
+ {
+ memcpy (p, buffer, count);
+ return;
+ }
+
+ memcpy (p, buffer, dataCount);
+
+ sha_byte_reverse (sha1->data, SHA1_DATASIZE);
+ sha1_transform (sha1->buf, sha1->data);
+
+ buffer += dataCount;
+ count -= dataCount;
+ }
+
+ /* Process data in SHA1_DATASIZE chunks */
+ while (count >= SHA1_DATASIZE)
+ {
+ memcpy (sha1->data, buffer, SHA1_DATASIZE);
+
+ sha_byte_reverse (sha1->data, SHA1_DATASIZE);
+ sha1_transform (sha1->buf, sha1->data);
+
+ buffer += SHA1_DATASIZE;
+ count -= SHA1_DATASIZE;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy (sha1->data, buffer, count);
+}
+
+/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
+ 1 0* (64-bit count of bits processed, MSB-first) */
+static void
+sha1_sum_close (Sha1sum *sha1)
+{
+ gint count;
+ guchar *data_p;
+
+ /* Compute number of bytes mod 64 */
+ count = (gint) ((sha1->bits[0] >> 3) & 0x3f);
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ data_p = (guchar *) sha1->data + count;
+ *data_p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = SHA1_DATASIZE - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8)
+ {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset (data_p, 0, count);
+
+ sha_byte_reverse (sha1->data, SHA1_DATASIZE);
+ sha1_transform (sha1->buf, sha1->data);
+
+ /* Now fill the next block with 56 bytes */
+ memset (sha1->data, 0, SHA1_DATASIZE - 8);
+ }
+ else
+ {
+ /* Pad block to 56 bytes */
+ memset (data_p, 0, count - 8);
+ }
+
+ /* Append length in bits and transform */
+ sha1->data[14] = sha1->bits[1];
+ sha1->data[15] = sha1->bits[0];
+
+ sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8);
+ sha1_transform (sha1->buf, sha1->data);
+ sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN);
+
+ memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN);
+
+ /* Reset buffers in case they contain sensitive data */
+ memset (sha1->buf, 0, sizeof (sha1->buf));
+ memset (sha1->data, 0, sizeof (sha1->data));
+}
+
+static gchar *
+sha1_sum_to_string (Sha1sum *sha1)
+{
+ return digest_to_string (sha1->digest, SHA1_DIGEST_LEN);
+}
+
+static void
+sha1_sum_digest (Sha1sum *sha1,
+ guint8 *digest)
+{
+ gint i;
+
+ for (i = 0; i < SHA1_DIGEST_LEN; i++)
+ digest[i] = sha1->digest[i];
+}
+
+/*
+ * SHA-256 Checksum
+ */
+
+/* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c.
+ *
+ * Copyright (C) 2006 Dave Benson
+ * Released under the terms of the GNU Lesser General Public License
+ */
+
+static void
+sha256_sum_init (Sha256sum *sha256)
+{
+ sha256->buf[0] = 0x6a09e667;
+ sha256->buf[1] = 0xbb67ae85;
+ sha256->buf[2] = 0x3c6ef372;
+ sha256->buf[3] = 0xa54ff53a;
+ sha256->buf[4] = 0x510e527f;
+ sha256->buf[5] = 0x9b05688c;
+ sha256->buf[6] = 0x1f83d9ab;
+ sha256->buf[7] = 0x5be0cd19;
+
+ sha256->bits[0] = sha256->bits[1] = 0;
+}
+
+#define GET_UINT32(n,b,i) G_STMT_START{ \
+ (n) = ((guint32) (b)[(i) ] << 24) \
+ | ((guint32) (b)[(i) + 1] << 16) \
+ | ((guint32) (b)[(i) + 2] << 8) \
+ | ((guint32) (b)[(i) + 3] ); } G_STMT_END
+
+#define PUT_UINT32(n,b,i) G_STMT_START{ \
+ (b)[(i) ] = (guint8) ((n) >> 24); \
+ (b)[(i) + 1] = (guint8) ((n) >> 16); \
+ (b)[(i) + 2] = (guint8) ((n) >> 8); \
+ (b)[(i) + 3] = (guint8) ((n) ); } G_STMT_END
+
+static void
+sha256_transform (guint32 buf[8],
+ guint8 const data[64])
+{
+ guint32 temp1, temp2, W[64];
+ guint32 A, B, C, D, E, F, G, H;
+
+ GET_UINT32 (W[0], data, 0);
+ GET_UINT32 (W[1], data, 4);
+ GET_UINT32 (W[2], data, 8);
+ GET_UINT32 (W[3], data, 12);
+ GET_UINT32 (W[4], data, 16);
+ GET_UINT32 (W[5], data, 20);
+ GET_UINT32 (W[6], data, 24);
+ GET_UINT32 (W[7], data, 28);
+ GET_UINT32 (W[8], data, 32);
+ GET_UINT32 (W[9], data, 36);
+ GET_UINT32 (W[10], data, 40);
+ GET_UINT32 (W[11], data, 44);
+ GET_UINT32 (W[12], data, 48);
+ GET_UINT32 (W[13], data, 52);
+ GET_UINT32 (W[14], data, 56);
+ GET_UINT32 (W[15], data, 60);
+
+#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR (x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^ SHR (x, 3))
+#define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^ SHR (x,10))
+#define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22))
+#define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t) (W[t] = S1(W[t - 2]) + W[t - 7] + \
+ S0(W[t - 15]) + W[t - 16])
+
+#define P(a,b,c,d,e,f,g,h,x,K) G_STMT_START { \
+ temp1 = h + S3(e) + F1(e,f,g) + K + x; \
+ temp2 = S2(a) + F0(a,b,c); \
+ d += temp1; h = temp1 + temp2; } G_STMT_END
+
+ A = buf[0];
+ B = buf[1];
+ C = buf[2];
+ D = buf[3];
+ E = buf[4];
+ F = buf[5];
+ G = buf[6];
+ H = buf[7];
+
+ P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
+ P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
+ P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
+ P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
+ P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
+ P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
+ P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
+ P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
+ P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
+ P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
+ P (G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+ P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+ P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+ P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+ P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+ P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+ P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+ P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+ P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+ P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+ P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+ P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+ P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+ P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+ P (A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+ P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+ P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+ P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+ P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+ P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+ P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+ P (B, C, D, E, F, G, H, A, R(31), 0x14292967);
+ P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+ P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+ P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+ P (F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+ P (E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+ P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+ P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+ P (B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+ P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+ P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+ P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+ P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+ P (E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+ P (D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+ P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+ P (B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+ P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+ P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+ P (G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+ P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+ P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+ P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+ P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+ P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+ P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+ P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+ P (G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+ P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+ P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+ P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+ P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+ P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+#undef SHR
+#undef ROTR
+#undef S0
+#undef S1
+#undef S2
+#undef S3
+#undef F0
+#undef F1
+#undef R
+#undef P
+
+ buf[0] += A;
+ buf[1] += B;
+ buf[2] += C;
+ buf[3] += D;
+ buf[4] += E;
+ buf[5] += F;
+ buf[6] += G;
+ buf[7] += H;
+}
+
+static void
+sha256_sum_update (Sha256sum *sha256,
+ const guchar *buffer,
+ gsize length)
+{
+ guint32 left, fill;
+ const guint8 *input = buffer;
+
+ if (length == 0)
+ return;
+
+ left = sha256->bits[0] & 0x3F;
+ fill = 64 - left;
+
+ sha256->bits[0] += length;
+ sha256->bits[0] &= 0xFFFFFFFF;
+
+ if (sha256->bits[0] < length)
+ sha256->bits[1]++;
+
+ if (left > 0 && length >= fill)
+ {
+ memcpy ((sha256->data + left), input, fill);
+
+ sha256_transform (sha256->buf, sha256->data);
+ length -= fill;
+ input += fill;
+
+ left = 0;
+ }
+
+ while (length >= SHA256_DATASIZE)
+ {
+ sha256_transform (sha256->buf, input);
+
+ length -= 64;
+ input += 64;
+ }
+
+ if (length)
+ memcpy (sha256->data + left, input, length);
+}
+
+static guint8 sha256_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 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 void
+sha256_sum_close (Sha256sum *sha256)
+{
+ guint32 last, padn;
+ guint32 high, low;
+ guint8 msglen[8];
+
+ high = (sha256->bits[0] >> 29)
+ | (sha256->bits[1] << 3);
+ low = (sha256->bits[0] << 3);
+
+ PUT_UINT32 (high, msglen, 0);
+ PUT_UINT32 (low, msglen, 4);
+
+ last = sha256->bits[0] & 0x3F;
+ padn = (last < 56) ? (56 - last) : (120 - last);
+
+ sha256_sum_update (sha256, sha256_padding, padn);
+ sha256_sum_update (sha256, msglen, 8);
+
+ PUT_UINT32 (sha256->buf[0], sha256->digest, 0);
+ PUT_UINT32 (sha256->buf[1], sha256->digest, 4);
+ PUT_UINT32 (sha256->buf[2], sha256->digest, 8);
+ PUT_UINT32 (sha256->buf[3], sha256->digest, 12);
+ PUT_UINT32 (sha256->buf[4], sha256->digest, 16);
+ PUT_UINT32 (sha256->buf[5], sha256->digest, 20);
+ PUT_UINT32 (sha256->buf[6], sha256->digest, 24);
+ PUT_UINT32 (sha256->buf[7], sha256->digest, 28);
+}
+
+#undef PUT_UINT32
+#undef GET_UINT32
+
+static gchar *
+sha256_sum_to_string (Sha256sum *sha256)
+{
+ return digest_to_string (sha256->digest, SHA256_DIGEST_LEN);
+}
+
+static void
+sha256_sum_digest (Sha256sum *sha256,
+ guint8 *digest)
+{
+ gint i;
+
+ for (i = 0; i < SHA256_DIGEST_LEN; i++)
+ digest[i] = sha256->digest[i];
+}
+
+
+/*
+ * Public API
+ */
+
+/**
+ * g_checksum_type_get_length:
+ * @checksum_type: a #GChecksumType
+ *
+ * Gets the length in bytes of digests of type @checksum_type
+ *
+ * Return value: the checksum length, or -1 if @checksum_type is
+ * not supported.
+ *
+ * Since: 2.16
+ */
+gssize
+g_checksum_type_get_length (GChecksumType checksum_type)
+{
+ gssize len = -1;
+
+ switch (checksum_type)
+ {
+ case G_CHECKSUM_MD5:
+ len = MD5_DIGEST_LEN;
+ break;
+ case G_CHECKSUM_SHA1:
+ len = SHA1_DIGEST_LEN;
+ break;
+ case G_CHECKSUM_SHA256:
+ len = SHA256_DIGEST_LEN;
+ break;
+ default:
+ len = -1;
+ break;
+ }
+
+ return len;
+}
+
+/**
+ * g_checksum_new:
+ * @checksum_type: the desired type of checksum
+ *
+ * Creates a new #GChecksum, using the checksum algorithm @checksum_type.
+ * If the @checksum_type is not known, %NULL is returned.
+ * A #GChecksum can be used to compute the checksum, or digest, of an
+ * arbitrary binary blob, using different hashing algorithms.
+ *
+ * A #GChecksum works by feeding a binary blob through g_checksum_update()
+ * until there is data to be checked; the digest can then be extracted
+ * using g_checksum_get_string(), which will return the checksum as a
+ * hexadecimal string; or g_checksum_get_digest(), which will return a
+ * vector of raw bytes. Once either g_checksum_get_string() or
+ * g_checksum_get_digest() have been called on a #GChecksum, the checksum
+ * will be closed and it won't be possible to call g_checksum_update()
+ * on it anymore.
+ *
+ * Return value: the newly created #GChecksum, or %NULL.
+ * Use g_checksum_free() to free the memory allocated by it.
+ *
+ * Since: 2.16
+ */
+GChecksum *
+g_checksum_new (GChecksumType checksum_type)
+{
+ GChecksum *checksum;
+
+ if (! IS_VALID_TYPE (checksum_type))
+ return NULL;
+
+ checksum = g_slice_new0 (GChecksum);
+ checksum->type = checksum_type;
+
+ g_checksum_reset (checksum);
+
+ return checksum;
+}
+
+/**
+ * g_checksum_reset:
+ * @checksum: the #GChecksum to reset
+ *
+ * Resets the state of the @checksum back to its initial state.
+ *
+ * Since: 2.18
+ **/
+void
+g_checksum_reset (GChecksum *checksum)
+{
+ g_return_if_fail (checksum != NULL);
+
+ g_free (checksum->digest_str);
+ checksum->digest_str = NULL;
+
+ switch (checksum->type)
+ {
+ case G_CHECKSUM_MD5:
+ md5_sum_init (&(checksum->sum.md5));
+ break;
+ case G_CHECKSUM_SHA1:
+ sha1_sum_init (&(checksum->sum.sha1));
+ break;
+ case G_CHECKSUM_SHA256:
+ sha256_sum_init (&(checksum->sum.sha256));
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+/**
+ * g_checksum_copy:
+ * @checksum: the #GChecksum to copy
+ *
+ * Copies a #GChecksum. If @checksum has been closed, by calling
+ * g_checksum_get_string() or g_checksum_get_digest(), the copied
+ * checksum will be closed as well.
+ *
+ * Return value: the copy of the passed #GChecksum. Use g_checksum_free()
+ * when finished using it.
+ *
+ * Since: 2.16
+ */
+GChecksum *
+g_checksum_copy (const GChecksum *checksum)
+{
+ GChecksum *copy;
+
+ g_return_val_if_fail (checksum != NULL, NULL);
+
+ copy = g_slice_new (GChecksum);
+ *copy = *checksum;
+
+ copy->digest_str = g_strdup (checksum->digest_str);
+
+ return copy;
+}
+
+/**
+ * g_checksum_free:
+ * @checksum: a #GChecksum
+ *
+ * Frees the memory allocated for @checksum.
+ *
+ * Since: 2.16
+ */
+void
+g_checksum_free (GChecksum *checksum)
+{
+ if (G_LIKELY (checksum))
+ {
+ g_free (checksum->digest_str);
+
+ g_slice_free (GChecksum, checksum);
+ }
+}
+
+/**
+ * g_checksum_update:
+ * @checksum: a #GChecksum
+ * @data: buffer used to compute the checksum
+ * @length: size of the buffer, or -1 if it is a null-terminated string.
+ *
+ * Feeds @data into an existing #GChecksum. The checksum must still be
+ * open, that is g_checksum_get_string() or g_checksum_get_digest() must
+ * not have been called on @checksum.
+ *
+ * Since: 2.16
+ */
+void
+g_checksum_update (GChecksum *checksum,
+ const guchar *data,
+ gssize length)
+{
+ g_return_if_fail (checksum != NULL);
+ g_return_if_fail (data != NULL);
+
+ if (length < 0)
+ length = strlen ((const gchar *) data);
+
+ if (checksum->digest_str)
+ {
+ g_warning ("The checksum `%s' has been closed and cannot be updated "
+ "anymore.",
+ checksum->digest_str);
+ return;
+ }
+
+ switch (checksum->type)
+ {
+ case G_CHECKSUM_MD5:
+ md5_sum_update (&(checksum->sum.md5), data, length);
+ break;
+ case G_CHECKSUM_SHA1:
+ sha1_sum_update (&(checksum->sum.sha1), data, length);
+ break;
+ case G_CHECKSUM_SHA256:
+ sha256_sum_update (&(checksum->sum.sha256), data, length);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+/**
+ * g_checksum_get_string:
+ * @checksum: a #GChecksum
+ *
+ * Gets the digest as an hexadecimal string.
+ *
+ * Once this function has been called the #GChecksum can no longer be
+ * updated with g_checksum_update().
+ *
+ * The hexadecimal characters will be lower case.
+ *
+ * Return value: the hexadecimal representation of the checksum. The
+ * returned string is owned by the checksum and should not be modified
+ * or freed.
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar *
+g_checksum_get_string (GChecksum *checksum)
+{
+ gchar *str = NULL;
+
+ g_return_val_if_fail (checksum != NULL, NULL);
+
+ if (checksum->digest_str)
+ return checksum->digest_str;
+
+ switch (checksum->type)
+ {
+ case G_CHECKSUM_MD5:
+ md5_sum_close (&(checksum->sum.md5));
+ str = md5_sum_to_string (&(checksum->sum.md5));
+ break;
+ case G_CHECKSUM_SHA1:
+ sha1_sum_close (&(checksum->sum.sha1));
+ str = sha1_sum_to_string (&(checksum->sum.sha1));
+ break;
+ case G_CHECKSUM_SHA256:
+ sha256_sum_close (&(checksum->sum.sha256));
+ str = sha256_sum_to_string (&(checksum->sum.sha256));
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ checksum->digest_str = str;
+
+ return checksum->digest_str;
+}
+
+/**
+ * g_checksum_get_digest:
+ * @checksum: a #GChecksum
+ * @buffer: output buffer
+ * @digest_len: an inout parameter. The caller initializes it to the size of @buffer.
+ * After the call it contains the length of the digest.
+ *
+ * Gets the digest from @checksum as a raw binary vector and places it
+ * into @buffer. The size of the digest depends on the type of checksum.
+ *
+ * Once this function has been called, the #GChecksum is closed and can
+ * no longer be updated with g_checksum_update().
+ *
+ * Since: 2.16
+ */
+void
+g_checksum_get_digest (GChecksum *checksum,
+ guint8 *buffer,
+ gsize *digest_len)
+{
+ gboolean checksum_open = FALSE;
+ gchar *str = NULL;
+ gsize len;
+
+ g_return_if_fail (checksum != NULL);
+
+ len = g_checksum_type_get_length (checksum->type);
+ g_return_if_fail (*digest_len >= len);
+
+ checksum_open = !!(checksum->digest_str == NULL);
+
+ switch (checksum->type)
+ {
+ case G_CHECKSUM_MD5:
+ if (checksum_open)
+ {
+ md5_sum_close (&(checksum->sum.md5));
+ str = md5_sum_to_string (&(checksum->sum.md5));
+ }
+ md5_sum_digest (&(checksum->sum.md5), buffer);
+ break;
+ case G_CHECKSUM_SHA1:
+ if (checksum_open)
+ {
+ sha1_sum_close (&(checksum->sum.sha1));
+ str = sha1_sum_to_string (&(checksum->sum.sha1));
+ }
+ sha1_sum_digest (&(checksum->sum.sha1), buffer);
+ break;
+ case G_CHECKSUM_SHA256:
+ if (checksum_open)
+ {
+ sha256_sum_close (&(checksum->sum.sha256));
+ str = sha256_sum_to_string (&(checksum->sum.sha256));
+ }
+ sha256_sum_digest (&(checksum->sum.sha256), buffer);
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ if (str)
+ checksum->digest_str = str;
+
+ *digest_len = len;
+}
+
+/**
+ * g_compute_checksum_for_data:
+ * @checksum_type: a #GChecksumType
+ * @data: binary blob to compute the digest of
+ * @length: length of @data
+ *
+ * Computes the checksum for a binary @data of @length. This is a
+ * convenience wrapper for g_checksum_new(), g_checksum_get_string()
+ * and g_checksum_free().
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Return value: the digest of the binary data as a string in hexadecimal.
+ * The returned string should be freed with g_free() when done using it.
+ *
+ * Since: 2.16
+ */
+gchar *
+g_compute_checksum_for_data (GChecksumType checksum_type,
+ const guchar *data,
+ gsize length)
+{
+ GChecksum *checksum;
+ gchar *retval;
+
+ g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ checksum = g_checksum_new (checksum_type);
+ if (!checksum)
+ return NULL;
+
+ g_checksum_update (checksum, data, length);
+ retval = g_strdup (g_checksum_get_string (checksum));
+ g_checksum_free (checksum);
+
+ return retval;
+}
+
+/**
+ * g_compute_checksum_for_string:
+ * @checksum_type: a #GChecksumType
+ * @str: the string to compute the checksum of
+ * @length: the length of the string, or -1 if the string is null-terminated.
+ *
+ * Computes the checksum of a string.
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Return value: the checksum as a hexadecimal string. The returned string
+ * should be freed with g_free() when done using it.
+ *
+ * Since: 2.16
+ */
+gchar *
+g_compute_checksum_for_string (GChecksumType checksum_type,
+ const gchar *str,
+ gssize length)
+{
+ g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
+ g_return_val_if_fail (str != NULL, NULL);
+
+ if (length < 0)
+ length = strlen (str);
+
+ return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length);
+}
+
+#define __G_CHECKSUM_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gchecksum.h b/desmume/src/windows/glib-2.20.1/build/glib/gchecksum.h
new file mode 100644
index 000000000..03f1e863a
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gchecksum.h
@@ -0,0 +1,86 @@
+/* gchecksum.h - data hashing functions
+ *
+ * Copyright (C) 2007 Emmanuele Bassi
+ *
+ * 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.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_CHECKSUM_H__
+#define __G_CHECKSUM_H__
+
+#include
+
+G_BEGIN_DECLS
+
+/**
+ * GChecksumType:
+ * @G_CHECKSUM_MD5: Use the MD5 hashing algorithm
+ * @G_CHECKSUM_SHA1: Use the SHA-1 hashing algorithm
+ * @G_CHECKSUM_SHA256: Use the SHA-256 hashing algorithm
+ *
+ * The hashing algorithm to be used by #GChecksum when performing the
+ * digest of some data.
+ *
+ * Note that the #GChecksumType enumeration may be extended at a later
+ * date to include new hashing algorithm types.
+ *
+ * Since: 2.16
+ */
+typedef enum {
+ G_CHECKSUM_MD5,
+ G_CHECKSUM_SHA1,
+ G_CHECKSUM_SHA256
+} GChecksumType;
+
+/**
+ * GChecksum:
+ *
+ * An opaque structure representing a checksumming operation.
+ * To create a new GChecksum, use g_checksum_new(). To free
+ * a GChecksum, use g_checksum_free().
+ *
+ * Since: 2.16
+ */
+typedef struct _GChecksum GChecksum;
+
+gssize g_checksum_type_get_length (GChecksumType checksum_type);
+
+GChecksum * g_checksum_new (GChecksumType checksum_type);
+void g_checksum_reset (GChecksum *checksum);
+GChecksum * g_checksum_copy (const GChecksum *checksum);
+void g_checksum_free (GChecksum *checksum);
+void g_checksum_update (GChecksum *checksum,
+ const guchar *data,
+ gssize length);
+G_CONST_RETURN gchar *g_checksum_get_string (GChecksum *checksum);
+void g_checksum_get_digest (GChecksum *checksum,
+ guint8 *buffer,
+ gsize *digest_len);
+
+gchar *g_compute_checksum_for_data (GChecksumType checksum_type,
+ const guchar *data,
+ gsize length);
+gchar *g_compute_checksum_for_string (GChecksumType checksum_type,
+ const gchar *str,
+ gssize length);
+
+G_END_DECLS
+
+#endif /* __G_CHECKSUM_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gcompletion.c b/desmume/src/windows/glib-2.20.1/build/glib/gcompletion.c
new file mode 100644
index 000000000..5d2607846
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gcompletion.c
@@ -0,0 +1,350 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include
+
+#include "glib.h"
+#include "galias.h"
+
+static void completion_check_cache (GCompletion* cmp,
+ gchar** new_prefix);
+
+GCompletion*
+g_completion_new (GCompletionFunc func)
+{
+ GCompletion* gcomp;
+
+ gcomp = g_new (GCompletion, 1);
+ gcomp->items = NULL;
+ gcomp->cache = NULL;
+ gcomp->prefix = NULL;
+ gcomp->func = func;
+ gcomp->strncmp_func = strncmp;
+
+ return gcomp;
+}
+
+void
+g_completion_add_items (GCompletion* cmp,
+ GList* items)
+{
+ GList* it;
+
+ g_return_if_fail (cmp != NULL);
+
+ /* optimize adding to cache? */
+ if (cmp->cache)
+ {
+ g_list_free (cmp->cache);
+ cmp->cache = NULL;
+ }
+
+ if (cmp->prefix)
+ {
+ g_free (cmp->prefix);
+ cmp->prefix = NULL;
+ }
+
+ it = items;
+ while (it)
+ {
+ cmp->items = g_list_prepend (cmp->items, it->data);
+ it = it->next;
+ }
+}
+
+void
+g_completion_remove_items (GCompletion* cmp,
+ GList* items)
+{
+ GList* it;
+
+ g_return_if_fail (cmp != NULL);
+
+ it = items;
+ while (cmp->items && it)
+ {
+ cmp->items = g_list_remove (cmp->items, it->data);
+ it = it->next;
+ }
+
+ it = items;
+ while (cmp->cache && it)
+ {
+ cmp->cache = g_list_remove(cmp->cache, it->data);
+ it = it->next;
+ }
+}
+
+void
+g_completion_clear_items (GCompletion* cmp)
+{
+ g_return_if_fail (cmp != NULL);
+
+ g_list_free (cmp->items);
+ cmp->items = NULL;
+ g_list_free (cmp->cache);
+ cmp->cache = NULL;
+ g_free (cmp->prefix);
+ cmp->prefix = NULL;
+}
+
+static void
+completion_check_cache (GCompletion* cmp,
+ gchar** new_prefix)
+{
+ register GList* list;
+ register gsize len;
+ register gsize i;
+ register gsize plen;
+ gchar* postfix;
+ gchar* s;
+
+ if (!new_prefix)
+ return;
+ if (!cmp->cache)
+ {
+ *new_prefix = NULL;
+ return;
+ }
+
+ len = strlen(cmp->prefix);
+ list = cmp->cache;
+ s = cmp->func ? cmp->func (list->data) : (gchar*) list->data;
+ postfix = s + len;
+ plen = strlen (postfix);
+ list = list->next;
+
+ while (list && plen)
+ {
+ s = cmp->func ? cmp->func (list->data) : (gchar*) list->data;
+ s += len;
+ for (i = 0; i < plen; ++i)
+ {
+ if (postfix[i] != s[i])
+ break;
+ }
+ plen = i;
+ list = list->next;
+ }
+
+ *new_prefix = g_new0 (gchar, len + plen + 1);
+ strncpy (*new_prefix, cmp->prefix, len);
+ strncpy (*new_prefix + len, postfix, plen);
+}
+
+/**
+ * g_completion_complete_utf8:
+ * @cmp: the #GCompletion
+ * @prefix: the prefix string, typically used by the user, which is compared
+ * with each of the items
+ * @new_prefix: if non-%NULL, returns the longest prefix which is common to all
+ * items that matched @prefix, or %NULL if no items matched @prefix.
+ * This string should be freed when no longer needed.
+ *
+ * Attempts to complete the string @prefix using the #GCompletion target items.
+ * In contrast to g_completion_complete(), this function returns the largest common
+ * prefix that is a valid UTF-8 string, omitting a possible common partial
+ * character.
+ *
+ * You should use this function instead of g_completion_complete() if your
+ * items are UTF-8 strings.
+ *
+ * Return value: the list of items whose strings begin with @prefix. This should
+ * not be changed.
+ *
+ * Since: 2.4
+ **/
+GList*
+g_completion_complete_utf8 (GCompletion *cmp,
+ const gchar *prefix,
+ gchar **new_prefix)
+{
+ GList *list;
+ gchar *p, *q;
+
+ list = g_completion_complete (cmp, prefix, new_prefix);
+
+ if (new_prefix && *new_prefix)
+ {
+ p = *new_prefix + strlen (*new_prefix);
+ q = g_utf8_find_prev_char (*new_prefix, p);
+
+ switch (g_utf8_get_char_validated (q, p - q))
+ {
+ case (gunichar)-2:
+ case (gunichar)-1:
+ *q = 0;
+ break;
+ default: ;
+ }
+
+ }
+
+ return list;
+}
+
+GList*
+g_completion_complete (GCompletion* cmp,
+ const gchar* prefix,
+ gchar** new_prefix)
+{
+ gsize plen, len;
+ gboolean done = FALSE;
+ GList* list;
+
+ g_return_val_if_fail (cmp != NULL, NULL);
+ g_return_val_if_fail (prefix != NULL, NULL);
+
+ len = strlen (prefix);
+ if (cmp->prefix && cmp->cache)
+ {
+ plen = strlen (cmp->prefix);
+ if (plen <= len && ! cmp->strncmp_func (prefix, cmp->prefix, plen))
+ {
+ /* use the cache */
+ list = cmp->cache;
+ while (list)
+ {
+ GList *next = list->next;
+
+ if (cmp->strncmp_func (prefix,
+ cmp->func ? cmp->func (list->data) : (gchar*) list->data,
+ len))
+ cmp->cache = g_list_delete_link (cmp->cache, list);
+
+ list = next;
+ }
+ done = TRUE;
+ }
+ }
+
+ if (!done)
+ {
+ /* normal code */
+ g_list_free (cmp->cache);
+ cmp->cache = NULL;
+ list = cmp->items;
+ while (*prefix && list)
+ {
+ if (!cmp->strncmp_func (prefix,
+ cmp->func ? cmp->func (list->data) : (gchar*) list->data,
+ len))
+ cmp->cache = g_list_prepend (cmp->cache, list->data);
+ list = list->next;
+ }
+ }
+ if (cmp->prefix)
+ {
+ g_free (cmp->prefix);
+ cmp->prefix = NULL;
+ }
+ if (cmp->cache)
+ cmp->prefix = g_strdup (prefix);
+ completion_check_cache (cmp, new_prefix);
+
+ return *prefix ? cmp->cache : cmp->items;
+}
+
+void
+g_completion_free (GCompletion* cmp)
+{
+ g_return_if_fail (cmp != NULL);
+
+ g_completion_clear_items (cmp);
+ g_free (cmp);
+}
+
+void
+g_completion_set_compare(GCompletion *cmp,
+ GCompletionStrncmpFunc strncmp_func)
+{
+ cmp->strncmp_func = strncmp_func;
+}
+
+#ifdef TEST_COMPLETION
+#include
+int
+main (int argc,
+ char* argv[])
+{
+ FILE *file;
+ gchar buf[1024];
+ GList *list;
+ GList *result;
+ GList *tmp;
+ GCompletion *cmp;
+ gint i;
+ gchar *longp = NULL;
+
+ if (argc < 3)
+ {
+ g_warning ("Usage: %s filename prefix1 [prefix2 ...]\n", argv[0]);
+ return 1;
+ }
+
+ file = fopen (argv[1], "r");
+ if (!file)
+ {
+ g_warning ("Cannot open %s\n", argv[1]);
+ return 1;
+ }
+
+ cmp = g_completion_new (NULL);
+ list = g_list_alloc ();
+ while (fgets (buf, 1024, file))
+ {
+ list->data = g_strdup (buf);
+ g_completion_add_items (cmp, list);
+ }
+ fclose (file);
+
+ for (i = 2; i < argc; ++i)
+ {
+ printf ("COMPLETING: %s\n", argv[i]);
+ result = g_completion_complete (cmp, argv[i], &longp);
+ g_list_foreach (result, (GFunc) printf, NULL);
+ printf ("LONG MATCH: %s\n", longp);
+ g_free (longp);
+ longp = NULL;
+ }
+
+ g_list_foreach (cmp->items, (GFunc) g_free, NULL);
+ g_completion_free (cmp);
+ g_list_free (list);
+
+ return 0;
+}
+#endif
+
+#define __G_COMPLETION_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gcompletion.h b/desmume/src/windows/glib-2.20.1/build/glib/gcompletion.h
new file mode 100644
index 000000000..900883eef
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gcompletion.h
@@ -0,0 +1,77 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_COMPLETION_H__
+#define __G_COMPLETION_H__
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct _GCompletion GCompletion;
+
+typedef gchar* (*GCompletionFunc) (gpointer);
+
+/* GCompletion
+ */
+
+typedef gint (*GCompletionStrncmpFunc) (const gchar *s1,
+ const gchar *s2,
+ gsize n);
+
+struct _GCompletion
+{
+ GList* items;
+ GCompletionFunc func;
+
+ gchar* prefix;
+ GList* cache;
+ GCompletionStrncmpFunc strncmp_func;
+};
+
+GCompletion* g_completion_new (GCompletionFunc func);
+void g_completion_add_items (GCompletion* cmp,
+ GList* items);
+void g_completion_remove_items (GCompletion* cmp,
+ GList* items);
+void g_completion_clear_items (GCompletion* cmp);
+GList* g_completion_complete (GCompletion* cmp,
+ const gchar* prefix,
+ gchar** new_prefix);
+GList* g_completion_complete_utf8 (GCompletion *cmp,
+ const gchar* prefix,
+ gchar** new_prefix);
+void g_completion_set_compare (GCompletion *cmp,
+ GCompletionStrncmpFunc strncmp_func);
+void g_completion_free (GCompletion* cmp);
+
+G_END_DECLS
+
+#endif /* __G_COMPLETION_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gconvert.c b/desmume/src/windows/glib-2.20.1/build/glib/gconvert.c
new file mode 100644
index 000000000..7aefe24f3
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gconvert.c
@@ -0,0 +1,2116 @@
+/* GLIB - Library of useful routines for C programming
+ *
+ * gconvert.c: Convert between character sets using iconv
+ * Copyright Red Hat Inc., 2000
+ * Authors: Havoc Pennington , Owen Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+
+#ifndef G_OS_WIN32
+#include
+#endif
+#include
+#include
+#include
+#include
+
+#include "gprintfint.h"
+#include "gthreadprivate.h"
+#include "gunicode.h"
+
+#ifdef G_OS_WIN32
+#include "win_iconv.c"
+#endif
+
+#ifdef G_PLATFORM_WIN32
+#define STRICT
+#include
+#undef STRICT
+#endif
+
+#include "glibintl.h"
+
+#if defined(USE_LIBICONV_GNU) && !defined (_LIBICONV_H)
+#error GNU libiconv in use but included iconv.h not from libiconv
+#endif
+#if !defined(USE_LIBICONV_GNU) && defined (_LIBICONV_H)
+#error GNU libiconv not in use but included iconv.h is from libiconv
+#endif
+
+#include "galias.h"
+
+GQuark
+g_convert_error_quark (void)
+{
+ return g_quark_from_static_string ("g_convert_error");
+}
+
+static gboolean
+try_conversion (const char *to_codeset,
+ const char *from_codeset,
+ iconv_t *cd)
+{
+ *cd = iconv_open (to_codeset, from_codeset);
+
+ if (*cd == (iconv_t)-1 && errno == EINVAL)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static gboolean
+try_to_aliases (const char **to_aliases,
+ const char *from_codeset,
+ iconv_t *cd)
+{
+ if (to_aliases)
+ {
+ const char **p = to_aliases;
+ while (*p)
+ {
+ if (try_conversion (*p, from_codeset, cd))
+ return TRUE;
+
+ p++;
+ }
+ }
+
+ return FALSE;
+}
+
+G_GNUC_INTERNAL extern const char **
+_g_charset_get_aliases (const char *canonical_name);
+
+/**
+ * g_iconv_open:
+ * @to_codeset: destination codeset
+ * @from_codeset: source codeset
+ *
+ * Same as the standard UNIX routine iconv_open(), but
+ * may be implemented via libiconv on UNIX flavors that lack
+ * a native implementation.
+ *
+ * GLib provides g_convert() and g_locale_to_utf8() which are likely
+ * more convenient than the raw iconv wrappers.
+ *
+ * Return value: a "conversion descriptor", or (GIConv)-1 if
+ * opening the converter failed.
+ **/
+GIConv
+g_iconv_open (const gchar *to_codeset,
+ const gchar *from_codeset)
+{
+ iconv_t cd;
+
+ if (!try_conversion (to_codeset, from_codeset, &cd))
+ {
+ const char **to_aliases = _g_charset_get_aliases (to_codeset);
+ const char **from_aliases = _g_charset_get_aliases (from_codeset);
+
+ if (from_aliases)
+ {
+ const char **p = from_aliases;
+ while (*p)
+ {
+ if (try_conversion (to_codeset, *p, &cd))
+ goto out;
+
+ if (try_to_aliases (to_aliases, *p, &cd))
+ goto out;
+
+ p++;
+ }
+ }
+
+ if (try_to_aliases (to_aliases, from_codeset, &cd))
+ goto out;
+ }
+
+ out:
+ return (cd == (iconv_t)-1) ? (GIConv)-1 : (GIConv)cd;
+}
+
+/**
+ * g_iconv:
+ * @converter: conversion descriptor from g_iconv_open()
+ * @inbuf: bytes to convert
+ * @inbytes_left: inout parameter, bytes remaining to convert in @inbuf
+ * @outbuf: converted output bytes
+ * @outbytes_left: inout parameter, bytes available to fill in @outbuf
+ *
+ * Same as the standard UNIX routine iconv(), but
+ * may be implemented via libiconv on UNIX flavors that lack
+ * a native implementation.
+ *
+ * GLib provides g_convert() and g_locale_to_utf8() which are likely
+ * more convenient than the raw iconv wrappers.
+ *
+ * Return value: count of non-reversible conversions, or -1 on error
+ **/
+gsize
+g_iconv (GIConv converter,
+ gchar **inbuf,
+ gsize *inbytes_left,
+ gchar **outbuf,
+ gsize *outbytes_left)
+{
+ iconv_t cd = (iconv_t)converter;
+
+ return iconv (cd, inbuf, inbytes_left, outbuf, outbytes_left);
+}
+
+/**
+ * g_iconv_close:
+ * @converter: a conversion descriptor from g_iconv_open()
+ *
+ * Same as the standard UNIX routine iconv_close(), but
+ * may be implemented via libiconv on UNIX flavors that lack
+ * a native implementation. Should be called to clean up
+ * the conversion descriptor from g_iconv_open() when
+ * you are done converting things.
+ *
+ * GLib provides g_convert() and g_locale_to_utf8() which are likely
+ * more convenient than the raw iconv wrappers.
+ *
+ * Return value: -1 on error, 0 on success
+ **/
+gint
+g_iconv_close (GIConv converter)
+{
+ iconv_t cd = (iconv_t)converter;
+
+ return iconv_close (cd);
+}
+
+
+#ifdef NEED_ICONV_CACHE
+
+#define ICONV_CACHE_SIZE (16)
+
+struct _iconv_cache_bucket {
+ gchar *key;
+ guint32 refcount;
+ gboolean used;
+ GIConv cd;
+};
+
+static GList *iconv_cache_list;
+static GHashTable *iconv_cache;
+static GHashTable *iconv_open_hash;
+static guint iconv_cache_size = 0;
+G_LOCK_DEFINE_STATIC (iconv_cache_lock);
+
+/* caller *must* hold the iconv_cache_lock */
+static void
+iconv_cache_init (void)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return;
+
+ iconv_cache_list = NULL;
+ iconv_cache = g_hash_table_new (g_str_hash, g_str_equal);
+ iconv_open_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ initialized = TRUE;
+}
+
+
+/*
+ * iconv_cache_bucket_new:
+ * @key: cache key
+ * @cd: iconv descriptor
+ *
+ * Creates a new cache bucket, inserts it into the cache and
+ * increments the cache size.
+ *
+ * This assumes ownership of @key.
+ *
+ * Returns a pointer to the newly allocated cache bucket.
+ **/
+static struct _iconv_cache_bucket *
+iconv_cache_bucket_new (gchar *key, GIConv cd)
+{
+ struct _iconv_cache_bucket *bucket;
+
+ bucket = g_new (struct _iconv_cache_bucket, 1);
+ bucket->key = key;
+ bucket->refcount = 1;
+ bucket->used = TRUE;
+ bucket->cd = cd;
+
+ g_hash_table_insert (iconv_cache, bucket->key, bucket);
+
+ /* FIXME: if we sorted the list so items with few refcounts were
+ first, then we could expire them faster in iconv_cache_expire_unused () */
+ iconv_cache_list = g_list_prepend (iconv_cache_list, bucket);
+
+ iconv_cache_size++;
+
+ return bucket;
+}
+
+
+/*
+ * iconv_cache_bucket_expire:
+ * @node: cache bucket's node
+ * @bucket: cache bucket
+ *
+ * Expires a single cache bucket @bucket. This should only ever be
+ * called on a bucket that currently has no used iconv descriptors
+ * open.
+ *
+ * @node is not a required argument. If @node is not supplied, we
+ * search for it ourselves.
+ **/
+static void
+iconv_cache_bucket_expire (GList *node, struct _iconv_cache_bucket *bucket)
+{
+ g_hash_table_remove (iconv_cache, bucket->key);
+
+ if (node == NULL)
+ node = g_list_find (iconv_cache_list, bucket);
+
+ g_assert (node != NULL);
+
+ if (node->prev)
+ {
+ node->prev->next = node->next;
+ if (node->next)
+ node->next->prev = node->prev;
+ }
+ else
+ {
+ iconv_cache_list = node->next;
+ if (node->next)
+ node->next->prev = NULL;
+ }
+
+ g_list_free_1 (node);
+
+ g_free (bucket->key);
+ g_iconv_close (bucket->cd);
+ g_free (bucket);
+
+ iconv_cache_size--;
+}
+
+
+/*
+ * iconv_cache_expire_unused:
+ *
+ * Expires as many unused cache buckets as it needs to in order to get
+ * the total number of buckets < ICONV_CACHE_SIZE.
+ **/
+static void
+iconv_cache_expire_unused (void)
+{
+ struct _iconv_cache_bucket *bucket;
+ GList *node, *next;
+
+ node = iconv_cache_list;
+ while (node && iconv_cache_size >= ICONV_CACHE_SIZE)
+ {
+ next = node->next;
+
+ bucket = node->data;
+ if (bucket->refcount == 0)
+ iconv_cache_bucket_expire (node, bucket);
+
+ node = next;
+ }
+}
+
+static GIConv
+open_converter (const gchar *to_codeset,
+ const gchar *from_codeset,
+ GError **error)
+{
+ struct _iconv_cache_bucket *bucket;
+ gchar *key, *dyn_key, auto_key[80];
+ GIConv cd;
+ gsize len_from_codeset, len_to_codeset;
+
+ /* create our key */
+ len_from_codeset = strlen (from_codeset);
+ len_to_codeset = strlen (to_codeset);
+ if (len_from_codeset + len_to_codeset + 2 < sizeof (auto_key))
+ {
+ key = auto_key;
+ dyn_key = NULL;
+ }
+ else
+ key = dyn_key = g_malloc (len_from_codeset + len_to_codeset + 2);
+ memcpy (key, from_codeset, len_from_codeset);
+ key[len_from_codeset] = ':';
+ strcpy (key + len_from_codeset + 1, to_codeset);
+
+ G_LOCK (iconv_cache_lock);
+
+ /* make sure the cache has been initialized */
+ iconv_cache_init ();
+
+ bucket = g_hash_table_lookup (iconv_cache, key);
+ if (bucket)
+ {
+ g_free (dyn_key);
+
+ if (bucket->used)
+ {
+ cd = g_iconv_open (to_codeset, from_codeset);
+ if (cd == (GIConv) -1)
+ goto error;
+ }
+ else
+ {
+ /* Apparently iconv on Solaris <= 7 segfaults if you pass in
+ * NULL for anything but inbuf; work around that. (NULL outbuf
+ * or NULL *outbuf is allowed by Unix98.)
+ */
+ gsize inbytes_left = 0;
+ gchar *outbuf = NULL;
+ gsize outbytes_left = 0;
+
+ cd = bucket->cd;
+ bucket->used = TRUE;
+
+ /* reset the descriptor */
+ g_iconv (cd, NULL, &inbytes_left, &outbuf, &outbytes_left);
+ }
+
+ bucket->refcount++;
+ }
+ else
+ {
+ cd = g_iconv_open (to_codeset, from_codeset);
+ if (cd == (GIConv) -1)
+ {
+ g_free (dyn_key);
+ goto error;
+ }
+
+ iconv_cache_expire_unused ();
+
+ bucket = iconv_cache_bucket_new (dyn_key ? dyn_key : g_strdup (key), cd);
+ }
+
+ g_hash_table_insert (iconv_open_hash, cd, bucket->key);
+
+ G_UNLOCK (iconv_cache_lock);
+
+ return cd;
+
+ error:
+
+ G_UNLOCK (iconv_cache_lock);
+
+ /* Something went wrong. */
+ if (error)
+ {
+ if (errno == EINVAL)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
+ _("Conversion from character set '%s' to '%s' is not supported"),
+ from_codeset, to_codeset);
+ else
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Could not open converter from '%s' to '%s'"),
+ from_codeset, to_codeset);
+ }
+
+ return cd;
+}
+
+static int
+close_converter (GIConv converter)
+{
+ struct _iconv_cache_bucket *bucket;
+ const gchar *key;
+ GIConv cd;
+
+ cd = converter;
+
+ if (cd == (GIConv) -1)
+ return 0;
+
+ G_LOCK (iconv_cache_lock);
+
+ key = g_hash_table_lookup (iconv_open_hash, cd);
+ if (key)
+ {
+ g_hash_table_remove (iconv_open_hash, cd);
+
+ bucket = g_hash_table_lookup (iconv_cache, key);
+ g_assert (bucket);
+
+ bucket->refcount--;
+
+ if (cd == bucket->cd)
+ bucket->used = FALSE;
+ else
+ g_iconv_close (cd);
+
+ if (!bucket->refcount && iconv_cache_size > ICONV_CACHE_SIZE)
+ {
+ /* expire this cache bucket */
+ iconv_cache_bucket_expire (NULL, bucket);
+ }
+ }
+ else
+ {
+ G_UNLOCK (iconv_cache_lock);
+
+ g_warning ("This iconv context wasn't opened using open_converter");
+
+ return g_iconv_close (converter);
+ }
+
+ G_UNLOCK (iconv_cache_lock);
+
+ return 0;
+}
+
+#else /* !NEED_ICONV_CACHE */
+
+static GIConv
+open_converter (const gchar *to_codeset,
+ const gchar *from_codeset,
+ GError **error)
+{
+ GIConv cd;
+
+ cd = g_iconv_open (to_codeset, from_codeset);
+
+ if (cd == (GIConv) -1)
+ {
+ /* Something went wrong. */
+ if (error)
+ {
+ if (errno == EINVAL)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
+ _("Conversion from character set '%s' to '%s' is not supported"),
+ from_codeset, to_codeset);
+ else
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Could not open converter from '%s' to '%s'"),
+ from_codeset, to_codeset);
+ }
+ }
+
+ return cd;
+}
+
+static int
+close_converter (GIConv cd)
+{
+ if (cd == (GIConv) -1)
+ return 0;
+
+ return g_iconv_close (cd);
+}
+
+#endif /* NEED_ICONV_CACHE */
+
+/**
+ * g_convert_with_iconv:
+ * @str: the string to convert
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated.
+ * @converter: conversion descriptor from g_iconv_open()
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input. If the error
+ * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ * stored will the byte offset after the last valid
+ * input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from one character set to another.
+ *
+ * Note that you should use g_iconv() for streaming
+ * conversions
+ *
+ * Despite the fact that @byes_read can return information about partial
+ * characters, the g_convert_... functions
+ * are not generally suitable for streaming. If the underlying converter
+ * being used maintains internal state, then this won't be preserved
+ * across successive calls to g_convert(), g_convert_with_iconv() or
+ * g_convert_with_fallback(). (An example of this is the GNU C converter
+ * for CP1255 which does not emit a base character until it knows that
+ * the next character is not a mark that could combine with the base
+ * character.)
+ *
+ * .
+ *
+ * Return value: If the conversion was successful, a newly allocated
+ * nul-terminated string, which must be freed with
+ * g_free(). Otherwise %NULL and @error will be set.
+ **/
+gchar*
+g_convert_with_iconv (const gchar *str,
+ gssize len,
+ GIConv converter,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ gchar *dest;
+ gchar *outp;
+ const gchar *p;
+ gsize inbytes_remaining;
+ gsize outbytes_remaining;
+ gsize err;
+ gsize outbuf_size;
+ gboolean have_error = FALSE;
+ gboolean done = FALSE;
+ gboolean reset = FALSE;
+
+ g_return_val_if_fail (converter != (GIConv) -1, NULL);
+
+ if (len < 0)
+ len = strlen (str);
+
+ p = str;
+ inbytes_remaining = len;
+ outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
+
+ outbytes_remaining = outbuf_size - 1; /* -1 for nul */
+ outp = dest = g_malloc (outbuf_size);
+
+ while (!done && !have_error)
+ {
+ if (reset)
+ err = g_iconv (converter, NULL, &inbytes_remaining, &outp, &outbytes_remaining);
+ else
+ err = g_iconv (converter, (char **)&p, &inbytes_remaining, &outp, &outbytes_remaining);
+
+ if (err == (gsize) -1)
+ {
+ switch (errno)
+ {
+ case EINVAL:
+ /* Incomplete text, do not report an error */
+ done = TRUE;
+ break;
+ case E2BIG:
+ {
+ gsize used = outp - dest;
+
+ outbuf_size *= 2;
+ dest = g_realloc (dest, outbuf_size);
+
+ outp = dest + used;
+ outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
+ }
+ break;
+ case EILSEQ:
+ if (error)
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Invalid byte sequence in conversion input"));
+ have_error = TRUE;
+ break;
+ default:
+ if (error)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Error during conversion: %s"),
+ g_strerror (errno));
+ have_error = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ if (!reset)
+ {
+ /* call g_iconv with NULL inbuf to cleanup shift state */
+ reset = TRUE;
+ inbytes_remaining = 0;
+ }
+ else
+ done = TRUE;
+ }
+ }
+
+ *outp = '\0';
+
+ if (bytes_read)
+ *bytes_read = p - str;
+ else
+ {
+ if ((p - str) != len)
+ {
+ if (!have_error)
+ {
+ if (error)
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+ _("Partial character sequence at end of input"));
+ have_error = TRUE;
+ }
+ }
+ }
+
+ if (bytes_written)
+ *bytes_written = outp - dest; /* Doesn't include '\0' */
+
+ if (have_error)
+ {
+ g_free (dest);
+ return NULL;
+ }
+ else
+ return dest;
+}
+
+/**
+ * g_convert:
+ * @str: the string to convert
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated
+
+ Note that some encodings may allow nul bytes to
+ occur inside strings. In that case, using -1 for
+ the @len parameter is unsafe.
+
+ .
+ * @to_codeset: name of character set into which to convert @str
+ * @from_codeset: character set of @str.
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input. If the error
+ * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ * stored will the byte offset after the last valid
+ * input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from one character set to another.
+ *
+ * Note that you should use g_iconv() for streaming
+ * conversions.
+ *
+ * Return value: If the conversion was successful, a newly allocated
+ * nul-terminated string, which must be freed with
+ * g_free(). Otherwise %NULL and @error will be set.
+ **/
+gchar*
+g_convert (const gchar *str,
+ gssize len,
+ const gchar *to_codeset,
+ const gchar *from_codeset,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ gchar *res;
+ GIConv cd;
+
+ g_return_val_if_fail (str != NULL, NULL);
+ g_return_val_if_fail (to_codeset != NULL, NULL);
+ g_return_val_if_fail (from_codeset != NULL, NULL);
+
+ cd = open_converter (to_codeset, from_codeset, error);
+
+ if (cd == (GIConv) -1)
+ {
+ if (bytes_read)
+ *bytes_read = 0;
+
+ if (bytes_written)
+ *bytes_written = 0;
+
+ return NULL;
+ }
+
+ res = g_convert_with_iconv (str, len, cd,
+ bytes_read, bytes_written,
+ error);
+
+ close_converter (cd);
+
+ return res;
+}
+
+/**
+ * g_convert_with_fallback:
+ * @str: the string to convert
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated.
+ * @to_codeset: name of character set into which to convert @str
+ * @from_codeset: character set of @str.
+ * @fallback: UTF-8 string to use in place of character not
+ * present in the target encoding. (The string must be
+ * representable in the target encoding).
+ If %NULL, characters not in the target encoding will
+ be represented as Unicode escapes \uxxxx or \Uxxxxyyyy.
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from one character set to another, possibly
+ * including fallback sequences for characters not representable
+ * in the output. Note that it is not guaranteed that the specification
+ * for the fallback sequences in @fallback will be honored. Some
+ * systems may do an approximate conversion from @from_codeset
+ * to @to_codeset in their iconv() functions,
+ * in which case GLib will simply return that approximate conversion.
+ *
+ * Note that you should use g_iconv() for streaming
+ * conversions.
+ *
+ * Return value: If the conversion was successful, a newly allocated
+ * nul-terminated string, which must be freed with
+ * g_free(). Otherwise %NULL and @error will be set.
+ **/
+gchar*
+g_convert_with_fallback (const gchar *str,
+ gssize len,
+ const gchar *to_codeset,
+ const gchar *from_codeset,
+ gchar *fallback,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ gchar *utf8;
+ gchar *dest;
+ gchar *outp;
+ const gchar *insert_str = NULL;
+ const gchar *p;
+ gsize inbytes_remaining;
+ const gchar *save_p = NULL;
+ gsize save_inbytes = 0;
+ gsize outbytes_remaining;
+ gsize err;
+ GIConv cd;
+ gsize outbuf_size;
+ gboolean have_error = FALSE;
+ gboolean done = FALSE;
+
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (str != NULL, NULL);
+ g_return_val_if_fail (to_codeset != NULL, NULL);
+ g_return_val_if_fail (from_codeset != NULL, NULL);
+
+ if (len < 0)
+ len = strlen (str);
+
+ /* Try an exact conversion; we only proceed if this fails
+ * due to an illegal sequence in the input string.
+ */
+ dest = g_convert (str, len, to_codeset, from_codeset,
+ bytes_read, bytes_written, &local_error);
+ if (!local_error)
+ return dest;
+
+ if (!g_error_matches (local_error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE))
+ {
+ g_propagate_error (error, local_error);
+ return NULL;
+ }
+ else
+ g_error_free (local_error);
+
+ local_error = NULL;
+
+ /* No go; to proceed, we need a converter from "UTF-8" to
+ * to_codeset, and the string as UTF-8.
+ */
+ cd = open_converter (to_codeset, "UTF-8", error);
+ if (cd == (GIConv) -1)
+ {
+ if (bytes_read)
+ *bytes_read = 0;
+
+ if (bytes_written)
+ *bytes_written = 0;
+
+ return NULL;
+ }
+
+ utf8 = g_convert (str, len, "UTF-8", from_codeset,
+ bytes_read, &inbytes_remaining, error);
+ if (!utf8)
+ {
+ close_converter (cd);
+ if (bytes_written)
+ *bytes_written = 0;
+ return NULL;
+ }
+
+ /* Now the heart of the code. We loop through the UTF-8 string, and
+ * whenever we hit an offending character, we form fallback, convert
+ * the fallback to the target codeset, and then go back to
+ * converting the original string after finishing with the fallback.
+ *
+ * The variables save_p and save_inbytes store the input state
+ * for the original string while we are converting the fallback
+ */
+ p = utf8;
+
+ outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
+ outbytes_remaining = outbuf_size - 1; /* -1 for nul */
+ outp = dest = g_malloc (outbuf_size);
+
+ while (!done && !have_error)
+ {
+ gsize inbytes_tmp = inbytes_remaining;
+ err = g_iconv (cd, (char **)&p, &inbytes_tmp, &outp, &outbytes_remaining);
+ inbytes_remaining = inbytes_tmp;
+
+ if (err == (gsize) -1)
+ {
+ switch (errno)
+ {
+ case EINVAL:
+ g_assert_not_reached();
+ break;
+ case E2BIG:
+ {
+ gsize used = outp - dest;
+
+ outbuf_size *= 2;
+ dest = g_realloc (dest, outbuf_size);
+
+ outp = dest + used;
+ outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
+
+ break;
+ }
+ case EILSEQ:
+ if (save_p)
+ {
+ /* Error converting fallback string - fatal
+ */
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Cannot convert fallback '%s' to codeset '%s'"),
+ insert_str, to_codeset);
+ have_error = TRUE;
+ break;
+ }
+ else if (p)
+ {
+ if (!fallback)
+ {
+ gunichar ch = g_utf8_get_char (p);
+ insert_str = g_strdup_printf (ch < 0x10000 ? "\\u%04x" : "\\U%08x",
+ ch);
+ }
+ else
+ insert_str = fallback;
+
+ save_p = g_utf8_next_char (p);
+ save_inbytes = inbytes_remaining - (save_p - p);
+ p = insert_str;
+ inbytes_remaining = strlen (p);
+ break;
+ }
+ /* fall thru if p is NULL */
+ default:
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Error during conversion: %s"),
+ g_strerror (errno));
+ have_error = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ if (save_p)
+ {
+ if (!fallback)
+ g_free ((gchar *)insert_str);
+ p = save_p;
+ inbytes_remaining = save_inbytes;
+ save_p = NULL;
+ }
+ else if (p)
+ {
+ /* call g_iconv with NULL inbuf to cleanup shift state */
+ p = NULL;
+ inbytes_remaining = 0;
+ }
+ else
+ done = TRUE;
+ }
+ }
+
+ /* Cleanup
+ */
+ *outp = '\0';
+
+ close_converter (cd);
+
+ if (bytes_written)
+ *bytes_written = outp - dest; /* Doesn't include '\0' */
+
+ g_free (utf8);
+
+ if (have_error)
+ {
+ if (save_p && !fallback)
+ g_free ((gchar *)insert_str);
+ g_free (dest);
+ return NULL;
+ }
+ else
+ return dest;
+}
+
+/*
+ * g_locale_to_utf8
+ *
+ *
+ */
+
+static gchar *
+strdup_len (const gchar *string,
+ gssize len,
+ gsize *bytes_written,
+ gsize *bytes_read,
+ GError **error)
+
+{
+ gsize real_len;
+
+ if (!g_utf8_validate (string, len, NULL))
+ {
+ if (bytes_read)
+ *bytes_read = 0;
+ if (bytes_written)
+ *bytes_written = 0;
+
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Invalid byte sequence in conversion input"));
+ return NULL;
+ }
+
+ if (len < 0)
+ real_len = strlen (string);
+ else
+ {
+ real_len = 0;
+
+ while (real_len < len && string[real_len])
+ real_len++;
+ }
+
+ if (bytes_read)
+ *bytes_read = real_len;
+ if (bytes_written)
+ *bytes_written = real_len;
+
+ return g_strndup (string, real_len);
+}
+
+/**
+ * g_locale_to_utf8:
+ * @opsysstring: a string in the encoding of the current locale. On Windows
+ * this means the system codepage.
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated.
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input. If the error
+ * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ * stored will the byte offset after the last valid
+ * input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string which is in the encoding used for strings by
+ * the C runtime (usually the same as that used by the operating
+ * system) in the current locale into a
+ * UTF-8 string.
+ *
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar *
+g_locale_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const char *charset;
+
+ if (g_get_charset (&charset))
+ return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (opsysstring, len,
+ "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+/**
+ * g_locale_from_utf8:
+ * @utf8string: a UTF-8 encoded string
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated.
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input. If the error
+ * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ * stored will the byte offset after the last valid
+ * input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from UTF-8 to the encoding used for strings by
+ * the C runtime (usually the same as that used by the operating
+ * system) in the current locale. On
+ * Windows this means the system codepage.
+ *
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar *
+g_locale_from_utf8 (const gchar *utf8string,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (g_get_charset (&charset))
+ return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (utf8string, len,
+ charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#ifndef G_PLATFORM_WIN32
+
+typedef struct _GFilenameCharsetCache GFilenameCharsetCache;
+
+struct _GFilenameCharsetCache {
+ gboolean is_utf8;
+ gchar *charset;
+ gchar **filename_charsets;
+};
+
+static void
+filename_charset_cache_free (gpointer data)
+{
+ GFilenameCharsetCache *cache = data;
+ g_free (cache->charset);
+ g_strfreev (cache->filename_charsets);
+ g_free (cache);
+}
+
+/**
+ * g_get_filename_charsets:
+ * @charsets: return location for the %NULL-terminated list of encoding names
+ *
+ * Determines the preferred character sets used for filenames.
+ * The first character set from the @charsets is the filename encoding, the
+ * subsequent character sets are used when trying to generate a displayable
+ * representation of a filename, see g_filename_display_name().
+ *
+ * On Unix, the character sets are determined by consulting the
+ * environment variables G_FILENAME_ENCODING and
+ * G_BROKEN_FILENAMES. On Windows, the character set
+ * used in the GLib API is always UTF-8 and said environment variables
+ * have no effect.
+ *
+ * G_FILENAME_ENCODING may be set to a comma-separated list
+ * of character set names. The special token "@locale" is taken to
+ * mean the character set for the current
+ * locale. If G_FILENAME_ENCODING is not set, but
+ * G_BROKEN_FILENAMES is, the character set of the current
+ * locale is taken as the filename encoding. If neither environment variable
+ * is set, UTF-8 is taken as the filename encoding, but the character
+ * set of the current locale is also put in the list of encodings.
+ *
+ * The returned @charsets belong to GLib and must not be freed.
+ *
+ * Note that on Unix, regardless of the locale character set or
+ * G_FILENAME_ENCODING value, the actual file names present
+ * on a system might be in any random encoding or just gibberish.
+ *
+ * Return value: %TRUE if the filename encoding is UTF-8.
+ *
+ * Since: 2.6
+ */
+gboolean
+g_get_filename_charsets (G_CONST_RETURN gchar ***filename_charsets)
+{
+ static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
+ GFilenameCharsetCache *cache = g_static_private_get (&cache_private);
+ const gchar *charset;
+
+ if (!cache)
+ {
+ cache = g_new0 (GFilenameCharsetCache, 1);
+ g_static_private_set (&cache_private, cache, filename_charset_cache_free);
+ }
+
+ g_get_charset (&charset);
+
+ if (!(cache->charset && strcmp (cache->charset, charset) == 0))
+ {
+ const gchar *new_charset;
+ gchar *p;
+ gint i;
+
+ g_free (cache->charset);
+ g_strfreev (cache->filename_charsets);
+ cache->charset = g_strdup (charset);
+
+ p = getenv ("G_FILENAME_ENCODING");
+ if (p != NULL && p[0] != '\0')
+ {
+ cache->filename_charsets = g_strsplit (p, ",", 0);
+ cache->is_utf8 = (strcmp (cache->filename_charsets[0], "UTF-8") == 0);
+
+ for (i = 0; cache->filename_charsets[i]; i++)
+ {
+ if (strcmp ("@locale", cache->filename_charsets[i]) == 0)
+ {
+ g_get_charset (&new_charset);
+ g_free (cache->filename_charsets[i]);
+ cache->filename_charsets[i] = g_strdup (new_charset);
+ }
+ }
+ }
+ else if (getenv ("G_BROKEN_FILENAMES") != NULL)
+ {
+ cache->filename_charsets = g_new0 (gchar *, 2);
+ cache->is_utf8 = g_get_charset (&new_charset);
+ cache->filename_charsets[0] = g_strdup (new_charset);
+ }
+ else
+ {
+ cache->filename_charsets = g_new0 (gchar *, 3);
+ cache->is_utf8 = TRUE;
+ cache->filename_charsets[0] = g_strdup ("UTF-8");
+ if (!g_get_charset (&new_charset))
+ cache->filename_charsets[1] = g_strdup (new_charset);
+ }
+ }
+
+ if (filename_charsets)
+ *filename_charsets = (const gchar **)cache->filename_charsets;
+
+ return cache->is_utf8;
+}
+
+#else /* G_PLATFORM_WIN32 */
+
+gboolean
+g_get_filename_charsets (G_CONST_RETURN gchar ***filename_charsets)
+{
+ static const gchar *charsets[] = {
+ "UTF-8",
+ NULL
+ };
+
+#ifdef G_OS_WIN32
+ /* On Windows GLib pretends that the filename charset is UTF-8 */
+ if (filename_charsets)
+ *filename_charsets = charsets;
+
+ return TRUE;
+#else
+ gboolean result;
+
+ /* Cygwin works like before */
+ result = g_get_charset (&(charsets[0]));
+
+ if (filename_charsets)
+ *filename_charsets = charsets;
+
+ return result;
+#endif
+}
+
+#endif /* G_PLATFORM_WIN32 */
+
+static gboolean
+get_filename_charset (const gchar **filename_charset)
+{
+ const gchar **charsets;
+ gboolean is_utf8;
+
+ is_utf8 = g_get_filename_charsets (&charsets);
+
+ if (filename_charset)
+ *filename_charset = charsets[0];
+
+ return is_utf8;
+}
+
+/* This is called from g_thread_init(). It's used to
+ * initialize some static data in a threadsafe way.
+ */
+void
+_g_convert_thread_init (void)
+{
+ const gchar **dummy;
+ (void) g_get_filename_charsets (&dummy);
+}
+
+/**
+ * g_filename_to_utf8:
+ * @opsysstring: a string in the encoding for filenames
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated.
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input. If the error
+ * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ * stored will the byte offset after the last valid
+ * input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string which is in the encoding used by GLib for
+ * filenames into a UTF-8 string. Note that on Windows GLib uses UTF-8
+ * for filenames; on other platforms, this function indirectly depends on
+ * the current locale.
+ *
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar*
+g_filename_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (get_filename_charset (&charset))
+ return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (opsysstring, len,
+ "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_to_utf8
+
+/* Binary compatibility version. Not for newly compiled code. Also not needed for
+ * 64-bit versions as there should be no old deployed binaries that would use
+ * the old versions.
+ */
+
+gchar*
+g_filename_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (g_get_charset (&charset))
+ return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (opsysstring, len,
+ "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+#endif
+
+/**
+ * g_filename_from_utf8:
+ * @utf8string: a UTF-8 encoded string.
+ * @len: the length of the string, or -1 if the string is
+ * nul-terminated.
+ * @bytes_read: location to store the number of bytes in the
+ * input string that were successfully converted, or %NULL.
+ * Even if the conversion was successful, this may be
+ * less than @len if there were partial characters
+ * at the end of the input. If the error
+ * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ * stored will the byte offset after the last valid
+ * input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not
+ * including the terminating nul).
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from UTF-8 to the encoding GLib uses for
+ * filenames. Note that on Windows GLib uses UTF-8 for filenames;
+ * on other platforms, this function indirectly depends on the
+ * current locale.
+ *
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar*
+g_filename_from_utf8 (const gchar *utf8string,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (get_filename_charset (&charset))
+ return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (utf8string, len,
+ charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_from_utf8
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gchar*
+g_filename_from_utf8 (const gchar *utf8string,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
+{
+ const gchar *charset;
+
+ if (g_get_charset (&charset))
+ return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+ else
+ return g_convert (utf8string, len,
+ charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#endif
+
+/* Test of haystack has the needle prefix, comparing case
+ * insensitive. haystack may be UTF-8, but needle must
+ * contain only ascii. */
+static gboolean
+has_case_prefix (const gchar *haystack, const gchar *needle)
+{
+ const gchar *h, *n;
+
+ /* Eat one character at a time. */
+ h = haystack;
+ n = needle;
+
+ while (*n && *h &&
+ g_ascii_tolower (*n) == g_ascii_tolower (*h))
+ {
+ n++;
+ h++;
+ }
+
+ return *n == '\0';
+}
+
+typedef enum {
+ UNSAFE_ALL = 0x1, /* Escape all unsafe characters */
+ UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */
+ UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
+ UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */
+ UNSAFE_SLASHES = 0x20 /* Allows all characters except for '/' and '%' */
+} UnsafeCharacterSet;
+
+static const guchar acceptable[96] = {
+ /* A table of the ASCII chars from space (32) to DEL (127) */
+ /* ! " # $ % & ' ( ) * + , - . / */
+ 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
+ /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
+ /* @ A B C D E F G H I J K L M N O */
+ 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ /* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
+ /* ` a b c d e f g h i j k l m n o */
+ 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+ /* p q r s t u v w x y z { | } ~ DEL */
+ 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20
+};
+
+static const gchar hex[16] = "0123456789ABCDEF";
+
+/* Note: This escape function works on file: URIs, but if you want to
+ * escape something else, please read RFC-2396 */
+static gchar *
+g_escape_uri_string (const gchar *string,
+ UnsafeCharacterSet mask)
+{
+#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))
+
+ const gchar *p;
+ gchar *q;
+ gchar *result;
+ int c;
+ gint unacceptable;
+ UnsafeCharacterSet use_mask;
+
+ g_return_val_if_fail (mask == UNSAFE_ALL
+ || mask == UNSAFE_ALLOW_PLUS
+ || mask == UNSAFE_PATH
+ || mask == UNSAFE_HOST
+ || mask == UNSAFE_SLASHES, NULL);
+
+ unacceptable = 0;
+ use_mask = mask;
+ for (p = string; *p != '\0'; p++)
+ {
+ c = (guchar) *p;
+ if (!ACCEPTABLE (c))
+ unacceptable++;
+ }
+
+ result = g_malloc (p - string + unacceptable * 2 + 1);
+
+ use_mask = mask;
+ for (q = result, p = string; *p != '\0'; p++)
+ {
+ c = (guchar) *p;
+
+ if (!ACCEPTABLE (c))
+ {
+ *q++ = '%'; /* means hex coming */
+ *q++ = hex[c >> 4];
+ *q++ = hex[c & 15];
+ }
+ else
+ *q++ = *p;
+ }
+
+ *q = '\0';
+
+ return result;
+}
+
+
+static gchar *
+g_escape_file_uri (const gchar *hostname,
+ const gchar *pathname)
+{
+ char *escaped_hostname = NULL;
+ char *escaped_path;
+ char *res;
+
+#ifdef G_OS_WIN32
+ char *p, *backslash;
+
+ /* Turn backslashes into forward slashes. That's what Netscape
+ * does, and they are actually more or less equivalent in Windows.
+ */
+
+ pathname = g_strdup (pathname);
+ p = (char *) pathname;
+
+ while ((backslash = strchr (p, '\\')) != NULL)
+ {
+ *backslash = '/';
+ p = backslash + 1;
+ }
+#endif
+
+ if (hostname && *hostname != '\0')
+ {
+ escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST);
+ }
+
+ escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH);
+
+ res = g_strconcat ("file://",
+ (escaped_hostname) ? escaped_hostname : "",
+ (*escaped_path != '/') ? "/" : "",
+ escaped_path,
+ NULL);
+
+#ifdef G_OS_WIN32
+ g_free ((char *) pathname);
+#endif
+
+ g_free (escaped_hostname);
+ g_free (escaped_path);
+
+ return res;
+}
+
+static int
+unescape_character (const char *scanner)
+{
+ int first_digit;
+ int second_digit;
+
+ first_digit = g_ascii_xdigit_value (scanner[0]);
+ if (first_digit < 0)
+ return -1;
+
+ second_digit = g_ascii_xdigit_value (scanner[1]);
+ if (second_digit < 0)
+ return -1;
+
+ return (first_digit << 4) | second_digit;
+}
+
+static gchar *
+g_unescape_uri_string (const char *escaped,
+ int len,
+ const char *illegal_escaped_characters,
+ gboolean ascii_must_not_be_escaped)
+{
+ const gchar *in, *in_end;
+ gchar *out, *result;
+ int c;
+
+ if (escaped == NULL)
+ return NULL;
+
+ if (len < 0)
+ len = strlen (escaped);
+
+ result = g_malloc (len + 1);
+
+ out = result;
+ for (in = escaped, in_end = escaped + len; in < in_end; in++)
+ {
+ c = *in;
+
+ if (c == '%')
+ {
+ /* catch partial escape sequences past the end of the substring */
+ if (in + 3 > in_end)
+ break;
+
+ c = unescape_character (in + 1);
+
+ /* catch bad escape sequences and NUL characters */
+ if (c <= 0)
+ break;
+
+ /* catch escaped ASCII */
+ if (ascii_must_not_be_escaped && c <= 0x7F)
+ break;
+
+ /* catch other illegal escaped characters */
+ if (strchr (illegal_escaped_characters, c) != NULL)
+ break;
+
+ in += 2;
+ }
+
+ *out++ = c;
+ }
+
+ g_assert (out - result <= len);
+ *out = '\0';
+
+ if (in != in_end)
+ {
+ g_free (result);
+ return NULL;
+ }
+
+ return result;
+}
+
+static gboolean
+is_asciialphanum (gunichar c)
+{
+ return c <= 0x7F && g_ascii_isalnum (c);
+}
+
+static gboolean
+is_asciialpha (gunichar c)
+{
+ return c <= 0x7F && g_ascii_isalpha (c);
+}
+
+/* allows an empty string */
+static gboolean
+hostname_validate (const char *hostname)
+{
+ const char *p;
+ gunichar c, first_char, last_char;
+
+ p = hostname;
+ if (*p == '\0')
+ return TRUE;
+ do
+ {
+ /* read in a label */
+ c = g_utf8_get_char (p);
+ p = g_utf8_next_char (p);
+ if (!is_asciialphanum (c))
+ return FALSE;
+ first_char = c;
+ do
+ {
+ last_char = c;
+ c = g_utf8_get_char (p);
+ p = g_utf8_next_char (p);
+ }
+ while (is_asciialphanum (c) || c == '-');
+ if (last_char == '-')
+ return FALSE;
+
+ /* if that was the last label, check that it was a toplabel */
+ if (c == '\0' || (c == '.' && *p == '\0'))
+ return is_asciialpha (first_char);
+ }
+ while (c == '.');
+ return FALSE;
+}
+
+/**
+ * g_filename_from_uri:
+ * @uri: a uri describing a filename (escaped, encoded in ASCII).
+ * @hostname: Location to store hostname for the URI, or %NULL.
+ * If there is no hostname in the URI, %NULL will be
+ * stored in this location.
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts an escaped ASCII-encoded URI to a local filename in the
+ * encoding used for filenames.
+ *
+ * Return value: a newly-allocated string holding the resulting
+ * filename, or %NULL on an error.
+ **/
+gchar *
+g_filename_from_uri (const gchar *uri,
+ gchar **hostname,
+ GError **error)
+{
+ const char *path_part;
+ const char *host_part;
+ char *unescaped_hostname;
+ char *result;
+ char *filename;
+ int offs;
+#ifdef G_OS_WIN32
+ char *p, *slash;
+#endif
+
+ if (hostname)
+ *hostname = NULL;
+
+ if (!has_case_prefix (uri, "file:/"))
+ {
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+ _("The URI '%s' is not an absolute URI using the \"file\" scheme"),
+ uri);
+ return NULL;
+ }
+
+ path_part = uri + strlen ("file:");
+
+ if (strchr (path_part, '#') != NULL)
+ {
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+ _("The local file URI '%s' may not include a '#'"),
+ uri);
+ return NULL;
+ }
+
+ if (has_case_prefix (path_part, "///"))
+ path_part += 2;
+ else if (has_case_prefix (path_part, "//"))
+ {
+ path_part += 2;
+ host_part = path_part;
+
+ path_part = strchr (path_part, '/');
+
+ if (path_part == NULL)
+ {
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+ _("The URI '%s' is invalid"),
+ uri);
+ return NULL;
+ }
+
+ unescaped_hostname = g_unescape_uri_string (host_part, path_part - host_part, "", TRUE);
+
+ if (unescaped_hostname == NULL ||
+ !hostname_validate (unescaped_hostname))
+ {
+ g_free (unescaped_hostname);
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+ _("The hostname of the URI '%s' is invalid"),
+ uri);
+ return NULL;
+ }
+
+ if (hostname)
+ *hostname = unescaped_hostname;
+ else
+ g_free (unescaped_hostname);
+ }
+
+ filename = g_unescape_uri_string (path_part, -1, "/", FALSE);
+
+ if (filename == NULL)
+ {
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+ _("The URI '%s' contains invalidly escaped characters"),
+ uri);
+ return NULL;
+ }
+
+ offs = 0;
+#ifdef G_OS_WIN32
+ /* Drop localhost */
+ if (hostname && *hostname != NULL &&
+ g_ascii_strcasecmp (*hostname, "localhost") == 0)
+ {
+ g_free (*hostname);
+ *hostname = NULL;
+ }
+
+ /* Turn slashes into backslashes, because that's the canonical spelling */
+ p = filename;
+ while ((slash = strchr (p, '/')) != NULL)
+ {
+ *slash = '\\';
+ p = slash + 1;
+ }
+
+ /* Windows URIs with a drive letter can be like "file://host/c:/foo"
+ * or "file://host/c|/foo" (some Netscape versions). In those cases, start
+ * the filename from the drive letter.
+ */
+ if (g_ascii_isalpha (filename[1]))
+ {
+ if (filename[2] == ':')
+ offs = 1;
+ else if (filename[2] == '|')
+ {
+ filename[2] = ':';
+ offs = 1;
+ }
+ }
+#endif
+
+ result = g_strdup (filename + offs);
+ g_free (filename);
+
+ return result;
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_from_uri
+
+gchar *
+g_filename_from_uri (const gchar *uri,
+ gchar **hostname,
+ GError **error)
+{
+ gchar *utf8_filename;
+ gchar *retval = NULL;
+
+ utf8_filename = g_filename_from_uri_utf8 (uri, hostname, error);
+ if (utf8_filename)
+ {
+ retval = g_locale_from_utf8 (utf8_filename, -1, NULL, NULL, error);
+ g_free (utf8_filename);
+ }
+ return retval;
+}
+
+#endif
+
+/**
+ * g_filename_to_uri:
+ * @filename: an absolute filename specified in the GLib file name encoding,
+ * which is the on-disk file name bytes on Unix, and UTF-8 on
+ * Windows
+ * @hostname: A UTF-8 encoded hostname, or %NULL for none.
+ * @error: location to store the error occuring, or %NULL to ignore
+ * errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts an absolute filename to an escaped ASCII-encoded URI, with the path
+ * component following Section 3.3. of RFC 2396.
+ *
+ * Return value: a newly-allocated string holding the resulting
+ * URI, or %NULL on an error.
+ **/
+gchar *
+g_filename_to_uri (const gchar *filename,
+ const gchar *hostname,
+ GError **error)
+{
+ char *escaped_uri;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ if (!g_path_is_absolute (filename))
+ {
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH,
+ _("The pathname '%s' is not an absolute path"),
+ filename);
+ return NULL;
+ }
+
+ if (hostname &&
+ !(g_utf8_validate (hostname, -1, NULL)
+ && hostname_validate (hostname)))
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Invalid hostname"));
+ return NULL;
+ }
+
+#ifdef G_OS_WIN32
+ /* Don't use localhost unnecessarily */
+ if (hostname && g_ascii_strcasecmp (hostname, "localhost") == 0)
+ hostname = NULL;
+#endif
+
+ escaped_uri = g_escape_file_uri (hostname, filename);
+
+ return escaped_uri;
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_to_uri
+
+gchar *
+g_filename_to_uri (const gchar *filename,
+ const gchar *hostname,
+ GError **error)
+{
+ gchar *utf8_filename;
+ gchar *retval = NULL;
+
+ utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+
+ if (utf8_filename)
+ {
+ retval = g_filename_to_uri_utf8 (utf8_filename, hostname, error);
+ g_free (utf8_filename);
+ }
+
+ return retval;
+}
+
+#endif
+
+/**
+ * g_uri_list_extract_uris:
+ * @uri_list: an URI list
+ *
+ * Splits an URI list conforming to the text/uri-list
+ * mime type defined in RFC 2483 into individual URIs,
+ * discarding any comments. The URIs are not validated.
+ *
+ * Returns: a newly allocated %NULL-terminated list of
+ * strings holding the individual URIs. The array should
+ * be freed with g_strfreev().
+ *
+ * Since: 2.6
+ */
+gchar **
+g_uri_list_extract_uris (const gchar *uri_list)
+{
+ GSList *uris, *u;
+ const gchar *p, *q;
+ gchar **result;
+ gint n_uris = 0;
+
+ uris = NULL;
+
+ p = uri_list;
+
+ /* We don't actually try to validate the URI according to RFC
+ * 2396, or even check for allowed characters - we just ignore
+ * comments and trim whitespace off the ends. We also
+ * allow LF delimination as well as the specified CRLF.
+ *
+ * We do allow comments like specified in RFC 2483.
+ */
+ while (p)
+ {
+ if (*p != '#')
+ {
+ while (g_ascii_isspace (*p))
+ p++;
+
+ q = p;
+ while (*q && (*q != '\n') && (*q != '\r'))
+ q++;
+
+ if (q > p)
+ {
+ q--;
+ while (q > p && g_ascii_isspace (*q))
+ q--;
+
+ if (q > p)
+ {
+ uris = g_slist_prepend (uris, g_strndup (p, q - p + 1));
+ n_uris++;
+ }
+ }
+ }
+ p = strchr (p, '\n');
+ if (p)
+ p++;
+ }
+
+ result = g_new (gchar *, n_uris + 1);
+
+ result[n_uris--] = NULL;
+ for (u = uris; u; u = u->next)
+ result[n_uris--] = u->data;
+
+ g_slist_free (uris);
+
+ return result;
+}
+
+/**
+ * g_filename_display_basename:
+ * @filename: an absolute pathname in the GLib file name encoding
+ *
+ * Returns the display basename for the particular filename, guaranteed
+ * to be valid UTF-8. The display name might not be identical to the filename,
+ * for instance there might be problems converting it to UTF-8, and some files
+ * can be translated in the display.
+ *
+ * If GLib can not make sense of the encoding of @filename, as a last resort it
+ * replaces unknown characters with U+FFFD, the Unicode replacement character.
+ * You can search the result for the UTF-8 encoding of this character (which is
+ * "\357\277\275" in octal notation) to find out if @filename was in an invalid
+ * encoding.
+ *
+ * You must pass the whole absolute pathname to this functions so that
+ * translation of well known locations can be done.
+ *
+ * This function is preferred over g_filename_display_name() if you know the
+ * whole path, as it allows translation.
+ *
+ * Return value: a newly allocated string containing
+ * a rendition of the basename of the filename in valid UTF-8
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_filename_display_basename (const gchar *filename)
+{
+ char *basename;
+ char *display_name;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ basename = g_path_get_basename (filename);
+ display_name = g_filename_display_name (basename);
+ g_free (basename);
+ return display_name;
+}
+
+/**
+ * g_filename_display_name:
+ * @filename: a pathname hopefully in the GLib file name encoding
+ *
+ * Converts a filename into a valid UTF-8 string. The conversion is
+ * not necessarily reversible, so you should keep the original around
+ * and use the return value of this function only for display purposes.
+ * Unlike g_filename_to_utf8(), the result is guaranteed to be non-%NULL
+ * even if the filename actually isn't in the GLib file name encoding.
+ *
+ * If GLib can not make sense of the encoding of @filename, as a last resort it
+ * replaces unknown characters with U+FFFD, the Unicode replacement character.
+ * You can search the result for the UTF-8 encoding of this character (which is
+ * "\357\277\275" in octal notation) to find out if @filename was in an invalid
+ * encoding.
+ *
+ * If you know the whole pathname of the file you should use
+ * g_filename_display_basename(), since that allows location-based
+ * translation of filenames.
+ *
+ * Return value: a newly allocated string containing
+ * a rendition of the filename in valid UTF-8
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_filename_display_name (const gchar *filename)
+{
+ gint i;
+ const gchar **charsets;
+ gchar *display_name = NULL;
+ gboolean is_utf8;
+
+ is_utf8 = g_get_filename_charsets (&charsets);
+
+ if (is_utf8)
+ {
+ if (g_utf8_validate (filename, -1, NULL))
+ display_name = g_strdup (filename);
+ }
+
+ if (!display_name)
+ {
+ /* Try to convert from the filename charsets to UTF-8.
+ * Skip the first charset if it is UTF-8.
+ */
+ for (i = is_utf8 ? 1 : 0; charsets[i]; i++)
+ {
+ display_name = g_convert (filename, -1, "UTF-8", charsets[i],
+ NULL, NULL, NULL);
+
+ if (display_name)
+ break;
+ }
+ }
+
+ /* if all conversions failed, we replace invalid UTF-8
+ * by a question mark
+ */
+ if (!display_name)
+ display_name = _g_utf8_make_valid (filename);
+
+ return display_name;
+}
+
+#define __G_CONVERT_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gconvert.h b/desmume/src/windows/glib-2.20.1/build/glib/gconvert.h
new file mode 100644
index 000000000..4d767841d
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gconvert.h
@@ -0,0 +1,138 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_CONVERT_H__
+#define __G_CONVERT_H__
+
+#include
+
+G_BEGIN_DECLS
+
+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;
+
+#define G_CONVERT_ERROR g_convert_error_quark()
+GQuark g_convert_error_quark (void);
+
+/* Thin wrappers around iconv
+ */
+typedef struct _GIConv *GIConv;
+
+GIConv g_iconv_open (const gchar *to_codeset,
+ const gchar *from_codeset);
+gsize g_iconv (GIConv converter,
+ gchar **inbuf,
+ gsize *inbytes_left,
+ gchar **outbuf,
+ gsize *outbytes_left);
+gint g_iconv_close (GIConv converter);
+
+
+gchar* g_convert (const gchar *str,
+ gssize len,
+ const gchar *to_codeset,
+ const gchar *from_codeset,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+gchar* g_convert_with_iconv (const gchar *str,
+ gssize len,
+ GIConv converter,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+gchar* g_convert_with_fallback (const gchar *str,
+ gssize len,
+ const gchar *to_codeset,
+ const gchar *from_codeset,
+ gchar *fallback,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+
+
+/* Convert between libc's idea of strings and UTF-8.
+ */
+gchar* g_locale_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+gchar* g_locale_from_utf8 (const gchar *utf8string,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+
+/* Convert between the operating system (or C runtime)
+ * representation of file names and UTF-8.
+ */
+#ifdef G_OS_WIN32
+#define g_filename_to_utf8 g_filename_to_utf8_utf8
+#define g_filename_from_utf8 g_filename_from_utf8_utf8
+#define g_filename_from_uri g_filename_from_uri_utf8
+#define g_filename_to_uri g_filename_to_uri_utf8
+#endif
+
+gchar* g_filename_to_utf8 (const gchar *opsysstring,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+gchar* g_filename_from_utf8 (const gchar *utf8string,
+ gssize len,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error) G_GNUC_MALLOC;
+
+gchar *g_filename_from_uri (const gchar *uri,
+ gchar **hostname,
+ GError **error) G_GNUC_MALLOC;
+
+gchar *g_filename_to_uri (const gchar *filename,
+ const gchar *hostname,
+ GError **error) G_GNUC_MALLOC;
+gchar *g_filename_display_name (const gchar *filename) G_GNUC_MALLOC;
+gboolean g_get_filename_charsets (G_CONST_RETURN gchar ***charsets);
+
+gchar *g_filename_display_basename (const gchar *filename) G_GNUC_MALLOC;
+
+gchar **g_uri_list_extract_uris (const gchar *uri_list) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* __G_CONVERT_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gdataset.c b/desmume/src/windows/glib-2.20.1/build/glib/gdataset.c
new file mode 100644
index 000000000..bf5eafe32
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdataset.c
@@ -0,0 +1,759 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gdataset.c: Generic dataset mechanism, similar to GtkObject data.
+ * Copyright (C) 1998 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe ; except for g_data*_foreach()
+ */
+
+#include "config.h"
+
+#include
+
+#include "glib.h"
+#include "gdatasetprivate.h"
+#include "galias.h"
+
+
+/* --- defines --- */
+#define G_QUARK_BLOCK_SIZE (512)
+
+/* 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))
+
+#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) | (gsize) pointer); \
+ } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \
+} G_STMT_END
+
+/* --- structures --- */
+typedef struct _GDataset GDataset;
+struct _GData
+{
+ GData *next;
+ GQuark id;
+ gpointer data;
+ GDestroyNotify destroy_func;
+};
+
+struct _GDataset
+{
+ gconstpointer location;
+ GData *datalist;
+};
+
+
+/* --- prototypes --- */
+static inline GDataset* g_dataset_lookup (gconstpointer dataset_location);
+static inline void g_datalist_clear_i (GData **datalist);
+static void g_dataset_destroy_internal (GDataset *dataset);
+static inline gpointer g_data_set_internal (GData **datalist,
+ GQuark key_id,
+ gpointer data,
+ GDestroyNotify destroy_func,
+ GDataset *dataset);
+static void g_data_initialize (void);
+static inline GQuark g_quark_new (gchar *string);
+
+
+/* --- variables --- */
+G_LOCK_DEFINE_STATIC (g_dataset_global);
+static GHashTable *g_dataset_location_ht = NULL;
+static GDataset *g_dataset_cached = NULL; /* should this be
+ threadspecific? */
+G_LOCK_DEFINE_STATIC (g_quark_global);
+static GHashTable *g_quark_ht = NULL;
+static gchar **g_quarks = NULL;
+static GQuark g_quark_seq_id = 0;
+
+/* --- functions --- */
+
+/* HOLDS: g_dataset_global_lock */
+static inline void
+g_datalist_clear_i (GData **datalist)
+{
+ register GData *list;
+
+ /* unlink *all* items before walking their destructors
+ */
+ list = G_DATALIST_GET_POINTER (datalist);
+ G_DATALIST_SET_POINTER (datalist, NULL);
+
+ while (list)
+ {
+ register GData *prev;
+
+ prev = list;
+ list = prev->next;
+
+ if (prev->destroy_func)
+ {
+ G_UNLOCK (g_dataset_global);
+ prev->destroy_func (prev->data);
+ G_LOCK (g_dataset_global);
+ }
+
+ g_slice_free (GData, prev);
+ }
+}
+
+void
+g_datalist_clear (GData **datalist)
+{
+ g_return_if_fail (datalist != NULL);
+
+ G_LOCK (g_dataset_global);
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
+
+ while (G_DATALIST_GET_POINTER (datalist))
+ g_datalist_clear_i (datalist);
+ G_UNLOCK (g_dataset_global);
+}
+
+/* HOLDS: g_dataset_global_lock */
+static inline GDataset*
+g_dataset_lookup (gconstpointer dataset_location)
+{
+ register GDataset *dataset;
+
+ if (g_dataset_cached && g_dataset_cached->location == dataset_location)
+ return g_dataset_cached;
+
+ dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
+ if (dataset)
+ g_dataset_cached = dataset;
+
+ return dataset;
+}
+
+/* HOLDS: g_dataset_global_lock */
+static void
+g_dataset_destroy_internal (GDataset *dataset)
+{
+ register gconstpointer dataset_location;
+
+ dataset_location = dataset->location;
+ while (dataset)
+ {
+ if (!dataset->datalist)
+ {
+ if (dataset == g_dataset_cached)
+ g_dataset_cached = NULL;
+ g_hash_table_remove (g_dataset_location_ht, dataset_location);
+ g_slice_free (GDataset, dataset);
+ break;
+ }
+
+ g_datalist_clear_i (&dataset->datalist);
+ dataset = g_dataset_lookup (dataset_location);
+ }
+}
+
+void
+g_dataset_destroy (gconstpointer dataset_location)
+{
+ g_return_if_fail (dataset_location != NULL);
+
+ G_LOCK (g_dataset_global);
+ if (g_dataset_location_ht)
+ {
+ register GDataset *dataset;
+
+ dataset = g_dataset_lookup (dataset_location);
+ if (dataset)
+ g_dataset_destroy_internal (dataset);
+ }
+ G_UNLOCK (g_dataset_global);
+}
+
+/* HOLDS: g_dataset_global_lock */
+static inline gpointer
+g_data_set_internal (GData **datalist,
+ GQuark key_id,
+ gpointer data,
+ GDestroyNotify destroy_func,
+ GDataset *dataset)
+{
+ register GData *list;
+
+ list = G_DATALIST_GET_POINTER (datalist);
+ if (!data)
+ {
+ register GData *prev;
+
+ prev = NULL;
+ while (list)
+ {
+ if (list->id == key_id)
+ {
+ gpointer ret_data = NULL;
+
+ if (prev)
+ prev->next = list->next;
+ else
+ {
+ G_DATALIST_SET_POINTER (datalist, list->next);
+
+ /* the dataset destruction *must* be done
+ * prior to invocation of the data destroy function
+ */
+ if (!list->next && dataset)
+ g_dataset_destroy_internal (dataset);
+ }
+
+ /* the GData struct *must* already be unlinked
+ * when invoking the destroy function.
+ * we use (data==NULL && destroy_func!=NULL) as
+ * a special hint combination to "steal"
+ * data without destroy notification
+ */
+ if (list->destroy_func && !destroy_func)
+ {
+ G_UNLOCK (g_dataset_global);
+ list->destroy_func (list->data);
+ G_LOCK (g_dataset_global);
+ }
+ else
+ ret_data = list->data;
+
+ g_slice_free (GData, list);
+
+ return ret_data;
+ }
+
+ prev = list;
+ list = list->next;
+ }
+ }
+ else
+ {
+ while (list)
+ {
+ if (list->id == key_id)
+ {
+ if (!list->destroy_func)
+ {
+ list->data = data;
+ list->destroy_func = destroy_func;
+ }
+ else
+ {
+ register GDestroyNotify dfunc;
+ register gpointer ddata;
+
+ dfunc = list->destroy_func;
+ ddata = list->data;
+ list->data = data;
+ list->destroy_func = destroy_func;
+
+ /* we need to have updated all structures prior to
+ * invocation of the destroy function
+ */
+ G_UNLOCK (g_dataset_global);
+ dfunc (ddata);
+ G_LOCK (g_dataset_global);
+ }
+
+ return NULL;
+ }
+
+ list = list->next;
+ }
+
+ list = g_slice_new (GData);
+ list->next = G_DATALIST_GET_POINTER (datalist);
+ list->id = key_id;
+ list->data = data;
+ list->destroy_func = destroy_func;
+ G_DATALIST_SET_POINTER (datalist, list);
+ }
+
+ return NULL;
+}
+
+void
+g_dataset_id_set_data_full (gconstpointer dataset_location,
+ GQuark key_id,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ register GDataset *dataset;
+
+ g_return_if_fail (dataset_location != NULL);
+ if (!data)
+ g_return_if_fail (destroy_func == NULL);
+ if (!key_id)
+ {
+ if (data)
+ g_return_if_fail (key_id > 0);
+ else
+ return;
+ }
+
+ G_LOCK (g_dataset_global);
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
+
+ dataset = g_dataset_lookup (dataset_location);
+ if (!dataset)
+ {
+ dataset = g_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);
+}
+
+void
+g_datalist_id_set_data_full (GData **datalist,
+ GQuark key_id,
+ gpointer data,
+ GDestroyNotify destroy_func)
+{
+ g_return_if_fail (datalist != NULL);
+ if (!data)
+ g_return_if_fail (destroy_func == NULL);
+ if (!key_id)
+ {
+ if (data)
+ g_return_if_fail (key_id > 0);
+ else
+ return;
+ }
+
+ G_LOCK (g_dataset_global);
+ if (!g_dataset_location_ht)
+ g_data_initialize ();
+
+ g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
+ G_UNLOCK (g_dataset_global);
+}
+
+gpointer
+g_dataset_id_remove_no_notify (gconstpointer dataset_location,
+ GQuark key_id)
+{
+ gpointer ret_data = NULL;
+
+ g_return_val_if_fail (dataset_location != NULL, NULL);
+
+ G_LOCK (g_dataset_global);
+ if (key_id && g_dataset_location_ht)
+ {
+ GDataset *dataset;
+
+ dataset = g_dataset_lookup (dataset_location);
+ if (dataset)
+ ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
+ }
+ G_UNLOCK (g_dataset_global);
+
+ return ret_data;
+}
+
+gpointer
+g_datalist_id_remove_no_notify (GData **datalist,
+ GQuark key_id)
+{
+ gpointer ret_data = NULL;
+
+ g_return_val_if_fail (datalist != NULL, NULL);
+
+ G_LOCK (g_dataset_global);
+ if (key_id && g_dataset_location_ht)
+ ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
+ G_UNLOCK (g_dataset_global);
+
+ return ret_data;
+}
+
+gpointer
+g_dataset_id_get_data (gconstpointer dataset_location,
+ GQuark key_id)
+{
+ g_return_val_if_fail (dataset_location != NULL, NULL);
+
+ G_LOCK (g_dataset_global);
+ if (key_id && g_dataset_location_ht)
+ {
+ register GDataset *dataset;
+
+ dataset = g_dataset_lookup (dataset_location);
+ if (dataset)
+ {
+ register GData *list;
+
+ for (list = dataset->datalist; list; list = list->next)
+ if (list->id == key_id)
+ {
+ G_UNLOCK (g_dataset_global);
+ return list->data;
+ }
+ }
+ }
+ G_UNLOCK (g_dataset_global);
+
+ return NULL;
+}
+
+gpointer
+g_datalist_id_get_data (GData **datalist,
+ GQuark key_id)
+{
+ gpointer data = NULL;
+ g_return_val_if_fail (datalist != NULL, NULL);
+ if (key_id)
+ {
+ register GData *list;
+ G_LOCK (g_dataset_global);
+ for (list = G_DATALIST_GET_POINTER (datalist); list; list = list->next)
+ if (list->id == key_id)
+ {
+ data = list->data;
+ break;
+ }
+ G_UNLOCK (g_dataset_global);
+ }
+ return data;
+}
+
+void
+g_dataset_foreach (gconstpointer dataset_location,
+ GDataForeachFunc func,
+ gpointer user_data)
+{
+ register GDataset *dataset;
+
+ g_return_if_fail (dataset_location != NULL);
+ g_return_if_fail (func != NULL);
+
+ G_LOCK (g_dataset_global);
+ if (g_dataset_location_ht)
+ {
+ dataset = g_dataset_lookup (dataset_location);
+ G_UNLOCK (g_dataset_global);
+ if (dataset)
+ {
+ register GData *list, *next;
+
+ for (list = dataset->datalist; list; list = next)
+ {
+ next = list->next;
+ func (list->id, list->data, user_data);
+ }
+ }
+ }
+ else
+ {
+ G_UNLOCK (g_dataset_global);
+ }
+}
+
+void
+g_datalist_foreach (GData **datalist,
+ GDataForeachFunc func,
+ gpointer user_data)
+{
+ register GData *list, *next;
+
+ g_return_if_fail (datalist != NULL);
+ g_return_if_fail (func != NULL);
+
+ for (list = G_DATALIST_GET_POINTER (datalist); list; list = next)
+ {
+ next = list->next;
+ func (list->id, list->data, user_data);
+ }
+}
+
+void
+g_datalist_init (GData **datalist)
+{
+ g_return_if_fail (datalist != NULL);
+
+ 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)
+{
+ gpointer oldvalue;
+ g_return_if_fail (datalist != NULL);
+ g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
+
+ do
+ {
+ oldvalue = g_atomic_pointer_get (datalist);
+ }
+ while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, oldvalue,
+ (gpointer) ((gsize) oldvalue | 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)
+{
+ gpointer oldvalue;
+ g_return_if_fail (datalist != NULL);
+ g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
+
+ do
+ {
+ oldvalue = g_atomic_pointer_get (datalist);
+ }
+ while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, oldvalue,
+ (gpointer) ((gsize) oldvalue & ~(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;
+}
+
+GQuark
+g_quark_try_string (const gchar *string)
+{
+ GQuark quark = 0;
+ g_return_val_if_fail (string != NULL, 0);
+
+ G_LOCK (g_quark_global);
+ if (g_quark_ht)
+ quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
+ G_UNLOCK (g_quark_global);
+
+ return quark;
+}
+
+/* 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 ? g_strdup (string) : (gchar *)string);
+
+ return quark;
+}
+
+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;
+}
+
+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_CONST_RETURN gchar*
+g_quark_to_string (GQuark quark)
+{
+ gchar* result = NULL;
+
+ G_LOCK (g_quark_global);
+ if (quark < g_quark_seq_id)
+ result = g_quarks[quark];
+ G_UNLOCK (g_quark_global);
+
+ return result;
+}
+
+/* HOLDS: g_quark_global_lock */
+static inline GQuark
+g_quark_new (gchar *string)
+{
+ GQuark quark;
+
+ if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
+ g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
+ 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;
+ }
+
+ quark = g_quark_seq_id++;
+ g_quarks[quark] = string;
+ g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
+
+ return quark;
+}
+
+/**
+ * g_intern_string:
+ * @string: 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
+ */
+G_CONST_RETURN 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: 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
+ */
+G_CONST_RETURN 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;
+}
+
+
+
+#define __G_DATASET_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gdataset.h b/desmume/src/windows/glib-2.20.1/build/glib/gdataset.h
new file mode 100644
index 000000000..2733ffb03
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdataset.h
@@ -0,0 +1,122 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_DATASET_H__
+#define __G_DATASET_H__
+
+#include
+
+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_get_data(dl, k) \
+ (g_datalist_id_get_data ((dl), g_quark_try_string (k)))
+#define g_datalist_set_data_full(dl, k, d, f) \
+ g_datalist_id_set_data_full ((dl), g_quark_from_string (k), (d), (f))
+#define g_datalist_remove_no_notify(dl, k) \
+ g_datalist_id_remove_no_notify ((dl), g_quark_try_string (k))
+#define g_datalist_set_data(dl, k, d) \
+ g_datalist_set_data_full ((dl), (k), (d), NULL)
+#define g_datalist_remove_data(dl, k) \
+ g_datalist_id_set_data ((dl), g_quark_try_string (k), NULL)
+
+
+/* Location Associated Keyed Data
+ */
+void g_dataset_destroy (gconstpointer dataset_location);
+gpointer g_dataset_id_get_data (gconstpointer dataset_location,
+ GQuark key_id);
+void g_dataset_id_set_data_full (gconstpointer dataset_location,
+ GQuark key_id,
+ gpointer data,
+ GDestroyNotify destroy_func);
+gpointer g_dataset_id_remove_no_notify (gconstpointer dataset_location,
+ GQuark key_id);
+void g_dataset_foreach (gconstpointer dataset_location,
+ GDataForeachFunc func,
+ gpointer user_data);
+#define g_dataset_id_set_data(l, k, d) \
+ g_dataset_id_set_data_full ((l), (k), (d), NULL)
+#define g_dataset_id_remove_data(l, k) \
+ g_dataset_id_set_data ((l), (k), NULL)
+#define g_dataset_get_data(l, k) \
+ (g_dataset_id_get_data ((l), g_quark_try_string (k)))
+#define g_dataset_set_data_full(l, k, d, f) \
+ g_dataset_id_set_data_full ((l), g_quark_from_string (k), (d), (f))
+#define g_dataset_remove_no_notify(l, k) \
+ g_dataset_id_remove_no_notify ((l), g_quark_try_string (k))
+#define g_dataset_set_data(l, k, d) \
+ g_dataset_set_data_full ((l), (k), (d), NULL)
+#define g_dataset_remove_data(l, k) \
+ g_dataset_id_set_data ((l), g_quark_try_string (k), NULL)
+
+G_END_DECLS
+
+#endif /* __G_DATASET_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gdatasetprivate.h b/desmume/src/windows/glib-2.20.1/build/glib/gdatasetprivate.h
new file mode 100644
index 000000000..fdbb87ab4
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdatasetprivate.h
@@ -0,0 +1,44 @@
+/* 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __G_DATASETPRIVATE_H__
+#define __G_DATASETPRIVATE_H__
+
+#include
+
+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/desmume/src/windows/glib-2.20.1/build/glib/gdate.c b/desmume/src/windows/glib-2.20.1/build/glib/gdate.c
new file mode 100644
index 000000000..cb25f3c56
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdate.c
@@ -0,0 +1,1905 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#define DEBUG_MSG(x) /* */
+#ifdef G_ENABLE_DEBUG
+/* #define DEBUG_MSG(args) g_message args ; */
+#endif
+
+#include "glib.h"
+
+#include
+#include
+#include
+#include
+
+#ifdef G_OS_WIN32
+#include
+#endif
+
+#include "galias.h"
+
+GDate*
+g_date_new (void)
+{
+ GDate *d = g_new0 (GDate, 1); /* happily, 0 is the invalid flag for everything. */
+
+ return d;
+}
+
+GDate*
+g_date_new_dmy (GDateDay day,
+ GDateMonth m,
+ GDateYear y)
+{
+ GDate *d;
+ g_return_val_if_fail (g_date_valid_dmy (day, m, y), NULL);
+
+ d = g_new (GDate, 1);
+
+ d->julian = FALSE;
+ d->dmy = TRUE;
+
+ d->month = m;
+ d->day = day;
+ d->year = y;
+
+ g_assert (g_date_valid (d));
+
+ return d;
+}
+
+GDate*
+g_date_new_julian (guint32 j)
+{
+ GDate *d;
+ g_return_val_if_fail (g_date_valid_julian (j), NULL);
+
+ d = g_new (GDate, 1);
+
+ d->julian = TRUE;
+ d->dmy = FALSE;
+
+ d->julian_days = j;
+
+ g_assert (g_date_valid (d));
+
+ return d;
+}
+
+void
+g_date_free (GDate *d)
+{
+ g_return_if_fail (d != NULL);
+
+ g_free (d);
+}
+
+gboolean
+g_date_valid (const GDate *d)
+{
+ g_return_val_if_fail (d != NULL, FALSE);
+
+ return (d->julian || d->dmy);
+}
+
+static const guint8 days_in_months[2][13] =
+{ /* error, jan feb mar apr may jun jul aug sep oct nov dec */
+ { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } /* leap year */
+};
+
+static const guint16 days_in_year[2][14] =
+{ /* 0, jan feb mar apr may jun jul aug sep oct nov dec */
+ { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+gboolean
+g_date_valid_month (GDateMonth m)
+{
+ return ( (m > G_DATE_BAD_MONTH) && (m < 13) );
+}
+
+gboolean
+g_date_valid_year (GDateYear y)
+{
+ return ( y > G_DATE_BAD_YEAR );
+}
+
+gboolean
+g_date_valid_day (GDateDay d)
+{
+ return ( (d > G_DATE_BAD_DAY) && (d < 32) );
+}
+
+gboolean
+g_date_valid_weekday (GDateWeekday w)
+{
+ return ( (w > G_DATE_BAD_WEEKDAY) && (w < 8) );
+}
+
+gboolean
+g_date_valid_julian (guint32 j)
+{
+ return (j > G_DATE_BAD_JULIAN);
+}
+
+gboolean
+g_date_valid_dmy (GDateDay d,
+ GDateMonth m,
+ GDateYear y)
+{
+ return ( (m > G_DATE_BAD_MONTH) &&
+ (m < 13) &&
+ (d > G_DATE_BAD_DAY) &&
+ (y > G_DATE_BAD_YEAR) && /* must check before using g_date_is_leap_year */
+ (d <= (g_date_is_leap_year (y) ?
+ days_in_months[1][m] : days_in_months[0][m])) );
+}
+
+
+/* "Julian days" just means an absolute number of days, where Day 1 ==
+ * Jan 1, Year 1
+ */
+static void
+g_date_update_julian (const GDate *const_d)
+{
+ GDate *d = (GDate *) const_d;
+ GDateYear year;
+ gint idx;
+
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (d->dmy);
+ g_return_if_fail (!d->julian);
+ g_return_if_fail (g_date_valid_dmy (d->day, d->month, d->year));
+
+ /* What we actually do is: multiply years * 365 days in the year,
+ * add the number of years divided by 4, subtract the number of
+ * years divided by 100 and add the number of years divided by 400,
+ * which accounts for leap year stuff. Code from Steffen Beyer's
+ * DateCalc.
+ */
+
+ year = d->year - 1; /* we know d->year > 0 since it's valid */
+
+ d->julian_days = year * 365U;
+ d->julian_days += (year >>= 2); /* divide by 4 and add */
+ d->julian_days -= (year /= 25); /* divides original # years by 100 */
+ d->julian_days += year >> 2; /* divides by 4, which divides original by 400 */
+
+ idx = g_date_is_leap_year (d->year) ? 1 : 0;
+
+ d->julian_days += days_in_year[idx][d->month] + d->day;
+
+ g_return_if_fail (g_date_valid_julian (d->julian_days));
+
+ d->julian = TRUE;
+}
+
+static void
+g_date_update_dmy (const GDate *const_d)
+{
+ GDate *d = (GDate *) const_d;
+ GDateYear y;
+ GDateMonth m;
+ GDateDay day;
+
+ guint32 A, B, C, D, E, M;
+
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (d->julian);
+ g_return_if_fail (!d->dmy);
+ g_return_if_fail (g_date_valid_julian (d->julian_days));
+
+ /* Formula taken from the Calendar FAQ; the formula was for the
+ * Julian Period which starts on 1 January 4713 BC, so we add
+ * 1,721,425 to the number of days before doing the formula.
+ *
+ * I'm sure this can be simplified for our 1 January 1 AD period
+ * start, but I can't figure out how to unpack the formula.
+ */
+
+ A = d->julian_days + 1721425 + 32045;
+ B = ( 4 *(A + 36524) )/ 146097 - 1;
+ C = A - (146097 * B)/4;
+ D = ( 4 * (C + 365) ) / 1461 - 1;
+ E = C - ((1461*D) / 4);
+ M = (5 * (E - 1) + 2)/153;
+
+ m = M + 3 - (12*(M/10));
+ day = E - (153*M + 2)/5;
+ y = 100 * B + D - 4800 + (M/10);
+
+#ifdef G_ENABLE_DEBUG
+ if (!g_date_valid_dmy (day, m, y))
+ g_warning ("\nOOPS julian: %u computed dmy: %u %u %u\n",
+ d->julian_days, day, m, y);
+#endif
+
+ d->month = m;
+ d->day = day;
+ d->year = y;
+
+ d->dmy = TRUE;
+}
+
+GDateWeekday
+g_date_get_weekday (const GDate *d)
+{
+ g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_WEEKDAY);
+
+ if (!d->julian)
+ g_date_update_julian (d);
+
+ g_return_val_if_fail (d->julian, G_DATE_BAD_WEEKDAY);
+
+ return ((d->julian_days - 1) % 7) + 1;
+}
+
+GDateMonth
+g_date_get_month (const GDate *d)
+{
+ g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_MONTH);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, G_DATE_BAD_MONTH);
+
+ return d->month;
+}
+
+GDateYear
+g_date_get_year (const GDate *d)
+{
+ g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_YEAR);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, G_DATE_BAD_YEAR);
+
+ return d->year;
+}
+
+GDateDay
+g_date_get_day (const GDate *d)
+{
+ g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_DAY);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, G_DATE_BAD_DAY);
+
+ return d->day;
+}
+
+guint32
+g_date_get_julian (const GDate *d)
+{
+ g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_JULIAN);
+
+ if (!d->julian)
+ g_date_update_julian (d);
+
+ g_return_val_if_fail (d->julian, G_DATE_BAD_JULIAN);
+
+ return d->julian_days;
+}
+
+guint
+g_date_get_day_of_year (const GDate *d)
+{
+ gint idx;
+
+ g_return_val_if_fail (g_date_valid (d), 0);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, 0);
+
+ idx = g_date_is_leap_year (d->year) ? 1 : 0;
+
+ return (days_in_year[idx][d->month] + d->day);
+}
+
+guint
+g_date_get_monday_week_of_year (const GDate *d)
+{
+ GDateWeekday wd;
+ guint day;
+ GDate first;
+
+ g_return_val_if_fail (g_date_valid (d), 0);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, 0);
+
+ g_date_clear (&first, 1);
+
+ g_date_set_dmy (&first, 1, 1, d->year);
+
+ wd = g_date_get_weekday (&first) - 1; /* make Monday day 0 */
+ day = g_date_get_day_of_year (d) - 1;
+
+ return ((day + wd)/7U + (wd == 0 ? 1 : 0));
+}
+
+guint
+g_date_get_sunday_week_of_year (const GDate *d)
+{
+ GDateWeekday wd;
+ guint day;
+ GDate first;
+
+ g_return_val_if_fail (g_date_valid (d), 0);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, 0);
+
+ g_date_clear (&first, 1);
+
+ g_date_set_dmy (&first, 1, 1, d->year);
+
+ wd = g_date_get_weekday (&first);
+ if (wd == 7) wd = 0; /* make Sunday day 0 */
+ day = g_date_get_day_of_year (d) - 1;
+
+ return ((day + wd)/7U + (wd == 0 ? 1 : 0));
+}
+
+/**
+ * g_date_get_iso8601_week_of_year:
+ * @date: a valid #GDate
+ *
+ * Returns the week of the year, where weeks are interpreted according
+ * to ISO 8601.
+ *
+ * Returns: ISO 8601 week number of the year.
+ *
+ * Since: 2.6
+ **/
+guint
+g_date_get_iso8601_week_of_year (const GDate *d)
+{
+ guint j, d4, L, d1, w;
+
+ g_return_val_if_fail (g_date_valid (d), 0);
+
+ if (!d->julian)
+ g_date_update_julian (d);
+
+ g_return_val_if_fail (d->julian, 0);
+
+ /* Formula taken from the Calendar FAQ; the formula was for the
+ * Julian Period which starts on 1 January 4713 BC, so we add
+ * 1,721,425 to the number of days before doing the formula.
+ */
+ j = d->julian_days + 1721425;
+ d4 = (j + 31741 - (j % 7)) % 146097 % 36524 % 1461;
+ L = d4 / 1460;
+ d1 = ((d4 - L) % 365) + L;
+ w = d1 / 7 + 1;
+
+ return w;
+}
+
+gint
+g_date_days_between (const GDate *d1,
+ const GDate *d2)
+{
+ g_return_val_if_fail (g_date_valid (d1), 0);
+ g_return_val_if_fail (g_date_valid (d2), 0);
+
+ return (gint)g_date_get_julian (d2) - (gint)g_date_get_julian (d1);
+}
+
+void
+g_date_clear (GDate *d, guint ndates)
+{
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (ndates != 0);
+
+ memset (d, 0x0, ndates*sizeof (GDate));
+}
+
+G_LOCK_DEFINE_STATIC (g_date_global);
+
+/* These are for the parser, output to the user should use *
+ * g_date_strftime () - this creates more never-freed memory to annoy
+ * all those memory debugger users. :-)
+ */
+
+static gchar *long_month_names[13] =
+{
+ NULL,
+};
+
+static gchar *short_month_names[13] =
+{
+ NULL,
+};
+
+/* This tells us if we need to update the parse info */
+static gchar *current_locale = NULL;
+
+/* order of these in the current locale */
+static GDateDMY dmy_order[3] =
+{
+ G_DATE_DAY, G_DATE_MONTH, G_DATE_YEAR
+};
+
+/* Where to chop two-digit years: i.e., for the 1930 default, numbers
+ * 29 and below are counted as in the year 2000, numbers 30 and above
+ * are counted as in the year 1900.
+ */
+
+static const GDateYear twodigit_start_year = 1930;
+
+/* It is impossible to enter a year between 1 AD and 99 AD with this
+ * in effect.
+ */
+static gboolean using_twodigit_years = FALSE;
+
+/* Adjustment of locale era to AD, non-zero means using locale era
+ */
+static gint locale_era_adjust = 0;
+
+struct _GDateParseTokens {
+ gint num_ints;
+ gint n[3];
+ guint month;
+};
+
+typedef struct _GDateParseTokens GDateParseTokens;
+
+#define NUM_LEN 10
+
+/* HOLDS: g_date_global_lock */
+static void
+g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
+{
+ gchar num[4][NUM_LEN+1];
+ gint i;
+ const guchar *s;
+
+ /* We count 4, but store 3; so we can give an error
+ * if there are 4.
+ */
+ num[0][0] = num[1][0] = num[2][0] = num[3][0] = '\0';
+
+ s = (const guchar *) str;
+ pt->num_ints = 0;
+ while (*s && pt->num_ints < 4)
+ {
+
+ i = 0;
+ while (*s && g_ascii_isdigit (*s) && i < NUM_LEN)
+ {
+ num[pt->num_ints][i] = *s;
+ ++s;
+ ++i;
+ }
+
+ if (i > 0)
+ {
+ num[pt->num_ints][i] = '\0';
+ ++(pt->num_ints);
+ }
+
+ if (*s == '\0') break;
+
+ ++s;
+ }
+
+ pt->n[0] = pt->num_ints > 0 ? atoi (num[0]) : 0;
+ pt->n[1] = pt->num_ints > 1 ? atoi (num[1]) : 0;
+ pt->n[2] = pt->num_ints > 2 ? atoi (num[2]) : 0;
+
+ pt->month = G_DATE_BAD_MONTH;
+
+ if (pt->num_ints < 3)
+ {
+ gchar *casefold;
+ gchar *normalized;
+
+ casefold = g_utf8_casefold (str, -1);
+ normalized = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
+ g_free (casefold);
+
+ i = 1;
+ while (i < 13)
+ {
+ if (long_month_names[i] != NULL)
+ {
+ const gchar *found = strstr (normalized, long_month_names[i]);
+
+ if (found != NULL)
+ {
+ pt->month = i;
+ break;
+ }
+ }
+
+ if (short_month_names[i] != NULL)
+ {
+ const gchar *found = strstr (normalized, short_month_names[i]);
+
+ if (found != NULL)
+ {
+ pt->month = i;
+ break;
+ }
+ }
+
+ ++i;
+ }
+
+ g_free (normalized);
+ }
+}
+
+/* HOLDS: g_date_global_lock */
+static void
+g_date_prepare_to_parse (const gchar *str,
+ GDateParseTokens *pt)
+{
+ const gchar *locale = setlocale (LC_TIME, NULL);
+ gboolean recompute_localeinfo = FALSE;
+ GDate d;
+
+ g_return_if_fail (locale != NULL); /* should not happen */
+
+ g_date_clear (&d, 1); /* clear for scratch use */
+
+ if ( (current_locale == NULL) || (strcmp (locale, current_locale) != 0) )
+ recompute_localeinfo = TRUE; /* Uh, there used to be a reason for the temporary */
+
+ if (recompute_localeinfo)
+ {
+ int i = 1;
+ GDateParseTokens testpt;
+ gchar buf[128];
+
+ g_free (current_locale); /* still works if current_locale == NULL */
+
+ current_locale = g_strdup (locale);
+
+ short_month_names[0] = "Error";
+ long_month_names[0] = "Error";
+
+ while (i < 13)
+ {
+ gchar *casefold;
+
+ g_date_set_dmy (&d, 1, i, 1);
+
+ g_return_if_fail (g_date_valid (&d));
+
+ g_date_strftime (buf, 127, "%b", &d);
+
+ casefold = g_utf8_casefold (buf, -1);
+ g_free (short_month_names[i]);
+ short_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
+ g_free (casefold);
+
+ g_date_strftime (buf, 127, "%B", &d);
+ casefold = g_utf8_casefold (buf, -1);
+ g_free (long_month_names[i]);
+ long_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
+ g_free (casefold);
+
+ ++i;
+ }
+
+ /* Determine DMY order */
+
+ /* had to pick a random day - don't change this, some strftimes
+ * are broken on some days, and this one is good so far. */
+ g_date_set_dmy (&d, 4, 7, 1976);
+
+ g_date_strftime (buf, 127, "%x", &d);
+
+ g_date_fill_parse_tokens (buf, &testpt);
+
+ i = 0;
+ while (i < testpt.num_ints)
+ {
+ switch (testpt.n[i])
+ {
+ case 7:
+ dmy_order[i] = G_DATE_MONTH;
+ break;
+ case 4:
+ dmy_order[i] = G_DATE_DAY;
+ break;
+ case 76:
+ using_twodigit_years = TRUE; /* FALL THRU */
+ case 1976:
+ dmy_order[i] = G_DATE_YEAR;
+ break;
+ default:
+ /* assume locale era */
+ locale_era_adjust = 1976 - testpt.n[i];
+ dmy_order[i] = G_DATE_YEAR;
+ break;
+ }
+ ++i;
+ }
+
+#ifdef G_ENABLE_DEBUG
+ DEBUG_MSG (("**GDate prepared a new set of locale-specific parse rules."));
+ i = 1;
+ while (i < 13)
+ {
+ DEBUG_MSG ((" %s %s", long_month_names[i], short_month_names[i]));
+ ++i;
+ }
+ if (using_twodigit_years)
+ {
+ DEBUG_MSG (("**Using twodigit years with cutoff year: %u", twodigit_start_year));
+ }
+ {
+ gchar *strings[3];
+ i = 0;
+ while (i < 3)
+ {
+ switch (dmy_order[i])
+ {
+ case G_DATE_MONTH:
+ strings[i] = "Month";
+ break;
+ case G_DATE_YEAR:
+ strings[i] = "Year";
+ break;
+ case G_DATE_DAY:
+ strings[i] = "Day";
+ break;
+ default:
+ strings[i] = NULL;
+ break;
+ }
+ ++i;
+ }
+ DEBUG_MSG (("**Order: %s, %s, %s", strings[0], strings[1], strings[2]));
+ DEBUG_MSG (("**Sample date in this locale: `%s'", buf));
+ }
+#endif
+ }
+
+ g_date_fill_parse_tokens (str, pt);
+}
+
+void
+g_date_set_parse (GDate *d,
+ const gchar *str)
+{
+ GDateParseTokens pt;
+ guint m = G_DATE_BAD_MONTH, day = G_DATE_BAD_DAY, y = G_DATE_BAD_YEAR;
+
+ g_return_if_fail (d != NULL);
+
+ /* set invalid */
+ g_date_clear (d, 1);
+
+ G_LOCK (g_date_global);
+
+ g_date_prepare_to_parse (str, &pt);
+
+ DEBUG_MSG (("Found %d ints, `%d' `%d' `%d' and written out month %d",
+ pt.num_ints, pt.n[0], pt.n[1], pt.n[2], pt.month));
+
+
+ if (pt.num_ints == 4)
+ {
+ G_UNLOCK (g_date_global);
+ return; /* presumably a typo; bail out. */
+ }
+
+ if (pt.num_ints > 1)
+ {
+ int i = 0;
+ int j = 0;
+
+ g_assert (pt.num_ints < 4); /* i.e., it is 2 or 3 */
+
+ while (i < pt.num_ints && j < 3)
+ {
+ switch (dmy_order[j])
+ {
+ case G_DATE_MONTH:
+ {
+ if (pt.num_ints == 2 && pt.month != G_DATE_BAD_MONTH)
+ {
+ m = pt.month;
+ ++j; /* skip months, but don't skip this number */
+ continue;
+ }
+ else
+ m = pt.n[i];
+ }
+ break;
+ case G_DATE_DAY:
+ {
+ if (pt.num_ints == 2 && pt.month == G_DATE_BAD_MONTH)
+ {
+ day = 1;
+ ++j; /* skip days, since we may have month/year */
+ continue;
+ }
+ day = pt.n[i];
+ }
+ break;
+ case G_DATE_YEAR:
+ {
+ y = pt.n[i];
+
+ if (locale_era_adjust != 0)
+ {
+ y += locale_era_adjust;
+ }
+ else if (using_twodigit_years && y < 100)
+ {
+ guint two = twodigit_start_year % 100;
+ guint century = (twodigit_start_year / 100) * 100;
+
+ if (y < two)
+ century += 100;
+
+ y += century;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ ++i;
+ ++j;
+ }
+
+
+ if (pt.num_ints == 3 && !g_date_valid_dmy (day, m, y))
+ {
+ /* Try YYYY MM DD */
+ y = pt.n[0];
+ m = pt.n[1];
+ day = pt.n[2];
+
+ if (using_twodigit_years && y < 100)
+ y = G_DATE_BAD_YEAR; /* avoids ambiguity */
+ }
+ else if (pt.num_ints == 2)
+ {
+ if (m == G_DATE_BAD_MONTH && pt.month != G_DATE_BAD_MONTH)
+ m = pt.month;
+ }
+ }
+ else if (pt.num_ints == 1)
+ {
+ if (pt.month != G_DATE_BAD_MONTH)
+ {
+ /* Month name and year? */
+ m = pt.month;
+ day = 1;
+ y = pt.n[0];
+ }
+ else
+ {
+ /* Try yyyymmdd and yymmdd */
+
+ m = (pt.n[0]/100) % 100;
+ day = pt.n[0] % 100;
+ y = pt.n[0]/10000;
+
+ /* FIXME move this into a separate function */
+ if (using_twodigit_years && y < 100)
+ {
+ guint two = twodigit_start_year % 100;
+ guint century = (twodigit_start_year / 100) * 100;
+
+ if (y < two)
+ century += 100;
+
+ y += century;
+ }
+ }
+ }
+
+ /* See if we got anything valid out of all this. */
+ /* y < 8000 is to catch 19998 style typos; the library is OK up to 65535 or so */
+ if (y < 8000 && g_date_valid_dmy (day, m, y))
+ {
+ d->month = m;
+ d->day = day;
+ d->year = y;
+ d->dmy = TRUE;
+ }
+#ifdef G_ENABLE_DEBUG
+ else
+ {
+ DEBUG_MSG (("Rejected DMY %u %u %u", day, m, y));
+ }
+#endif
+ G_UNLOCK (g_date_global);
+}
+
+/**
+ * g_date_set_time_t:
+ * @date: a #GDate
+ * @timet: time_t value to set
+ *
+ * Sets the value of a date to the date corresponding to a time
+ * specified as a time_t. The time to date conversion is done using
+ * the user's current timezone.
+ *
+ * To set the value of a date to the current day, you could write:
+ * |[
+ * g_date_set_time_t (date, time (NULL));
+ * ]|
+ *
+ * Since: 2.10
+ */
+void
+g_date_set_time_t (GDate *date,
+ time_t timet)
+{
+ struct tm tm;
+
+ g_return_if_fail (date != NULL);
+
+#ifdef HAVE_LOCALTIME_R
+ localtime_r (&timet, &tm);
+#else
+ {
+ struct tm *ptm = localtime (&timet);
+
+ if (ptm == NULL)
+ {
+ /* Happens at least in Microsoft's C library if you pass a
+ * negative time_t. Use 2000-01-01 as default date.
+ */
+#ifndef G_DISABLE_CHECKS
+ g_return_if_fail_warning (G_LOG_DOMAIN, "g_date_set_time", "ptm != NULL");
+#endif
+
+ tm.tm_mon = 0;
+ tm.tm_mday = 1;
+ tm.tm_year = 100;
+ }
+ else
+ memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm));
+ }
+#endif
+
+ date->julian = FALSE;
+
+ date->month = tm.tm_mon + 1;
+ date->day = tm.tm_mday;
+ date->year = tm.tm_year + 1900;
+
+ g_return_if_fail (g_date_valid_dmy (date->day, date->month, date->year));
+
+ date->dmy = TRUE;
+}
+
+
+/**
+ * g_date_set_time:
+ * @date: a #GDate.
+ * @time_: #GTime value to set.
+ *
+ * Sets the value of a date from a #GTime value.
+ * The time to date conversion is done using the user's current timezone.
+ *
+ * @Deprecated:2.10: Use g_date_set_time_t() instead.
+ */
+void
+g_date_set_time (GDate *date,
+ GTime time_)
+{
+ g_date_set_time_t (date, (time_t) time_);
+}
+
+/**
+ * g_date_set_time_val:
+ * @date: a #GDate
+ * @timeval: #GTimeVal value to set
+ *
+ * Sets the value of a date from a #GTimeVal value. Note that the
+ * @tv_usec member is ignored, because #GDate can't make use of the
+ * additional precision.
+ *
+ * Since: 2.10
+ */
+void
+g_date_set_time_val (GDate *date,
+ GTimeVal *timeval)
+{
+ g_date_set_time_t (date, (time_t) timeval->tv_sec);
+}
+
+void
+g_date_set_month (GDate *d,
+ GDateMonth m)
+{
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (g_date_valid_month (m));
+
+ if (d->julian && !d->dmy) g_date_update_dmy(d);
+ d->julian = FALSE;
+
+ d->month = m;
+
+ if (g_date_valid_dmy (d->day, d->month, d->year))
+ d->dmy = TRUE;
+ else
+ d->dmy = FALSE;
+}
+
+void
+g_date_set_day (GDate *d,
+ GDateDay day)
+{
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (g_date_valid_day (day));
+
+ if (d->julian && !d->dmy) g_date_update_dmy(d);
+ d->julian = FALSE;
+
+ d->day = day;
+
+ if (g_date_valid_dmy (d->day, d->month, d->year))
+ d->dmy = TRUE;
+ else
+ d->dmy = FALSE;
+}
+
+void
+g_date_set_year (GDate *d,
+ GDateYear y)
+{
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (g_date_valid_year (y));
+
+ if (d->julian && !d->dmy) g_date_update_dmy(d);
+ d->julian = FALSE;
+
+ d->year = y;
+
+ if (g_date_valid_dmy (d->day, d->month, d->year))
+ d->dmy = TRUE;
+ else
+ d->dmy = FALSE;
+}
+
+void
+g_date_set_dmy (GDate *d,
+ GDateDay day,
+ GDateMonth m,
+ GDateYear y)
+{
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (g_date_valid_dmy (day, m, y));
+
+ d->julian = FALSE;
+
+ d->month = m;
+ d->day = day;
+ d->year = y;
+
+ d->dmy = TRUE;
+}
+
+void
+g_date_set_julian (GDate *d,
+ guint32 j)
+{
+ g_return_if_fail (d != NULL);
+ g_return_if_fail (g_date_valid_julian (j));
+
+ d->julian_days = j;
+ d->julian = TRUE;
+ d->dmy = FALSE;
+}
+
+
+gboolean
+g_date_is_first_of_month (const GDate *d)
+{
+ g_return_val_if_fail (g_date_valid (d), FALSE);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, FALSE);
+
+ if (d->day == 1) return TRUE;
+ else return FALSE;
+}
+
+gboolean
+g_date_is_last_of_month (const GDate *d)
+{
+ gint idx;
+
+ g_return_val_if_fail (g_date_valid (d), FALSE);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_val_if_fail (d->dmy, FALSE);
+
+ idx = g_date_is_leap_year (d->year) ? 1 : 0;
+
+ if (d->day == days_in_months[idx][d->month]) return TRUE;
+ else return FALSE;
+}
+
+void
+g_date_add_days (GDate *d,
+ guint ndays)
+{
+ g_return_if_fail (g_date_valid (d));
+
+ if (!d->julian)
+ g_date_update_julian (d);
+
+ g_return_if_fail (d->julian);
+
+ d->julian_days += ndays;
+ d->dmy = FALSE;
+}
+
+void
+g_date_subtract_days (GDate *d,
+ guint ndays)
+{
+ g_return_if_fail (g_date_valid (d));
+
+ if (!d->julian)
+ g_date_update_julian (d);
+
+ g_return_if_fail (d->julian);
+ g_return_if_fail (d->julian_days > ndays);
+
+ d->julian_days -= ndays;
+ d->dmy = FALSE;
+}
+
+void
+g_date_add_months (GDate *d,
+ guint nmonths)
+{
+ guint years, months;
+ gint idx;
+
+ g_return_if_fail (g_date_valid (d));
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_if_fail (d->dmy);
+
+ nmonths += d->month - 1;
+
+ years = nmonths/12;
+ months = nmonths%12;
+
+ d->month = months + 1;
+ d->year += years;
+
+ idx = g_date_is_leap_year (d->year) ? 1 : 0;
+
+ if (d->day > days_in_months[idx][d->month])
+ d->day = days_in_months[idx][d->month];
+
+ d->julian = FALSE;
+
+ g_return_if_fail (g_date_valid (d));
+}
+
+void
+g_date_subtract_months (GDate *d,
+ guint nmonths)
+{
+ guint years, months;
+ gint idx;
+
+ g_return_if_fail (g_date_valid (d));
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_if_fail (d->dmy);
+
+ years = nmonths/12;
+ months = nmonths%12;
+
+ g_return_if_fail (d->year > years);
+
+ d->year -= years;
+
+ if (d->month > months) d->month -= months;
+ else
+ {
+ months -= d->month;
+ d->month = 12 - months;
+ d->year -= 1;
+ }
+
+ idx = g_date_is_leap_year (d->year) ? 1 : 0;
+
+ if (d->day > days_in_months[idx][d->month])
+ d->day = days_in_months[idx][d->month];
+
+ d->julian = FALSE;
+
+ g_return_if_fail (g_date_valid (d));
+}
+
+void
+g_date_add_years (GDate *d,
+ guint nyears)
+{
+ g_return_if_fail (g_date_valid (d));
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_if_fail (d->dmy);
+
+ d->year += nyears;
+
+ if (d->month == 2 && d->day == 29)
+ {
+ if (!g_date_is_leap_year (d->year))
+ d->day = 28;
+ }
+
+ d->julian = FALSE;
+}
+
+void
+g_date_subtract_years (GDate *d,
+ guint nyears)
+{
+ g_return_if_fail (g_date_valid (d));
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_if_fail (d->dmy);
+ g_return_if_fail (d->year > nyears);
+
+ d->year -= nyears;
+
+ if (d->month == 2 && d->day == 29)
+ {
+ if (!g_date_is_leap_year (d->year))
+ d->day = 28;
+ }
+
+ d->julian = FALSE;
+}
+
+gboolean
+g_date_is_leap_year (GDateYear year)
+{
+ g_return_val_if_fail (g_date_valid_year (year), FALSE);
+
+ return ( (((year % 4) == 0) && ((year % 100) != 0)) ||
+ (year % 400) == 0 );
+}
+
+guint8
+g_date_get_days_in_month (GDateMonth month,
+ GDateYear year)
+{
+ gint idx;
+
+ g_return_val_if_fail (g_date_valid_year (year), 0);
+ g_return_val_if_fail (g_date_valid_month (month), 0);
+
+ idx = g_date_is_leap_year (year) ? 1 : 0;
+
+ return days_in_months[idx][month];
+}
+
+guint8
+g_date_get_monday_weeks_in_year (GDateYear year)
+{
+ GDate d;
+
+ g_return_val_if_fail (g_date_valid_year (year), 0);
+
+ g_date_clear (&d, 1);
+ g_date_set_dmy (&d, 1, 1, year);
+ if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+ g_date_set_dmy (&d, 31, 12, year);
+ if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+ if (g_date_is_leap_year (year))
+ {
+ g_date_set_dmy (&d, 2, 1, year);
+ if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+ g_date_set_dmy (&d, 30, 12, year);
+ if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+ }
+ return 52;
+}
+
+guint8
+g_date_get_sunday_weeks_in_year (GDateYear year)
+{
+ GDate d;
+
+ g_return_val_if_fail (g_date_valid_year (year), 0);
+
+ g_date_clear (&d, 1);
+ g_date_set_dmy (&d, 1, 1, year);
+ if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+ g_date_set_dmy (&d, 31, 12, year);
+ if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+ if (g_date_is_leap_year (year))
+ {
+ g_date_set_dmy (&d, 2, 1, year);
+ if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+ g_date_set_dmy (&d, 30, 12, year);
+ if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+ }
+ return 52;
+}
+
+gint
+g_date_compare (const GDate *lhs,
+ const GDate *rhs)
+{
+ g_return_val_if_fail (lhs != NULL, 0);
+ g_return_val_if_fail (rhs != NULL, 0);
+ g_return_val_if_fail (g_date_valid (lhs), 0);
+ g_return_val_if_fail (g_date_valid (rhs), 0);
+
+ /* Remember the self-comparison case! I think it works right now. */
+
+ while (TRUE)
+ {
+ if (lhs->julian && rhs->julian)
+ {
+ if (lhs->julian_days < rhs->julian_days) return -1;
+ else if (lhs->julian_days > rhs->julian_days) return 1;
+ else return 0;
+ }
+ else if (lhs->dmy && rhs->dmy)
+ {
+ if (lhs->year < rhs->year) return -1;
+ else if (lhs->year > rhs->year) return 1;
+ else
+ {
+ if (lhs->month < rhs->month) return -1;
+ else if (lhs->month > rhs->month) return 1;
+ else
+ {
+ if (lhs->day < rhs->day) return -1;
+ else if (lhs->day > rhs->day) return 1;
+ else return 0;
+ }
+
+ }
+
+ }
+ else
+ {
+ if (!lhs->julian) g_date_update_julian (lhs);
+ if (!rhs->julian) g_date_update_julian (rhs);
+ g_return_val_if_fail (lhs->julian, 0);
+ g_return_val_if_fail (rhs->julian, 0);
+ }
+
+ }
+ return 0; /* warnings */
+}
+
+
+void
+g_date_to_struct_tm (const GDate *d,
+ struct tm *tm)
+{
+ GDateWeekday day;
+
+ g_return_if_fail (g_date_valid (d));
+ g_return_if_fail (tm != NULL);
+
+ if (!d->dmy)
+ g_date_update_dmy (d);
+
+ g_return_if_fail (d->dmy);
+
+ /* zero all the irrelevant fields to be sure they're valid */
+
+ /* On Linux and maybe other systems, there are weird non-POSIX
+ * fields on the end of struct tm that choke strftime if they
+ * contain garbage. So we need to 0 the entire struct, not just the
+ * fields we know to exist.
+ */
+
+ memset (tm, 0x0, sizeof (struct tm));
+
+ tm->tm_mday = d->day;
+ tm->tm_mon = d->month - 1; /* 0-11 goes in tm */
+ tm->tm_year = ((int)d->year) - 1900; /* X/Open says tm_year can be negative */
+
+ day = g_date_get_weekday (d);
+ if (day == 7) day = 0; /* struct tm wants days since Sunday, so Sunday is 0 */
+
+ tm->tm_wday = (int)day;
+
+ tm->tm_yday = g_date_get_day_of_year (d) - 1; /* 0 to 365 */
+ tm->tm_isdst = -1; /* -1 means "information not available" */
+}
+
+void
+g_date_clamp (GDate *date,
+ const GDate *min_date,
+ const GDate *max_date)
+{
+ g_return_if_fail (g_date_valid (date));
+
+ if (min_date != NULL)
+ g_return_if_fail (g_date_valid (min_date));
+
+ if (max_date != NULL)
+ g_return_if_fail (g_date_valid (max_date));
+
+ if (min_date != NULL && max_date != NULL)
+ g_return_if_fail (g_date_compare (min_date, max_date) <= 0);
+
+ if (min_date && g_date_compare (date, min_date) < 0)
+ *date = *min_date;
+
+ if (max_date && g_date_compare (max_date, date) < 0)
+ *date = *max_date;
+}
+
+void
+g_date_order (GDate *date1,
+ GDate *date2)
+{
+ g_return_if_fail (g_date_valid (date1));
+ g_return_if_fail (g_date_valid (date2));
+
+ if (g_date_compare (date1, date2) > 0)
+ {
+ GDate tmp = *date1;
+ *date1 = *date2;
+ *date2 = tmp;
+ }
+}
+
+#ifdef G_OS_WIN32
+static gsize
+win32_strftime_helper (const GDate *d,
+ const gchar *format,
+ const struct tm *tm,
+ gchar *s,
+ gsize slen)
+{
+ SYSTEMTIME systemtime;
+ TIME_ZONE_INFORMATION tzinfo;
+ LCID lcid;
+ int n, k;
+ GArray *result;
+ const gchar *p;
+ gunichar c;
+ const wchar_t digits[] = L"0123456789";
+ gchar *convbuf;
+ glong convlen = 0;
+ gsize retval;
+
+ systemtime.wYear = tm->tm_year + 1900;
+ systemtime.wMonth = tm->tm_mon + 1;
+ systemtime.wDayOfWeek = tm->tm_wday;
+ systemtime.wDay = tm->tm_mday;
+ systemtime.wHour = tm->tm_hour;
+ systemtime.wMinute = tm->tm_min;
+ systemtime.wSecond = tm->tm_sec;
+ systemtime.wMilliseconds = 0;
+
+ lcid = GetThreadLocale ();
+ result = g_array_sized_new (FALSE, FALSE, sizeof (wchar_t), MAX (128, strlen (format) * 2));
+
+ p = format;
+ while (*p)
+ {
+ c = g_utf8_get_char (p);
+ if (c == '%')
+ {
+ p = g_utf8_next_char (p);
+ if (!*p)
+ {
+ s[0] = '\0';
+ g_array_free (result, TRUE);
+
+ return 0;
+ }
+
+ c = g_utf8_get_char (p);
+ if (c == 'E' || c == 'O')
+ {
+ /* Ignore modified conversion specifiers for now. */
+ p = g_utf8_next_char (p);
+ if (!*p)
+ {
+ s[0] = '\0';
+ g_array_free (result, TRUE);
+
+ return 0;
+ }
+
+ c = g_utf8_get_char (p);
+ }
+
+ switch (c)
+ {
+ case 'a':
+ if (systemtime.wDayOfWeek == 0)
+ k = 6;
+ else
+ k = systemtime.wDayOfWeek - 1;
+ n = GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, NULL, 0);
+ g_array_set_size (result, result->len + n);
+ GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ break;
+ case 'A':
+ if (systemtime.wDayOfWeek == 0)
+ k = 6;
+ else
+ k = systemtime.wDayOfWeek - 1;
+ n = GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, NULL, 0);
+ g_array_set_size (result, result->len + n);
+ GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ break;
+ case 'b':
+ case 'h':
+ n = GetLocaleInfoW (lcid, LOCALE_SABBREVMONTHNAME1+systemtime.wMonth-1, NULL, 0);
+ g_array_set_size (result, result->len + n);
+ GetLocaleInfoW (lcid, LOCALE_SABBREVMONTHNAME1+systemtime.wMonth-1, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ break;
+ case 'B':
+ n = GetLocaleInfoW (lcid, LOCALE_SMONTHNAME1+systemtime.wMonth-1, NULL, 0);
+ g_array_set_size (result, result->len + n);
+ GetLocaleInfoW (lcid, LOCALE_SMONTHNAME1+systemtime.wMonth-1, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ break;
+ case 'c':
+ n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+ if (n > 0)
+ {
+ g_array_set_size (result, result->len + n);
+ GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ }
+ g_array_append_vals (result, L" ", 1);
+ n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+ if (n > 0)
+ {
+ g_array_set_size (result, result->len + n);
+ GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ }
+ break;
+ case 'C':
+ g_array_append_vals (result, digits + systemtime.wYear/1000, 1);
+ g_array_append_vals (result, digits + (systemtime.wYear/1000)%10, 1);
+ break;
+ case 'd':
+ g_array_append_vals (result, digits + systemtime.wDay/10, 1);
+ g_array_append_vals (result, digits + systemtime.wDay%10, 1);
+ break;
+ case 'D':
+ g_array_append_vals (result, digits + systemtime.wMonth/10, 1);
+ g_array_append_vals (result, digits + systemtime.wMonth%10, 1);
+ g_array_append_vals (result, L"/", 1);
+ g_array_append_vals (result, digits + systemtime.wDay/10, 1);
+ g_array_append_vals (result, digits + systemtime.wDay%10, 1);
+ g_array_append_vals (result, L"/", 1);
+ g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1);
+ g_array_append_vals (result, digits + systemtime.wYear%10, 1);
+ break;
+ case 'e':
+ if (systemtime.wDay >= 10)
+ g_array_append_vals (result, digits + systemtime.wDay/10, 1);
+ else
+ g_array_append_vals (result, L" ", 1);
+ g_array_append_vals (result, digits + systemtime.wDay%10, 1);
+ break;
+
+ /* A GDate has no time fields, so for now we can
+ * hardcode all time conversions into zeros (or 12 for
+ * %I). The alternative code snippets in the #else
+ * branches are here ready to be taken into use when
+ * needed by a g_strftime() or g_date_and_time_format()
+ * or whatever.
+ */
+ case 'H':
+#if 1
+ g_array_append_vals (result, L"00", 2);
+#else
+ g_array_append_vals (result, digits + systemtime.wHour/10, 1);
+ g_array_append_vals (result, digits + systemtime.wHour%10, 1);
+#endif
+ break;
+ case 'I':
+#if 1
+ g_array_append_vals (result, L"12", 2);
+#else
+ if (systemtime.wHour == 0)
+ g_array_append_vals (result, L"12", 2);
+ else
+ {
+ g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1);
+ g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1);
+ }
+#endif
+ break;
+ case 'j':
+ g_array_append_vals (result, digits + (tm->tm_yday+1)/100, 1);
+ g_array_append_vals (result, digits + ((tm->tm_yday+1)/10)%10, 1);
+ g_array_append_vals (result, digits + (tm->tm_yday+1)%10, 1);
+ break;
+ case 'm':
+ g_array_append_vals (result, digits + systemtime.wMonth/10, 1);
+ g_array_append_vals (result, digits + systemtime.wMonth%10, 1);
+ break;
+ case 'M':
+#if 1
+ g_array_append_vals (result, L"00", 2);
+#else
+ g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+ g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+#endif
+ break;
+ case 'n':
+ g_array_append_vals (result, L"\n", 1);
+ break;
+ case 'p':
+ n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0);
+ if (n > 0)
+ {
+ g_array_set_size (result, result->len + n);
+ GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ }
+ break;
+ case 'r':
+ /* This is a rather odd format. Hard to say what to do.
+ * Let's always use the POSIX %I:%M:%S %p
+ */
+#if 1
+ g_array_append_vals (result, L"12:00:00", 8);
+#else
+ if (systemtime.wHour == 0)
+ g_array_append_vals (result, L"12", 2);
+ else
+ {
+ g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1);
+ g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1);
+ }
+ g_array_append_vals (result, L":", 1);
+ g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+ g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+ g_array_append_vals (result, L":", 1);
+ g_array_append_vals (result, digits + systemtime.wSecond/10, 1);
+ g_array_append_vals (result, digits + systemtime.wSecond%10, 1);
+ g_array_append_vals (result, L" ", 1);
+#endif
+ n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0);
+ if (n > 0)
+ {
+ g_array_set_size (result, result->len + n);
+ GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ }
+ break;
+ case 'R':
+#if 1
+ g_array_append_vals (result, L"00:00", 5);
+#else
+ g_array_append_vals (result, digits + systemtime.wHour/10, 1);
+ g_array_append_vals (result, digits + systemtime.wHour%10, 1);
+ g_array_append_vals (result, L":", 1);
+ g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+ g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+#endif
+ break;
+ case 'S':
+#if 1
+ g_array_append_vals (result, L"00", 2);
+#else
+ g_array_append_vals (result, digits + systemtime.wSecond/10, 1);
+ g_array_append_vals (result, digits + systemtime.wSecond%10, 1);
+#endif
+ break;
+ case 't':
+ g_array_append_vals (result, L"\t", 1);
+ break;
+ case 'T':
+#if 1
+ g_array_append_vals (result, L"00:00:00", 8);
+#else
+ g_array_append_vals (result, digits + systemtime.wHour/10, 1);
+ g_array_append_vals (result, digits + systemtime.wHour%10, 1);
+ g_array_append_vals (result, L":", 1);
+ g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+ g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+ g_array_append_vals (result, L":", 1);
+ g_array_append_vals (result, digits + systemtime.wSecond/10, 1);
+ g_array_append_vals (result, digits + systemtime.wSecond%10, 1);
+#endif
+ break;
+ case 'u':
+ if (systemtime.wDayOfWeek == 0)
+ g_array_append_vals (result, L"7", 1);
+ else
+ g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1);
+ break;
+ case 'U':
+ n = g_date_get_sunday_week_of_year (d);
+ g_array_append_vals (result, digits + n/10, 1);
+ g_array_append_vals (result, digits + n%10, 1);
+ break;
+ case 'V':
+ n = g_date_get_iso8601_week_of_year (d);
+ g_array_append_vals (result, digits + n/10, 1);
+ g_array_append_vals (result, digits + n%10, 1);
+ break;
+ case 'w':
+ g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1);
+ break;
+ case 'W':
+ n = g_date_get_monday_week_of_year (d);
+ g_array_append_vals (result, digits + n/10, 1);
+ g_array_append_vals (result, digits + n%10, 1);
+ break;
+ case 'x':
+ n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+ if (n > 0)
+ {
+ g_array_set_size (result, result->len + n);
+ GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ }
+ break;
+ case 'X':
+ n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+ if (n > 0)
+ {
+ g_array_set_size (result, result->len + n);
+ GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+ g_array_set_size (result, result->len - 1);
+ }
+ break;
+ case 'y':
+ g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1);
+ g_array_append_vals (result, digits + systemtime.wYear%10, 1);
+ break;
+ case 'Y':
+ g_array_append_vals (result, digits + systemtime.wYear/1000, 1);
+ g_array_append_vals (result, digits + (systemtime.wYear/100)%10, 1);
+ g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1);
+ g_array_append_vals (result, digits + systemtime.wYear%10, 1);
+ break;
+ case 'Z':
+ n = GetTimeZoneInformation (&tzinfo);
+ if (n == TIME_ZONE_ID_UNKNOWN)
+ ;
+ else if (n == TIME_ZONE_ID_STANDARD)
+ g_array_append_vals (result, tzinfo.StandardName, wcslen (tzinfo.StandardName));
+ else if (n == TIME_ZONE_ID_DAYLIGHT)
+ g_array_append_vals (result, tzinfo.DaylightName, wcslen (tzinfo.DaylightName));
+ break;
+ case '%':
+ g_array_append_vals (result, L"%", 1);
+ break;
+ }
+ }
+ else if (c <= 0xFFFF)
+ {
+ wchar_t wc = c;
+ g_array_append_vals (result, &wc, 1);
+ }
+ else
+ {
+ glong nwc;
+ wchar_t *ws;
+
+ ws = g_ucs4_to_utf16 (&c, 1, NULL, &nwc, NULL);
+ g_array_append_vals (result, ws, nwc);
+ g_free (ws);
+ }
+ p = g_utf8_next_char (p);
+ }
+
+ convbuf = g_utf16_to_utf8 ((wchar_t *) result->data, result->len, NULL, &convlen, NULL);
+ g_array_free (result, TRUE);
+
+ if (!convbuf)
+ {
+ s[0] = '\0';
+ return 0;
+ }
+
+ if (slen <= convlen)
+ {
+ /* Ensure only whole characters are copied into the buffer. */
+ gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen);
+ g_assert (end != NULL);
+ convlen = end - convbuf;
+
+ /* Return 0 because the buffer isn't large enough. */
+ retval = 0;
+ }
+ else
+ retval = convlen;
+
+ memcpy (s, convbuf, convlen);
+ s[convlen] = '\0';
+ g_free (convbuf);
+
+ return retval;
+}
+
+#endif
+
+gsize
+g_date_strftime (gchar *s,
+ gsize slen,
+ const gchar *format,
+ const GDate *d)
+{
+ struct tm tm;
+#ifndef G_OS_WIN32
+ gsize locale_format_len = 0;
+ gchar *locale_format;
+ gsize tmplen;
+ gchar *tmpbuf;
+ gsize tmpbufsize;
+ gsize convlen = 0;
+ gchar *convbuf;
+ GError *error = NULL;
+ gsize retval;
+#endif
+
+ g_return_val_if_fail (g_date_valid (d), 0);
+ g_return_val_if_fail (slen > 0, 0);
+ g_return_val_if_fail (format != NULL, 0);
+ g_return_val_if_fail (s != NULL, 0);
+
+ g_date_to_struct_tm (d, &tm);
+
+#ifdef G_OS_WIN32
+ if (!g_utf8_validate (format, -1, NULL))
+ {
+ s[0] = '\0';
+ return 0;
+ }
+ return win32_strftime_helper (d, format, &tm, s, slen);
+#else
+
+ locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);
+
+ if (error)
+ {
+ g_warning (G_STRLOC "Error converting format to locale encoding: %s\n", error->message);
+ g_error_free (error);
+
+ s[0] = '\0';
+ return 0;
+ }
+
+ tmpbufsize = MAX (128, locale_format_len * 2);
+ while (TRUE)
+ {
+ tmpbuf = g_malloc (tmpbufsize);
+
+ /* Set the first byte to something other than '\0', to be able to
+ * recognize whether strftime actually failed or just returned "".
+ */
+ tmpbuf[0] = '\1';
+ tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm);
+
+ if (tmplen == 0 && tmpbuf[0] != '\0')
+ {
+ g_free (tmpbuf);
+ tmpbufsize *= 2;
+
+ if (tmpbufsize > 65536)
+ {
+ g_warning (G_STRLOC "Maximum buffer size for g_date_strftime exceeded: giving up\n");
+ g_free (locale_format);
+
+ s[0] = '\0';
+ return 0;
+ }
+ }
+ else
+ break;
+ }
+ g_free (locale_format);
+
+ convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);
+ g_free (tmpbuf);
+
+ if (error)
+ {
+ g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s\n", error->message);
+ g_error_free (error);
+
+ s[0] = '\0';
+ return 0;
+ }
+
+ if (slen <= convlen)
+ {
+ /* Ensure only whole characters are copied into the buffer.
+ */
+ gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen);
+ g_assert (end != NULL);
+ convlen = end - convbuf;
+
+ /* Return 0 because the buffer isn't large enough.
+ */
+ retval = 0;
+ }
+ else
+ retval = convlen;
+
+ memcpy (s, convbuf, convlen);
+ s[convlen] = '\0';
+ g_free (convbuf);
+
+ return retval;
+#endif
+}
+
+#define __G_DATE_C__
+#include "galiasdef.c"
+
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gdate.h b/desmume/src/windows/glib-2.20.1/build/glib/gdate.h
new file mode 100644
index 000000000..cb1f56615
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdate.h
@@ -0,0 +1,263 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_DATE_H__
+#define __G_DATE_H__
+
+#include
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+/* GDate
+ *
+ * Date calculations (not time for now, to be resolved). These are a
+ * mutant combination of Steffen Beyer's DateCalc routines
+ * (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's
+ * date routines (written for in-house software). Written by Havoc
+ * Pennington
+ */
+
+typedef gint32 GTime;
+typedef guint16 GDateYear;
+typedef guint8 GDateDay; /* day of the month */
+typedef struct _GDate GDate;
+
+/* enum used to specify order of appearance in parsed date strings */
+typedef enum
+{
+ G_DATE_DAY = 0,
+ G_DATE_MONTH = 1,
+ G_DATE_YEAR = 2
+} GDateDMY;
+
+/* actual week and month values */
+typedef enum
+{
+ G_DATE_BAD_WEEKDAY = 0,
+ G_DATE_MONDAY = 1,
+ G_DATE_TUESDAY = 2,
+ G_DATE_WEDNESDAY = 3,
+ G_DATE_THURSDAY = 4,
+ G_DATE_FRIDAY = 5,
+ G_DATE_SATURDAY = 6,
+ G_DATE_SUNDAY = 7
+} GDateWeekday;
+typedef enum
+{
+ G_DATE_BAD_MONTH = 0,
+ G_DATE_JANUARY = 1,
+ G_DATE_FEBRUARY = 2,
+ G_DATE_MARCH = 3,
+ G_DATE_APRIL = 4,
+ G_DATE_MAY = 5,
+ G_DATE_JUNE = 6,
+ G_DATE_JULY = 7,
+ G_DATE_AUGUST = 8,
+ G_DATE_SEPTEMBER = 9,
+ G_DATE_OCTOBER = 10,
+ G_DATE_NOVEMBER = 11,
+ G_DATE_DECEMBER = 12
+} GDateMonth;
+
+#define G_DATE_BAD_JULIAN 0U
+#define G_DATE_BAD_DAY 0U
+#define G_DATE_BAD_YEAR 0U
+
+/* Note: directly manipulating structs is generally a bad idea, but
+ * in this case it's an *incredibly* bad idea, because all or part
+ * of this struct can be invalid at any given time. Use the functions,
+ * or you will get hosed, I promise.
+ */
+struct _GDate
+{
+ guint julian_days : 32; /* julian days representation - we use a
+ * bitfield hoping that 64 bit platforms
+ * will pack this whole struct in one big
+ * int
+ */
+
+ guint julian : 1; /* julian is valid */
+ guint dmy : 1; /* dmy is valid */
+
+ /* DMY representation */
+ guint day : 6;
+ guint month : 4;
+ guint year : 16;
+};
+
+/* g_date_new() returns an invalid date, you then have to _set() stuff
+ * to get a usable object. You can also allocate a GDate statically,
+ * then call g_date_clear() to initialize.
+ */
+GDate* g_date_new (void);
+GDate* g_date_new_dmy (GDateDay day,
+ GDateMonth month,
+ GDateYear year);
+GDate* g_date_new_julian (guint32 julian_day);
+void g_date_free (GDate *date);
+
+/* check g_date_valid() after doing an operation that might fail, like
+ * _parse. Almost all g_date operations are undefined on invalid
+ * dates (the exceptions are the mutators, since you need those to
+ * return to validity).
+ */
+gboolean g_date_valid (const GDate *date);
+gboolean g_date_valid_day (GDateDay day) G_GNUC_CONST;
+gboolean g_date_valid_month (GDateMonth month) G_GNUC_CONST;
+gboolean g_date_valid_year (GDateYear year) G_GNUC_CONST;
+gboolean g_date_valid_weekday (GDateWeekday weekday) G_GNUC_CONST;
+gboolean g_date_valid_julian (guint32 julian_date) G_GNUC_CONST;
+gboolean g_date_valid_dmy (GDateDay day,
+ GDateMonth month,
+ GDateYear year) G_GNUC_CONST;
+
+GDateWeekday g_date_get_weekday (const GDate *date);
+GDateMonth g_date_get_month (const GDate *date);
+GDateYear g_date_get_year (const GDate *date);
+GDateDay g_date_get_day (const GDate *date);
+guint32 g_date_get_julian (const GDate *date);
+guint g_date_get_day_of_year (const GDate *date);
+/* First monday/sunday is the start of week 1; if we haven't reached
+ * that day, return 0. These are not ISO weeks of the year; that
+ * routine needs to be added.
+ * these functions return the number of weeks, starting on the
+ * corrsponding day
+ */
+guint g_date_get_monday_week_of_year (const GDate *date);
+guint g_date_get_sunday_week_of_year (const GDate *date);
+guint g_date_get_iso8601_week_of_year (const GDate *date);
+
+/* If you create a static date struct you need to clear it to get it
+ * in a sane state before use. You can clear a whole array at
+ * once with the ndates argument.
+ */
+void g_date_clear (GDate *date,
+ guint n_dates);
+
+/* The parse routine is meant for dates typed in by a user, so it
+ * permits many formats but tries to catch common typos. If your data
+ * needs to be strictly validated, it is not an appropriate function.
+ */
+void g_date_set_parse (GDate *date,
+ const gchar *str);
+void g_date_set_time_t (GDate *date,
+ time_t timet);
+void g_date_set_time_val (GDate *date,
+ GTimeVal *timeval);
+#ifndef G_DISABLE_DEPRECATED
+void g_date_set_time (GDate *date,
+ GTime time_);
+#endif
+void g_date_set_month (GDate *date,
+ GDateMonth month);
+void g_date_set_day (GDate *date,
+ GDateDay day);
+void g_date_set_year (GDate *date,
+ GDateYear year);
+void g_date_set_dmy (GDate *date,
+ GDateDay day,
+ GDateMonth month,
+ GDateYear y);
+void g_date_set_julian (GDate *date,
+ guint32 julian_date);
+gboolean g_date_is_first_of_month (const GDate *date);
+gboolean g_date_is_last_of_month (const GDate *date);
+
+/* To go forward by some number of weeks just go forward weeks*7 days */
+void g_date_add_days (GDate *date,
+ guint n_days);
+void g_date_subtract_days (GDate *date,
+ guint n_days);
+
+/* If you add/sub months while day > 28, the day might change */
+void g_date_add_months (GDate *date,
+ guint n_months);
+void g_date_subtract_months (GDate *date,
+ guint n_months);
+
+/* If it's feb 29, changing years can move you to the 28th */
+void g_date_add_years (GDate *date,
+ guint n_years);
+void g_date_subtract_years (GDate *date,
+ guint n_years);
+gboolean g_date_is_leap_year (GDateYear year) G_GNUC_CONST;
+guint8 g_date_get_days_in_month (GDateMonth month,
+ GDateYear year) G_GNUC_CONST;
+guint8 g_date_get_monday_weeks_in_year (GDateYear year) G_GNUC_CONST;
+guint8 g_date_get_sunday_weeks_in_year (GDateYear year) G_GNUC_CONST;
+
+/* Returns the number of days between the two dates. If date2 comes
+ before date1, a negative value is return. */
+gint g_date_days_between (const GDate *date1,
+ const GDate *date2);
+
+/* qsort-friendly (with a cast...) */
+gint g_date_compare (const GDate *lhs,
+ const GDate *rhs);
+void g_date_to_struct_tm (const GDate *date,
+ struct tm *tm);
+
+void g_date_clamp (GDate *date,
+ const GDate *min_date,
+ const GDate *max_date);
+
+/* Swap date1 and date2's values if date1 > date2. */
+void g_date_order (GDate *date1, GDate *date2);
+
+/* Just like strftime() except you can only use date-related formats.
+ * Using a time format is undefined.
+ */
+gsize g_date_strftime (gchar *s,
+ gsize slen,
+ const gchar *format,
+ const GDate *date);
+
+#ifndef G_DISABLE_DEPRECATED
+
+#define g_date_weekday g_date_get_weekday
+#define g_date_month g_date_get_month
+#define g_date_year g_date_get_year
+#define g_date_day g_date_get_day
+#define g_date_julian g_date_get_julian
+#define g_date_day_of_year g_date_get_day_of_year
+#define g_date_monday_week_of_year g_date_get_monday_week_of_year
+#define g_date_sunday_week_of_year g_date_get_sunday_week_of_year
+#define g_date_days_in_month g_date_get_days_in_month
+#define g_date_monday_weeks_in_year g_date_get_monday_weeks_in_year
+#define g_date_sunday_weeks_in_year g_date_get_sunday_weeks_in_year
+
+#endif /* G_DISABLE_DEPRECATED */
+
+G_END_DECLS
+
+#endif /* __G_DATE_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gdebug.h b/desmume/src/windows/glib-2.20.1/build/glib/gdebug.h
new file mode 100644
index 000000000..dea3dde7d
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdebug.h
@@ -0,0 +1,59 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * 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/desmume/src/windows/glib-2.20.1/build/glib/gdir.c b/desmume/src/windows/glib-2.20.1/build/glib/gdir.c
new file mode 100644
index 000000000..a4c4dc342
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdir.c
@@ -0,0 +1,302 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gdir.c: Simplified wrapper around the DIRENT functions.
+ *
+ * Copyright 2001 Hans Breuer
+ * Copyright 2004 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_DIRENT_H
+#include
+#include
+#endif
+
+#include "glib.h"
+#include "gdir.h"
+
+#include "glibintl.h"
+
+#include "galias.h"
+
+#if defined (_MSC_VER) && !defined (HAVE_DIRENT_H)
+#include "../dirent/dirent.h"
+#include "../dirent/wdirent.c"
+#endif
+
+struct _GDir
+{
+#ifdef G_OS_WIN32
+ _WDIR *wdirp;
+#else
+ DIR *dirp;
+#endif
+#ifdef G_OS_WIN32
+ gchar utf8_buf[FILENAME_MAX*4];
+#endif
+};
+
+/**
+ * g_dir_open:
+ * @path: the path to the directory you are interested in. On Unix
+ * in the on-disk encoding. On Windows in UTF-8
+ * @flags: Currently must be set to 0. Reserved for future use.
+ * @error: return location for a #GError, or %NULL.
+ * If non-%NULL, an error will be set if and only if
+ * g_dir_open() fails.
+ *
+ * Opens a directory for reading. The names of the files in the
+ * directory can then be retrieved using g_dir_read_name().
+ *
+ * Return value: a newly allocated #GDir on success, %NULL on failure.
+ * If non-%NULL, you must free the result with g_dir_close()
+ * when you are finished with it.
+ **/
+GDir *
+g_dir_open (const gchar *path,
+ guint flags,
+ GError **error)
+{
+ GDir *dir;
+#ifdef G_OS_WIN32
+ wchar_t *wpath;
+#else
+ gchar *utf8_path;
+#endif
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+#ifdef G_OS_WIN32
+ wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, error);
+
+ if (wpath == NULL)
+ return NULL;
+
+ dir = g_new (GDir, 1);
+
+ dir->wdirp = _wopendir (wpath);
+ g_free (wpath);
+
+ if (dir->wdirp)
+ return dir;
+
+ /* error case */
+
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ _("Error opening directory '%s': %s"),
+ path, g_strerror (errno));
+
+ g_free (dir);
+
+ return NULL;
+#else
+ dir = g_new (GDir, 1);
+
+ dir->dirp = opendir (path);
+
+ if (dir->dirp)
+ return dir;
+
+ /* error case */
+ utf8_path = g_filename_to_utf8 (path, -1,
+ NULL, NULL, NULL);
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ _("Error opening directory '%s': %s"),
+ utf8_path, g_strerror (errno));
+
+ g_free (utf8_path);
+ g_free (dir);
+
+ return NULL;
+#endif
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+/* The above function actually is called g_dir_open_utf8, and it's
+ * that what applications compiled with this GLib version will
+ * use.
+ */
+
+#undef g_dir_open
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+GDir *
+g_dir_open (const gchar *path,
+ guint flags,
+ GError **error)
+{
+ gchar *utf8_path = g_locale_to_utf8 (path, -1, NULL, NULL, error);
+ GDir *retval;
+
+ if (utf8_path == NULL)
+ return NULL;
+
+ retval = g_dir_open_utf8 (utf8_path, flags, error);
+
+ g_free (utf8_path);
+
+ return retval;
+}
+#endif
+
+/**
+ * g_dir_read_name:
+ * @dir: a #GDir* created by g_dir_open()
+ *
+ * Retrieves the name of the next entry in the directory. The '.' and
+ * '..' entries are omitted. On Windows, the returned name is in
+ * UTF-8. On Unix, it is in the on-disk encoding.
+ *
+ * Return value: The entry's name or %NULL if there are no
+ * more entries. The return value is owned by GLib and
+ * must not be modified or freed.
+ **/
+G_CONST_RETURN gchar*
+g_dir_read_name (GDir *dir)
+{
+#ifdef G_OS_WIN32
+ gchar *utf8_name;
+ struct _wdirent *wentry;
+#else
+ struct dirent *entry;
+#endif
+
+ g_return_val_if_fail (dir != NULL, NULL);
+
+#ifdef G_OS_WIN32
+ while (1)
+ {
+ wentry = _wreaddir (dir->wdirp);
+ while (wentry
+ && (0 == wcscmp (wentry->d_name, L".") ||
+ 0 == wcscmp (wentry->d_name, L"..")))
+ wentry = _wreaddir (dir->wdirp);
+
+ if (wentry == NULL)
+ return NULL;
+
+ utf8_name = g_utf16_to_utf8 (wentry->d_name, -1, NULL, NULL, NULL);
+
+ if (utf8_name == NULL)
+ continue; /* Huh, impossible? Skip it anyway */
+
+ strcpy (dir->utf8_buf, utf8_name);
+ g_free (utf8_name);
+
+ return dir->utf8_buf;
+ }
+#else
+ entry = readdir (dir->dirp);
+ while (entry
+ && (0 == strcmp (entry->d_name, ".") ||
+ 0 == strcmp (entry->d_name, "..")))
+ entry = readdir (dir->dirp);
+
+ if (entry)
+ return entry->d_name;
+ else
+ return NULL;
+#endif
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+/* Ditto for g_dir_read_name */
+
+#undef g_dir_read_name
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+G_CONST_RETURN gchar*
+g_dir_read_name (GDir *dir)
+{
+ while (1)
+ {
+ const gchar *utf8_name = g_dir_read_name_utf8 (dir);
+ gchar *retval;
+
+ if (utf8_name == NULL)
+ return NULL;
+
+ retval = g_locale_from_utf8 (utf8_name, -1, NULL, NULL, NULL);
+
+ if (retval != NULL)
+ {
+ strcpy (dir->utf8_buf, retval);
+ g_free (retval);
+
+ return dir->utf8_buf;
+ }
+ }
+}
+
+#endif
+
+/**
+ * g_dir_rewind:
+ * @dir: a #GDir* created by g_dir_open()
+ *
+ * Resets the given directory. The next call to g_dir_read_name()
+ * will return the first entry again.
+ **/
+void
+g_dir_rewind (GDir *dir)
+{
+ g_return_if_fail (dir != NULL);
+
+#ifdef G_OS_WIN32
+ _wrewinddir (dir->wdirp);
+#else
+ rewinddir (dir->dirp);
+#endif
+}
+
+/**
+ * g_dir_close:
+ * @dir: a #GDir* created by g_dir_open()
+ *
+ * Closes the directory and deallocates all related resources.
+ **/
+void
+g_dir_close (GDir *dir)
+{
+ g_return_if_fail (dir != NULL);
+
+#ifdef G_OS_WIN32
+ _wclosedir (dir->wdirp);
+#else
+ closedir (dir->dirp);
+#endif
+ g_free (dir);
+}
+
+#define __G_DIR_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gdir.h b/desmume/src/windows/glib-2.20.1/build/glib/gdir.h
new file mode 100644
index 000000000..85e989695
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gdir.h
@@ -0,0 +1,52 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gdir.c: Simplified wrapper around the DIRENT functions.
+ *
+ * Copyright 2001 Hans Breuer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_DIR_H__
+#define __G_DIR_H__
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct _GDir GDir;
+
+#ifdef G_OS_WIN32
+/* For DLL ABI stability, keep old names for old (non-UTF-8) functionality. */
+#define g_dir_open g_dir_open_utf8
+#define g_dir_read_name g_dir_read_name_utf8
+#endif
+
+GDir * g_dir_open (const gchar *path,
+ guint flags,
+ GError **error);
+G_CONST_RETURN gchar *g_dir_read_name (GDir *dir);
+void g_dir_rewind (GDir *dir);
+void g_dir_close (GDir *dir);
+
+G_END_DECLS
+
+#endif /* __G_DIR_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gerror.c b/desmume/src/windows/glib-2.20.1/build/glib/gerror.c
new file mode 100644
index 000000000..940856003
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gerror.c
@@ -0,0 +1,375 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "galias.h"
+
+
+static 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
+ * @Varargs: parameters for message format
+ *
+ * Creates a new #GError with the given @domain and @code,
+ * and a message formatted with @format.
+ *
+ * Return value: a new #GError
+ **/
+GError*
+g_error_new (GQuark domain,
+ gint code,
+ const gchar *format,
+ ...)
+{
+ GError* error;
+ va_list args;
+
+ g_return_val_if_fail (format != NULL, NULL);
+ g_return_val_if_fail (domain != 0, NULL);
+
+ va_start (args, format);
+ error = g_error_new_valist (domain, code, format, args);
+ va_end (args);
+
+ return error;
+}
+
+/**
+ * g_error_new_literal:
+ * @domain: error domain
+ * @code: error code
+ * @message: error message
+ *
+ * Creates a new #GError; unlike g_error_new(), @message is not
+ * a printf()-style format string. Use this
+ * function if @message contains text you don't have control over,
+ * that could include printf() escape sequences.
+ *
+ * Return value: a new #GError
+ **/
+GError*
+g_error_new_literal (GQuark domain,
+ gint code,
+ const gchar *message)
+{
+ GError* err;
+
+ g_return_val_if_fail (message != NULL, NULL);
+ g_return_val_if_fail (domain != 0, NULL);
+
+ err = g_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
+ * @domain: an error domain
+ * @code: an error code
+ *
+ * Returns %TRUE if @error matches @domain and @code, %FALSE
+ * otherwise.
+ *
+ * Return value: whether @error has @domain and @code
+ **/
+gboolean
+g_error_matches (const GError *error,
+ GQuark domain,
+ gint code)
+{
+ return error &&
+ error->domain == domain &&
+ error->code == code;
+}
+
+#define ERROR_OVERWRITTEN_WARNING "GError set over the top of a previous GError or uninitialized memory.\n" \
+ "This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n" \
+ "The overwriting error message was: %s"
+
+/**
+ * g_set_error:
+ * @err: a return location for a #GError, or %NULL
+ * @domain: error domain
+ * @code: error code
+ * @format: printf()-style format
+ * @Varargs: args for @format
+ *
+ * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err must
+ * be %NULL. A new #GError is created and assigned to *@err.
+ **/
+void
+g_set_error (GError **err,
+ GQuark domain,
+ gint code,
+ const gchar *format,
+ ...)
+{
+ GError *new;
+
+ va_list args;
+
+ if (err == NULL)
+ return;
+
+ va_start (args, format);
+ new = g_error_new_valist (domain, code, format, args);
+ va_end (args);
+
+ if (*err == NULL)
+ *err = new;
+ else
+ g_warning (ERROR_OVERWRITTEN_WARNING, new->message);
+}
+
+/**
+ * g_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);
+ }
+}
+
+#define __G_ERROR_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gerror.h b/desmume/src/windows/glib-2.20.1/build/glib/gerror.h
new file mode 100644
index 000000000..d3d42d59c
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gerror.h
@@ -0,0 +1,92 @@
+/* gerror.h - Error reporting system
+ *
+ * Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_ERROR_H__
+#define __G_ERROR_H__
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct _GError GError;
+
+struct _GError
+{
+ GQuark domain;
+ gint code;
+ gchar *message;
+};
+
+GError* g_error_new (GQuark domain,
+ gint code,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (3, 4);
+
+GError* g_error_new_literal (GQuark domain,
+ gint code,
+ const gchar *message);
+
+void g_error_free (GError *error);
+GError* g_error_copy (const GError *error);
+
+gboolean g_error_matches (const GError *error,
+ GQuark domain,
+ gint code);
+
+/* if (err) *err = g_error_new(domain, code, format, ...), also has
+ * some sanity checks.
+ */
+void g_set_error (GError **err,
+ GQuark domain,
+ gint code,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (4, 5);
+
+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/desmume/src/windows/glib-2.20.1/build/glib/gfileutils.c b/desmume/src/windows/glib-2.20.1/build/glib/gfileutils.c
new file mode 100644
index 000000000..4f5c669bd
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gfileutils.c
@@ -0,0 +1,1965 @@
+/* gfileutils.c - File utility functions
+ *
+ * Copyright 2000 Red Hat, Inc.
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+
+#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef G_OS_WIN32
+#include
+#include
+#endif /* G_OS_WIN32 */
+
+#ifndef S_ISLNK
+#define S_ISLNK(x) 0
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "gstdio.h"
+#include "glibintl.h"
+
+#include "galias.h"
+
+static gint create_temp_file (gchar *tmpl,
+ int permissions);
+
+/**
+ * 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)
+ {
+ 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, (G_FILE_TEST_EXISTS |
+ * G_FILE_TEST_IS_DIR) will return %TRUE if the file exists;
+ * the check whether it's a directory doesn't matter since the existence
+ * test is %TRUE. With the current set of available tests, there's no point
+ * passing in more than one test at a time.
+ *
+ * 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)
+ return (attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0;
+
+ if (test & G_FILE_TEST_IS_DIR)
+ return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
+
+ if (test & G_FILE_TEST_IS_EXECUTABLE)
+ {
+ const gchar *lastdot = strrchr (filename, '.');
+ const gchar *pathext = NULL, *p;
+ int extlen;
+
+ if (lastdot == NULL)
+ return FALSE;
+
+ 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)
+ return FALSE;
+
+ 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);
+ return FALSE;
+ }
+
+ 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: name of a file to read contents from, in the GLib file name encoding
+ * @contents: location to store an allocated string, use g_free() to free
+ * the returned string
+ * @length: 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 = create_temp_file (tmp_name, 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));
+
+ g_unlink (tmp_name);
+
+ goto out;
+ }
+
+#ifdef HAVE_FSYNC
+ errno = 0;
+ /* If the final destination exists, 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_file_test (dest_file, G_FILE_TEST_EXISTS) &&
+ 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));
+
+ g_unlink (tmp_name);
+
+ goto out;
+ }
+#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));
+
+ 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: name of a file to write @contents to, in the GLib file name
+ * encoding
+ * @contents: 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:
+ *
+ *
+ * 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.
+ *
+ *
+ * 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.
+ *
+ *
+ * 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.
+ *
+ *
+ *
+ * If the call was sucessful, 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.
+ *
+ * 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;
+}
+
+/*
+ * create_temp_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.
+ */
+static gint
+create_temp_file (gchar *tmpl,
+ int permissions)
+{
+ 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;
+
+ /* 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];
+
+ /* tmpl is in UTF-8 on Windows, thus use g_open() */
+ fd = g_open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, permissions);
+
+ 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;
+}
+
+/**
+ * g_mkstemp:
+ * @tmpl: 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.
+ */
+gint
+g_mkstemp (gchar *tmpl)
+{
+ return create_temp_file (tmpl, 0600);
+}
+
+/**
+ * g_file_open_tmp:
+ * @tmpl: Template for file name, as in g_mkstemp(), basename only,
+ * or %NULL, to a default template
+ * @name_used: 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.
+ *
+ * The actual name used is returned in @name_used if non-%NULL. This
+ * string should be freed with g_free() when not needed any longer.
+ * 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)
+{
+ 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 = g_mkstemp (fulltemplate);
+
+ 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;
+ }
+
+ if (name_used)
+ *name_used = fulltemplate;
+ else
+ g_free (fulltemplate);
+
+ return retval;
+}
+
+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 (start &&
+ 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: %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
+ * @Varargs: 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 ABA, ABABA
+ * 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: %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
+ * @Varargs: 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 g_build_path
+ * (G_DIR_SEPARATOR_S, first_element, ....).
+ *
+ * On Windows, it takes into account that either the backslash
+ * (\ or slash (/) 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 1024.0
+#define MEGABYTE_FACTOR (1024.0 * 1024.0)
+#define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0)
+
+/**
+ * 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.
+ *
+ * Since: 2.16
+ **/
+char *
+g_format_size_for_display (goffset size)
+{
+ if (size < (goffset) KILOBYTE_FACTOR)
+ return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
+ else
+ {
+ gdouble displayed_size;
+
+ if (size < (goffset) MEGABYTE_FACTOR)
+ {
+ displayed_size = (gdouble) size / KILOBYTE_FACTOR;
+ return g_strdup_printf (_("%.1f KB"), displayed_size);
+ }
+ else if (size < (goffset) GIGABYTE_FACTOR)
+ {
+ displayed_size = (gdouble) size / MEGABYTE_FACTOR;
+ return g_strdup_printf (_("%.1f MB"), displayed_size);
+ }
+ else
+ {
+ displayed_size = (gdouble) size / GIGABYTE_FACTOR;
+ return g_strdup_printf (_("%.1f GB"), 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)
+{
+ 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;
+
+ /* find the last occurrence of 'XXXXXX' */
+ XXXXXX = g_strrstr (tmpl, "XXXXXX");
+
+ if (!XXXXXX)
+ {
+ 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];
+
+ /* This is the backward compatibility system codepage version,
+ * thus use normal open().
+ */
+ fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+
+ if (fd >= 0)
+ return fd;
+ else if (errno != EEXIST)
+ /* Any other error will apply also to other names we might
+ * try, and there are 2^32 or so of them, so give up now.
+ */
+ return -1;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ errno = EEXIST;
+ return -1;
+}
+
+#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
+
+#define __G_FILEUTILS_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gfileutils.h b/desmume/src/windows/glib-2.20.1/build/glib/gfileutils.h
new file mode 100644
index 000000000..9a4b2af38
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gfileutils.h
@@ -0,0 +1,125 @@
+/* gfileutils.h - File utility functions
+ *
+ * Copyright 2000 Red Hat, Inc.
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_FILEUTILS_H__
+#define __G_FILEUTILS_H__
+
+#include
+
+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);
+
+#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
+
+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 mkstemp() */
+gint g_mkstemp (gchar *tmpl);
+
+/* Wrapper for g_mkstemp */
+gint g_file_open_tmp (const gchar *tmpl,
+ gchar **name_used,
+ GError **error);
+
+char *g_format_size_for_display (goffset size);
+
+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/desmume/src/windows/glib-2.20.1/build/glib/ghash.c b/desmume/src/windows/glib-2.20.1/build/glib/ghash.c
new file mode 100644
index 000000000..ba332669d
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/ghash.c
@@ -0,0 +1,1346 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include /* memset */
+
+#include "glib.h"
+#include "galias.h"
+
+#define HASH_TABLE_MIN_SHIFT 3 /* 1 << 3 == 8 buckets */
+
+typedef struct _GHashNode GHashNode;
+
+struct _GHashNode
+{
+ gpointer key;
+ gpointer value;
+
+ /* If key_hash == 0, node is not in use
+ * If key_hash == 1, node is a tombstone
+ * If key_hash >= 2, node contains data */
+ guint key_hash;
+};
+
+struct _GHashTable
+{
+ gint size;
+ gint mod;
+ guint mask;
+ gint nnodes;
+ gint noccupied; /* nnodes + tombstones */
+ GHashNode *nodes;
+ GHashFunc hash_func;
+ GEqualFunc key_equal_func;
+ volatile 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: optional key hash return location
+ * Return value: index of the described #GHashNode
+ *
+ * Performs a lookup in the hash table. Virtually all hash operations
+ * will use this function internally.
+ *
+ * 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 empty node (never a tombstone).
+ */
+static inline guint
+g_hash_table_lookup_node (GHashTable *hash_table,
+ gconstpointer key)
+{
+ GHashNode *node;
+ guint node_index;
+ guint hash_value;
+ guint step = 0;
+
+ /* Empty buckets have hash_value set to 0, and for tombstones, it's 1.
+ * We need to make sure our hash value is not one of these. */
+
+ hash_value = (* hash_table->hash_func) (key);
+ if (G_UNLIKELY (hash_value <= 1))
+ hash_value = 2;
+
+ node_index = hash_value % hash_table->mod;
+ node = &hash_table->nodes [node_index];
+
+ while (node->key_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->key_hash == hash_value)
+ {
+ if (hash_table->key_equal_func)
+ {
+ if (hash_table->key_equal_func (node->key, key))
+ break;
+ }
+ else if (node->key == key)
+ {
+ break;
+ }
+ }
+
+ step++;
+ node_index += step;
+ node_index &= hash_table->mask;
+ node = &hash_table->nodes [node_index];
+ }
+
+ return node_index;
+}
+
+/*
+ * g_hash_table_lookup_node_for_insertion:
+ * @hash_table: our #GHashTable
+ * @key: the key to lookup against
+ * @hash_return: key hash return location
+ * Return value: index of the described #GHashNode
+ *
+ * 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_for_insertion (GHashTable *hash_table,
+ gconstpointer key,
+ guint *hash_return)
+{
+ GHashNode *node;
+ guint node_index;
+ guint hash_value;
+ guint first_tombstone;
+ gboolean have_tombstone = FALSE;
+ guint step = 0;
+
+ /* Empty buckets have hash_value set to 0, and for tombstones, it's 1.
+ * We need to make sure our hash value is not one of these. */
+
+ hash_value = (* hash_table->hash_func) (key);
+ if (G_UNLIKELY (hash_value <= 1))
+ hash_value = 2;
+
+ *hash_return = hash_value;
+
+ node_index = hash_value % hash_table->mod;
+ node = &hash_table->nodes [node_index];
+
+ while (node->key_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->key_hash == hash_value)
+ {
+ 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 (node->key_hash == 1 && !have_tombstone)
+ {
+ first_tombstone = node_index;
+ have_tombstone = TRUE;
+ }
+
+ step++;
+ node_index += step;
+ node_index &= hash_table->mask;
+ node = &hash_table->nodes [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,
+ GHashNode *node,
+ gboolean notify)
+{
+ if (notify && hash_table->key_destroy_func)
+ hash_table->key_destroy_func (node->key);
+
+ if (notify && hash_table->value_destroy_func)
+ hash_table->value_destroy_func (node->value);
+
+ /* Erect tombstone */
+ node->key_hash = 1;
+
+ /* Be GC friendly */
+ node->key = NULL;
+ node->value = NULL;
+
+ hash_table->nnodes--;
+}
+
+/*
+ * 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;
+
+ for (i = 0; i < hash_table->size; i++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+
+ if (node->key_hash > 1)
+ {
+ if (notify && hash_table->key_destroy_func)
+ hash_table->key_destroy_func (node->key);
+
+ if (notify && hash_table->value_destroy_func)
+ hash_table->value_destroy_func (node->value);
+ }
+ }
+
+ /* We need to set node->key_hash = 0 for all nodes - might as well be GC
+ * friendly and clear everything */
+ memset (hash_table->nodes, 0, hash_table->size * sizeof (GHashNode));
+
+ hash_table->nnodes = 0;
+ hash_table->noccupied = 0;
+}
+
+/*
+ * 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)
+{
+ GHashNode *new_nodes;
+ gint old_size;
+ gint i;
+
+ old_size = hash_table->size;
+ g_hash_table_set_shift_from_size (hash_table, hash_table->nnodes * 2);
+
+ new_nodes = g_new0 (GHashNode, hash_table->size);
+
+ for (i = 0; i < old_size; i++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+ GHashNode *new_node;
+ guint hash_val;
+ guint step = 0;
+
+ if (node->key_hash <= 1)
+ continue;
+
+ hash_val = node->key_hash % hash_table->mod;
+ new_node = &new_nodes [hash_val];
+
+ while (new_node->key_hash)
+ {
+ step++;
+ hash_val += step;
+ hash_val &= hash_table->mask;
+ new_node = &new_nodes [hash_val];
+ }
+
+ *new_node = *node;
+ }
+
+ g_free (hash_table->nodes);
+ hash_table->nodes = new_nodes;
+ 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() and
+ * g_str_hash() functions are provided for some common types of keys.
+ * If hash_func is %NULL, g_direct_hash() is used.
+ * @key_equal_func: a function to check two keys for equality. This is
+ * used when looking up keys in the #GHashTable. The g_direct_equal(),
+ * g_int_equal() and g_str_equal() functions are provided for the most
+ * common types of keys. If @key_equal_func is %NULL, keys are compared
+ * directly in a similar fashion to g_direct_equal(), but without the
+ * overhead of a function call.
+ *
+ * Creates a new #GHashTable 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->nodes = g_new0 (GHashNode, 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;
+ GHashNode *node;
+ 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;
+ }
+
+ node = &ri->hash_table->nodes [position];
+ }
+ while (node->key_hash <= 1);
+
+ if (key != NULL)
+ *key = node->key;
+ if (value != NULL)
+ *value = node->value;
+
+ 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->hash_table->nodes [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_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_return_val_if_fail (hash_table->ref_count > 0, hash_table);
+
+ g_atomic_int_add (&hash_table->ref_count, 1);
+ 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);
+ g_return_if_fail (hash_table->ref_count > 0);
+
+ if (g_atomic_int_exchange_and_add (&hash_table->ref_count, -1) - 1 == 0)
+ {
+ g_hash_table_remove_all_nodes (hash_table, TRUE);
+ g_free (hash_table->nodes);
+ 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_return_if_fail (hash_table->ref_count > 0);
+
+ 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)
+{
+ GHashNode *node;
+ guint node_index;
+
+ g_return_val_if_fail (hash_table != NULL, NULL);
+
+ node_index = g_hash_table_lookup_node (hash_table, key);
+ node = &hash_table->nodes [node_index];
+
+ return node->key_hash ? node->value : 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.
+ *
+ * Return value: %TRUE if the key was found in the #GHashTable.
+ **/
+gboolean
+g_hash_table_lookup_extended (GHashTable *hash_table,
+ gconstpointer lookup_key,
+ gpointer *orig_key,
+ gpointer *value)
+{
+ GHashNode *node;
+ guint node_index;
+
+ g_return_val_if_fail (hash_table != NULL, FALSE);
+
+ node_index = g_hash_table_lookup_node (hash_table, lookup_key);
+ node = &hash_table->nodes [node_index];
+
+ if (!node->key_hash)
+ return FALSE;
+
+ if (orig_key)
+ *orig_key = node->key;
+
+ if (value)
+ *value = node->value;
+
+ 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)
+{
+ GHashNode *node;
+ guint node_index;
+ guint key_hash;
+ guint old_hash;
+
+ g_return_if_fail (hash_table != NULL);
+ g_return_if_fail (hash_table->ref_count > 0);
+
+ node_index = g_hash_table_lookup_node_for_insertion (hash_table, key, &key_hash);
+ node = &hash_table->nodes [node_index];
+
+ old_hash = node->key_hash;
+
+ if (old_hash > 1)
+ {
+ if (keep_new_key)
+ {
+ if (hash_table->key_destroy_func)
+ hash_table->key_destroy_func (node->key);
+ node->key = key;
+ }
+ else
+ {
+ if (hash_table->key_destroy_func)
+ hash_table->key_destroy_func (key);
+ }
+
+ if (hash_table->value_destroy_func)
+ hash_table->value_destroy_func (node->value);
+
+ node->value = value;
+ }
+ else
+ {
+ node->key = key;
+ node->value = value;
+ node->key_hash = key_hash;
+
+ hash_table->nnodes++;
+
+ if (old_hash == 0)
+ {
+ /* 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
+ }
+}
+
+/**
+ * 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)
+{
+ GHashNode *node;
+ guint node_index;
+
+ g_return_val_if_fail (hash_table != NULL, FALSE);
+
+ node_index = g_hash_table_lookup_node (hash_table, key);
+ node = &hash_table->nodes [node_index];
+
+ /* g_hash_table_lookup_node() never returns a tombstone, so this is safe */
+ if (!node->key_hash)
+ return FALSE;
+
+ g_hash_table_remove_node (hash_table, node, 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;
+
+ for (i = 0; i < hash_table->size; i++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+
+ if (node->key_hash > 1 && (* func) (node->key, node->value, user_data))
+ {
+ g_hash_table_remove_node (hash_table, node, notify);
+ deleted++;
+ }
+ }
+
+ 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;
+
+ g_return_if_fail (hash_table != NULL);
+ g_return_if_fail (func != NULL);
+
+ for (i = 0; i < hash_table->size; i++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+
+ if (node->key_hash > 1)
+ (* func) (node->key, node->value, user_data);
+ }
+}
+
+/**
+ * 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
+ * func 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;
+
+ g_return_val_if_fail (hash_table != NULL, NULL);
+ g_return_val_if_fail (predicate != NULL, NULL);
+
+ for (i = 0; i < hash_table->size; i++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+
+ if (node->key_hash > 1 && predicate (node->key, node->value, user_data))
+ 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++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+
+ if (node->key_hash > 1)
+ retval = g_list_prepend (retval, node->key);
+ }
+
+ 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++)
+ {
+ GHashNode *node = &hash_table->nodes [i];
+
+ if (node->key_hash > 1)
+ retval = g_list_prepend (retval, node->value);
+ }
+
+ return retval;
+}
+
+#define __G_HASH_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/ghash.h b/desmume/src/windows/glib-2.20.1/build/glib/ghash.h
new file mode 100644
index 000000000..afdd07297
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/ghash.h
@@ -0,0 +1,145 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_HASH_H__
+#define __G_HASH_H__
+
+#include
+#include
+
+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_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
+
+/* The following two functions are deprecated and will be removed in
+ * the next major release. They do no good. */
+#define g_hash_table_freeze(hash_table) ((void)0)
+#define g_hash_table_thaw(hash_table) ((void)0)
+
+#endif /* G_DISABLE_DEPRECATED */
+
+/* Hash Functions
+ */
+gboolean g_str_equal (gconstpointer v1,
+ gconstpointer v2);
+guint g_str_hash (gconstpointer v);
+
+gboolean g_int_equal (gconstpointer v1,
+ gconstpointer v2);
+guint g_int_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/desmume/src/windows/glib-2.20.1/build/glib/ghook.c b/desmume/src/windows/glib-2.20.1/build/glib/ghook.c
new file mode 100644
index 000000000..d038ee2c2
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/ghook.c
@@ -0,0 +1,638 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GHook: Callback maintenance functions
+ * Copyright (C) 1998 Tim Janik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "galias.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;
+}
+
+#define __G_HOOK_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/ghook.h b/desmume/src/windows/glib-2.20.1/build/glib/ghook.h
new file mode 100644
index 000000000..5577fc3e2
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/ghook.h
@@ -0,0 +1,181 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_HOOK_H__
+#define __G_HOOK_H__
+
+#include
+
+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/desmume/src/windows/glib-2.20.1/build/glib/gi18n-lib.h b/desmume/src/windows/glib-2.20.1/build/glib/gi18n-lib.h
new file mode 100644
index 000000000..ca002a722
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gi18n-lib.h
@@ -0,0 +1,38 @@
+/* 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_I18N_LIB_H__
+#define __G_I18N_LIB_H__
+
+#include
+
+#include
+#include
+
+#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/desmume/src/windows/glib-2.20.1/build/glib/gi18n.h b/desmume/src/windows/glib-2.20.1/build/glib/gi18n.h
new file mode 100644
index 000000000..c710046ee
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gi18n.h
@@ -0,0 +1,34 @@
+/* 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_I18N_H__
+#define __G_I18N_H__
+
+#include
+
+#include
+#include
+
+#define _(String) gettext (String)
+#define Q_(String) g_dpgettext (NULL, String, 0)
+#define N_(String) (String)
+#define C_(Context,String) g_dpgettext (NULL, Context "\004" String, strlen (Context) + 1)
+#define NC_(Context, String) (String)
+
+#endif /* __G_I18N_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/giochannel.c b/desmume/src/windows/glib-2.20.1/build/glib/giochannel.c
new file mode 100644
index 000000000..537fdb654
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/giochannel.c
@@ -0,0 +1,2389 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giochannel.c: IO Channel abstraction
+ * Copyright 1998 Owen Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include
+#include
+
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+
+#undef G_DISABLE_DEPRECATED
+
+#include "glib.h"
+
+#include "giochannel.h"
+
+#include "glibintl.h"
+
+#include "galias.h"
+
+#define G_IO_NICE_BUF_SIZE 1024
+
+/* This needs to be as wide as the largest character in any possible encoding */
+#define MAX_CHAR_SIZE 10
+
+/* Some simplifying macros, which reduce the need to worry whether the
+ * buffers have been allocated. These also make USE_BUF () an lvalue,
+ * which is used in g_io_channel_read_to_end ().
+ */
+#define USE_BUF(channel) ((channel)->encoding ? (channel)->encoded_read_buf \
+ : (channel)->read_buf)
+#define BUF_LEN(string) ((string) ? (string)->len : 0)
+
+static GIOError g_io_error_get_from_g_error (GIOStatus status,
+ GError *err);
+static void g_io_channel_purge (GIOChannel *channel);
+static GIOStatus g_io_channel_fill_buffer (GIOChannel *channel,
+ GError **err);
+static GIOStatus g_io_channel_read_line_backend (GIOChannel *channel,
+ gsize *length,
+ gsize *terminator_pos,
+ GError **error);
+
+/**
+ * g_io_channel_init:
+ * @channel: a #GIOChannel
+ *
+ * Initializes a #GIOChannel struct.
+ *
+ * This is called by each of the above functions when creating a
+ * #GIOChannel, and so is not often needed by the application
+ * programmer (unless you are creating a new type of #GIOChannel).
+ */
+void
+g_io_channel_init (GIOChannel *channel)
+{
+ channel->ref_count = 1;
+ channel->encoding = g_strdup ("UTF-8");
+ channel->line_term = NULL;
+ channel->line_term_len = 0;
+ channel->buf_size = G_IO_NICE_BUF_SIZE;
+ channel->read_cd = (GIConv) -1;
+ channel->write_cd = (GIConv) -1;
+ channel->read_buf = NULL; /* Lazy allocate buffers */
+ channel->encoded_read_buf = NULL;
+ channel->write_buf = NULL;
+ channel->partial_write_buf[0] = '\0';
+ channel->use_buffer = TRUE;
+ channel->do_encode = FALSE;
+ channel->close_on_unref = FALSE;
+}
+
+/**
+ * g_io_channel_ref:
+ * @channel: a #GIOChannel
+ *
+ * Increments the reference count of a #GIOChannel.
+ *
+ * Returns: the @channel that was passed in (since 2.6)
+ */
+GIOChannel *
+g_io_channel_ref (GIOChannel *channel)
+{
+ g_return_val_if_fail (channel != NULL, NULL);
+
+ g_atomic_int_inc (&channel->ref_count);
+
+ return channel;
+}
+
+/**
+ * g_io_channel_unref:
+ * @channel: a #GIOChannel
+ *
+ * Decrements the reference count of a #GIOChannel.
+ */
+void
+g_io_channel_unref (GIOChannel *channel)
+{
+ gboolean is_zero;
+
+ g_return_if_fail (channel != NULL);
+
+ is_zero = g_atomic_int_dec_and_test (&channel->ref_count);
+
+ if (G_UNLIKELY (is_zero))
+ {
+ if (channel->close_on_unref)
+ g_io_channel_shutdown (channel, TRUE, NULL);
+ else
+ g_io_channel_purge (channel);
+ g_free (channel->encoding);
+ if (channel->read_cd != (GIConv) -1)
+ g_iconv_close (channel->read_cd);
+ if (channel->write_cd != (GIConv) -1)
+ g_iconv_close (channel->write_cd);
+ g_free (channel->line_term);
+ if (channel->read_buf)
+ g_string_free (channel->read_buf, TRUE);
+ if (channel->write_buf)
+ g_string_free (channel->write_buf, TRUE);
+ if (channel->encoded_read_buf)
+ g_string_free (channel->encoded_read_buf, TRUE);
+ channel->funcs->io_free (channel);
+ }
+}
+
+static GIOError
+g_io_error_get_from_g_error (GIOStatus status,
+ GError *err)
+{
+ switch (status)
+ {
+ case G_IO_STATUS_NORMAL:
+ case G_IO_STATUS_EOF:
+ return G_IO_ERROR_NONE;
+ case G_IO_STATUS_AGAIN:
+ return G_IO_ERROR_AGAIN;
+ case G_IO_STATUS_ERROR:
+ g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN);
+
+ if (err->domain != G_IO_CHANNEL_ERROR)
+ return G_IO_ERROR_UNKNOWN;
+ switch (err->code)
+ {
+ case G_IO_CHANNEL_ERROR_INVAL:
+ return G_IO_ERROR_INVAL;
+ default:
+ return G_IO_ERROR_UNKNOWN;
+ }
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+/**
+ * g_io_channel_read:
+ * @channel: a #GIOChannel
+ * @buf: a buffer to read the data into (which should be at least
+ * count bytes long)
+ * @count: the number of bytes to read from the #GIOChannel
+ * @bytes_read: returns the number of bytes actually read
+ *
+ * Reads data from a #GIOChannel.
+ *
+ * Return value: %G_IO_ERROR_NONE if the operation was successful.
+ *
+ * Deprecated:2.2: Use g_io_channel_read_chars() instead.
+ **/
+GIOError
+g_io_channel_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read)
+{
+ GError *err = NULL;
+ GIOError error;
+ GIOStatus status;
+
+ g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
+ g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN);
+
+ if (count == 0)
+ {
+ if (bytes_read)
+ *bytes_read = 0;
+ return G_IO_ERROR_NONE;
+ }
+
+ g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN);
+
+ status = channel->funcs->io_read (channel, buf, count, bytes_read, &err);
+
+ error = g_io_error_get_from_g_error (status, err);
+
+ if (err)
+ g_error_free (err);
+
+ return error;
+}
+
+/**
+ * g_io_channel_write:
+ * @channel: a #GIOChannel
+ * @buf: the buffer containing the data to write
+ * @count: the number of bytes to write
+ * @bytes_written: the number of bytes actually written
+ *
+ * Writes data to a #GIOChannel.
+ *
+ * Return value: %G_IO_ERROR_NONE if the operation was successful.
+ *
+ * Deprecated:2.2: Use g_io_channel_write_chars() instead.
+ **/
+GIOError
+g_io_channel_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written)
+{
+ GError *err = NULL;
+ GIOError error;
+ GIOStatus status;
+
+ g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
+ g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN);
+
+ status = channel->funcs->io_write (channel, buf, count, bytes_written, &err);
+
+ error = g_io_error_get_from_g_error (status, err);
+
+ if (err)
+ g_error_free (err);
+
+ return error;
+}
+
+/**
+ * g_io_channel_seek:
+ * @channel: a #GIOChannel
+ * @offset: an offset, in bytes, which is added to the position specified
+ * by @type
+ * @type: the position in the file, which can be %G_SEEK_CUR (the current
+ * position), %G_SEEK_SET (the start of the file), or %G_SEEK_END
+ * (the end of the file)
+ *
+ * Sets the current position in the #GIOChannel, similar to the standard
+ * library function fseek().
+ *
+ * Return value: %G_IO_ERROR_NONE if the operation was successful.
+ *
+ * Deprecated:2.2: Use g_io_channel_seek_position() instead.
+ **/
+GIOError
+g_io_channel_seek (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type)
+{
+ GError *err = NULL;
+ GIOError error;
+ GIOStatus status;
+
+ g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
+ g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN);
+
+ switch (type)
+ {
+ case G_SEEK_CUR:
+ case G_SEEK_SET:
+ case G_SEEK_END:
+ break;
+ default:
+ g_warning ("g_io_channel_seek: unknown seek type");
+ return G_IO_ERROR_UNKNOWN;
+ }
+
+ status = channel->funcs->io_seek (channel, offset, type, &err);
+
+ error = g_io_error_get_from_g_error (status, err);
+
+ if (err)
+ g_error_free (err);
+
+ return error;
+}
+
+/* The function g_io_channel_new_file() is prototyped in both
+ * giounix.c and giowin32.c, so we stick its documentation here.
+ */
+
+/**
+ * g_io_channel_new_file:
+ * @filename: A string containing the name of a file
+ * @mode: One of "r", "w", "a", "r+", "w+", "a+". These have
+ * the same meaning as in fopen()
+ * @error: A location to return an error of type %G_FILE_ERROR
+ *
+ * Open a file @filename as a #GIOChannel using mode @mode. This
+ * channel will be closed when the last reference to it is dropped,
+ * so there is no need to call g_io_channel_close() (though doing
+ * so will not cause problems, as long as no attempt is made to
+ * access the channel after it is closed).
+ *
+ * Return value: A #GIOChannel on success, %NULL on failure.
+ **/
+
+/**
+ * g_io_channel_close:
+ * @channel: A #GIOChannel
+ *
+ * Close an IO channel. Any pending data to be written will be
+ * flushed, ignoring errors. The channel will not be freed until the
+ * last reference is dropped using g_io_channel_unref().
+ *
+ * Deprecated:2.2: Use g_io_channel_shutdown() instead.
+ **/
+void
+g_io_channel_close (GIOChannel *channel)
+{
+ GError *err = NULL;
+
+ g_return_if_fail (channel != NULL);
+
+ g_io_channel_purge (channel);
+
+ channel->funcs->io_close (channel, &err);
+
+ if (err)
+ { /* No way to return the error */
+ g_warning ("Error closing channel: %s", err->message);
+ g_error_free (err);
+ }
+
+ channel->close_on_unref = FALSE; /* Because we already did */
+ channel->is_readable = FALSE;
+ channel->is_writeable = FALSE;
+ channel->is_seekable = FALSE;
+}
+
+/**
+ * g_io_channel_shutdown:
+ * @channel: a #GIOChannel
+ * @flush: if %TRUE, flush pending
+ * @err: location to store a #GIOChannelError
+ *
+ * Close an IO channel. Any pending data to be written will be
+ * flushed if @flush is %TRUE. The channel will not be freed until the
+ * last reference is dropped using g_io_channel_unref().
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_shutdown (GIOChannel *channel,
+ gboolean flush,
+ GError **err)
+{
+ GIOStatus status, result;
+ GError *tmperr = NULL;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR);
+
+ if (channel->write_buf && channel->write_buf->len > 0)
+ {
+ if (flush)
+ {
+ GIOFlags flags;
+
+ /* Set the channel to blocking, to avoid a busy loop
+ */
+ flags = g_io_channel_get_flags (channel);
+ /* Ignore any errors here, they're irrelevant */
+ g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
+
+ result = g_io_channel_flush (channel, &tmperr);
+ }
+ else
+ result = G_IO_STATUS_NORMAL;
+
+ g_string_truncate(channel->write_buf, 0);
+ }
+ else
+ result = G_IO_STATUS_NORMAL;
+
+ if (channel->partial_write_buf[0] != '\0')
+ {
+ if (flush)
+ g_warning ("Partial character at end of write buffer not flushed.\n");
+ channel->partial_write_buf[0] = '\0';
+ }
+
+ status = channel->funcs->io_close (channel, err);
+
+ channel->close_on_unref = FALSE; /* Because we already did */
+ channel->is_readable = FALSE;
+ channel->is_writeable = FALSE;
+ channel->is_seekable = FALSE;
+
+ if (status != G_IO_STATUS_NORMAL)
+ {
+ g_clear_error (&tmperr);
+ return status;
+ }
+ else if (result != G_IO_STATUS_NORMAL)
+ {
+ g_propagate_error (err, tmperr);
+ return result;
+ }
+ else
+ return G_IO_STATUS_NORMAL;
+}
+
+/* This function is used for the final flush on close or unref */
+static void
+g_io_channel_purge (GIOChannel *channel)
+{
+ GError *err = NULL;
+ GIOStatus status;
+
+ g_return_if_fail (channel != NULL);
+
+ if (channel->write_buf && channel->write_buf->len > 0)
+ {
+ GIOFlags flags;
+
+ /* Set the channel to blocking, to avoid a busy loop
+ */
+ flags = g_io_channel_get_flags (channel);
+ g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
+
+ status = g_io_channel_flush (channel, &err);
+
+ if (err)
+ { /* No way to return the error */
+ g_warning ("Error flushing string: %s", err->message);
+ g_error_free (err);
+ }
+ }
+
+ /* Flush these in case anyone tries to close without unrefing */
+
+ if (channel->read_buf)
+ g_string_truncate (channel->read_buf, 0);
+ if (channel->write_buf)
+ g_string_truncate (channel->write_buf, 0);
+ if (channel->encoding)
+ {
+ if (channel->encoded_read_buf)
+ g_string_truncate (channel->encoded_read_buf, 0);
+
+ if (channel->partial_write_buf[0] != '\0')
+ {
+ g_warning ("Partial character at end of write buffer not flushed.\n");
+ channel->partial_write_buf[0] = '\0';
+ }
+ }
+}
+
+/**
+ * g_io_create_watch:
+ * @channel: a #GIOChannel to watch
+ * @condition: conditions to watch for
+ *
+ * Creates a #GSource that's dispatched when @condition is met for the
+ * given @channel. For example, if condition is #G_IO_IN, the source will
+ * be dispatched when there's data available for reading.
+ *
+ * g_io_add_watch() is a simpler interface to this same functionality, for
+ * the case where you want to add the source to the default main loop context
+ * at the default priority.
+ *
+ * On Windows, polling a #GSource created to watch a channel for a socket
+ * puts the socket in non-blocking mode. This is a side-effect of the
+ * implementation and unavoidable.
+ *
+ * Returns: a new #GSource
+ */
+GSource *
+g_io_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ g_return_val_if_fail (channel != NULL, NULL);
+
+ return channel->funcs->io_create_watch (channel, condition);
+}
+
+/**
+ * g_io_add_watch_full:
+ * @channel: a #GIOChannel
+ * @priority: the priority of the #GIOChannel source
+ * @condition: the condition to watch for
+ * @func: the function to call when the condition is satisfied
+ * @user_data: user data to pass to @func
+ * @notify: the function to call when the source is removed
+ *
+ * Adds the #GIOChannel into the default main loop context
+ * with the given priority.
+ *
+ * This internally creates a main loop source using g_io_create_watch()
+ * and attaches it to the main loop context with g_source_attach().
+ * You can do these steps manuallt if you need greater control.
+ *
+ * Returns: the event source id
+ */
+guint
+g_io_add_watch_full (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify)
+{
+ GSource *source;
+ guint id;
+
+ g_return_val_if_fail (channel != NULL, 0);
+
+ source = g_io_create_watch (channel, condition);
+
+ if (priority != G_PRIORITY_DEFAULT)
+ g_source_set_priority (source, priority);
+ g_source_set_callback (source, (GSourceFunc)func, user_data, notify);
+
+ id = g_source_attach (source, NULL);
+ g_source_unref (source);
+
+ return id;
+}
+
+/**
+ * g_io_add_watch:
+ * @channel: a #GIOChannel
+ * @condition: the condition to watch for
+ * @func: the function to call when the condition is satisfied
+ * @user_data: user data to pass to @func
+ *
+ * Adds the #GIOChannel into the default main loop context
+ * with the default priority.
+ *
+ * Returns: the event source id
+ */
+guint
+g_io_add_watch (GIOChannel *channel,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data)
+{
+ return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL);
+}
+
+/**
+ * g_io_channel_get_buffer_condition:
+ * @channel: A #GIOChannel
+ *
+ * This function returns a #GIOCondition depending on whether there
+ * is data to be read/space to write data in the internal buffers in
+ * the #GIOChannel. Only the flags %G_IO_IN and %G_IO_OUT may be set.
+ *
+ * Return value: A #GIOCondition
+ **/
+GIOCondition
+g_io_channel_get_buffer_condition (GIOChannel *channel)
+{
+ GIOCondition condition = 0;
+
+ if (channel->encoding)
+ {
+ if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0))
+ condition |= G_IO_IN; /* Only return if we have full characters */
+ }
+ else
+ {
+ if (channel->read_buf && (channel->read_buf->len > 0))
+ condition |= G_IO_IN;
+ }
+
+ if (channel->write_buf && (channel->write_buf->len < channel->buf_size))
+ condition |= G_IO_OUT;
+
+ return condition;
+}
+
+/**
+ * g_io_channel_error_from_errno:
+ * @en: an errno error number, e.g. %EINVAL
+ *
+ * Converts an errno error number to a #GIOChannelError.
+ *
+ * Return value: a #GIOChannelError error number, e.g.
+ * %G_IO_CHANNEL_ERROR_INVAL.
+ **/
+GIOChannelError
+g_io_channel_error_from_errno (gint en)
+{
+#ifdef EAGAIN
+ g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED);
+#endif
+
+ switch (en)
+ {
+#ifdef EBADF
+ case EBADF:
+ g_warning("Invalid file descriptor.\n");
+ return G_IO_CHANNEL_ERROR_FAILED;
+#endif
+
+#ifdef EFAULT
+ case EFAULT:
+ g_warning("Buffer outside valid address space.\n");
+ return G_IO_CHANNEL_ERROR_FAILED;
+#endif
+
+#ifdef EFBIG
+ case EFBIG:
+ return G_IO_CHANNEL_ERROR_FBIG;
+#endif
+
+#ifdef EINTR
+ /* In general, we should catch EINTR before we get here,
+ * but close() is allowed to return EINTR by POSIX, so
+ * we need to catch it here; EINTR from close() is
+ * unrecoverable, because it's undefined whether
+ * the fd was actually closed or not, so we just return
+ * a generic error code.
+ */
+ case EINTR:
+ return G_IO_CHANNEL_ERROR_FAILED;
+#endif
+
+#ifdef EINVAL
+ case EINVAL:
+ return G_IO_CHANNEL_ERROR_INVAL;
+#endif
+
+#ifdef EIO
+ case EIO:
+ return G_IO_CHANNEL_ERROR_IO;
+#endif
+
+#ifdef EISDIR
+ case EISDIR:
+ return G_IO_CHANNEL_ERROR_ISDIR;
+#endif
+
+#ifdef ENOSPC
+ case ENOSPC:
+ return G_IO_CHANNEL_ERROR_NOSPC;
+#endif
+
+#ifdef ENXIO
+ case ENXIO:
+ return G_IO_CHANNEL_ERROR_NXIO;
+#endif
+
+#ifdef EOVERFLOW
+ case EOVERFLOW:
+ return G_IO_CHANNEL_ERROR_OVERFLOW;
+#endif
+
+#ifdef EPIPE
+ case EPIPE:
+ return G_IO_CHANNEL_ERROR_PIPE;
+#endif
+
+ default:
+ return G_IO_CHANNEL_ERROR_FAILED;
+ }
+}
+
+/**
+ * g_io_channel_set_buffer_size:
+ * @channel: a #GIOChannel
+ * @size: the size of the buffer, or 0 to let GLib pick a good size
+ *
+ * Sets the buffer size.
+ **/
+void
+g_io_channel_set_buffer_size (GIOChannel *channel,
+ gsize size)
+{
+ g_return_if_fail (channel != NULL);
+
+ if (size == 0)
+ size = G_IO_NICE_BUF_SIZE;
+
+ if (size < MAX_CHAR_SIZE)
+ size = MAX_CHAR_SIZE;
+
+ channel->buf_size = size;
+}
+
+/**
+ * g_io_channel_get_buffer_size:
+ * @channel: a #GIOChannel
+ *
+ * Gets the buffer size.
+ *
+ * Return value: the size of the buffer.
+ **/
+gsize
+g_io_channel_get_buffer_size (GIOChannel *channel)
+{
+ g_return_val_if_fail (channel != NULL, 0);
+
+ return channel->buf_size;
+}
+
+/**
+ * g_io_channel_set_line_term:
+ * @channel: a #GIOChannel
+ * @line_term: The line termination string. Use %NULL for autodetect.
+ * Autodetection breaks on "\n", "\r\n", "\r", "\0", and
+ * the Unicode paragraph separator. Autodetection should
+ * not be used for anything other than file-based channels.
+ * @length: The length of the termination string. If -1 is passed, the
+ * string is assumed to be nul-terminated. This option allows
+ * termination strings with embedded nuls.
+ *
+ * This sets the string that #GIOChannel uses to determine
+ * where in the file a line break occurs.
+ **/
+void
+g_io_channel_set_line_term (GIOChannel *channel,
+ const gchar *line_term,
+ gint length)
+{
+ g_return_if_fail (channel != NULL);
+ g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
+
+ if (line_term == NULL)
+ length = 0;
+ else if (length < 0)
+ length = strlen (line_term);
+
+ g_free (channel->line_term);
+ channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
+ channel->line_term_len = length;
+}
+
+/**
+ * g_io_channel_get_line_term:
+ * @channel: a #GIOChannel
+ * @length: a location to return the length of the line terminator
+ *
+ * This returns the string that #GIOChannel uses to determine
+ * where in the file a line break occurs. A value of %NULL
+ * indicates autodetection.
+ *
+ * Return value: The line termination string. This value
+ * is owned by GLib and must not be freed.
+ **/
+G_CONST_RETURN gchar*
+g_io_channel_get_line_term (GIOChannel *channel,
+ gint *length)
+{
+ g_return_val_if_fail (channel != NULL, NULL);
+
+ if (length)
+ *length = channel->line_term_len;
+
+ return channel->line_term;
+}
+
+/**
+ * g_io_channel_set_flags:
+ * @channel: a #GIOChannel
+ * @flags: the flags to set on the IO channel
+ * @error: A location to return an error of type #GIOChannelError
+ *
+ * Sets the (writeable) flags in @channel to (@flags & %G_IO_CHANNEL_SET_MASK).
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_set_flags (GIOChannel *channel,
+ GIOFlags flags,
+ GError **error)
+{
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+
+ return (*channel->funcs->io_set_flags) (channel,
+ flags & G_IO_FLAG_SET_MASK,
+ error);
+}
+
+/**
+ * g_io_channel_get_flags:
+ * @channel: a #GIOChannel
+ *
+ * Gets the current flags for a #GIOChannel, including read-only
+ * flags such as %G_IO_FLAG_IS_READABLE.
+ *
+ * The values of the flags %G_IO_FLAG_IS_READABLE and %G_IO_FLAG_IS_WRITEABLE
+ * are cached for internal use by the channel when it is created.
+ * If they should change at some later point (e.g. partial shutdown
+ * of a socket with the UNIX shutdown() function), the user
+ * should immediately call g_io_channel_get_flags() to update
+ * the internal values of these flags.
+ *
+ * Return value: the flags which are set on the channel
+ **/
+GIOFlags
+g_io_channel_get_flags (GIOChannel *channel)
+{
+ GIOFlags flags;
+
+ g_return_val_if_fail (channel != NULL, 0);
+
+ flags = (* channel->funcs->io_get_flags) (channel);
+
+ /* Cross implementation code */
+
+ if (channel->is_seekable)
+ flags |= G_IO_FLAG_IS_SEEKABLE;
+ if (channel->is_readable)
+ flags |= G_IO_FLAG_IS_READABLE;
+ if (channel->is_writeable)
+ flags |= G_IO_FLAG_IS_WRITEABLE;
+
+ return flags;
+}
+
+/**
+ * g_io_channel_set_close_on_unref:
+ * @channel: a #GIOChannel
+ * @do_close: Whether to close the channel on the final unref of
+ * the GIOChannel data structure. The default value of
+ * this is %TRUE for channels created by g_io_channel_new_file (),
+ * and %FALSE for all other channels.
+ *
+ * Setting this flag to %TRUE for a channel you have already closed
+ * can cause problems.
+ **/
+void
+g_io_channel_set_close_on_unref (GIOChannel *channel,
+ gboolean do_close)
+{
+ g_return_if_fail (channel != NULL);
+
+ channel->close_on_unref = do_close;
+}
+
+/**
+ * g_io_channel_get_close_on_unref:
+ * @channel: a #GIOChannel.
+ *
+ * Returns whether the file/socket/whatever associated with @channel
+ * will be closed when @channel receives its final unref and is
+ * destroyed. The default value of this is %TRUE for channels created
+ * by g_io_channel_new_file (), and %FALSE for all other channels.
+ *
+ * Return value: Whether the channel will be closed on the final unref of
+ * the GIOChannel data structure.
+ **/
+gboolean
+g_io_channel_get_close_on_unref (GIOChannel *channel)
+{
+ g_return_val_if_fail (channel != NULL, FALSE);
+
+ return channel->close_on_unref;
+}
+
+/**
+ * g_io_channel_seek_position:
+ * @channel: a #GIOChannel
+ * @offset: The offset in bytes from the position specified by @type
+ * @type: a #GSeekType. The type %G_SEEK_CUR is only allowed in those
+ * cases where a call to g_io_channel_set_encoding ()
+ * is allowed. See the documentation for
+ * g_io_channel_set_encoding () for details.
+ * @error: A location to return an error of type #GIOChannelError
+ *
+ * Replacement for g_io_channel_seek() with the new API.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_seek_position (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type,
+ GError **error)
+{
+ GIOStatus status;
+
+ /* For files, only one of the read and write buffers can contain data.
+ * For sockets, both can contain data.
+ */
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR);
+
+ switch (type)
+ {
+ case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */
+ if (channel->use_buffer)
+ {
+ if (channel->do_encode && channel->encoded_read_buf
+ && channel->encoded_read_buf->len > 0)
+ {
+ g_warning ("Seek type G_SEEK_CUR not allowed for this"
+ " channel's encoding.\n");
+ return G_IO_STATUS_ERROR;
+ }
+ if (channel->read_buf)
+ offset -= channel->read_buf->len;
+ if (channel->encoded_read_buf)
+ {
+ g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
+
+ /* If there's anything here, it's because the encoding is UTF-8,
+ * so we can just subtract the buffer length, the same as for
+ * the unencoded data.
+ */
+
+ offset -= channel->encoded_read_buf->len;
+ }
+ }
+ break;
+ case G_SEEK_SET:
+ case G_SEEK_END:
+ break;
+ default:
+ g_warning ("g_io_channel_seek_position: unknown seek type");
+ return G_IO_STATUS_ERROR;
+ }
+
+ if (channel->use_buffer)
+ {
+ status = g_io_channel_flush (channel, error);
+ if (status != G_IO_STATUS_NORMAL)
+ return status;
+ }
+
+ status = channel->funcs->io_seek (channel, offset, type, error);
+
+ if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer))
+ {
+ if (channel->read_buf)
+ g_string_truncate (channel->read_buf, 0);
+
+ /* Conversion state no longer matches position in file */
+ if (channel->read_cd != (GIConv) -1)
+ g_iconv (channel->read_cd, NULL, NULL, NULL, NULL);
+ if (channel->write_cd != (GIConv) -1)
+ g_iconv (channel->write_cd, NULL, NULL, NULL, NULL);
+
+ if (channel->encoded_read_buf)
+ {
+ g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
+ g_string_truncate (channel->encoded_read_buf, 0);
+ }
+
+ if (channel->partial_write_buf[0] != '\0')
+ {
+ g_warning ("Partial character at end of write buffer not flushed.\n");
+ channel->partial_write_buf[0] = '\0';
+ }
+ }
+
+ return status;
+}
+
+/**
+ * g_io_channel_flush:
+ * @channel: a #GIOChannel
+ * @error: location to store an error of type #GIOChannelError
+ *
+ * Flushes the write buffer for the GIOChannel.
+ *
+ * Return value: the status of the operation: One of
+ * #G_IO_STATUS_NORMAL, #G_IO_STATUS_AGAIN, or
+ * #G_IO_STATUS_ERROR.
+ **/
+GIOStatus
+g_io_channel_flush (GIOChannel *channel,
+ GError **error)
+{
+ GIOStatus status;
+ gsize this_time = 1, bytes_written = 0;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
+
+ if (channel->write_buf == NULL || channel->write_buf->len == 0)
+ return G_IO_STATUS_NORMAL;
+
+ do
+ {
+ g_assert (this_time > 0);
+
+ status = channel->funcs->io_write (channel,
+ channel->write_buf->str + bytes_written,
+ channel->write_buf->len - bytes_written,
+ &this_time, error);
+ bytes_written += this_time;
+ }
+ while ((bytes_written < channel->write_buf->len)
+ && (status == G_IO_STATUS_NORMAL));
+
+ g_string_erase (channel->write_buf, 0, bytes_written);
+
+ return status;
+}
+
+/**
+ * g_io_channel_set_buffered:
+ * @channel: a #GIOChannel
+ * @buffered: whether to set the channel buffered or unbuffered
+ *
+ * The buffering state can only be set if the channel's encoding
+ * is %NULL. For any other encoding, the channel must be buffered.
+ *
+ * A buffered channel can only be set unbuffered if the channel's
+ * internal buffers have been flushed. Newly created channels or
+ * channels which have returned %G_IO_STATUS_EOF
+ * not require such a flush. For write-only channels, a call to
+ * g_io_channel_flush () is sufficient. For all other channels,
+ * the buffers may be flushed by a call to g_io_channel_seek_position ().
+ * This includes the possibility of seeking with seek type %G_SEEK_CUR
+ * and an offset of zero. Note that this means that socket-based
+ * channels cannot be set unbuffered once they have had data
+ * read from them.
+ *
+ * On unbuffered channels, it is safe to mix read and write
+ * calls from the new and old APIs, if this is necessary for
+ * maintaining old code.
+ *
+ * The default state of the channel is buffered.
+ **/
+void
+g_io_channel_set_buffered (GIOChannel *channel,
+ gboolean buffered)
+{
+ g_return_if_fail (channel != NULL);
+
+ if (channel->encoding != NULL)
+ {
+ g_warning ("Need to have NULL encoding to set the buffering state of the "
+ "channel.\n");
+ return;
+ }
+
+ g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0);
+ g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0);
+
+ channel->use_buffer = buffered;
+}
+
+/**
+ * g_io_channel_get_buffered:
+ * @channel: a #GIOChannel
+ *
+ * Returns whether @channel is buffered.
+ *
+ * Return Value: %TRUE if the @channel is buffered.
+ **/
+gboolean
+g_io_channel_get_buffered (GIOChannel *channel)
+{
+ g_return_val_if_fail (channel != NULL, FALSE);
+
+ return channel->use_buffer;
+}
+
+/**
+ * g_io_channel_set_encoding:
+ * @channel: a #GIOChannel
+ * @encoding: the encoding type
+ * @error: location to store an error of type #GConvertError
+ *
+ * Sets the encoding for the input/output of the channel.
+ * The internal encoding is always UTF-8. The default encoding
+ * for the external file is UTF-8.
+ *
+ * The encoding %NULL is safe to use with binary data.
+ *
+ * The encoding can only be set if one of the following conditions
+ * is true:
+ *
+ *
+ * The channel was just created, and has not been written to or read
+ * from yet.
+ *
+ *
+ * The channel is write-only.
+ *
+ *
+ * The channel is a file, and the file pointer was just
+ * repositioned by a call to g_io_channel_seek_position().
+ * (This flushes all the internal buffers.)
+ *
+ *
+ * The current encoding is %NULL or UTF-8.
+ *
+ *
+ * One of the (new API) read functions has just returned %G_IO_STATUS_EOF
+ * (or, in the case of g_io_channel_read_to_end(), %G_IO_STATUS_NORMAL).
+ *
+ *
+ * One of the functions g_io_channel_read_chars() or
+ * g_io_channel_read_unichar() has returned %G_IO_STATUS_AGAIN or
+ * %G_IO_STATUS_ERROR. This may be useful in the case of
+ * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE.
+ * Returning one of these statuses from g_io_channel_read_line(),
+ * g_io_channel_read_line_string(), or g_io_channel_read_to_end()
+ * does not guarantee that the encoding can
+ * be changed.
+ *
+ *
+ * Channels which do not meet one of the above conditions cannot call
+ * g_io_channel_seek_position() with an offset of %G_SEEK_CUR, and, if
+ * they are "seekable", cannot call g_io_channel_write_chars() after
+ * calling one of the API "read" functions.
+ *
+ * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set.
+ **/
+GIOStatus
+g_io_channel_set_encoding (GIOChannel *channel,
+ const gchar *encoding,
+ GError **error)
+{
+ GIConv read_cd, write_cd;
+ gboolean did_encode;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
+
+ /* Make sure the encoded buffers are empty */
+
+ g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf ||
+ channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR);
+
+ if (!channel->use_buffer)
+ {
+ g_warning ("Need to set the channel buffered before setting the encoding.\n");
+ g_warning ("Assuming this is what you meant and acting accordingly.\n");
+
+ channel->use_buffer = TRUE;
+ }
+
+ if (channel->partial_write_buf[0] != '\0')
+ {
+ g_warning ("Partial character at end of write buffer not flushed.\n");
+ channel->partial_write_buf[0] = '\0';
+ }
+
+ did_encode = channel->do_encode;
+
+ if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0)
+ {
+ channel->do_encode = FALSE;
+ read_cd = write_cd = (GIConv) -1;
+ }
+ else
+ {
+ gint err = 0;
+ const gchar *from_enc = NULL, *to_enc = NULL;
+
+ if (channel->is_readable)
+ {
+ read_cd = g_iconv_open ("UTF-8", encoding);
+
+ if (read_cd == (GIConv) -1)
+ {
+ err = errno;
+ from_enc = encoding;
+ to_enc = "UTF-8";
+ }
+ }
+ else
+ read_cd = (GIConv) -1;
+
+ if (channel->is_writeable && err == 0)
+ {
+ write_cd = g_iconv_open (encoding, "UTF-8");
+
+ if (write_cd == (GIConv) -1)
+ {
+ err = errno;
+ from_enc = "UTF-8";
+ to_enc = encoding;
+ }
+ }
+ else
+ write_cd = (GIConv) -1;
+
+ if (err != 0)
+ {
+ g_assert (from_enc);
+ g_assert (to_enc);
+
+ if (err == EINVAL)
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
+ _("Conversion from character set '%s' to '%s' is not supported"),
+ from_enc, to_enc);
+ else
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Could not open converter from '%s' to '%s': %s"),
+ from_enc, to_enc, g_strerror (err));
+
+ if (read_cd != (GIConv) -1)
+ g_iconv_close (read_cd);
+ if (write_cd != (GIConv) -1)
+ g_iconv_close (write_cd);
+
+ return G_IO_STATUS_ERROR;
+ }
+
+ channel->do_encode = TRUE;
+ }
+
+ /* The encoding is ok, so set the fields in channel */
+
+ if (channel->read_cd != (GIConv) -1)
+ g_iconv_close (channel->read_cd);
+ if (channel->write_cd != (GIConv) -1)
+ g_iconv_close (channel->write_cd);
+
+ if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0)
+ {
+ g_assert (!did_encode); /* Encoding UTF-8, NULL doesn't use encoded_read_buf */
+
+ /* This is just validated UTF-8, so we can copy it back into read_buf
+ * so it can be encoded in whatever the new encoding is.
+ */
+
+ g_string_prepend_len (channel->read_buf, channel->encoded_read_buf->str,
+ channel->encoded_read_buf->len);
+ g_string_truncate (channel->encoded_read_buf, 0);
+ }
+
+ channel->read_cd = read_cd;
+ channel->write_cd = write_cd;
+
+ g_free (channel->encoding);
+ channel->encoding = g_strdup (encoding);
+
+ return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_get_encoding:
+ * @channel: a #GIOChannel
+ *
+ * Gets the encoding for the input/output of the channel.
+ * The internal encoding is always UTF-8. The encoding %NULL
+ * makes the channel safe for binary data.
+ *
+ * Return value: A string containing the encoding, this string is
+ * owned by GLib and must not be freed.
+ **/
+G_CONST_RETURN gchar*
+g_io_channel_get_encoding (GIOChannel *channel)
+{
+ g_return_val_if_fail (channel != NULL, NULL);
+
+ return channel->encoding;
+}
+
+static GIOStatus
+g_io_channel_fill_buffer (GIOChannel *channel,
+ GError **err)
+{
+ gsize read_size, cur_len, oldlen;
+ GIOStatus status;
+
+ if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0)
+ {
+ status = g_io_channel_flush (channel, err);
+ if (status != G_IO_STATUS_NORMAL)
+ return status;
+ }
+ if (channel->is_seekable && channel->partial_write_buf[0] != '\0')
+ {
+ g_warning ("Partial character at end of write buffer not flushed.\n");
+ channel->partial_write_buf[0] = '\0';
+ }
+
+ if (!channel->read_buf)
+ channel->read_buf = g_string_sized_new (channel->buf_size);
+
+ cur_len = channel->read_buf->len;
+
+ g_string_set_size (channel->read_buf, channel->read_buf->len + channel->buf_size);
+
+ status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len,
+ channel->buf_size, &read_size, err);
+
+ g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0));
+
+ g_string_truncate (channel->read_buf, read_size + cur_len);
+
+ if ((status != G_IO_STATUS_NORMAL) &&
+ ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0)))
+ return status;
+
+ g_assert (channel->read_buf->len > 0);
+
+ if (channel->encoded_read_buf)
+ oldlen = channel->encoded_read_buf->len;
+ else
+ {
+ oldlen = 0;
+ if (channel->encoding)
+ channel->encoded_read_buf = g_string_sized_new (channel->buf_size);
+ }
+
+ if (channel->do_encode)
+ {
+ gsize errnum, inbytes_left, outbytes_left;
+ gchar *inbuf, *outbuf;
+ int errval;
+
+ g_assert (channel->encoded_read_buf);
+
+reencode:
+
+ inbytes_left = channel->read_buf->len;
+ outbytes_left = MAX (channel->read_buf->len,
+ channel->encoded_read_buf->allocated_len
+ - channel->encoded_read_buf->len - 1); /* 1 for NULL */
+ outbytes_left = MAX (outbytes_left, 6);
+
+ inbuf = channel->read_buf->str;
+ g_string_set_size (channel->encoded_read_buf,
+ channel->encoded_read_buf->len + outbytes_left);
+ outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len
+ - outbytes_left;
+
+ errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left,
+ &outbuf, &outbytes_left);
+ errval = errno;
+
+ g_assert (inbuf + inbytes_left == channel->read_buf->str
+ + channel->read_buf->len);
+ g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str
+ + channel->encoded_read_buf->len);
+
+ g_string_erase (channel->read_buf, 0,
+ channel->read_buf->len - inbytes_left);
+ g_string_truncate (channel->encoded_read_buf,
+ channel->encoded_read_buf->len - outbytes_left);
+
+ if (errnum == (gsize) -1)
+ {
+ switch (errval)
+ {
+ case EINVAL:
+ if ((oldlen == channel->encoded_read_buf->len)
+ && (status == G_IO_STATUS_EOF))
+ status = G_IO_STATUS_EOF;
+ else
+ status = G_IO_STATUS_NORMAL;
+ break;
+ case E2BIG:
+ /* Buffer size at least 6, wrote at least on character */
+ g_assert (inbuf != channel->read_buf->str);
+ goto reencode;
+ case EILSEQ:
+ if (oldlen < channel->encoded_read_buf->len)
+ status = G_IO_STATUS_NORMAL;
+ else
+ {
+ g_set_error_literal (err, G_CONVERT_ERROR,
+ G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Invalid byte sequence in conversion input"));
+ return G_IO_STATUS_ERROR;
+ }
+ break;
+ default:
+ g_assert (errval != EBADF); /* The converter should be open */
+ g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Error during conversion: %s"), g_strerror (errval));
+ return G_IO_STATUS_ERROR;
+ }
+ }
+ g_assert ((status != G_IO_STATUS_NORMAL)
+ || (channel->encoded_read_buf->len > 0));
+ }
+ else if (channel->encoding) /* UTF-8 */
+ {
+ gchar *nextchar, *lastchar;
+
+ g_assert (channel->encoded_read_buf);
+
+ nextchar = channel->read_buf->str;
+ lastchar = channel->read_buf->str + channel->read_buf->len;
+
+ while (nextchar < lastchar)
+ {
+ gunichar val_char;
+
+ val_char = g_utf8_get_char_validated (nextchar, lastchar - nextchar);
+
+ switch (val_char)
+ {
+ case -2:
+ /* stop, leave partial character in buffer */
+ lastchar = nextchar;
+ break;
+ case -1:
+ if (oldlen < channel->encoded_read_buf->len)
+ status = G_IO_STATUS_NORMAL;
+ else
+ {
+ g_set_error_literal (err, G_CONVERT_ERROR,
+ G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Invalid byte sequence in conversion input"));
+ status = G_IO_STATUS_ERROR;
+ }
+ lastchar = nextchar;
+ break;
+ default:
+ nextchar = g_utf8_next_char (nextchar);
+ break;
+ }
+ }
+
+ if (lastchar > channel->read_buf->str)
+ {
+ gint copy_len = lastchar - channel->read_buf->str;
+
+ g_string_append_len (channel->encoded_read_buf, channel->read_buf->str,
+ copy_len);
+ g_string_erase (channel->read_buf, 0, copy_len);
+ }
+ }
+
+ return status;
+}
+
+/**
+ * g_io_channel_read_line:
+ * @channel: a #GIOChannel
+ * @str_return: The line read from the #GIOChannel, including the
+ * line terminator. This data should be freed with g_free()
+ * when no longer needed. This is a nul-terminated string.
+ * If a @length of zero is returned, this will be %NULL instead.
+ * @length: location to store length of the read data, or %NULL
+ * @terminator_pos: location to store position of line terminator, or %NULL
+ * @error: A location to return an error of type #GConvertError
+ * or #GIOChannelError
+ *
+ * Reads a line, including the terminating character(s),
+ * from a #GIOChannel into a newly-allocated string.
+ * @str_return will contain allocated memory if the return
+ * is %G_IO_STATUS_NORMAL.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_read_line (GIOChannel *channel,
+ gchar **str_return,
+ gsize *length,
+ gsize *terminator_pos,
+ GError **error)
+{
+ GIOStatus status;
+ gsize got_length;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail (str_return != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+ status = g_io_channel_read_line_backend (channel, &got_length, terminator_pos, error);
+
+ if (length)
+ *length = got_length;
+
+ if (status == G_IO_STATUS_NORMAL)
+ {
+ g_assert (USE_BUF (channel));
+ *str_return = g_strndup (USE_BUF (channel)->str, got_length);
+ g_string_erase (USE_BUF (channel), 0, got_length);
+ }
+ else
+ *str_return = NULL;
+
+ return status;
+}
+
+/**
+ * g_io_channel_read_line_string:
+ * @channel: a #GIOChannel
+ * @buffer: a #GString into which the line will be written.
+ * If @buffer already contains data, the old data will
+ * be overwritten.
+ * @terminator_pos: location to store position of line terminator, or %NULL
+ * @error: a location to store an error of type #GConvertError
+ * or #GIOChannelError
+ *
+ * Reads a line from a #GIOChannel, using a #GString as a buffer.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_read_line_string (GIOChannel *channel,
+ GString *buffer,
+ gsize *terminator_pos,
+ GError **error)
+{
+ gsize length;
+ GIOStatus status;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail (buffer != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+ if (buffer->len > 0)
+ g_string_truncate (buffer, 0); /* clear out the buffer */
+
+ status = g_io_channel_read_line_backend (channel, &length, terminator_pos, error);
+
+ if (status == G_IO_STATUS_NORMAL)
+ {
+ g_assert (USE_BUF (channel));
+ g_string_append_len (buffer, USE_BUF (channel)->str, length);
+ g_string_erase (USE_BUF (channel), 0, length);
+ }
+
+ return status;
+}
+
+
+static GIOStatus
+g_io_channel_read_line_backend (GIOChannel *channel,
+ gsize *length,
+ gsize *terminator_pos,
+ GError **error)
+{
+ GIOStatus status;
+ gsize checked_to, line_term_len, line_length, got_term_len;
+ gboolean first_time = TRUE;
+
+ if (!channel->use_buffer)
+ {
+ /* Can't do a raw read in read_line */
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Can't do a raw read in g_io_channel_read_line_string"));
+ return G_IO_STATUS_ERROR;
+ }
+
+ status = G_IO_STATUS_NORMAL;
+
+ if (channel->line_term)
+ line_term_len = channel->line_term_len;
+ else
+ line_term_len = 3;
+ /* This value used for setting checked_to, it's the longest of the four
+ * we autodetect for.
+ */
+
+ checked_to = 0;
+
+ while (TRUE)
+ {
+ gchar *nextchar, *lastchar;
+ GString *use_buf;
+
+ if (!first_time || (BUF_LEN (USE_BUF (channel)) == 0))
+ {
+read_again:
+ status = g_io_channel_fill_buffer (channel, error);
+ switch (status)
+ {
+ case G_IO_STATUS_NORMAL:
+ if (BUF_LEN (USE_BUF (channel)) == 0)
+ /* Can happen when using conversion and only read
+ * part of a character
+ */
+ {
+ first_time = FALSE;
+ continue;
+ }
+ break;
+ case G_IO_STATUS_EOF:
+ if (BUF_LEN (USE_BUF (channel)) == 0)
+ {
+ if (length)
+ *length = 0;
+
+ if (channel->encoding && channel->read_buf->len != 0)
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR,
+ G_CONVERT_ERROR_PARTIAL_INPUT,
+ _("Leftover unconverted data in "
+ "read buffer"));
+ return G_IO_STATUS_ERROR;
+ }
+ else
+ return G_IO_STATUS_EOF;
+ }
+ break;
+ default:
+ if (length)
+ *length = 0;
+ return status;
+ }
+ }
+
+ g_assert (BUF_LEN (USE_BUF (channel)) != 0);
+
+ use_buf = USE_BUF (channel); /* The buffer has been created by this point */
+
+ first_time = FALSE;
+
+ lastchar = use_buf->str + use_buf->len;
+
+ for (nextchar = use_buf->str + checked_to; nextchar < lastchar;
+ channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++)
+ {
+ if (channel->line_term)
+ {
+ if (memcmp (channel->line_term, nextchar, line_term_len) == 0)
+ {
+ line_length = nextchar - use_buf->str;
+ got_term_len = line_term_len;
+ goto done;
+ }
+ }
+ else /* auto detect */
+ {
+ switch (*nextchar)
+ {
+ case '\n': /* unix */
+ line_length = nextchar - use_buf->str;
+ got_term_len = 1;
+ goto done;
+ case '\r': /* Warning: do not use with sockets */
+ line_length = nextchar - use_buf->str;
+ if ((nextchar == lastchar - 1) && (status != G_IO_STATUS_EOF)
+ && (lastchar == use_buf->str + use_buf->len))
+ goto read_again; /* Try to read more data */
+ if ((nextchar < lastchar - 1) && (*(nextchar + 1) == '\n')) /* dos */
+ got_term_len = 2;
+ else /* mac */
+ got_term_len = 1;
+ goto done;
+ case '\xe2': /* Unicode paragraph separator */
+ if (strncmp ("\xe2\x80\xa9", nextchar, 3) == 0)
+ {
+ line_length = nextchar - use_buf->str;
+ got_term_len = 3;
+ goto done;
+ }
+ break;
+ case '\0': /* Embeded null in input */
+ line_length = nextchar - use_buf->str;
+ got_term_len = 1;
+ goto done;
+ default: /* no match */
+ break;
+ }
+ }
+ }
+
+ /* If encoding != NULL, valid UTF-8, didn't overshoot */
+ g_assert (nextchar == lastchar);
+
+ /* Check for EOF */
+
+ if (status == G_IO_STATUS_EOF)
+ {
+ if (channel->encoding && channel->read_buf->len > 0)
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+ _("Channel terminates in a partial character"));
+ return G_IO_STATUS_ERROR;
+ }
+ line_length = use_buf->len;
+ got_term_len = 0;
+ break;
+ }
+
+ if (use_buf->len > line_term_len - 1)
+ checked_to = use_buf->len - (line_term_len - 1);
+ else
+ checked_to = 0;
+ }
+
+done:
+
+ if (terminator_pos)
+ *terminator_pos = line_length;
+
+ if (length)
+ *length = line_length + got_term_len;
+
+ return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_read_to_end:
+ * @channel: a #GIOChannel
+ * @str_return: Location to store a pointer to a string holding
+ * the remaining data in the #GIOChannel. This data should
+ * be freed with g_free() when no longer needed. This
+ * data is terminated by an extra nul character, but there
+ * may be other nuls in the intervening data.
+ * @length: location to store length of the data
+ * @error: location to return an error of type #GConvertError
+ * or #GIOChannelError
+ *
+ * Reads all the remaining data from the file.
+ *
+ * Return value: %G_IO_STATUS_NORMAL on success.
+ * This function never returns %G_IO_STATUS_EOF.
+ **/
+GIOStatus
+g_io_channel_read_to_end (GIOChannel *channel,
+ gchar **str_return,
+ gsize *length,
+ GError **error)
+{
+ GIOStatus status;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+ if (str_return)
+ *str_return = NULL;
+ if (length)
+ *length = 0;
+
+ if (!channel->use_buffer)
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Can't do a raw read in g_io_channel_read_to_end"));
+ return G_IO_STATUS_ERROR;
+ }
+
+ do
+ status = g_io_channel_fill_buffer (channel, error);
+ while (status == G_IO_STATUS_NORMAL);
+
+ if (status != G_IO_STATUS_EOF)
+ return status;
+
+ if (channel->encoding && channel->read_buf->len > 0)
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+ _("Channel terminates in a partial character"));
+ return G_IO_STATUS_ERROR;
+ }
+
+ if (USE_BUF (channel) == NULL)
+ {
+ /* length is already set to zero */
+ if (str_return)
+ *str_return = g_strdup ("");
+ }
+ else
+ {
+ if (length)
+ *length = USE_BUF (channel)->len;
+
+ if (str_return)
+ *str_return = g_string_free (USE_BUF (channel), FALSE);
+ else
+ g_string_free (USE_BUF (channel), TRUE);
+
+ if (channel->encoding)
+ channel->encoded_read_buf = NULL;
+ else
+ channel->read_buf = NULL;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_read_chars:
+ * @channel: a #GIOChannel
+ * @buf: a buffer to read data into
+ * @count: the size of the buffer. Note that the buffer may
+ * not be complelely filled even if there is data
+ * in the buffer if the remaining data is not a
+ * complete character.
+ * @bytes_read: The number of bytes read. This may be zero even on
+ * success if count < 6 and the channel's encoding is non-%NULL.
+ * This indicates that the next UTF-8 character is too wide for
+ * the buffer.
+ * @error: a location to return an error of type #GConvertError
+ * or #GIOChannelError.
+ *
+ * Replacement for g_io_channel_read() with the new API.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_read_chars (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **error)
+{
+ GIOStatus status;
+ gsize got_bytes;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+ if (count == 0)
+ {
+ *bytes_read = 0;
+ return G_IO_STATUS_NORMAL;
+ }
+ g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);
+
+ if (!channel->use_buffer)
+ {
+ gsize tmp_bytes;
+
+ g_assert (!channel->read_buf || channel->read_buf->len == 0);
+
+ status = channel->funcs->io_read (channel, buf, count, &tmp_bytes, error);
+
+ if (bytes_read)
+ *bytes_read = tmp_bytes;
+
+ return status;
+ }
+
+ status = G_IO_STATUS_NORMAL;
+
+ while (BUF_LEN (USE_BUF (channel)) < count && status == G_IO_STATUS_NORMAL)
+ status = g_io_channel_fill_buffer (channel, error);
+
+ /* Only return an error if we have no data */
+
+ if (BUF_LEN (USE_BUF (channel)) == 0)
+ {
+ g_assert (status != G_IO_STATUS_NORMAL);
+
+ if (status == G_IO_STATUS_EOF && channel->encoding
+ && BUF_LEN (channel->read_buf) > 0)
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR,
+ G_CONVERT_ERROR_PARTIAL_INPUT,
+ _("Leftover unconverted data in read buffer"));
+ status = G_IO_STATUS_ERROR;
+ }
+
+ if (bytes_read)
+ *bytes_read = 0;
+
+ return status;
+ }
+
+ if (status == G_IO_STATUS_ERROR)
+ g_clear_error (error);
+
+ got_bytes = MIN (count, BUF_LEN (USE_BUF (channel)));
+
+ g_assert (got_bytes > 0);
+
+ if (channel->encoding)
+ /* Don't validate for NULL encoding, binary safe */
+ {
+ gchar *nextchar, *prevchar;
+
+ g_assert (USE_BUF (channel) == channel->encoded_read_buf);
+
+ nextchar = channel->encoded_read_buf->str;
+
+ do
+ {
+ prevchar = nextchar;
+ nextchar = g_utf8_next_char (nextchar);
+ g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */
+ }
+ while (nextchar < channel->encoded_read_buf->str + got_bytes);
+
+ if (nextchar > channel->encoded_read_buf->str + got_bytes)
+ got_bytes = prevchar - channel->encoded_read_buf->str;
+
+ g_assert (got_bytes > 0 || count < 6);
+ }
+
+ memcpy (buf, USE_BUF (channel)->str, got_bytes);
+ g_string_erase (USE_BUF (channel), 0, got_bytes);
+
+ if (bytes_read)
+ *bytes_read = got_bytes;
+
+ return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_read_unichar:
+ * @channel: a #GIOChannel
+ * @thechar: a location to return a character
+ * @error: a location to return an error of type #GConvertError
+ * or #GIOChannelError
+ *
+ * Reads a Unicode character from @channel.
+ * This function cannot be called on a channel with %NULL encoding.
+ *
+ * Return value: a #GIOStatus
+ **/
+GIOStatus
+g_io_channel_read_unichar (GIOChannel *channel,
+ gunichar *thechar,
+ GError **error)
+{
+ GIOStatus status = G_IO_STATUS_NORMAL;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+ while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL)
+ status = g_io_channel_fill_buffer (channel, error);
+
+ /* Only return an error if we have no data */
+
+ if (BUF_LEN (USE_BUF (channel)) == 0)
+ {
+ g_assert (status != G_IO_STATUS_NORMAL);
+
+ if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0)
+ {
+ g_set_error_literal (error, G_CONVERT_ERROR,
+ G_CONVERT_ERROR_PARTIAL_INPUT,
+ _("Leftover unconverted data in read buffer"));
+ status = G_IO_STATUS_ERROR;
+ }
+
+ if (thechar)
+ *thechar = (gunichar) -1;
+
+ return status;
+ }
+
+ if (status == G_IO_STATUS_ERROR)
+ g_clear_error (error);
+
+ if (thechar)
+ *thechar = g_utf8_get_char (channel->encoded_read_buf->str);
+
+ g_string_erase (channel->encoded_read_buf, 0,
+ g_utf8_next_char (channel->encoded_read_buf->str)
+ - channel->encoded_read_buf->str);
+
+ return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_write_chars:
+ * @channel: a #GIOChannel
+ * @buf: a buffer to write data from
+ * @count: the size of the buffer. If -1, the buffer
+ * is taken to be a nul-terminated string.
+ * @bytes_written: The number of bytes written. This can be nonzero
+ * even if the return value is not %G_IO_STATUS_NORMAL.
+ * If the return value is %G_IO_STATUS_NORMAL and the
+ * channel is blocking, this will always be equal
+ * to @count if @count >= 0.
+ * @error: a location to return an error of type #GConvertError
+ * or #GIOChannelError
+ *
+ * Replacement for g_io_channel_write() with the new API.
+ *
+ * On seekable channels with encodings other than %NULL or UTF-8, generic
+ * mixing of reading and writing is not allowed. A call to g_io_channel_write_chars ()
+ * may only be made on a channel from which data has been read in the
+ * cases described in the documentation for g_io_channel_set_encoding ().
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_write_chars (GIOChannel *channel,
+ const gchar *buf,
+ gssize count,
+ gsize *bytes_written,
+ GError **error)
+{
+ GIOStatus status;
+ gssize wrote_bytes = 0;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
+
+ if ((count < 0) && buf)
+ count = strlen (buf);
+
+ if (count == 0)
+ {
+ if (bytes_written)
+ *bytes_written = 0;
+ return G_IO_STATUS_NORMAL;
+ }
+
+ g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail (count > 0, G_IO_STATUS_ERROR);
+
+ /* Raw write case */
+
+ if (!channel->use_buffer)
+ {
+ gsize tmp_bytes;
+
+ g_assert (!channel->write_buf || channel->write_buf->len == 0);
+ g_assert (channel->partial_write_buf[0] == '\0');
+
+ status = channel->funcs->io_write (channel, buf, count, &tmp_bytes, error);
+
+ if (bytes_written)
+ *bytes_written = tmp_bytes;
+
+ return status;
+ }
+
+ /* General case */
+
+ if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0)
+ || (BUF_LEN (channel->encoded_read_buf) > 0)))
+ {
+ if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0)
+ {
+ g_warning("Mixed reading and writing not allowed on encoded files");
+ return G_IO_STATUS_ERROR;
+ }
+ status = g_io_channel_seek_position (channel, 0, G_SEEK_CUR, error);
+ if (status != G_IO_STATUS_NORMAL)
+ {
+ if (bytes_written)
+ *bytes_written = 0;
+ return status;
+ }
+ }
+
+ if (!channel->write_buf)
+ channel->write_buf = g_string_sized_new (channel->buf_size);
+
+ while (wrote_bytes < count)
+ {
+ gsize space_in_buf;
+
+ /* If the buffer is full, try a write immediately. In
+ * the nonblocking case, this prevents the user from
+ * writing just a little bit to the buffer every time
+ * and never receiving an EAGAIN.
+ */
+
+ if (channel->write_buf->len >= channel->buf_size - MAX_CHAR_SIZE)
+ {
+ gsize did_write = 0, this_time;
+
+ do
+ {
+ status = channel->funcs->io_write (channel, channel->write_buf->str
+ + did_write, channel->write_buf->len
+ - did_write, &this_time, error);
+ did_write += this_time;
+ }
+ while (status == G_IO_STATUS_NORMAL &&
+ did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE));
+
+ g_string_erase (channel->write_buf, 0, did_write);
+
+ if (status != G_IO_STATUS_NORMAL)
+ {
+ if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0)
+ status = G_IO_STATUS_NORMAL;
+ if (bytes_written)
+ *bytes_written = wrote_bytes;
+ return status;
+ }
+ }
+
+ space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1)
+ - channel->write_buf->len; /* 1 for NULL */
+
+ /* This is only true because g_io_channel_set_buffer_size ()
+ * ensures that channel->buf_size >= MAX_CHAR_SIZE.
+ */
+ g_assert (space_in_buf >= MAX_CHAR_SIZE);
+
+ if (!channel->encoding)
+ {
+ gssize write_this = MIN (space_in_buf, count - wrote_bytes);
+
+ g_string_append_len (channel->write_buf, buf, write_this);
+ buf += write_this;
+ wrote_bytes += write_this;
+ }
+ else
+ {
+ const gchar *from_buf;
+ gsize from_buf_len, from_buf_old_len, left_len;
+ gsize err;
+ gint errnum;
+
+ if (channel->partial_write_buf[0] != '\0')
+ {
+ g_assert (wrote_bytes == 0);
+
+ from_buf = channel->partial_write_buf;
+ from_buf_old_len = strlen (channel->partial_write_buf);
+ g_assert (from_buf_old_len > 0);
+ from_buf_len = MIN (6, from_buf_old_len + count);
+
+ memcpy (channel->partial_write_buf + from_buf_old_len, buf,
+ from_buf_len - from_buf_old_len);
+ }
+ else
+ {
+ from_buf = buf;
+ from_buf_len = count - wrote_bytes;
+ from_buf_old_len = 0;
+ }
+
+reconvert:
+
+ if (!channel->do_encode) /* UTF-8 encoding */
+ {
+ const gchar *badchar;
+ gsize try_len = MIN (from_buf_len, space_in_buf);
+
+ /* UTF-8, just validate, emulate g_iconv */
+
+ if (!g_utf8_validate (from_buf, try_len, &badchar))
+ {
+ gunichar try_char;
+ gsize incomplete_len = from_buf + try_len - badchar;
+
+ left_len = from_buf + from_buf_len - badchar;
+
+ try_char = g_utf8_get_char_validated (badchar, incomplete_len);
+
+ switch (try_char)
+ {
+ case -2:
+ g_assert (incomplete_len < 6);
+ if (try_len == from_buf_len)
+ {
+ errnum = EINVAL;
+ err = (gsize) -1;
+ }
+ else
+ {
+ errnum = 0;
+ err = (gsize) 0;
+ }
+ break;
+ case -1:
+ g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars().");
+ /* FIXME bail here? */
+ errnum = EILSEQ;
+ err = (gsize) -1;
+ break;
+ default:
+ g_assert_not_reached ();
+ err = (gsize) -1;
+ errnum = 0; /* Don't confunse the compiler */
+ }
+ }
+ else
+ {
+ err = (gsize) 0;
+ errnum = 0;
+ left_len = from_buf_len - try_len;
+ }
+
+ g_string_append_len (channel->write_buf, from_buf,
+ from_buf_len - left_len);
+ from_buf += from_buf_len - left_len;
+ }
+ else
+ {
+ gchar *outbuf;
+
+ left_len = from_buf_len;
+ g_string_set_size (channel->write_buf, channel->write_buf->len
+ + space_in_buf);
+ outbuf = channel->write_buf->str + channel->write_buf->len
+ - space_in_buf;
+ err = g_iconv (channel->write_cd, (gchar **) &from_buf, &left_len,
+ &outbuf, &space_in_buf);
+ errnum = errno;
+ g_string_truncate (channel->write_buf, channel->write_buf->len
+ - space_in_buf);
+ }
+
+ if (err == (gsize) -1)
+ {
+ switch (errnum)
+ {
+ case EINVAL:
+ g_assert (left_len < 6);
+
+ if (from_buf_old_len == 0)
+ {
+ /* Not from partial_write_buf */
+
+ memcpy (channel->partial_write_buf, from_buf, left_len);
+ channel->partial_write_buf[left_len] = '\0';
+ if (bytes_written)
+ *bytes_written = count;
+ return G_IO_STATUS_NORMAL;
+ }
+
+ /* Working in partial_write_buf */
+
+ if (left_len == from_buf_len)
+ {
+ /* Didn't convert anything, must still have
+ * less than a full character
+ */
+
+ g_assert (count == from_buf_len - from_buf_old_len);
+
+ channel->partial_write_buf[from_buf_len] = '\0';
+
+ if (bytes_written)
+ *bytes_written = count;
+
+ return G_IO_STATUS_NORMAL;
+ }
+
+ g_assert (from_buf_len - left_len >= from_buf_old_len);
+
+ /* We converted all the old data. This is fine */
+
+ break;
+ case E2BIG:
+ if (from_buf_len == left_len)
+ {
+ /* Nothing was written, add enough space for
+ * at least one character.
+ */
+ space_in_buf += MAX_CHAR_SIZE;
+ goto reconvert;
+ }
+ break;
+ case EILSEQ:
+ g_set_error_literal (error, G_CONVERT_ERROR,
+ G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+ _("Invalid byte sequence in conversion input"));
+ if (from_buf_old_len > 0 && from_buf_len == left_len)
+ g_warning ("Illegal sequence due to partial character "
+ "at the end of a previous write.\n");
+ else
+ wrote_bytes += from_buf_len - left_len - from_buf_old_len;
+ if (bytes_written)
+ *bytes_written = wrote_bytes;
+ channel->partial_write_buf[0] = '\0';
+ return G_IO_STATUS_ERROR;
+ default:
+ g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+ _("Error during conversion: %s"), g_strerror (errnum));
+ if (from_buf_len >= left_len + from_buf_old_len)
+ wrote_bytes += from_buf_len - left_len - from_buf_old_len;
+ if (bytes_written)
+ *bytes_written = wrote_bytes;
+ channel->partial_write_buf[0] = '\0';
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ g_assert (from_buf_len - left_len >= from_buf_old_len);
+
+ wrote_bytes += from_buf_len - left_len - from_buf_old_len;
+
+ if (from_buf_old_len > 0)
+ {
+ /* We were working in partial_write_buf */
+
+ buf += from_buf_len - left_len - from_buf_old_len;
+ channel->partial_write_buf[0] = '\0';
+ }
+ else
+ buf = from_buf;
+ }
+ }
+
+ if (bytes_written)
+ *bytes_written = count;
+
+ return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_write_unichar:
+ * @channel: a #GIOChannel
+ * @thechar: a character
+ * @error: location to return an error of type #GConvertError
+ * or #GIOChannelError
+ *
+ * Writes a Unicode character to @channel.
+ * This function cannot be called on a channel with %NULL encoding.
+ *
+ * Return value: a #GIOStatus
+ **/
+GIOStatus
+g_io_channel_write_unichar (GIOChannel *channel,
+ gunichar thechar,
+ GError **error)
+{
+ GIOStatus status;
+ gchar static_buf[6];
+ gsize char_len, wrote_len;
+
+ g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL),
+ G_IO_STATUS_ERROR);
+ g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
+
+ char_len = g_unichar_to_utf8 (thechar, static_buf);
+
+ if (channel->partial_write_buf[0] != '\0')
+ {
+ g_warning ("Partial charater written before writing unichar.\n");
+ channel->partial_write_buf[0] = '\0';
+ }
+
+ status = g_io_channel_write_chars (channel, static_buf,
+ char_len, &wrote_len, error);
+
+ /* We validate UTF-8, so we can't get a partial write */
+
+ g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL);
+
+ return status;
+}
+
+/**
+ * g_io_channel_error_quark:
+ *
+ * Return value: the quark used as %G_IO_CHANNEL_ERROR
+ **/
+GQuark
+g_io_channel_error_quark (void)
+{
+ return g_quark_from_static_string ("g-io-channel-error-quark");
+}
+
+#define __G_IOCHANNEL_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/giochannel.h b/desmume/src/windows/glib-2.20.1/build/glib/giochannel.h
new file mode 100644
index 000000000..2a40aa29a
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/giochannel.h
@@ -0,0 +1,366 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_IOCHANNEL_H__
+#define __G_IOCHANNEL_H__
+
+#include
+#include
+#include
+
+G_BEGIN_DECLS
+
+/* GIOChannel
+ */
+
+typedef struct _GIOChannel GIOChannel;
+typedef struct _GIOFuncs GIOFuncs;
+
+typedef enum
+{
+ G_IO_ERROR_NONE,
+ G_IO_ERROR_AGAIN,
+ G_IO_ERROR_INVAL,
+ G_IO_ERROR_UNKNOWN
+} GIOError;
+
+#define G_IO_CHANNEL_ERROR g_io_channel_error_quark()
+
+typedef enum
+{
+ /* Derived from errno */
+ G_IO_CHANNEL_ERROR_FBIG,
+ G_IO_CHANNEL_ERROR_INVAL,
+ G_IO_CHANNEL_ERROR_IO,
+ G_IO_CHANNEL_ERROR_ISDIR,
+ G_IO_CHANNEL_ERROR_NOSPC,
+ G_IO_CHANNEL_ERROR_NXIO,
+ G_IO_CHANNEL_ERROR_OVERFLOW,
+ G_IO_CHANNEL_ERROR_PIPE,
+ /* Other */
+ G_IO_CHANNEL_ERROR_FAILED
+} GIOChannelError;
+
+typedef enum
+{
+ G_IO_STATUS_ERROR,
+ G_IO_STATUS_NORMAL,
+ G_IO_STATUS_EOF,
+ G_IO_STATUS_AGAIN
+} GIOStatus;
+
+typedef enum
+{
+ G_SEEK_CUR,
+ G_SEEK_SET,
+ G_SEEK_END
+} GSeekType;
+
+typedef enum
+{
+ G_IO_IN GLIB_SYSDEF_POLLIN,
+ G_IO_OUT GLIB_SYSDEF_POLLOUT,
+ G_IO_PRI GLIB_SYSDEF_POLLPRI,
+ G_IO_ERR GLIB_SYSDEF_POLLERR,
+ G_IO_HUP GLIB_SYSDEF_POLLHUP,
+ G_IO_NVAL GLIB_SYSDEF_POLLNVAL
+} GIOCondition;
+
+typedef enum
+{
+ G_IO_FLAG_APPEND = 1 << 0,
+ G_IO_FLAG_NONBLOCK = 1 << 1,
+ G_IO_FLAG_IS_READABLE = 1 << 2, /* Read only flag */
+ G_IO_FLAG_IS_WRITEABLE = 1 << 3, /* Read only flag */
+ G_IO_FLAG_IS_SEEKABLE = 1 << 4, /* Read only flag */
+ G_IO_FLAG_MASK = (1 << 5) - 1,
+ G_IO_FLAG_GET_MASK = G_IO_FLAG_MASK,
+ G_IO_FLAG_SET_MASK = G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK
+} GIOFlags;
+
+struct _GIOChannel
+{
+ /*< private >*/
+ gint ref_count;
+ GIOFuncs *funcs;
+
+ gchar *encoding;
+ GIConv read_cd;
+ GIConv write_cd;
+ gchar *line_term; /* String which indicates the end of a line of text */
+ guint line_term_len; /* So we can have null in the line term */
+
+ gsize buf_size;
+ GString *read_buf; /* Raw data from the channel */
+ GString *encoded_read_buf; /* Channel data converted to UTF-8 */
+ GString *write_buf; /* Data ready to be written to the file */
+ gchar partial_write_buf[6]; /* UTF-8 partial characters, null terminated */
+
+ /* Group the flags together, immediately after partial_write_buf, to save memory */
+
+ guint use_buffer : 1; /* The encoding uses the buffers */
+ guint do_encode : 1; /* The encoding uses the GIConv coverters */
+ guint close_on_unref : 1; /* Close the channel on final unref */
+ guint is_readable : 1; /* Cached GIOFlag */
+ guint is_writeable : 1; /* ditto */
+ guint is_seekable : 1; /* ditto */
+
+ gpointer reserved1;
+ gpointer reserved2;
+};
+
+typedef gboolean (*GIOFunc) (GIOChannel *source,
+ GIOCondition condition,
+ gpointer data);
+struct _GIOFuncs
+{
+ GIOStatus (*io_read) (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **err);
+ GIOStatus (*io_write) (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written,
+ GError **err);
+ GIOStatus (*io_seek) (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type,
+ GError **err);
+ GIOStatus (*io_close) (GIOChannel *channel,
+ GError **err);
+ GSource* (*io_create_watch) (GIOChannel *channel,
+ GIOCondition condition);
+ void (*io_free) (GIOChannel *channel);
+ GIOStatus (*io_set_flags) (GIOChannel *channel,
+ GIOFlags flags,
+ GError **err);
+ GIOFlags (*io_get_flags) (GIOChannel *channel);
+};
+
+void g_io_channel_init (GIOChannel *channel);
+GIOChannel *g_io_channel_ref (GIOChannel *channel);
+void g_io_channel_unref (GIOChannel *channel);
+
+#ifndef G_DISABLE_DEPRECATED
+GIOError g_io_channel_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read);
+GIOError g_io_channel_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written);
+GIOError g_io_channel_seek (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type);
+void g_io_channel_close (GIOChannel *channel);
+#endif /* G_DISABLE_DEPRECATED */
+
+GIOStatus g_io_channel_shutdown (GIOChannel *channel,
+ gboolean flush,
+ GError **err);
+guint g_io_add_watch_full (GIOChannel *channel,
+ gint priority,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data,
+ GDestroyNotify notify);
+GSource * g_io_create_watch (GIOChannel *channel,
+ GIOCondition condition);
+guint g_io_add_watch (GIOChannel *channel,
+ GIOCondition condition,
+ GIOFunc func,
+ gpointer user_data);
+
+/* character encoding conversion involved functions.
+ */
+
+void g_io_channel_set_buffer_size (GIOChannel *channel,
+ gsize size);
+gsize g_io_channel_get_buffer_size (GIOChannel *channel);
+GIOCondition g_io_channel_get_buffer_condition (GIOChannel *channel);
+GIOStatus g_io_channel_set_flags (GIOChannel *channel,
+ GIOFlags flags,
+ GError **error);
+GIOFlags g_io_channel_get_flags (GIOChannel *channel);
+void g_io_channel_set_line_term (GIOChannel *channel,
+ const gchar *line_term,
+ gint length);
+G_CONST_RETURN gchar* g_io_channel_get_line_term (GIOChannel *channel,
+ gint *length);
+void g_io_channel_set_buffered (GIOChannel *channel,
+ gboolean buffered);
+gboolean g_io_channel_get_buffered (GIOChannel *channel);
+GIOStatus g_io_channel_set_encoding (GIOChannel *channel,
+ const gchar *encoding,
+ GError **error);
+G_CONST_RETURN gchar* g_io_channel_get_encoding (GIOChannel *channel);
+void g_io_channel_set_close_on_unref (GIOChannel *channel,
+ gboolean do_close);
+gboolean g_io_channel_get_close_on_unref (GIOChannel *channel);
+
+
+GIOStatus g_io_channel_flush (GIOChannel *channel,
+ GError **error);
+GIOStatus g_io_channel_read_line (GIOChannel *channel,
+ gchar **str_return,
+ gsize *length,
+ gsize *terminator_pos,
+ GError **error);
+GIOStatus g_io_channel_read_line_string (GIOChannel *channel,
+ GString *buffer,
+ gsize *terminator_pos,
+ GError **error);
+GIOStatus g_io_channel_read_to_end (GIOChannel *channel,
+ gchar **str_return,
+ gsize *length,
+ GError **error);
+GIOStatus g_io_channel_read_chars (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **error);
+GIOStatus g_io_channel_read_unichar (GIOChannel *channel,
+ gunichar *thechar,
+ GError **error);
+GIOStatus g_io_channel_write_chars (GIOChannel *channel,
+ const gchar *buf,
+ gssize count,
+ gsize *bytes_written,
+ GError **error);
+GIOStatus g_io_channel_write_unichar (GIOChannel *channel,
+ gunichar thechar,
+ GError **error);
+GIOStatus g_io_channel_seek_position (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type,
+ GError **error);
+#ifdef G_OS_WIN32
+#define g_io_channel_new_file g_io_channel_new_file_utf8
+#endif
+
+GIOChannel* g_io_channel_new_file (const gchar *filename,
+ const gchar *mode,
+ GError **error);
+
+/* Error handling */
+
+GQuark g_io_channel_error_quark (void);
+GIOChannelError g_io_channel_error_from_errno (gint en);
+
+/* On Unix, IO channels created with this function for any file
+ * descriptor or socket.
+ *
+ * On Win32, this can be used either for files opened with the MSVCRT
+ * (the Microsoft run-time C library) _open() or _pipe, including file
+ * descriptors 0, 1 and 2 (corresponding to stdin, stdout and stderr),
+ * or for Winsock SOCKETs. If the parameter is a legal file
+ * descriptor, it is assumed to be such, otherwise it should be a
+ * SOCKET. This relies on SOCKETs and file descriptors not
+ * overlapping. If you want to be certain, call either
+ * g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket()
+ * instead as appropriate.
+ *
+ * The term file descriptor as used in the context of Win32 refers to
+ * the emulated Unix-like file descriptors MSVCRT provides. The native
+ * corresponding concept is file HANDLE. There isn't as of yet a way to
+ * get GIOChannels for Win32 file HANDLEs.
+ */
+GIOChannel* g_io_channel_unix_new (int fd);
+gint g_io_channel_unix_get_fd (GIOChannel *channel);
+
+
+/* Hook for GClosure / GSource integration. Don't touch */
+GLIB_VAR GSourceFuncs g_io_watch_funcs;
+
+#ifdef G_OS_WIN32
+
+/* You can use this "pseudo file descriptor" in a GPollFD to add
+ * polling for Windows messages. GTK applications should not do that.
+ */
+
+#define G_WIN32_MSG_HANDLE 19981206
+
+/* Use this to get a GPollFD from a GIOChannel, so that you can call
+ * g_io_channel_win32_poll(). After calling this you should only use
+ * g_io_channel_read() to read from the GIOChannel, i.e. never read()
+ * from the underlying file descriptor. For SOCKETs, it is possible to call
+ * recv().
+ */
+void g_io_channel_win32_make_pollfd (GIOChannel *channel,
+ GIOCondition condition,
+ GPollFD *fd);
+
+/* This can be used to wait a until at least one of the channels is readable.
+ * On Unix you would do a select() on the file descriptors of the channels.
+ */
+gint g_io_channel_win32_poll (GPollFD *fds,
+ gint n_fds,
+ gint timeout_);
+
+/* Create an IO channel for Windows messages for window handle hwnd. */
+#if GLIB_SIZEOF_VOID_P == 8
+/* We use gsize here so that it is still an integer type and not a
+ * pointer, like the guint in the traditional prototype. We can't use
+ * intptr_t as that is not portable enough.
+ */
+GIOChannel *g_io_channel_win32_new_messages (gsize hwnd);
+#else
+GIOChannel *g_io_channel_win32_new_messages (guint hwnd);
+#endif
+
+/* Create an IO channel for C runtime (emulated Unix-like) file
+ * descriptors. After calling g_io_add_watch() on a IO channel
+ * returned by this function, you shouldn't call read() on the file
+ * descriptor. This is because adding polling for a file descriptor is
+ * implemented on Win32 by starting a thread that sits blocked in a
+ * read() from the file descriptor most of the time. All reads from
+ * the file descriptor should be done by this internal GLib
+ * thread. Your code should call only g_io_channel_read_chars().
+ */
+GIOChannel* g_io_channel_win32_new_fd (gint fd);
+
+/* Get the C runtime file descriptor of a channel. */
+gint g_io_channel_win32_get_fd (GIOChannel *channel);
+
+/* Create an IO channel for a winsock socket. The parameter should be
+ * a SOCKET. Contrary to IO channels for file descriptors (on *Win32),
+ * you can use normal recv() or recvfrom() on sockets even if GLib
+ * is polling them.
+ */
+GIOChannel *g_io_channel_win32_new_socket (gint socket);
+
+#endif
+
+G_END_DECLS
+
+#endif /* __G_IOCHANNEL_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/giounix.c b/desmume/src/windows/glib-2.20.1/build/glib/giounix.c
new file mode 100644
index 000000000..eaff939ae
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/giounix.c
@@ -0,0 +1,609 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giounix.c: IO Channels using unix file descriptors
+ * Copyright 1998 Owen Taylor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#define _POSIX_SOURCE /* for SSIZE_MAX */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "glib.h"
+#include "galias.h"
+
+/*
+ * Unix IO Channels
+ */
+
+typedef struct _GIOUnixChannel GIOUnixChannel;
+typedef struct _GIOUnixWatch GIOUnixWatch;
+
+struct _GIOUnixChannel
+{
+ GIOChannel channel;
+ gint fd;
+};
+
+struct _GIOUnixWatch
+{
+ GSource source;
+ GPollFD pollfd;
+ GIOChannel *channel;
+ GIOCondition condition;
+};
+
+
+static GIOStatus g_io_unix_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **err);
+static GIOStatus g_io_unix_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written,
+ GError **err);
+static GIOStatus g_io_unix_seek (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type,
+ GError **err);
+static GIOStatus g_io_unix_close (GIOChannel *channel,
+ GError **err);
+static void g_io_unix_free (GIOChannel *channel);
+static GSource* g_io_unix_create_watch (GIOChannel *channel,
+ GIOCondition condition);
+static GIOStatus g_io_unix_set_flags (GIOChannel *channel,
+ GIOFlags flags,
+ GError **err);
+static GIOFlags g_io_unix_get_flags (GIOChannel *channel);
+
+static gboolean g_io_unix_prepare (GSource *source,
+ gint *timeout);
+static gboolean g_io_unix_check (GSource *source);
+static gboolean g_io_unix_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data);
+static void g_io_unix_finalize (GSource *source);
+
+GSourceFuncs g_io_watch_funcs = {
+ g_io_unix_prepare,
+ g_io_unix_check,
+ g_io_unix_dispatch,
+ g_io_unix_finalize
+};
+
+static GIOFuncs unix_channel_funcs = {
+ g_io_unix_read,
+ g_io_unix_write,
+ g_io_unix_seek,
+ g_io_unix_close,
+ g_io_unix_create_watch,
+ g_io_unix_free,
+ g_io_unix_set_flags,
+ g_io_unix_get_flags,
+};
+
+static gboolean
+g_io_unix_prepare (GSource *source,
+ gint *timeout)
+{
+ GIOUnixWatch *watch = (GIOUnixWatch *)source;
+ GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+
+ *timeout = -1;
+
+ /* Only return TRUE here if _all_ bits in watch->condition will be set
+ */
+ return ((watch->condition & buffer_condition) == watch->condition);
+}
+
+static gboolean
+g_io_unix_check (GSource *source)
+{
+ GIOUnixWatch *watch = (GIOUnixWatch *)source;
+ GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+ GIOCondition poll_condition = watch->pollfd.revents;
+
+ return ((poll_condition | buffer_condition) & watch->condition);
+}
+
+static gboolean
+g_io_unix_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+
+{
+ GIOFunc func = (GIOFunc)callback;
+ GIOUnixWatch *watch = (GIOUnixWatch *)source;
+ GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+
+ if (!func)
+ {
+ g_warning ("IO watch dispatched without callback\n"
+ "You must call g_source_connect().");
+ return FALSE;
+ }
+
+ return (*func) (watch->channel,
+ (watch->pollfd.revents | buffer_condition) & watch->condition,
+ user_data);
+}
+
+static void
+g_io_unix_finalize (GSource *source)
+{
+ GIOUnixWatch *watch = (GIOUnixWatch *)source;
+
+ g_io_channel_unref (watch->channel);
+}
+
+static GIOStatus
+g_io_unix_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **err)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+ gssize result;
+
+ if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */
+ count = SSIZE_MAX;
+
+ retry:
+ result = read (unix_channel->fd, buf, count);
+
+ if (result < 0)
+ {
+ int errsv = errno;
+ *bytes_read = 0;
+
+ switch (errsv)
+ {
+#ifdef EINTR
+ case EINTR:
+ goto retry;
+#endif
+#ifdef EAGAIN
+ case EAGAIN:
+ return G_IO_STATUS_AGAIN;
+#endif
+ default:
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errsv),
+ g_strerror (errsv));
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ *bytes_read = result;
+
+ return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+static GIOStatus
+g_io_unix_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written,
+ GError **err)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+ gssize result;
+
+ retry:
+ result = write (unix_channel->fd, buf, count);
+
+ if (result < 0)
+ {
+ int errsv = errno;
+ *bytes_written = 0;
+
+ switch (errsv)
+ {
+#ifdef EINTR
+ case EINTR:
+ goto retry;
+#endif
+#ifdef EAGAIN
+ case EAGAIN:
+ return G_IO_STATUS_AGAIN;
+#endif
+ default:
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errsv),
+ g_strerror (errsv));
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ *bytes_written = result;
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_unix_seek (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type,
+ GError **err)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+ int whence;
+ off_t tmp_offset;
+ off_t result;
+
+ switch (type)
+ {
+ case G_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+ case G_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+ case G_SEEK_END:
+ whence = SEEK_END;
+ break;
+ default:
+ whence = -1; /* Shut the compiler up */
+ g_assert_not_reached ();
+ }
+
+ tmp_offset = offset;
+ if (tmp_offset != offset)
+ {
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (EINVAL),
+ g_strerror (EINVAL));
+ return G_IO_STATUS_ERROR;
+ }
+
+ result = lseek (unix_channel->fd, tmp_offset, whence);
+
+ if (result < 0)
+ {
+ int errsv = errno;
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errsv),
+ g_strerror (errsv));
+ return G_IO_STATUS_ERROR;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+
+static GIOStatus
+g_io_unix_close (GIOChannel *channel,
+ GError **err)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+
+ if (close (unix_channel->fd) < 0)
+ {
+ int errsv = errno;
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errsv),
+ g_strerror (errsv));
+ return G_IO_STATUS_ERROR;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static void
+g_io_unix_free (GIOChannel *channel)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+
+ g_free (unix_channel);
+}
+
+static GSource *
+g_io_unix_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+ GSource *source;
+ GIOUnixWatch *watch;
+
+
+ source = g_source_new (&g_io_watch_funcs, sizeof (GIOUnixWatch));
+ watch = (GIOUnixWatch *)source;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->condition = condition;
+
+ watch->pollfd.fd = unix_channel->fd;
+ watch->pollfd.events = condition;
+
+ g_source_add_poll (source, &watch->pollfd);
+
+ return source;
+}
+
+static GIOStatus
+g_io_unix_set_flags (GIOChannel *channel,
+ GIOFlags flags,
+ GError **err)
+{
+ glong fcntl_flags;
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel;
+
+ fcntl_flags = 0;
+
+ if (flags & G_IO_FLAG_APPEND)
+ fcntl_flags |= O_APPEND;
+ if (flags & G_IO_FLAG_NONBLOCK)
+#ifdef O_NONBLOCK
+ fcntl_flags |= O_NONBLOCK;
+#else
+ fcntl_flags |= O_NDELAY;
+#endif
+
+ if (fcntl (unix_channel->fd, F_SETFL, fcntl_flags) == -1)
+ {
+ int errsv = errno;
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errsv),
+ g_strerror (errsv));
+ return G_IO_STATUS_ERROR;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOFlags
+g_io_unix_get_flags (GIOChannel *channel)
+{
+ GIOFlags flags = 0;
+ glong fcntl_flags;
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel;
+
+ fcntl_flags = fcntl (unix_channel->fd, F_GETFL);
+
+ if (fcntl_flags == -1)
+ {
+ int err = errno;
+ g_warning (G_STRLOC "Error while getting flags for FD: %s (%d)\n",
+ g_strerror (err), err);
+ return 0;
+ }
+
+ if (fcntl_flags & O_APPEND)
+ flags |= G_IO_FLAG_APPEND;
+#ifdef O_NONBLOCK
+ if (fcntl_flags & O_NONBLOCK)
+#else
+ if (fcntl_flags & O_NDELAY)
+#endif
+ flags |= G_IO_FLAG_NONBLOCK;
+
+ switch (fcntl_flags & (O_RDONLY | O_WRONLY | O_RDWR))
+ {
+ case O_RDONLY:
+ channel->is_readable = TRUE;
+ channel->is_writeable = FALSE;
+ break;
+ case O_WRONLY:
+ channel->is_readable = FALSE;
+ channel->is_writeable = TRUE;
+ break;
+ case O_RDWR:
+ channel->is_readable = TRUE;
+ channel->is_writeable = TRUE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return flags;
+}
+
+GIOChannel *
+g_io_channel_new_file (const gchar *filename,
+ const gchar *mode,
+ GError **error)
+{
+ int fid, flags;
+ mode_t create_mode;
+ GIOChannel *channel;
+ enum { /* Cheesy hack */
+ MODE_R = 1 << 0,
+ MODE_W = 1 << 1,
+ MODE_A = 1 << 2,
+ MODE_PLUS = 1 << 3
+ } mode_num;
+ struct stat buffer;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+ g_return_val_if_fail (mode != NULL, NULL);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
+
+ switch (mode[0])
+ {
+ case 'r':
+ mode_num = MODE_R;
+ break;
+ case 'w':
+ mode_num = MODE_W;
+ break;
+ case 'a':
+ mode_num = MODE_A;
+ break;
+ default:
+ g_warning ("Invalid GIOFileMode %s.\n", mode);
+ return NULL;
+ }
+
+ switch (mode[1])
+ {
+ case '\0':
+ break;
+ case '+':
+ if (mode[2] == '\0')
+ {
+ mode_num |= MODE_PLUS;
+ break;
+ }
+ /* Fall through */
+ default:
+ g_warning ("Invalid GIOFileMode %s.\n", mode);
+ return NULL;
+ }
+
+ switch (mode_num)
+ {
+ case MODE_R:
+ flags = O_RDONLY;
+ break;
+ case MODE_W:
+ flags = O_WRONLY | O_TRUNC | O_CREAT;
+ break;
+ case MODE_A:
+ flags = O_WRONLY | O_APPEND | O_CREAT;
+ break;
+ case MODE_R | MODE_PLUS:
+ flags = O_RDWR;
+ break;
+ case MODE_W | MODE_PLUS:
+ flags = O_RDWR | O_TRUNC | O_CREAT;
+ break;
+ case MODE_A | MODE_PLUS:
+ flags = O_RDWR | O_APPEND | O_CREAT;
+ break;
+ default:
+ g_assert_not_reached ();
+ flags = 0;
+ }
+
+ create_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ fid = open (filename, flags, create_mode);
+ if (fid == -1)
+ {
+ int err = errno;
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno (err),
+ g_strerror (err));
+ return (GIOChannel *)NULL;
+ }
+
+ if (fstat (fid, &buffer) == -1) /* In case someone opens a FIFO */
+ {
+ int err = errno;
+ close (fid);
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno (err),
+ g_strerror (err));
+ return (GIOChannel *)NULL;
+ }
+
+ channel = (GIOChannel *) g_new (GIOUnixChannel, 1);
+
+ channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
+ || S_ISBLK (buffer.st_mode);
+
+ switch (mode_num)
+ {
+ case MODE_R:
+ channel->is_readable = TRUE;
+ channel->is_writeable = FALSE;
+ break;
+ case MODE_W:
+ case MODE_A:
+ channel->is_readable = FALSE;
+ channel->is_writeable = TRUE;
+ break;
+ case MODE_R | MODE_PLUS:
+ case MODE_W | MODE_PLUS:
+ case MODE_A | MODE_PLUS:
+ channel->is_readable = TRUE;
+ channel->is_writeable = TRUE;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_io_channel_init (channel);
+ channel->close_on_unref = TRUE; /* must be after g_io_channel_init () */
+ channel->funcs = &unix_channel_funcs;
+
+ ((GIOUnixChannel *) channel)->fd = fid;
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_unix_new (gint fd)
+{
+ struct stat buffer;
+ GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
+ GIOChannel *channel = (GIOChannel *)unix_channel;
+
+ g_io_channel_init (channel);
+ channel->funcs = &unix_channel_funcs;
+
+ unix_channel->fd = fd;
+
+ /* I'm not sure if fstat on a non-file (e.g., socket) works
+ * it should be safe to say if it fails, the fd isn't seekable.
+ */
+ /* Newer UNIX versions support S_ISSOCK(), fstat() will probably
+ * succeed in most cases.
+ */
+ if (fstat (unix_channel->fd, &buffer) == 0)
+ channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
+ || S_ISBLK (buffer.st_mode);
+ else /* Assume not seekable */
+ channel->is_seekable = FALSE;
+
+ g_io_unix_get_flags (channel); /* Sets is_readable, is_writeable */
+
+ return channel;
+}
+
+gint
+g_io_channel_unix_get_fd (GIOChannel *channel)
+{
+ GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+ return unix_channel->fd;
+}
+
+#define __G_IO_UNIX_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/giowin32.c b/desmume/src/windows/glib-2.20.1/build/glib/giowin32.c
new file mode 100644
index 000000000..7f395473d
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/giowin32.c
@@ -0,0 +1,2191 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giowin32.c: IO Channels for Win32.
+ * Copyright 1998 Owen Taylor and Tor Lillqvist
+ * Copyright 1999-2000 Tor Lillqvist and Craig Setera
+ * Copyright 2001-2003 Andrew Lanoix
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * Bugs that are related to the code in this file:
+ *
+ * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition
+ * http://bugzilla.gnome.org/show_bug.cgi?id=137968
+ *
+ * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely
+ * http://bugzilla.gnome.org/show_bug.cgi?id=324234
+ *
+ * Bug 331214 - g_io_channel async socket io stalls
+ * http://bugzilla.gnome.org/show_bug.cgi?id=331214
+ *
+ * Bug 338943 - Multiple watches on the same socket
+ * http://bugzilla.gnome.org/show_bug.cgi?id=338943
+ *
+ * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless
+ * http://bugzilla.gnome.org/show_bug.cgi?id=357674
+ *
+ * Bug 425156 - GIOChannel deadlocks on a win32 socket
+ * http://bugzilla.gnome.org/show_bug.cgi?id=425156
+ *
+ * Bug 468910 - giofunc condition=0
+ * http://bugzilla.gnome.org/show_bug.cgi?id=468910
+ *
+ * Bug 500246 - Bug fixes for giowin32
+ * http://bugzilla.gnome.org/show_bug.cgi?id=500246
+ *
+ * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows
+ * http://bugzilla.gnome.org/show_bug.cgi?id=548278
+ *
+ * Bug 548536 - giowin32 problem when adding and removing watches
+ * http://bugzilla.gnome.org/show_bug.cgi?id=548536
+ *
+ * When fixing bugs related to the code in this file, either the above
+ * bugs or others, make sure that the test programs attached to the
+ * above bugs continue to work.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "gstdio.h"
+#include "glibintl.h"
+
+#include "galias.h"
+
+typedef struct _GIOWin32Channel GIOWin32Channel;
+typedef struct _GIOWin32Watch GIOWin32Watch;
+
+#define BUFFER_SIZE 4096
+
+typedef enum {
+ G_IO_WIN32_WINDOWS_MESSAGES, /* Windows messages */
+
+ G_IO_WIN32_FILE_DESC, /* Unix-like file descriptors from
+ * _open() or _pipe(), except for
+ * console IO. Separate thread to read
+ * or write.
+ */
+
+ G_IO_WIN32_CONSOLE, /* Console IO (usually stdin, stdout, stderr) */
+
+ G_IO_WIN32_SOCKET /* Sockets. No separate thread. */
+} GIOWin32ChannelType;
+
+struct _GIOWin32Channel {
+ GIOChannel channel;
+ gint fd; /* Either a Unix-like file handle as provided
+ * by the Microsoft C runtime, or a SOCKET
+ * as provided by WinSock.
+ */
+ GIOWin32ChannelType type;
+
+ gboolean debug;
+
+ /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */
+ HWND hwnd; /* Handle of window, or NULL */
+
+ /* Fields used by G_IO_WIN32_FILE_DESC channels. */
+ CRITICAL_SECTION mutex;
+
+ int direction; /* 0 means we read from it,
+ * 1 means we write to it.
+ */
+
+ gboolean running; /* Is reader or writer thread
+ * running. FALSE if EOF has been
+ * reached by the reader thread.
+ */
+
+ gboolean needs_close; /* If the channel has been closed while
+ * the reader thread was still running.
+ */
+
+ guint thread_id; /* If non-NULL the channel has or has
+ * had a reader or writer thread.
+ */
+ HANDLE data_avail_event;
+
+ gushort revents;
+
+ /* Data is kept in a circular buffer. To be able to distinguish between
+ * empty and full buffers, we cannot fill it completely, but have to
+ * leave a one character gap.
+ *
+ * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
+ *
+ * Empty: wrp == rdp
+ * Full: (wrp + 1) % BUFFER_SIZE == rdp
+ * Partial: otherwise
+ */
+ guchar *buffer; /* (Circular) buffer */
+ gint wrp, rdp; /* Buffer indices for writing and reading */
+ HANDLE space_avail_event;
+
+ /* Fields used by G_IO_WIN32_SOCKET channels */
+ int event_mask;
+ int last_events;
+ HANDLE event;
+ gboolean write_would_have_blocked;
+ gboolean ever_writable;
+};
+
+struct _GIOWin32Watch {
+ GSource source;
+ GPollFD pollfd;
+ GIOChannel *channel;
+ GIOCondition condition;
+};
+
+static void
+g_win32_print_access_mode (int flags)
+{
+ g_print ("%s%s%s%s%s%s%s%s%s%s",
+ ((flags & 0x3) == _O_RDWR ? "O_RDWR" :
+ ((flags & 0x3) == _O_RDONLY ? "O_RDONLY" :
+ ((flags & 0x3) == _O_WRONLY ? "O_WRONLY" : "0"))),
+ (flags & _O_APPEND ? "|O_APPEND" : ""),
+ (flags & _O_RANDOM ? "|O_RANDOM" : ""),
+ (flags & _O_SEQUENTIAL ? "|O_SEQUENTIAL" : ""),
+ (flags & _O_TEMPORARY ? "|O_TEMPORARY" : ""),
+ (flags & _O_CREAT ? "|O_CREAT" : ""),
+ (flags & _O_TRUNC ? "|O_TRUNC" : ""),
+ (flags & _O_EXCL ? "|O_EXCL" : ""),
+ (flags & _O_TEXT ? "|O_TEXT" : ""),
+ (flags & _O_BINARY ? "|O_BINARY" : ""));
+}
+
+static void
+g_win32_print_gioflags (GIOFlags flags)
+{
+ char *bar = "";
+
+ if (flags & G_IO_FLAG_APPEND)
+ bar = "|", g_print ("APPEND");
+ if (flags & G_IO_FLAG_NONBLOCK)
+ g_print ("%sNONBLOCK", bar), bar = "|";
+ if (flags & G_IO_FLAG_IS_READABLE)
+ g_print ("%sREADABLE", bar), bar = "|";
+ if (flags & G_IO_FLAG_IS_WRITEABLE)
+ g_print ("%sWRITEABLE", bar), bar = "|";
+ if (flags & G_IO_FLAG_IS_SEEKABLE)
+ g_print ("%sSEEKABLE", bar), bar = "|";
+}
+
+static const char *
+event_mask_to_string (int mask)
+{
+ char buf[100];
+ int checked_bits = 0;
+ char *bufp = buf;
+
+ if (mask == 0)
+ return "";
+
+#define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
+
+ BIT (READ);
+ BIT (WRITE);
+ BIT (OOB);
+ BIT (ACCEPT);
+ BIT (CONNECT);
+ BIT (CLOSE);
+ BIT (QOS);
+ BIT (GROUP_QOS);
+ BIT (ROUTING_INTERFACE_CHANGE);
+ BIT (ADDRESS_LIST_CHANGE);
+
+#undef BIT
+
+ if ((mask & ~checked_bits) != 0)
+ bufp += sprintf (bufp, "|%#x", mask & ~checked_bits);
+
+ return g_quark_to_string (g_quark_from_string (buf));
+}
+
+static const char *
+condition_to_string (GIOCondition condition)
+{
+ char buf[100];
+ int checked_bits = 0;
+ char *bufp = buf;
+
+ if (condition == 0)
+ return "";
+
+#define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
+
+ BIT (IN);
+ BIT (OUT);
+ BIT (PRI);
+ BIT (ERR);
+ BIT (HUP);
+ BIT (NVAL);
+
+#undef BIT
+
+ if ((condition & ~checked_bits) != 0)
+ bufp += sprintf (bufp, "|%#x", condition & ~checked_bits);
+
+ return g_quark_to_string (g_quark_from_string (buf));
+}
+
+static gboolean
+g_io_win32_get_debug_flag (void)
+{
+ return (getenv ("G_IO_WIN32_DEBUG") != NULL);
+}
+
+static void
+g_io_channel_win32_init (GIOWin32Channel *channel)
+{
+ channel->debug = g_io_win32_get_debug_flag ();
+
+ InitializeCriticalSection (&channel->mutex);
+ channel->running = FALSE;
+ channel->needs_close = FALSE;
+ channel->thread_id = 0;
+ channel->data_avail_event = NULL;
+ channel->revents = 0;
+ channel->buffer = NULL;
+ channel->space_avail_event = NULL;
+
+ channel->event_mask = 0;
+ channel->last_events = 0;
+ channel->event = NULL;
+ channel->write_would_have_blocked = FALSE;
+ channel->ever_writable = FALSE;
+}
+
+static void
+create_events (GIOWin32Channel *channel)
+{
+ SECURITY_ATTRIBUTES sec_attrs;
+
+ sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
+ sec_attrs.lpSecurityDescriptor = NULL;
+ sec_attrs.bInheritHandle = FALSE;
+
+ /* The data available event is manual reset, the space available event
+ * is automatic reset.
+ */
+ if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
+ || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
+ {
+ gchar *emsg = g_win32_error_message (GetLastError ());
+
+ g_error ("Error creating event: %s", emsg);
+ g_free (emsg);
+ }
+}
+
+static unsigned __stdcall
+read_thread (void *parameter)
+{
+ GIOWin32Channel *channel = parameter;
+ guchar *buffer;
+ gint nbytes;
+
+ g_io_channel_ref ((GIOChannel *)channel);
+
+ if (channel->debug)
+ g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
+ channel->thread_id,
+ channel->fd,
+ channel->data_avail_event,
+ channel->space_avail_event);
+
+ channel->direction = 0;
+ channel->buffer = g_malloc (BUFFER_SIZE);
+ channel->rdp = channel->wrp = 0;
+ channel->running = TRUE;
+
+ SetEvent (channel->space_avail_event);
+
+ EnterCriticalSection (&channel->mutex);
+ while (channel->running)
+ {
+ if (channel->debug)
+ g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+ {
+ /* Buffer is full */
+ if (channel->debug)
+ g_print ("read_thread %#x: resetting space_avail\n",
+ channel->thread_id);
+ ResetEvent (channel->space_avail_event);
+ if (channel->debug)
+ g_print ("read_thread %#x: waiting for space\n",
+ channel->thread_id);
+ LeaveCriticalSection (&channel->mutex);
+ WaitForSingleObject (channel->space_avail_event, INFINITE);
+ EnterCriticalSection (&channel->mutex);
+ if (channel->debug)
+ g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ }
+
+ buffer = channel->buffer + channel->wrp;
+
+ /* Always leave at least one byte unused gap to be able to
+ * distinguish between the full and empty condition...
+ */
+ nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
+ BUFFER_SIZE - channel->wrp);
+
+ if (channel->debug)
+ g_print ("read_thread %#x: calling read() for %d bytes\n",
+ channel->thread_id, nbytes);
+
+ LeaveCriticalSection (&channel->mutex);
+
+ nbytes = read (channel->fd, buffer, nbytes);
+
+ EnterCriticalSection (&channel->mutex);
+
+ channel->revents = G_IO_IN;
+ if (nbytes == 0)
+ channel->revents |= G_IO_HUP;
+ else if (nbytes < 0)
+ channel->revents |= G_IO_ERR;
+
+ if (channel->debug)
+ g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
+ channel->thread_id, nbytes, channel->rdp, channel->wrp);
+
+ if (nbytes <= 0)
+ break;
+
+ channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
+ if (channel->debug)
+ g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ SetEvent (channel->data_avail_event);
+ }
+
+ channel->running = FALSE;
+ if (channel->needs_close)
+ {
+ if (channel->debug)
+ g_print ("read_thread %#x: channel fd %d needs closing\n",
+ channel->thread_id, channel->fd);
+ close (channel->fd);
+ channel->fd = -1;
+ }
+
+ if (channel->debug)
+ g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ SetEvent (channel->data_avail_event);
+ LeaveCriticalSection (&channel->mutex);
+
+ g_io_channel_unref ((GIOChannel *)channel);
+
+ /* No need to call _endthreadex(), the actual thread starter routine
+ * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
+ * _endthreadex() for us.
+ */
+
+ return 0;
+}
+
+static unsigned __stdcall
+write_thread (void *parameter)
+{
+ GIOWin32Channel *channel = parameter;
+ guchar *buffer;
+ gint nbytes;
+
+ g_io_channel_ref ((GIOChannel *)channel);
+
+ if (channel->debug)
+ g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
+ channel->thread_id,
+ channel->fd,
+ channel->data_avail_event,
+ channel->space_avail_event);
+
+ channel->direction = 1;
+ channel->buffer = g_malloc (BUFFER_SIZE);
+ channel->rdp = channel->wrp = 0;
+ channel->running = TRUE;
+
+ SetEvent (channel->space_avail_event);
+
+ /* We use the same event objects as for a reader thread, but with
+ * reversed meaning. So, space_avail is used if data is available
+ * for writing, and data_avail is used if space is available in the
+ * write buffer.
+ */
+
+ EnterCriticalSection (&channel->mutex);
+ while (channel->running || channel->rdp != channel->wrp)
+ {
+ if (channel->debug)
+ g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ if (channel->wrp == channel->rdp)
+ {
+ /* Buffer is empty. */
+ if (channel->debug)
+ g_print ("write_thread %#x: resetting space_avail\n",
+ channel->thread_id);
+ ResetEvent (channel->space_avail_event);
+ if (channel->debug)
+ g_print ("write_thread %#x: waiting for data\n",
+ channel->thread_id);
+ channel->revents = G_IO_OUT;
+ SetEvent (channel->data_avail_event);
+ LeaveCriticalSection (&channel->mutex);
+ WaitForSingleObject (channel->space_avail_event, INFINITE);
+
+ EnterCriticalSection (&channel->mutex);
+ if (channel->rdp == channel->wrp)
+ break;
+
+ if (channel->debug)
+ g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ }
+
+ buffer = channel->buffer + channel->rdp;
+ if (channel->rdp < channel->wrp)
+ nbytes = channel->wrp - channel->rdp;
+ else
+ nbytes = BUFFER_SIZE - channel->rdp;
+
+ if (channel->debug)
+ g_print ("write_thread %#x: calling write() for %d bytes\n",
+ channel->thread_id, nbytes);
+
+ LeaveCriticalSection (&channel->mutex);
+ nbytes = write (channel->fd, buffer, nbytes);
+ EnterCriticalSection (&channel->mutex);
+
+ if (channel->debug)
+ g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->fd, nbytes, channel->rdp, channel->wrp);
+
+ channel->revents = 0;
+ if (nbytes > 0)
+ channel->revents |= G_IO_OUT;
+ else if (nbytes <= 0)
+ channel->revents |= G_IO_ERR;
+
+ channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
+
+ if (nbytes <= 0)
+ break;
+
+ if (channel->debug)
+ g_print ("write_thread: setting data_avail for thread %#x\n",
+ channel->thread_id);
+ SetEvent (channel->data_avail_event);
+ }
+
+ channel->running = FALSE;
+ if (channel->needs_close)
+ {
+ if (channel->debug)
+ g_print ("write_thread %#x: channel fd %d needs closing\n",
+ channel->thread_id, channel->fd);
+ close (channel->fd);
+ channel->fd = -1;
+ }
+
+ LeaveCriticalSection (&channel->mutex);
+
+ g_io_channel_unref ((GIOChannel *)channel);
+
+ return 0;
+}
+
+static void
+create_thread (GIOWin32Channel *channel,
+ GIOCondition condition,
+ unsigned (__stdcall *thread) (void *parameter))
+{
+ HANDLE thread_handle;
+
+ thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
+ &channel->thread_id);
+ if (thread_handle == 0)
+ g_warning ("Error creating thread: %s.",
+ g_strerror (errno));
+ else if (!CloseHandle (thread_handle))
+ {
+ gchar *emsg = g_win32_error_message (GetLastError ());
+
+ g_warning ("Error closing thread handle: %s.", emsg);
+ g_free (emsg);
+ }
+
+ WaitForSingleObject (channel->space_avail_event, INFINITE);
+}
+
+static GIOStatus
+buffer_read (GIOWin32Channel *channel,
+ gchar *dest,
+ gsize count,
+ gsize *bytes_read,
+ GError **err)
+{
+ guint nbytes;
+ guint left = count;
+
+ EnterCriticalSection (&channel->mutex);
+ if (channel->debug)
+ g_print ("reading from thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
+ channel->thread_id, count, channel->rdp, channel->wrp);
+
+ if (channel->wrp == channel->rdp)
+ {
+ LeaveCriticalSection (&channel->mutex);
+ if (channel->debug)
+ g_print ("waiting for data from thread %#x\n", channel->thread_id);
+ WaitForSingleObject (channel->data_avail_event, INFINITE);
+ if (channel->debug)
+ g_print ("done waiting for data from thread %#x\n", channel->thread_id);
+ EnterCriticalSection (&channel->mutex);
+ if (channel->wrp == channel->rdp && !channel->running)
+ {
+ if (channel->debug)
+ g_print ("wrp==rdp, !running\n");
+ LeaveCriticalSection (&channel->mutex);
+ *bytes_read = 0;
+ return G_IO_STATUS_EOF;
+ }
+ }
+
+ if (channel->rdp < channel->wrp)
+ nbytes = channel->wrp - channel->rdp;
+ else
+ nbytes = BUFFER_SIZE - channel->rdp;
+ LeaveCriticalSection (&channel->mutex);
+ nbytes = MIN (left, nbytes);
+ if (channel->debug)
+ g_print ("moving %d bytes from thread %#x\n",
+ nbytes, channel->thread_id);
+ memcpy (dest, channel->buffer + channel->rdp, nbytes);
+ dest += nbytes;
+ left -= nbytes;
+ EnterCriticalSection (&channel->mutex);
+ channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
+ if (channel->debug)
+ g_print ("setting space_avail for thread %#x\n", channel->thread_id);
+ SetEvent (channel->space_avail_event);
+ if (channel->debug)
+ g_print ("for thread %#x: rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ if (channel->running && channel->wrp == channel->rdp)
+ {
+ if (channel->debug)
+ g_print ("resetting data_avail of thread %#x\n",
+ channel->thread_id);
+ ResetEvent (channel->data_avail_event);
+ };
+ LeaveCriticalSection (&channel->mutex);
+
+ /* We have no way to indicate any errors form the actual
+ * read() or recv() call in the reader thread. Should we have?
+ */
+ *bytes_read = count - left;
+ return (*bytes_read > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+
+static GIOStatus
+buffer_write (GIOWin32Channel *channel,
+ const gchar *dest,
+ gsize count,
+ gsize *bytes_written,
+ GError **err)
+{
+ guint nbytes;
+ guint left = count;
+
+ EnterCriticalSection (&channel->mutex);
+ if (channel->debug)
+ g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
+ channel->thread_id, count, channel->rdp, channel->wrp);
+
+ if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+ {
+ /* Buffer is full */
+ if (channel->debug)
+ g_print ("buffer_write: tid %#x: resetting data_avail\n",
+ channel->thread_id);
+ ResetEvent (channel->data_avail_event);
+ if (channel->debug)
+ g_print ("buffer_write: tid %#x: waiting for space\n",
+ channel->thread_id);
+ LeaveCriticalSection (&channel->mutex);
+ WaitForSingleObject (channel->data_avail_event, INFINITE);
+ EnterCriticalSection (&channel->mutex);
+ if (channel->debug)
+ g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ }
+
+ nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
+ BUFFER_SIZE - channel->wrp);
+
+ LeaveCriticalSection (&channel->mutex);
+ nbytes = MIN (left, nbytes);
+ if (channel->debug)
+ g_print ("buffer_write: tid %#x: writing %d bytes\n",
+ channel->thread_id, nbytes);
+ memcpy (channel->buffer + channel->wrp, dest, nbytes);
+ dest += nbytes;
+ left -= nbytes;
+ EnterCriticalSection (&channel->mutex);
+
+ channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
+ if (channel->debug)
+ g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
+ channel->thread_id, channel->rdp, channel->wrp);
+ SetEvent (channel->space_avail_event);
+
+ if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+ {
+ /* Buffer is full */
+ if (channel->debug)
+ g_print ("buffer_write: tid %#x: resetting data_avail\n",
+ channel->thread_id);
+ ResetEvent (channel->data_avail_event);
+ }
+
+ LeaveCriticalSection (&channel->mutex);
+
+ /* We have no way to indicate any errors form the actual
+ * write() call in the writer thread. Should we have?
+ */
+ *bytes_written = count - left;
+ return (*bytes_written > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+
+static gboolean
+g_io_win32_prepare (GSource *source,
+ gint *timeout)
+{
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+ GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+ GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+ int event_mask;
+
+ *timeout = -1;
+
+ if (channel->debug)
+ g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel);
+
+ switch (channel->type)
+ {
+ case G_IO_WIN32_WINDOWS_MESSAGES:
+ if (channel->debug)
+ g_print (" MSG");
+ break;
+
+ case G_IO_WIN32_CONSOLE:
+ if (channel->debug)
+ g_print (" CON");
+ break;
+
+ case G_IO_WIN32_FILE_DESC:
+ if (channel->debug)
+ g_print (" FD thread=%#x buffer_condition:{%s}"
+ "\n watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}",
+ channel->thread_id, condition_to_string (buffer_condition),
+ condition_to_string (watch->pollfd.events),
+ condition_to_string (watch->pollfd.revents),
+ condition_to_string (channel->revents));
+
+ EnterCriticalSection (&channel->mutex);
+ if (channel->running)
+ {
+ if (channel->direction == 0 && channel->wrp == channel->rdp)
+ {
+ if (channel->debug)
+ g_print ("\n setting revents=0");
+ channel->revents = 0;
+ }
+ }
+ else
+ {
+ if (channel->direction == 1
+ && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+ {
+ if (channel->debug)
+ g_print ("\n setting revents=0");
+ channel->revents = 0;
+ }
+ }
+ LeaveCriticalSection (&channel->mutex);
+ break;
+
+ case G_IO_WIN32_SOCKET:
+ if (channel->debug)
+ g_print (" SOCK");
+ event_mask = 0;
+ if (watch->condition & G_IO_IN)
+ event_mask |= (FD_READ | FD_ACCEPT);
+ if (watch->condition & G_IO_OUT)
+ event_mask |= (FD_WRITE | FD_CONNECT);
+ event_mask |= FD_CLOSE;
+
+ if (channel->event_mask != event_mask)
+ {
+ if (channel->debug)
+ g_print ("\n WSAEventSelect(%d,%p,{%s})",
+ channel->fd, (HANDLE) watch->pollfd.fd,
+ event_mask_to_string (event_mask));
+ if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd,
+ event_mask) == SOCKET_ERROR)
+ if (channel->debug)
+ {
+ gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+ g_print (" failed: %s", emsg);
+ g_free (emsg);
+ }
+ channel->event_mask = event_mask;
+
+ if (channel->debug)
+ g_print ("\n setting last_events=0");
+ channel->last_events = 0;
+
+ if ((event_mask & FD_WRITE) &&
+ channel->ever_writable &&
+ !channel->write_would_have_blocked)
+ {
+ if (channel->debug)
+ g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
+ WSASetEvent ((WSAEVENT) watch->pollfd.fd);
+ }
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ abort ();
+ }
+ if (channel->debug)
+ g_print ("\n");
+
+ return ((watch->condition & buffer_condition) == watch->condition);
+}
+
+static gboolean
+g_io_win32_check (GSource *source)
+{
+ MSG msg;
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+ GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+ GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+ WSANETWORKEVENTS events;
+
+ if (channel->debug)
+ g_print ("g_io_win32_check: source=%p channel=%p", source, channel);
+
+ switch (channel->type)
+ {
+ case G_IO_WIN32_WINDOWS_MESSAGES:
+ if (channel->debug)
+ g_print (" MSG\n");
+ return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
+
+ case G_IO_WIN32_FILE_DESC:
+ if (channel->debug)
+ g_print (" FD thread=%#x buffer_condition=%s\n"
+ " watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
+ channel->thread_id, condition_to_string (buffer_condition),
+ condition_to_string (watch->pollfd.events),
+ condition_to_string (watch->pollfd.revents),
+ condition_to_string (channel->revents));
+
+ watch->pollfd.revents = (watch->pollfd.events & channel->revents);
+
+ return ((watch->pollfd.revents | buffer_condition) & watch->condition);
+
+ case G_IO_WIN32_CONSOLE:
+ if (channel->debug)
+ g_print (" CON\n");
+ if (watch->channel->is_writeable)
+ return TRUE;
+ else if (watch->channel->is_readable)
+ {
+ INPUT_RECORD buffer;
+ DWORD n;
+ if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) &&
+ n == 1)
+ {
+ /* _kbhit() does quite complex processing to find out
+ * whether at least one of the key events pending corresponds
+ * to a "real" character that can be read.
+ */
+ if (_kbhit ())
+ return TRUE;
+
+ /* Discard all other kinds of events */
+ ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n);
+ }
+ }
+ return FALSE;
+
+ case G_IO_WIN32_SOCKET:
+ if (channel->debug)
+ g_print (" SOCK");
+ if (channel->last_events & FD_WRITE)
+ {
+ if (channel->debug)
+ g_print (" sock=%d event=%p last_events has FD_WRITE",
+ channel->fd, (HANDLE) watch->pollfd.fd);
+ }
+ else
+ {
+ WSAEnumNetworkEvents (channel->fd, 0, &events);
+
+ if (channel->debug)
+ g_print ("\n revents={%s} condition={%s}"
+ "\n WSAEnumNetworkEvents(%d,0) sets events={%s}",
+ condition_to_string (watch->pollfd.revents),
+ condition_to_string (watch->condition),
+ channel->fd,
+ event_mask_to_string (events.lNetworkEvents));
+
+ if (watch->pollfd.revents != 0 &&
+ events.lNetworkEvents == 0 &&
+ !(channel->event_mask & FD_WRITE))
+ {
+ channel->event_mask = 0;
+ if (channel->debug)
+ g_print ("\n WSAEventSelect(%d,%p,{})",
+ channel->fd, (HANDLE) watch->pollfd.fd);
+ WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0);
+ if (channel->debug)
+ g_print (" ResetEvent(%p)",
+ (HANDLE) watch->pollfd.fd);
+ ResetEvent ((HANDLE) watch->pollfd.fd);
+ }
+ else if (events.lNetworkEvents & FD_WRITE)
+ channel->ever_writable = TRUE;
+ channel->last_events = events.lNetworkEvents;
+ }
+
+ watch->pollfd.revents = 0;
+ if (channel->last_events & (FD_READ | FD_ACCEPT))
+ watch->pollfd.revents |= G_IO_IN;
+
+ if (channel->last_events & FD_WRITE)
+ watch->pollfd.revents |= G_IO_OUT;
+ else
+ {
+ /* We have called WSAEnumNetworkEvents() above but it didn't
+ * set FD_WRITE.
+ */
+ if (events.lNetworkEvents & FD_CONNECT)
+ {
+ if (events.iErrorCode[FD_CONNECT_BIT] == 0)
+ watch->pollfd.revents |= G_IO_OUT;
+ else
+ watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR);
+ }
+ if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
+ watch->pollfd.revents |= G_IO_HUP;
+ }
+
+ /* Regardless of WSAEnumNetworkEvents() result, if watching for
+ * writability, and if we have ever got a FD_WRITE event, and
+ * unless last write would have blocked, set G_IO_OUT. But never
+ * set both G_IO_OUT and G_IO_HUP.
+ */
+ if (!(watch->pollfd.revents & G_IO_HUP) &&
+ channel->ever_writable &&
+ !channel->write_would_have_blocked &&
+ (channel->event_mask & FD_WRITE))
+ watch->pollfd.revents |= G_IO_OUT;
+
+ if (channel->debug)
+ g_print ("\n revents={%s} retval={%s}\n",
+ condition_to_string (watch->pollfd.revents),
+ condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
+
+ return ((watch->pollfd.revents | buffer_condition) & watch->condition);
+
+ default:
+ g_assert_not_reached ();
+ abort ();
+ }
+}
+
+static gboolean
+g_io_win32_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ GIOFunc func = (GIOFunc)callback;
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+ GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+ GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+
+ if (!func)
+ {
+ g_warning ("IO Watch dispatched without callback\n"
+ "You must call g_source_connect().");
+ return FALSE;
+ }
+
+ if (channel->debug)
+ g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
+ condition_to_string (watch->pollfd.revents),
+ condition_to_string (watch->condition),
+ condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
+
+ return (*func) (watch->channel,
+ (watch->pollfd.revents | buffer_condition) & watch->condition,
+ user_data);
+}
+
+static void
+g_io_win32_finalize (GSource *source)
+{
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+ GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+
+ if (channel->debug)
+ g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel);
+
+ switch (channel->type)
+ {
+ case G_IO_WIN32_WINDOWS_MESSAGES:
+ if (channel->debug)
+ g_print (" MSG");
+ break;
+
+ case G_IO_WIN32_CONSOLE:
+ if (channel->debug)
+ g_print (" CON");
+ break;
+
+ case G_IO_WIN32_FILE_DESC:
+ if (channel->debug)
+ g_print (" FD thread=%#x", channel->thread_id);
+ break;
+
+ case G_IO_WIN32_SOCKET:
+ if (channel->debug)
+ g_print (" SOCK sock=%d", channel->fd);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ abort ();
+ }
+ if (channel->debug)
+ g_print ("\n");
+ g_io_channel_unref (watch->channel);
+}
+
+GSourceFuncs g_io_watch_funcs = {
+ g_io_win32_prepare,
+ g_io_win32_check,
+ g_io_win32_dispatch,
+ g_io_win32_finalize
+};
+
+static GIOStatus
+g_io_win32_msg_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ MSG msg; /* In case of alignment problems */
+
+ if (count < sizeof (MSG))
+ {
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
+ "Incorrect message size"); /* Informative enough error message? */
+ return G_IO_STATUS_ERROR;
+ }
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n",
+ channel, win32_channel->hwnd);
+ if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
+ return G_IO_STATUS_AGAIN;
+
+ memmove (buf, &msg, sizeof (MSG));
+ *bytes_read = sizeof (MSG);
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_msg_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ MSG msg;
+
+ if (count != sizeof (MSG))
+ {
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
+ "Incorrect message size"); /* Informative enough error message? */
+ return G_IO_STATUS_ERROR;
+ }
+
+ /* In case of alignment problems */
+ memmove (&msg, buf, sizeof (MSG));
+ if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
+ {
+ gchar *emsg = g_win32_error_message (GetLastError ());
+
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg);
+ g_free (emsg);
+
+ return G_IO_STATUS_ERROR;
+ }
+
+ *bytes_written = sizeof (MSG);
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_msg_close (GIOChannel *channel,
+ GError **err)
+{
+ /* Nothing to be done. Or should we set hwnd to some invalid value? */
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static void
+g_io_win32_free (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd);
+
+ DeleteCriticalSection (&win32_channel->mutex);
+
+ if (win32_channel->data_avail_event)
+ if (!CloseHandle (win32_channel->data_avail_event))
+ if (win32_channel->debug)
+ {
+ gchar *emsg = g_win32_error_message (GetLastError ());
+
+ g_print (" CloseHandle(%p) failed: %s\n",
+ win32_channel->data_avail_event, emsg);
+ g_free (emsg);
+ }
+
+ g_free (win32_channel->buffer);
+
+ if (win32_channel->space_avail_event)
+ if (!CloseHandle (win32_channel->space_avail_event))
+ if (win32_channel->debug)
+ {
+ gchar *emsg = g_win32_error_message (GetLastError ());
+
+ g_print (" CloseHandle(%p) failed: %s\n",
+ win32_channel->space_avail_event, emsg);
+ g_free (emsg);
+ }
+
+ if (win32_channel->type == G_IO_WIN32_SOCKET)
+ if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR)
+ if (win32_channel->debug)
+ {
+ gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+ g_print (" WSAEventSelect(%d,NULL,{}) failed: %s\n",
+ win32_channel->fd, emsg);
+ g_free (emsg);
+ }
+
+ if (win32_channel->event)
+ if (!WSACloseEvent (win32_channel->event))
+ if (win32_channel->debug)
+ {
+ gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+ g_print (" WSACloseEvent(%p) failed: %s\n",
+ win32_channel->event, emsg);
+ g_free (emsg);
+ }
+
+ g_free (win32_channel);
+}
+
+static GSource *
+g_io_win32_msg_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ GIOWin32Watch *watch;
+ GSource *source;
+
+ source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+ watch = (GIOWin32Watch *)source;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->condition = condition;
+
+ watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE;
+ watch->pollfd.events = condition;
+
+ g_source_add_poll (source, &watch->pollfd);
+
+ return source;
+}
+
+static GIOStatus
+g_io_win32_fd_and_console_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ gint result;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
+ win32_channel->fd, count);
+
+ if (win32_channel->thread_id)
+ {
+ return buffer_read (win32_channel, buf, count, bytes_read, err);
+ }
+
+ result = read (win32_channel->fd, buf, count);
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_read: read() => %d\n", result);
+
+ if (result < 0)
+ {
+ *bytes_read = 0;
+
+ switch (errno)
+ {
+#ifdef EAGAIN
+ case EAGAIN:
+ return G_IO_STATUS_AGAIN;
+#endif
+ default:
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errno),
+ g_strerror (errno));
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ *bytes_read = result;
+
+ return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+static GIOStatus
+g_io_win32_fd_and_console_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ gint result;
+
+ if (win32_channel->thread_id)
+ {
+ return buffer_write (win32_channel, buf, count, bytes_written, err);
+ }
+
+ result = write (win32_channel->fd, buf, count);
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
+ win32_channel->fd, count, result);
+
+ if (result < 0)
+ {
+ *bytes_written = 0;
+
+ switch (errno)
+ {
+#ifdef EAGAIN
+ case EAGAIN:
+ return G_IO_STATUS_AGAIN;
+#endif
+ default:
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errno),
+ g_strerror (errno));
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ *bytes_written = result;
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_fd_seek (GIOChannel *channel,
+ gint64 offset,
+ GSeekType type,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ int whence;
+ off_t tmp_offset;
+ off_t result;
+
+ switch (type)
+ {
+ case G_SEEK_SET:
+ whence = SEEK_SET;
+ break;
+ case G_SEEK_CUR:
+ whence = SEEK_CUR;
+ break;
+ case G_SEEK_END:
+ whence = SEEK_END;
+ break;
+ default:
+ whence = -1; /* Keep the compiler quiet */
+ g_assert_not_reached ();
+ abort ();
+ }
+
+ tmp_offset = offset;
+ if (tmp_offset != offset)
+ {
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (EINVAL),
+ g_strerror (EINVAL));
+ return G_IO_STATUS_ERROR;
+ }
+
+ result = lseek (win32_channel->fd, tmp_offset, whence);
+
+ if (result < 0)
+ {
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errno),
+ g_strerror (errno));
+ return G_IO_STATUS_ERROR;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_fd_close (GIOChannel *channel,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
+ win32_channel->thread_id,
+ win32_channel->fd);
+ EnterCriticalSection (&win32_channel->mutex);
+ if (win32_channel->running)
+ {
+ if (win32_channel->debug)
+ g_print ("thread %#x: running, marking fd %d for later close\n",
+ win32_channel->thread_id, win32_channel->fd);
+ win32_channel->running = FALSE;
+ win32_channel->needs_close = TRUE;
+ if (win32_channel->direction == 0)
+ SetEvent (win32_channel->data_avail_event);
+ else
+ SetEvent (win32_channel->space_avail_event);
+ }
+ else
+ {
+ if (win32_channel->debug)
+ g_print ("closing fd %d\n", win32_channel->fd);
+ close (win32_channel->fd);
+ if (win32_channel->debug)
+ g_print ("closed fd %d, setting to -1\n",
+ win32_channel->fd);
+ win32_channel->fd = -1;
+ }
+ LeaveCriticalSection (&win32_channel->mutex);
+
+ /* FIXME error detection? */
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_fd_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->condition = condition;
+
+ if (win32_channel->data_avail_event == NULL)
+ create_events (win32_channel);
+
+ watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
+ watch->pollfd.events = condition;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
+ channel, win32_channel->fd,
+ condition_to_string (condition), (HANDLE) watch->pollfd.fd);
+
+ EnterCriticalSection (&win32_channel->mutex);
+ if (win32_channel->thread_id == 0)
+ {
+ if (condition & G_IO_IN)
+ create_thread (win32_channel, condition, read_thread);
+ else if (condition & G_IO_OUT)
+ create_thread (win32_channel, condition, write_thread);
+ }
+
+ g_source_add_poll (source, &watch->pollfd);
+ LeaveCriticalSection (&win32_channel->mutex);
+
+ return source;
+}
+
+static GIOStatus
+g_io_win32_console_close (GIOChannel *channel,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ if (close (win32_channel->fd) < 0)
+ {
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ g_io_channel_error_from_errno (errno),
+ g_strerror (errno));
+ return G_IO_STATUS_ERROR;
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_console_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->condition = condition;
+
+ watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
+ watch->pollfd.events = condition;
+
+ g_source_add_poll (source, &watch->pollfd);
+
+ return source;
+}
+
+static GIOStatus
+g_io_win32_sock_read (GIOChannel *channel,
+ gchar *buf,
+ gsize count,
+ gsize *bytes_read,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ gint result;
+ GIOChannelError error;
+ int winsock_error;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
+ channel, win32_channel->fd, count);
+
+ result = recv (win32_channel->fd, buf, count, 0);
+ if (result == SOCKET_ERROR)
+ winsock_error = WSAGetLastError ();
+
+ if (win32_channel->debug)
+ g_print (" recv=%d", result);
+
+ if (result == SOCKET_ERROR)
+ {
+ gchar *emsg = g_win32_error_message (winsock_error);
+
+ if (win32_channel->debug)
+ g_print (" %s\n", emsg);
+
+ *bytes_read = 0;
+
+ switch (winsock_error)
+ {
+ case WSAEINVAL:
+ error = G_IO_CHANNEL_ERROR_INVAL;
+ break;
+ case WSAEWOULDBLOCK:
+ g_free (emsg);
+ return G_IO_STATUS_AGAIN;
+ default:
+ error = G_IO_CHANNEL_ERROR_FAILED;
+ break;
+ }
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
+ g_free (emsg);
+
+ return G_IO_STATUS_ERROR;
+ }
+ else
+ {
+ if (win32_channel->debug)
+ g_print ("\n");
+ *bytes_read = result;
+ if (result == 0)
+ return G_IO_STATUS_EOF;
+ else
+ return G_IO_STATUS_NORMAL;
+ }
+}
+
+static GIOStatus
+g_io_win32_sock_write (GIOChannel *channel,
+ const gchar *buf,
+ gsize count,
+ gsize *bytes_written,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ gint result;
+ GIOChannelError error;
+ int winsock_error;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
+ channel, win32_channel->fd, count);
+
+ result = send (win32_channel->fd, buf, count, 0);
+ if (result == SOCKET_ERROR)
+ winsock_error = WSAGetLastError ();
+
+ if (win32_channel->debug)
+ g_print (" send=%d", result);
+
+ if (result == SOCKET_ERROR)
+ {
+ gchar *emsg = g_win32_error_message (winsock_error);
+
+ if (win32_channel->debug)
+ g_print (" %s\n", emsg);
+
+ *bytes_written = 0;
+
+ switch (winsock_error)
+ {
+ case WSAEINVAL:
+ error = G_IO_CHANNEL_ERROR_INVAL;
+ break;
+ case WSAEWOULDBLOCK:
+ win32_channel->write_would_have_blocked = TRUE;
+ win32_channel->last_events = 0;
+ g_free (emsg);
+ return G_IO_STATUS_AGAIN;
+ default:
+ error = G_IO_CHANNEL_ERROR_FAILED;
+ break;
+ }
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
+ g_free (emsg);
+
+ return G_IO_STATUS_ERROR;
+ }
+ else
+ {
+ if (win32_channel->debug)
+ g_print ("\n");
+ *bytes_written = result;
+ win32_channel->write_would_have_blocked = FALSE;
+
+ return G_IO_STATUS_NORMAL;
+ }
+}
+
+static GIOStatus
+g_io_win32_sock_close (GIOChannel *channel,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ if (win32_channel->fd != -1)
+ {
+ if (win32_channel->debug)
+ g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
+ channel, win32_channel->fd);
+
+ closesocket (win32_channel->fd);
+ win32_channel->fd = -1;
+ }
+
+ /* FIXME error detection? */
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_sock_create_watch (GIOChannel *channel,
+ GIOCondition condition)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+ GIOWin32Watch *watch = (GIOWin32Watch *)source;
+
+ watch->channel = channel;
+ g_io_channel_ref (channel);
+
+ watch->condition = condition;
+
+ if (win32_channel->event == 0)
+ win32_channel->event = WSACreateEvent ();
+
+ watch->pollfd.fd = (gintptr) win32_channel->event;
+ watch->pollfd.events = condition;
+
+ if (win32_channel->debug)
+ g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
+ channel, win32_channel->fd, (HANDLE) watch->pollfd.fd,
+ condition_to_string (watch->condition));
+
+ g_source_add_poll (source, &watch->pollfd);
+
+ return source;
+}
+
+GIOChannel *
+g_io_channel_new_file (const gchar *filename,
+ const gchar *mode,
+ GError **error)
+{
+ int fid, flags, pmode;
+ GIOChannel *channel;
+
+ enum { /* Cheesy hack */
+ MODE_R = 1 << 0,
+ MODE_W = 1 << 1,
+ MODE_A = 1 << 2,
+ MODE_PLUS = 1 << 3,
+ } mode_num;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+ g_return_val_if_fail (mode != NULL, NULL);
+ g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
+
+ switch (mode[0])
+ {
+ case 'r':
+ mode_num = MODE_R;
+ break;
+ case 'w':
+ mode_num = MODE_W;
+ break;
+ case 'a':
+ mode_num = MODE_A;
+ break;
+ default:
+ g_warning ("Invalid GIOFileMode %s.", mode);
+ return NULL;
+ }
+
+ switch (mode[1])
+ {
+ case '\0':
+ break;
+ case '+':
+ if (mode[2] == '\0')
+ {
+ mode_num |= MODE_PLUS;
+ break;
+ }
+ /* Fall through */
+ default:
+ g_warning ("Invalid GIOFileMode %s.", mode);
+ return NULL;
+ }
+
+ switch (mode_num)
+ {
+ case MODE_R:
+ flags = O_RDONLY;
+ pmode = _S_IREAD;
+ break;
+ case MODE_W:
+ flags = O_WRONLY | O_TRUNC | O_CREAT;
+ pmode = _S_IWRITE;
+ break;
+ case MODE_A:
+ flags = O_WRONLY | O_APPEND | O_CREAT;
+ pmode = _S_IWRITE;
+ break;
+ case MODE_R | MODE_PLUS:
+ flags = O_RDWR;
+ pmode = _S_IREAD | _S_IWRITE;
+ break;
+ case MODE_W | MODE_PLUS:
+ flags = O_RDWR | O_TRUNC | O_CREAT;
+ pmode = _S_IREAD | _S_IWRITE;
+ break;
+ case MODE_A | MODE_PLUS:
+ flags = O_RDWR | O_APPEND | O_CREAT;
+ pmode = _S_IREAD | _S_IWRITE;
+ break;
+ default:
+ g_assert_not_reached ();
+ abort ();
+ }
+
+ /* always open 'untranslated' */
+ fid = g_open (filename, flags | _O_BINARY, pmode);
+
+ if (g_io_win32_get_debug_flag ())
+ {
+ g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename);
+ g_win32_print_access_mode (flags|_O_BINARY);
+ g_print (",%#o)=%d\n", pmode, fid);
+ }
+
+ if (fid < 0)
+ {
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ g_strerror (errno));
+ return (GIOChannel *)NULL;
+ }
+
+ channel = g_io_channel_win32_new_fd (fid);
+
+ /* XXX: move this to g_io_channel_win32_new_fd () */
+ channel->close_on_unref = TRUE;
+ channel->is_seekable = TRUE;
+
+ /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
+ * correspond to actual readability/writeability. Set to FALSE those
+ * that mode doesn't allow
+ */
+ switch (mode_num)
+ {
+ case MODE_R:
+ channel->is_writeable = FALSE;
+ break;
+ case MODE_W:
+ case MODE_A:
+ channel->is_readable = FALSE;
+ break;
+ case MODE_R | MODE_PLUS:
+ case MODE_W | MODE_PLUS:
+ case MODE_A | MODE_PLUS:
+ break;
+ default:
+ g_assert_not_reached ();
+ abort ();
+ }
+
+ return channel;
+}
+
+#if !defined (_WIN64)
+
+#undef g_io_channel_new_file
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+GIOChannel *
+g_io_channel_new_file (const gchar *filename,
+ const gchar *mode,
+ GError **error)
+{
+ gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+ GIOChannel *retval;
+
+ if (utf8_filename == NULL)
+ return NULL;
+
+ retval = g_io_channel_new_file_utf8 (utf8_filename, mode, error);
+
+ g_free (utf8_filename);
+
+ return retval;
+}
+
+#endif
+
+static GIOStatus
+g_io_win32_unimpl_set_flags (GIOChannel *channel,
+ GIOFlags flags,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ if (win32_channel->debug)
+ {
+ g_print ("g_io_win32_unimpl_set_flags: ");
+ g_win32_print_gioflags (flags);
+ g_print ("\n");
+ }
+
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED,
+ "Not implemented on Win32");
+
+ return G_IO_STATUS_ERROR;
+}
+
+static GIOFlags
+g_io_win32_fd_get_flags_internal (GIOChannel *channel,
+ struct stat *st)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ gchar c;
+ DWORD count;
+
+ if (st->st_mode & _S_IFIFO)
+ {
+ channel->is_readable =
+ (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) != 0) || GetLastError () == ERROR_BROKEN_PIPE;
+ channel->is_writeable =
+ (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
+ channel->is_seekable = FALSE;
+ }
+ else
+ {
+ channel->is_readable =
+ (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
+ channel->is_writeable =
+ (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
+ channel->is_seekable = TRUE;
+ }
+
+ /* XXX: G_IO_FLAG_APPEND */
+ /* XXX: G_IO_FLAG_NONBLOCK */
+
+ return 0;
+}
+
+static GIOFlags
+g_io_win32_fd_get_flags (GIOChannel *channel)
+{
+ struct stat st;
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ g_return_val_if_fail (win32_channel != NULL, 0);
+ g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0);
+
+ if (0 == fstat (win32_channel->fd, &st))
+ return g_io_win32_fd_get_flags_internal (channel, &st);
+ else
+ return 0;
+}
+
+static GIOFlags
+g_io_win32_console_get_flags_internal (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+ HANDLE handle = (HANDLE) _get_osfhandle (win32_channel->fd);
+ gchar c;
+ DWORD count;
+ INPUT_RECORD record;
+
+ channel->is_readable = PeekConsoleInput (handle, &record, 1, &count);
+ channel->is_writeable = WriteFile (handle, &c, 0, &count, NULL);
+ channel->is_seekable = FALSE;
+
+ return 0;
+}
+
+static GIOFlags
+g_io_win32_console_get_flags (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ g_return_val_if_fail (win32_channel != NULL, 0);
+ g_return_val_if_fail (win32_channel->type == G_IO_WIN32_CONSOLE, 0);
+
+ return g_io_win32_console_get_flags_internal (channel);
+}
+
+static GIOFlags
+g_io_win32_msg_get_flags (GIOChannel *channel)
+{
+ return 0;
+}
+
+static GIOStatus
+g_io_win32_sock_set_flags (GIOChannel *channel,
+ GIOFlags flags,
+ GError **err)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+ u_long arg;
+
+ if (win32_channel->debug)
+ {
+ g_print ("g_io_win32_sock_set_flags: ");
+ g_win32_print_gioflags (flags);
+ g_print ("\n");
+ }
+
+ if (flags & G_IO_FLAG_NONBLOCK)
+ {
+ arg = 1;
+ if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
+ {
+ gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED,
+ emsg);
+ g_free (emsg);
+
+ return G_IO_STATUS_ERROR;
+ }
+ }
+ else
+ {
+ arg = 0;
+ if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
+ {
+ gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+ g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+ G_IO_CHANNEL_ERROR_FAILED,
+ emsg);
+ g_free (emsg);
+
+ return G_IO_STATUS_ERROR;
+ }
+ }
+
+ return G_IO_STATUS_NORMAL;
+}
+
+static GIOFlags
+g_io_win32_sock_get_flags (GIOChannel *channel)
+{
+ /* Could we do something here? */
+ return 0;
+}
+
+static GIOFuncs win32_channel_msg_funcs = {
+ g_io_win32_msg_read,
+ g_io_win32_msg_write,
+ NULL,
+ g_io_win32_msg_close,
+ g_io_win32_msg_create_watch,
+ g_io_win32_free,
+ g_io_win32_unimpl_set_flags,
+ g_io_win32_msg_get_flags,
+};
+
+static GIOFuncs win32_channel_fd_funcs = {
+ g_io_win32_fd_and_console_read,
+ g_io_win32_fd_and_console_write,
+ g_io_win32_fd_seek,
+ g_io_win32_fd_close,
+ g_io_win32_fd_create_watch,
+ g_io_win32_free,
+ g_io_win32_unimpl_set_flags,
+ g_io_win32_fd_get_flags,
+};
+
+static GIOFuncs win32_channel_console_funcs = {
+ g_io_win32_fd_and_console_read,
+ g_io_win32_fd_and_console_write,
+ NULL,
+ g_io_win32_console_close,
+ g_io_win32_console_create_watch,
+ g_io_win32_free,
+ g_io_win32_unimpl_set_flags,
+ g_io_win32_console_get_flags,
+};
+
+static GIOFuncs win32_channel_sock_funcs = {
+ g_io_win32_sock_read,
+ g_io_win32_sock_write,
+ NULL,
+ g_io_win32_sock_close,
+ g_io_win32_sock_create_watch,
+ g_io_win32_free,
+ g_io_win32_sock_set_flags,
+ g_io_win32_sock_get_flags,
+};
+
+GIOChannel *
+#if GLIB_SIZEOF_VOID_P == 8
+g_io_channel_win32_new_messages (gsize hwnd)
+#else
+g_io_channel_win32_new_messages (guint hwnd)
+#endif
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *)win32_channel;
+
+ g_io_channel_init (channel);
+ g_io_channel_win32_init (win32_channel);
+ if (win32_channel->debug)
+ g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n",
+ channel, (HWND) hwnd);
+ channel->funcs = &win32_channel_msg_funcs;
+ win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
+ win32_channel->hwnd = (HWND) hwnd;
+
+ /* XXX: check this. */
+ channel->is_readable = IsWindow (win32_channel->hwnd);
+ channel->is_writeable = IsWindow (win32_channel->hwnd);
+
+ channel->is_seekable = FALSE;
+
+ return channel;
+}
+
+static GIOChannel *
+g_io_channel_win32_new_fd_internal (gint fd,
+ struct stat *st)
+{
+ GIOWin32Channel *win32_channel;
+ GIOChannel *channel;
+
+ win32_channel = g_new (GIOWin32Channel, 1);
+ channel = (GIOChannel *)win32_channel;
+
+ g_io_channel_init (channel);
+ g_io_channel_win32_init (win32_channel);
+
+ win32_channel->fd = fd;
+
+ if (win32_channel->debug)
+ g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n",
+ channel, fd);
+
+ if (st->st_mode & _S_IFCHR) /* console */
+ {
+ channel->funcs = &win32_channel_console_funcs;
+ win32_channel->type = G_IO_WIN32_CONSOLE;
+ g_io_win32_console_get_flags_internal (channel);
+ }
+ else
+ {
+ channel->funcs = &win32_channel_fd_funcs;
+ win32_channel->type = G_IO_WIN32_FILE_DESC;
+ g_io_win32_fd_get_flags_internal (channel, st);
+ }
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_win32_new_fd (gint fd)
+{
+ struct stat st;
+
+ if (fstat (fd, &st) == -1)
+ {
+ g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd);
+ return NULL;
+ }
+
+ return g_io_channel_win32_new_fd_internal (fd, &st);
+}
+
+gint
+g_io_channel_win32_get_fd (GIOChannel *channel)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ return win32_channel->fd;
+}
+
+GIOChannel *
+g_io_channel_win32_new_socket (int socket)
+{
+ GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+ GIOChannel *channel = (GIOChannel *)win32_channel;
+
+ g_io_channel_init (channel);
+ g_io_channel_win32_init (win32_channel);
+ if (win32_channel->debug)
+ g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
+ channel, socket);
+ channel->funcs = &win32_channel_sock_funcs;
+ win32_channel->type = G_IO_WIN32_SOCKET;
+ win32_channel->fd = socket;
+
+ channel->is_readable = TRUE;
+ channel->is_writeable = TRUE;
+ channel->is_seekable = FALSE;
+
+ return channel;
+}
+
+GIOChannel *
+g_io_channel_unix_new (gint fd)
+{
+ gboolean is_fd, is_socket;
+ struct stat st;
+ int optval, optlen;
+
+ is_fd = (fstat (fd, &st) == 0);
+
+ optlen = sizeof (optval);
+ is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
+
+ if (is_fd && is_socket)
+ g_warning ("g_io_channel_unix_new: %d is both a file descriptor and a socket. File descriptor interpretation assumed. To avoid ambiguity, call either g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket() instead.", fd);
+
+ if (is_fd)
+ return g_io_channel_win32_new_fd_internal (fd, &st);
+
+ if (is_socket)
+ return g_io_channel_win32_new_socket(fd);
+
+ g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd);
+
+ return NULL;
+}
+
+gint
+g_io_channel_unix_get_fd (GIOChannel *channel)
+{
+ return g_io_channel_win32_get_fd (channel);
+}
+
+void
+g_io_channel_win32_set_debug (GIOChannel *channel,
+ gboolean flag)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ win32_channel->debug = flag;
+}
+
+gint
+g_io_channel_win32_poll (GPollFD *fds,
+ gint n_fds,
+ gint timeout)
+{
+ g_return_val_if_fail (n_fds >= 0, 0);
+
+ return g_poll (fds, n_fds, timeout);
+}
+
+void
+g_io_channel_win32_make_pollfd (GIOChannel *channel,
+ GIOCondition condition,
+ GPollFD *fd)
+{
+ GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+ switch (win32_channel->type)
+ {
+ case G_IO_WIN32_FILE_DESC:
+ if (win32_channel->data_avail_event == NULL)
+ create_events (win32_channel);
+
+ fd->fd = (gintptr) win32_channel->data_avail_event;
+
+ if (win32_channel->thread_id == 0)
+ {
+ /* Is it meaningful for a file descriptor to be polled for
+ * both IN and OUT? For what kind of file descriptor would
+ * that be? Doesn't seem to make sense, in practise the file
+ * descriptors handled here are always read or write ends of
+ * pipes surely, and thus unidirectional.
+ */
+ if (condition & G_IO_IN)
+ create_thread (win32_channel, condition, read_thread);
+ else if (condition & G_IO_OUT)
+ create_thread (win32_channel, condition, write_thread);
+ }
+ break;
+
+ case G_IO_WIN32_CONSOLE:
+ fd->fd = _get_osfhandle (win32_channel->fd);
+ break;
+
+ case G_IO_WIN32_SOCKET:
+ fd->fd = (gintptr) WSACreateEvent ();
+ break;
+
+ case G_IO_WIN32_WINDOWS_MESSAGES:
+ fd->fd = G_WIN32_MSG_HANDLE;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ abort ();
+ }
+
+ fd->events = condition;
+}
+
+#ifndef _WIN64
+
+/* Binary compatibility */
+GIOChannel *
+g_io_channel_win32_new_stream_socket (int socket)
+{
+ return g_io_channel_win32_new_socket (socket);
+}
+
+#endif
+
+#define __G_IO_WIN32_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gkeyfile.c b/desmume/src/windows/glib-2.20.1/build/glib/gkeyfile.c
new file mode 100644
index 000000000..19301ce8a
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gkeyfile.c
@@ -0,0 +1,3780 @@
+/* gkeyfile.c - key file parser
+ *
+ * Copyright 2004 Red Hat, Inc.
+ *
+ * Written by Ray Strode
+ * Matthias Clasen
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkeyfile.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+#ifdef G_OS_WIN32
+#include
+
+#ifndef S_ISREG
+#define S_ISREG(mode) ((mode)&_S_IFREG)
+#endif
+
+#endif /* G_OS_WIN23 */
+
+#include "gconvert.h"
+#include "gdataset.h"
+#include "gerror.h"
+#include "gfileutils.h"
+#include "ghash.h"
+#include "glibintl.h"
+#include "glist.h"
+#include "gslist.h"
+#include "gmem.h"
+#include "gmessages.h"
+#include "gstdio.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gutils.h"
+
+#include "galias.h"
+
+typedef struct _GKeyFileGroup GKeyFileGroup;
+
+struct _GKeyFile
+{
+ GList *groups;
+ GHashTable *group_hash;
+
+ GKeyFileGroup *start_group;
+ GKeyFileGroup *current_group;
+
+ GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */
+
+ /* Used for sizing the output buffer during serialization
+ */
+ gsize approximate_size;
+
+ gchar list_separator;
+
+ GKeyFileFlags flags;
+
+ gchar **locales;
+};
+
+typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;
+
+struct _GKeyFileGroup
+{
+ const gchar *name; /* NULL for above first group (which will be comments) */
+
+ GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */
+ gboolean has_trailing_blank_line;
+
+ GList *key_value_pairs;
+
+ /* Used in parallel with key_value_pairs for
+ * increased lookup performance
+ */
+ GHashTable *lookup_map;
+};
+
+struct _GKeyFileKeyValuePair
+{
+ gchar *key; /* NULL for comments */
+ gchar *value;
+};
+
+static gint find_file_in_data_dirs (const gchar *file,
+ const gchar **data_dirs,
+ gchar **output_file,
+ GError **error);
+static gboolean g_key_file_load_from_fd (GKeyFile *key_file,
+ gint fd,
+ GKeyFileFlags flags,
+ GError **error);
+static GList *g_key_file_lookup_group_node (GKeyFile *key_file,
+ const gchar *group_name);
+static GKeyFileGroup *g_key_file_lookup_group (GKeyFile *key_file,
+ const gchar *group_name);
+
+static GList *g_key_file_lookup_key_value_pair_node (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ const gchar *key);
+static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ const gchar *key);
+
+static void g_key_file_remove_group_node (GKeyFile *key_file,
+ GList *group_node);
+static void g_key_file_remove_key_value_pair_node (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ GList *pair_node);
+
+static void g_key_file_add_key (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ const gchar *key,
+ const gchar *value);
+static void g_key_file_add_group (GKeyFile *key_file,
+ const gchar *group_name);
+static gboolean g_key_file_is_group_name (const gchar *name);
+static gboolean g_key_file_is_key_name (const gchar *name);
+static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair);
+static gboolean g_key_file_line_is_comment (const gchar *line);
+static gboolean g_key_file_line_is_group (const gchar *line);
+static gboolean g_key_file_line_is_key_value_pair (const gchar *line);
+static gchar *g_key_file_parse_value_as_string (GKeyFile *key_file,
+ const gchar *value,
+ GSList **separators,
+ GError **error);
+static gchar *g_key_file_parse_string_as_value (GKeyFile *key_file,
+ const gchar *string,
+ gboolean escape_separator);
+static gint g_key_file_parse_value_as_integer (GKeyFile *key_file,
+ const gchar *value,
+ GError **error);
+static gchar *g_key_file_parse_integer_as_value (GKeyFile *key_file,
+ gint value);
+static gdouble g_key_file_parse_value_as_double (GKeyFile *key_file,
+ const gchar *value,
+ GError **error);
+static gboolean g_key_file_parse_value_as_boolean (GKeyFile *key_file,
+ const gchar *value,
+ GError **error);
+static gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file,
+ gboolean value);
+static gchar *g_key_file_parse_value_as_comment (GKeyFile *key_file,
+ const gchar *value);
+static gchar *g_key_file_parse_comment_as_value (GKeyFile *key_file,
+ const gchar *comment);
+static void g_key_file_parse_key_value_pair (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error);
+static void g_key_file_parse_comment (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error);
+static void g_key_file_parse_group (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error);
+static gchar *key_get_locale (const gchar *key);
+static void g_key_file_parse_data (GKeyFile *key_file,
+ const gchar *data,
+ gsize length,
+ GError **error);
+static void g_key_file_flush_parse_buffer (GKeyFile *key_file,
+ GError **error);
+
+
+GQuark
+g_key_file_error_quark (void)
+{
+ return g_quark_from_static_string ("g-key-file-error-quark");
+}
+
+static void
+g_key_file_init (GKeyFile *key_file)
+{
+ key_file->current_group = g_slice_new0 (GKeyFileGroup);
+ key_file->groups = g_list_prepend (NULL, key_file->current_group);
+ key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ key_file->start_group = NULL;
+ key_file->parse_buffer = g_string_sized_new (128);
+ key_file->approximate_size = 0;
+ key_file->list_separator = ';';
+ key_file->flags = 0;
+ key_file->locales = g_strdupv ((gchar **)g_get_language_names ());
+}
+
+static void
+g_key_file_clear (GKeyFile *key_file)
+{
+ GList *tmp, *group_node;
+
+ if (key_file->locales)
+ {
+ g_strfreev (key_file->locales);
+ key_file->locales = NULL;
+ }
+
+ if (key_file->parse_buffer)
+ {
+ g_string_free (key_file->parse_buffer, TRUE);
+ key_file->parse_buffer = NULL;
+ }
+
+ tmp = key_file->groups;
+ while (tmp != NULL)
+ {
+ group_node = tmp;
+ tmp = tmp->next;
+ g_key_file_remove_group_node (key_file, group_node);
+ }
+
+ g_hash_table_destroy (key_file->group_hash);
+ key_file->group_hash = NULL;
+
+ g_warn_if_fail (key_file->groups == NULL);
+}
+
+
+/**
+ * g_key_file_new:
+ *
+ * Creates a new empty #GKeyFile object. Use
+ * g_key_file_load_from_file(), g_key_file_load_from_data(),
+ * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to
+ * read an existing key file.
+ *
+ * Return value: an empty #GKeyFile.
+ *
+ * Since: 2.6
+ **/
+GKeyFile *
+g_key_file_new (void)
+{
+ GKeyFile *key_file;
+
+ key_file = g_slice_new0 (GKeyFile);
+ g_key_file_init (key_file);
+
+ return key_file;
+}
+
+/**
+ * g_key_file_set_list_separator:
+ * @key_file: a #GKeyFile
+ * @separator: the separator
+ *
+ * Sets the character which is used to separate
+ * values in lists. Typically ';' or ',' are used
+ * as separators. The default list separator is ';'.
+ *
+ * Since: 2.6
+ */
+void
+g_key_file_set_list_separator (GKeyFile *key_file,
+ gchar separator)
+{
+ g_return_if_fail (key_file != NULL);
+
+ key_file->list_separator = separator;
+}
+
+
+/* Iterates through all the directories in *dirs trying to
+ * open file. When it successfully locates and opens a file it
+ * returns the file descriptor to the open file. It also
+ * outputs the absolute path of the file in output_file.
+ */
+static gint
+find_file_in_data_dirs (const gchar *file,
+ const gchar **dirs,
+ gchar **output_file,
+ GError **error)
+{
+ const gchar **data_dirs, *data_dir;
+ gchar *path;
+ gint fd;
+
+ path = NULL;
+ fd = -1;
+
+ if (dirs == NULL)
+ return fd;
+
+ data_dirs = dirs;
+
+ while (data_dirs && (data_dir = *data_dirs) && fd < 0)
+ {
+ gchar *candidate_file, *sub_dir;
+
+ candidate_file = (gchar *) file;
+ sub_dir = g_strdup ("");
+ while (candidate_file != NULL && fd < 0)
+ {
+ gchar *p;
+
+ path = g_build_filename (data_dir, sub_dir,
+ candidate_file, NULL);
+
+ fd = g_open (path, O_RDONLY, 0);
+
+ if (fd < 0)
+ {
+ g_free (path);
+ path = NULL;
+ }
+
+ candidate_file = strchr (candidate_file, '-');
+
+ if (candidate_file == NULL)
+ break;
+
+ candidate_file++;
+
+ g_free (sub_dir);
+ sub_dir = g_strndup (file, candidate_file - file - 1);
+
+ for (p = sub_dir; *p != '\0'; p++)
+ {
+ if (*p == '-')
+ *p = G_DIR_SEPARATOR;
+ }
+ }
+ g_free (sub_dir);
+ data_dirs++;
+ }
+
+ if (fd < 0)
+ {
+ g_set_error_literal (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_NOT_FOUND,
+ _("Valid key file could not be "
+ "found in search dirs"));
+ }
+
+ if (output_file != NULL && fd > 0)
+ *output_file = g_strdup (path);
+
+ g_free (path);
+
+ return fd;
+}
+
+static gboolean
+g_key_file_load_from_fd (GKeyFile *key_file,
+ gint fd,
+ GKeyFileFlags flags,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ gssize bytes_read;
+ struct stat stat_buf;
+ gchar read_buf[4096];
+
+ if (fstat (fd, &stat_buf) < 0)
+ {
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ if (!S_ISREG (stat_buf.st_mode))
+ {
+ g_set_error_literal (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_PARSE,
+ _("Not a regular file"));
+ return FALSE;
+ }
+
+ if (stat_buf.st_size == 0)
+ {
+ g_set_error_literal (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_PARSE,
+ _("File is empty"));
+ return FALSE;
+ }
+
+ if (key_file->approximate_size > 0)
+ {
+ g_key_file_clear (key_file);
+ g_key_file_init (key_file);
+ }
+ key_file->flags = flags;
+
+ bytes_read = 0;
+ do
+ {
+ bytes_read = read (fd, read_buf, 4096);
+
+ if (bytes_read == 0) /* End of File */
+ break;
+
+ if (bytes_read < 0)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ g_key_file_parse_data (key_file,
+ read_buf, bytes_read,
+ &key_file_error);
+ }
+ while (!key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return FALSE;
+ }
+
+ g_key_file_flush_parse_buffer (key_file, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * g_key_file_load_from_file:
+ * @key_file: an empty #GKeyFile struct
+ * @file: the path of a filename to load, in the GLib filename encoding
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a key file into an empty #GKeyFile structure.
+ * If the file could not be loaded then %error is set to
+ * either a #GFileError or #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_load_from_file (GKeyFile *key_file,
+ const gchar *file,
+ GKeyFileFlags flags,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ gint fd;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (file != NULL, FALSE);
+
+ fd = g_open (file, O_RDONLY, 0);
+
+ if (fd < 0)
+ {
+ g_set_error_literal (error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ g_key_file_load_from_fd (key_file, fd, flags, &key_file_error);
+ close (fd);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * g_key_file_load_from_data:
+ * @key_file: an empty #GKeyFile struct
+ * @data: key file loaded in memory
+ * @length: the length of @data in bytes
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a key file from memory into an empty #GKeyFile structure.
+ * If the object cannot be created then %error is set to a #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_load_from_data (GKeyFile *key_file,
+ const gchar *data,
+ gsize length,
+ GKeyFileFlags flags,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (length != 0, FALSE);
+
+ if (length == (gsize)-1)
+ length = strlen (data);
+
+ if (key_file->approximate_size > 0)
+ {
+ g_key_file_clear (key_file);
+ g_key_file_init (key_file);
+ }
+ key_file->flags = flags;
+
+ g_key_file_parse_data (key_file, data, length, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return FALSE;
+ }
+
+ g_key_file_flush_parse_buffer (key_file, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * g_key_file_load_from_dirs:
+ * @key_file: an empty #GKeyFile struct
+ * @file: a relative path to a filename to open and parse
+ * @search_dirs: %NULL-terminated array of directories to search
+ * @full_path: return location for a string containing the full path
+ * of the file, or %NULL
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function looks for a key file named @file in the paths
+ * specified in @search_dirs, loads the file into @key_file and
+ * returns the file's full path in @full_path. If the file could not
+ * be loaded then an %error is set to either a #GFileError or
+ * #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_key_file_load_from_dirs (GKeyFile *key_file,
+ const gchar *file,
+ const gchar **search_dirs,
+ gchar **full_path,
+ GKeyFileFlags flags,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ const gchar **data_dirs;
+ gchar *output_path;
+ gint fd;
+ gboolean found_file;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
+ g_return_val_if_fail (search_dirs != NULL, FALSE);
+
+ found_file = FALSE;
+ data_dirs = search_dirs;
+ output_path = NULL;
+ while (*data_dirs != NULL && !found_file)
+ {
+ g_free (output_path);
+
+ fd = find_file_in_data_dirs (file, data_dirs, &output_path,
+ &key_file_error);
+
+ if (fd < 0)
+ {
+ if (key_file_error)
+ g_propagate_error (error, key_file_error);
+ break;
+ }
+
+ found_file = g_key_file_load_from_fd (key_file, fd, flags,
+ &key_file_error);
+ close (fd);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ break;
+ }
+ }
+
+ if (found_file && full_path)
+ *full_path = output_path;
+ else
+ g_free (output_path);
+
+ return found_file;
+}
+
+/**
+ * g_key_file_load_from_data_dirs:
+ * @key_file: an empty #GKeyFile struct
+ * @file: a relative path to a filename to open and parse
+ * @full_path: return location for a string containing the full path
+ * of the file, or %NULL
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function looks for a key file named @file in the paths
+ * returned from g_get_user_data_dir() and g_get_system_data_dirs(),
+ * loads the file into @key_file and returns the file's full path in
+ * @full_path. If the file could not be loaded then an %error is
+ * set to either a #GFileError or #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE othewise
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_load_from_data_dirs (GKeyFile *key_file,
+ const gchar *file,
+ gchar **full_path,
+ GKeyFileFlags flags,
+ GError **error)
+{
+ gchar **all_data_dirs;
+ const gchar * user_data_dir;
+ const gchar * const * system_data_dirs;
+ gsize i, j;
+ gboolean found_file;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
+
+ user_data_dir = g_get_user_data_dir ();
+ system_data_dirs = g_get_system_data_dirs ();
+ all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);
+
+ i = 0;
+ all_data_dirs[i++] = g_strdup (user_data_dir);
+
+ j = 0;
+ while (system_data_dirs[j] != NULL)
+ all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
+ all_data_dirs[i] = NULL;
+
+ found_file = g_key_file_load_from_dirs (key_file,
+ file,
+ (const gchar **)all_data_dirs,
+ full_path,
+ flags,
+ error);
+
+ g_strfreev (all_data_dirs);
+
+ return found_file;
+}
+
+/**
+ * g_key_file_free:
+ * @key_file: a #GKeyFile
+ *
+ * Frees a #GKeyFile.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_free (GKeyFile *key_file)
+{
+ g_return_if_fail (key_file != NULL);
+
+ g_key_file_clear (key_file);
+ g_slice_free (GKeyFile, key_file);
+}
+
+/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
+ * true for locales that match those in g_get_language_names().
+ */
+static gboolean
+g_key_file_locale_is_interesting (GKeyFile *key_file,
+ const gchar *locale)
+{
+ gsize i;
+
+ if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS)
+ return TRUE;
+
+ for (i = 0; key_file->locales[i] != NULL; i++)
+ {
+ if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+g_key_file_parse_line (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error)
+{
+ GError *parse_error = NULL;
+ gchar *line_start;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (line != NULL);
+
+ line_start = (gchar *) line;
+ while (g_ascii_isspace (*line_start))
+ line_start++;
+
+ if (g_key_file_line_is_comment (line_start))
+ g_key_file_parse_comment (key_file, line, length, &parse_error);
+ else if (g_key_file_line_is_group (line_start))
+ g_key_file_parse_group (key_file, line_start,
+ length - (line_start - line),
+ &parse_error);
+ else if (g_key_file_line_is_key_value_pair (line_start))
+ g_key_file_parse_key_value_pair (key_file, line_start,
+ length - (line_start - line),
+ &parse_error);
+ else
+ {
+ gchar *line_utf8 = _g_utf8_make_valid (line);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_PARSE,
+ _("Key file contains line '%s' which is not "
+ "a key-value pair, group, or comment"),
+ line_utf8);
+ g_free (line_utf8);
+
+ return;
+ }
+
+ if (parse_error)
+ g_propagate_error (error, parse_error);
+}
+
+static void
+g_key_file_parse_comment (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error)
+{
+ GKeyFileKeyValuePair *pair;
+
+ if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS))
+ return;
+
+ g_warn_if_fail (key_file->current_group != NULL);
+
+ pair = g_slice_new (GKeyFileKeyValuePair);
+ pair->key = NULL;
+ pair->value = g_strndup (line, length);
+
+ key_file->current_group->key_value_pairs =
+ g_list_prepend (key_file->current_group->key_value_pairs, pair);
+
+ if (length == 0 || line[0] != '#')
+ key_file->current_group->has_trailing_blank_line = TRUE;
+}
+
+static void
+g_key_file_parse_group (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error)
+{
+ gchar *group_name;
+ const gchar *group_name_start, *group_name_end;
+
+ /* advance past opening '['
+ */
+ group_name_start = line + 1;
+ group_name_end = line + length - 1;
+
+ while (*group_name_end != ']')
+ group_name_end--;
+
+ group_name = g_strndup (group_name_start,
+ group_name_end - group_name_start);
+
+ if (!g_key_file_is_group_name (group_name))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_PARSE,
+ _("Invalid group name: %s"), group_name);
+ g_free (group_name);
+ return;
+ }
+
+ g_key_file_add_group (key_file, group_name);
+ g_free (group_name);
+}
+
+static void
+g_key_file_parse_key_value_pair (GKeyFile *key_file,
+ const gchar *line,
+ gsize length,
+ GError **error)
+{
+ gchar *key, *value, *key_end, *value_start, *locale;
+ gsize key_len, value_len;
+
+ if (key_file->current_group == NULL || key_file->current_group->name == NULL)
+ {
+ g_set_error_literal (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not start with a group"));
+ return;
+ }
+
+ key_end = value_start = strchr (line, '=');
+
+ g_warn_if_fail (key_end != NULL);
+
+ key_end--;
+ value_start++;
+
+ /* Pull the key name from the line (chomping trailing whitespace)
+ */
+ while (g_ascii_isspace (*key_end))
+ key_end--;
+
+ key_len = key_end - line + 2;
+
+ g_warn_if_fail (key_len <= length);
+
+ key = g_strndup (line, key_len - 1);
+
+ if (!g_key_file_is_key_name (key))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_PARSE,
+ _("Invalid key name: %s"), key);
+ g_free (key);
+ return;
+ }
+
+ /* Pull the value from the line (chugging leading whitespace)
+ */
+ while (g_ascii_isspace (*value_start))
+ value_start++;
+
+ value_len = line + length - value_start + 1;
+
+ value = g_strndup (value_start, value_len);
+
+ g_warn_if_fail (key_file->start_group != NULL);
+
+ if (key_file->current_group
+ && key_file->current_group->name
+ && strcmp (key_file->start_group->name,
+ key_file->current_group->name) == 0
+ && strcmp (key, "Encoding") == 0)
+ {
+ if (g_ascii_strcasecmp (value, "UTF-8") != 0)
+ {
+ gchar *value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+ _("Key file contains unsupported "
+ "encoding '%s'"), value_utf8);
+ g_free (value_utf8);
+
+ g_free (key);
+ g_free (value);
+ return;
+ }
+ }
+
+ /* Is this key a translation? If so, is it one that we care about?
+ */
+ locale = key_get_locale (key);
+
+ if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
+ g_key_file_add_key (key_file, key_file->current_group, key, value);
+
+ g_free (locale);
+ g_free (key);
+ g_free (value);
+}
+
+static gchar *
+key_get_locale (const gchar *key)
+{
+ gchar *locale;
+
+ locale = g_strrstr (key, "[");
+
+ if (locale && strlen (locale) <= 2)
+ locale = NULL;
+
+ if (locale)
+ locale = g_strndup (locale + 1, strlen (locale) - 2);
+
+ return locale;
+}
+
+static void
+g_key_file_parse_data (GKeyFile *key_file,
+ const gchar *data,
+ gsize length,
+ GError **error)
+{
+ GError *parse_error;
+ gsize i;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (data != NULL);
+
+ parse_error = NULL;
+
+ for (i = 0; i < length; i++)
+ {
+ if (data[i] == '\n')
+ {
+ if (i > 0 && data[i - 1] == '\r')
+ g_string_erase (key_file->parse_buffer,
+ key_file->parse_buffer->len - 1,
+ 1);
+
+ /* When a newline is encountered flush the parse buffer so that the
+ * line can be parsed. Note that completely blank lines won't show
+ * up in the parse buffer, so they get parsed directly.
+ */
+ if (key_file->parse_buffer->len > 0)
+ g_key_file_flush_parse_buffer (key_file, &parse_error);
+ else
+ g_key_file_parse_comment (key_file, "", 1, &parse_error);
+
+ if (parse_error)
+ {
+ g_propagate_error (error, parse_error);
+ return;
+ }
+ }
+ else
+ g_string_append_c (key_file->parse_buffer, data[i]);
+ }
+
+ key_file->approximate_size += length;
+}
+
+static void
+g_key_file_flush_parse_buffer (GKeyFile *key_file,
+ GError **error)
+{
+ GError *file_error = NULL;
+
+ g_return_if_fail (key_file != NULL);
+
+ file_error = NULL;
+
+ if (key_file->parse_buffer->len > 0)
+ {
+ g_key_file_parse_line (key_file, key_file->parse_buffer->str,
+ key_file->parse_buffer->len,
+ &file_error);
+ g_string_erase (key_file->parse_buffer, 0, -1);
+
+ if (file_error)
+ {
+ g_propagate_error (error, file_error);
+ return;
+ }
+ }
+}
+
+/**
+ * g_key_file_to_data:
+ * @key_file: a #GKeyFile
+ * @length: return location for the length of the
+ * returned string, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function outputs @key_file as a string.
+ *
+ * Note that this function never reports an error,
+ * so it is safe to pass %NULL as @error.
+ *
+ * Return value: a newly allocated string holding
+ * the contents of the #GKeyFile
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_to_data (GKeyFile *key_file,
+ gsize *length,
+ GError **error)
+{
+ GString *data_string;
+ GList *group_node, *key_file_node;
+ gboolean has_blank_line = TRUE;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+
+ data_string = g_string_sized_new (2 * key_file->approximate_size);
+
+ for (group_node = g_list_last (key_file->groups);
+ group_node != NULL;
+ group_node = group_node->prev)
+ {
+ GKeyFileGroup *group;
+
+ group = (GKeyFileGroup *) group_node->data;
+
+ /* separate groups by at least an empty line */
+ if (!has_blank_line)
+ g_string_append_c (data_string, '\n');
+ has_blank_line = group->has_trailing_blank_line;
+
+ if (group->comment != NULL)
+ g_string_append_printf (data_string, "%s\n", group->comment->value);
+
+ if (group->name != NULL)
+ g_string_append_printf (data_string, "[%s]\n", group->name);
+
+ for (key_file_node = g_list_last (group->key_value_pairs);
+ key_file_node != NULL;
+ key_file_node = key_file_node->prev)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) key_file_node->data;
+
+ if (pair->key != NULL)
+ g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value);
+ else
+ g_string_append_printf (data_string, "%s\n", pair->value);
+ }
+ }
+
+ if (length)
+ *length = data_string->len;
+
+ return g_string_free (data_string, FALSE);
+}
+
+/**
+ * g_key_file_get_keys:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @length: return location for the number of keys returned, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns all keys for the group name @group_name. The array of
+ * returned keys will be %NULL-terminated, so @length may
+ * optionally be %NULL. In the event that the @group_name cannot
+ * be found, %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a newly-allocated %NULL-terminated array of strings.
+ * Use g_strfreev() to free it.
+ *
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_keys (GKeyFile *key_file,
+ const gchar *group_name,
+ gsize *length,
+ GError **error)
+{
+ GKeyFileGroup *group;
+ GList *tmp;
+ gchar **keys;
+ gsize i, num_keys;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ group = g_key_file_lookup_group (key_file, group_name);
+
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+ return NULL;
+ }
+
+ num_keys = 0;
+ for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (pair->key)
+ num_keys++;
+ }
+
+ keys = g_new (gchar *, num_keys + 1);
+
+ i = num_keys - 1;
+ for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (pair->key)
+ {
+ keys[i] = g_strdup (pair->key);
+ i--;
+ }
+ }
+
+ keys[num_keys] = NULL;
+
+ if (length)
+ *length = num_keys;
+
+ return keys;
+}
+
+/**
+ * g_key_file_get_start_group:
+ * @key_file: a #GKeyFile
+ *
+ * Returns the name of the start group of the file.
+ *
+ * Return value: The start group of the key file.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_start_group (GKeyFile *key_file)
+{
+ g_return_val_if_fail (key_file != NULL, NULL);
+
+ if (key_file->start_group)
+ return g_strdup (key_file->start_group->name);
+
+ return NULL;
+}
+
+/**
+ * g_key_file_get_groups:
+ * @key_file: a #GKeyFile
+ * @length: return location for the number of returned groups, or %NULL
+ *
+ * Returns all groups in the key file loaded with @key_file.
+ * The array of returned groups will be %NULL-terminated, so
+ * @length may optionally be %NULL.
+ *
+ * Return value: a newly-allocated %NULL-terminated array of strings.
+ * Use g_strfreev() to free it.
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_groups (GKeyFile *key_file,
+ gsize *length)
+{
+ GList *group_node;
+ gchar **groups;
+ gsize i, num_groups;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+
+ num_groups = g_list_length (key_file->groups);
+
+ g_return_val_if_fail (num_groups > 0, NULL);
+
+ group_node = g_list_last (key_file->groups);
+
+ g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL);
+
+ /* Only need num_groups instead of num_groups + 1
+ * because the first group of the file (last in the
+ * list) is always the comment group at the top,
+ * which we skip
+ */
+ groups = g_new (gchar *, num_groups);
+
+
+ i = 0;
+ for (group_node = group_node->prev;
+ group_node != NULL;
+ group_node = group_node->prev)
+ {
+ GKeyFileGroup *group;
+
+ group = (GKeyFileGroup *) group_node->data;
+
+ g_warn_if_fail (group->name != NULL);
+
+ groups[i++] = g_strdup (group->name);
+ }
+ groups[i] = NULL;
+
+ if (length)
+ *length = i;
+
+ return groups;
+}
+
+/**
+ * g_key_file_get_value:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the raw value associated with @key under @group_name.
+ * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string.
+ *
+ * In the event the key cannot be found, %NULL is returned and
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the
+ * event that the @group_name cannot be found, %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ * key cannot be found.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_value (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
+ gchar *value = NULL;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ group = g_key_file_lookup_group (key_file, group_name);
+
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+ return NULL;
+ }
+
+ pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+ if (pair)
+ value = g_strdup (pair->value);
+ else
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+ _("Key file does not have key '%s'"), key);
+
+ return value;
+}
+
+/**
+ * g_key_file_set_value:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: a string
+ *
+ * Associates a new value with @key under @group_name.
+ *
+ * If @key cannot be found then it is created. If @group_name cannot
+ * be found then it is created. To set an UTF-8 string which may contain
+ * characters that need escaping (such as newlines or spaces), use
+ * g_key_file_set_string().
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_value (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *value)
+{
+ GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (g_key_file_is_group_name (group_name));
+ g_return_if_fail (g_key_file_is_key_name (key));
+ g_return_if_fail (value != NULL);
+
+ group = g_key_file_lookup_group (key_file, group_name);
+
+ if (!group)
+ {
+ g_key_file_add_group (key_file, group_name);
+ group = (GKeyFileGroup *) key_file->groups->data;
+
+ g_key_file_add_key (key_file, group, key, value);
+ }
+ else
+ {
+ pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+ if (!pair)
+ g_key_file_add_key (key_file, group, key, value);
+ else
+ {
+ g_free (pair->value);
+ pair->value = g_strdup (value);
+ }
+ }
+}
+
+/**
+ * g_key_file_get_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the string value associated with @key under @group_name.
+ * Unlike g_key_file_get_value(), this function handles escape sequences
+ * like \s.
+ *
+ * In the event the key cannot be found, %NULL is returned and
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the
+ * event that the @group_name cannot be found, %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ * key cannot be found.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ gchar *value, *string_value;
+ GError *key_file_error;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ key_file_error = NULL;
+
+ value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return NULL;
+ }
+
+ if (!g_utf8_validate (value, -1, NULL))
+ {
+ gchar *value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+ _("Key file contains key '%s' with value '%s' "
+ "which is not UTF-8"), key, value_utf8);
+ g_free (value_utf8);
+ g_free (value);
+
+ return NULL;
+ }
+
+ string_value = g_key_file_parse_value_as_string (key_file, value, NULL,
+ &key_file_error);
+ g_free (value);
+
+ if (key_file_error)
+ {
+ if (g_error_matches (key_file_error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains key '%s' "
+ "which has value that cannot be interpreted."),
+ key);
+ g_error_free (key_file_error);
+ }
+ else
+ g_propagate_error (error, key_file_error);
+ }
+
+ return string_value;
+}
+
+/**
+ * g_key_file_set_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @string: a string
+ *
+ * Associates a new string value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ * If @group_name cannot be found then it is created.
+ * Unlike g_key_file_set_value(), this function handles characters
+ * that need escaping, such as newlines.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *string)
+{
+ gchar *value;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (string != NULL);
+
+ value = g_key_file_parse_string_as_value (key_file, string, FALSE);
+ g_key_file_set_value (key_file, group_name, key, value);
+ g_free (value);
+}
+
+/**
+ * g_key_file_get_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: return location for the number of returned strings, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the values associated with @key under @group_name.
+ *
+ * In the event the key cannot be found, %NULL is returned and
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the
+ * event that the @group_name cannot be found, %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a %NULL-terminated string array or %NULL if the specified
+ * key cannot be found. The array should be freed with g_strfreev().
+ *
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ gchar *value, *string_value, **values;
+ gint i, len;
+ GSList *p, *pieces = NULL;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ if (length)
+ *length = 0;
+
+ value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return NULL;
+ }
+
+ if (!g_utf8_validate (value, -1, NULL))
+ {
+ gchar *value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+ _("Key file contains key '%s' with value '%s' "
+ "which is not UTF-8"), key, value_utf8);
+ g_free (value_utf8);
+ g_free (value);
+
+ return NULL;
+ }
+
+ string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error);
+ g_free (value);
+ g_free (string_value);
+
+ if (key_file_error)
+ {
+ if (g_error_matches (key_file_error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains key '%s' "
+ "which has value that cannot be interpreted."),
+ key);
+ g_error_free (key_file_error);
+ }
+ else
+ g_propagate_error (error, key_file_error);
+
+ return NULL;
+ }
+
+ len = g_slist_length (pieces);
+ values = g_new (gchar *, len + 1);
+ for (p = pieces, i = 0; p; p = p->next)
+ values[i++] = p->data;
+ values[len] = NULL;
+
+ g_slist_free (pieces);
+
+ if (length)
+ *length = len;
+
+ return values;
+}
+
+/**
+ * g_key_file_set_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of string values
+ * @length: number of string values in @list
+ *
+ * Associates a list of string values for @key under @group_name.
+ * If @key cannot be found then it is created.
+ * If @group_name cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar * const list[],
+ gsize length)
+{
+ GString *value_list;
+ gsize i;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (list != NULL);
+
+ value_list = g_string_sized_new (length * 128);
+ for (i = 0; i < length && list[i] != NULL; i++)
+ {
+ gchar *value;
+
+ value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
+ g_string_append (value_list, value);
+ g_string_append_c (value_list, key_file->list_separator);
+
+ g_free (value);
+ }
+
+ g_key_file_set_value (key_file, group_name, key, value_list->str);
+ g_string_free (value_list, TRUE);
+}
+
+/**
+ * g_key_file_set_locale_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier
+ * @string: a string
+ *
+ * Associates a string value for @key and @locale under @group_name.
+ * If the translation for @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_locale_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ const gchar *string)
+{
+ gchar *full_key, *value;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (locale != NULL);
+ g_return_if_fail (string != NULL);
+
+ value = g_key_file_parse_string_as_value (key_file, string, FALSE);
+ full_key = g_strdup_printf ("%s[%s]", key, locale);
+ g_key_file_set_value (key_file, group_name, full_key, value);
+ g_free (full_key);
+ g_free (value);
+}
+
+extern GSList *_g_compute_locale_variants (const gchar *locale);
+
+/**
+ * g_key_file_get_locale_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the value associated with @key under @group_name
+ * translated in the given @locale if available. If @locale is
+ * %NULL then the current locale is assumed.
+ *
+ * If @key cannot be found then %NULL is returned and @error is set
+ * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated
+ * with @key cannot be interpreted or no suitable translation can
+ * be found then the untranslated value is returned.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ * key cannot be found.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_locale_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ GError **error)
+{
+ gchar *candidate_key, *translated_value;
+ GError *key_file_error;
+ gchar **languages;
+ gboolean free_languages = FALSE;
+ gint i;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ candidate_key = NULL;
+ translated_value = NULL;
+ key_file_error = NULL;
+
+ if (locale)
+ {
+ GSList *l, *list;
+
+ list = _g_compute_locale_variants (locale);
+
+ languages = g_new (gchar *, g_slist_length (list) + 1);
+ for (l = list, i = 0; l; l = l->next, i++)
+ languages[i] = l->data;
+ languages[i] = NULL;
+
+ g_slist_free (list);
+ free_languages = TRUE;
+ }
+ else
+ {
+ languages = (gchar **) g_get_language_names ();
+ free_languages = FALSE;
+ }
+
+ for (i = 0; languages[i]; i++)
+ {
+ candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
+
+ translated_value = g_key_file_get_string (key_file,
+ group_name,
+ candidate_key, NULL);
+ g_free (candidate_key);
+
+ if (translated_value)
+ break;
+
+ g_free (translated_value);
+ translated_value = NULL;
+ }
+
+ /* Fallback to untranslated key
+ */
+ if (!translated_value)
+ {
+ translated_value = g_key_file_get_string (key_file, group_name, key,
+ &key_file_error);
+
+ if (!translated_value)
+ g_propagate_error (error, key_file_error);
+ }
+
+ if (free_languages)
+ g_strfreev (languages);
+
+ return translated_value;
+}
+
+/**
+ * g_key_file_get_locale_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier or %NULL
+ * @length: return location for the number of returned strings or %NULL
+ * @error: return location for a #GError or %NULL
+ *
+ * Returns the values associated with @key under @group_name
+ * translated in the given @locale if available. If @locale is
+ * %NULL then the current locale is assumed.
+
+ * If @key cannot be found then %NULL is returned and @error is set
+ * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
+ * with @key cannot be interpreted or no suitable translations
+ * can be found then the untranslated values are returned. The
+ * returned array is %NULL-terminated, so @length may optionally
+ * be %NULL.
+ *
+ * Return value: a newly allocated %NULL-terminated string array
+ * or %NULL if the key isn't found. The string array should be freed
+ * with g_strfreev().
+ *
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_locale_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ gsize *length,
+ GError **error)
+{
+ GError *key_file_error;
+ gchar **values, *value;
+ char list_separator[2];
+ gsize len;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ key_file_error = NULL;
+
+ value = g_key_file_get_locale_string (key_file, group_name,
+ key, locale,
+ &key_file_error);
+
+ if (key_file_error)
+ g_propagate_error (error, key_file_error);
+
+ if (!value)
+ {
+ if (length)
+ *length = 0;
+ return NULL;
+ }
+
+ len = strlen (value);
+ if (value[len - 1] == key_file->list_separator)
+ value[len - 1] = '\0';
+
+ list_separator[0] = key_file->list_separator;
+ list_separator[1] = '\0';
+ values = g_strsplit (value, list_separator, 0);
+
+ g_free (value);
+
+ if (length)
+ *length = g_strv_length (values);
+
+ return values;
+}
+
+/**
+ * g_key_file_set_locale_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier
+ * @list: a %NULL-terminated array of locale string values
+ * @length: the length of @list
+ *
+ * Associates a list of string values for @key and @locale under
+ * @group_name. If the translation for @key cannot be found then
+ * it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_locale_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ const gchar * const list[],
+ gsize length)
+{
+ GString *value_list;
+ gchar *full_key;
+ gsize i;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (locale != NULL);
+ g_return_if_fail (length != 0);
+
+ value_list = g_string_sized_new (length * 128);
+ for (i = 0; i < length && list[i] != NULL; i++)
+ {
+ gchar *value;
+
+ value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
+ g_string_append (value_list, value);
+ g_string_append_c (value_list, key_file->list_separator);
+
+ g_free (value);
+ }
+
+ full_key = g_strdup_printf ("%s[%s]", key, locale);
+ g_key_file_set_value (key_file, group_name, full_key, value_list->str);
+ g_free (full_key);
+ g_string_free (value_list, TRUE);
+}
+
+/**
+ * g_key_file_get_boolean:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as a
+ * boolean.
+ *
+ * If @key cannot be found then %FALSE is returned and @error is set
+ * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value
+ * associated with @key cannot be interpreted as a boolean then %FALSE
+ * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as a boolean,
+ * or %FALSE if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_get_boolean (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ gchar *value;
+ gboolean bool_value;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (group_name != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+ if (!value)
+ {
+ g_propagate_error (error, key_file_error);
+ return FALSE;
+ }
+
+ bool_value = g_key_file_parse_value_as_boolean (key_file, value,
+ &key_file_error);
+ g_free (value);
+
+ if (key_file_error)
+ {
+ if (g_error_matches (key_file_error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains key '%s' "
+ "which has value that cannot be interpreted."),
+ key);
+ g_error_free (key_file_error);
+ }
+ else
+ g_propagate_error (error, key_file_error);
+ }
+
+ return bool_value;
+}
+
+/**
+ * g_key_file_set_boolean:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: %TRUE or %FALSE
+ *
+ * Associates a new boolean value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_boolean (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gboolean value)
+{
+ gchar *result;
+
+ g_return_if_fail (key_file != NULL);
+
+ result = g_key_file_parse_boolean_as_value (key_file, value);
+ g_key_file_set_value (key_file, group_name, key, result);
+ g_free (result);
+}
+
+/**
+ * g_key_file_get_boolean_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of booleans returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * booleans.
+ *
+ * If @key cannot be found then %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
+ * with @key cannot be interpreted as booleans then %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a list of
+ * booleans, or %NULL if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gboolean *
+g_key_file_get_boolean_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error)
+{
+ GError *key_file_error;
+ gchar **values;
+ gboolean *bool_values;
+ gsize i, num_bools;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ if (length)
+ *length = 0;
+
+ key_file_error = NULL;
+
+ values = g_key_file_get_string_list (key_file, group_name, key,
+ &num_bools, &key_file_error);
+
+ if (key_file_error)
+ g_propagate_error (error, key_file_error);
+
+ if (!values)
+ return NULL;
+
+ bool_values = g_new (gboolean, num_bools);
+
+ for (i = 0; i < num_bools; i++)
+ {
+ bool_values[i] = g_key_file_parse_value_as_boolean (key_file,
+ values[i],
+ &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ g_strfreev (values);
+ g_free (bool_values);
+
+ return NULL;
+ }
+ }
+ g_strfreev (values);
+
+ if (length)
+ *length = num_bools;
+
+ return bool_values;
+}
+
+/**
+ * g_key_file_set_boolean_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of boolean values
+ * @length: length of @list
+ *
+ * Associates a list of boolean values with @key under @group_name.
+ * If @key cannot be found then it is created.
+ * If @group_name is %NULL, the start_group is used.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_boolean_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gboolean list[],
+ gsize length)
+{
+ GString *value_list;
+ gsize i;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (list != NULL);
+
+ value_list = g_string_sized_new (length * 8);
+ for (i = 0; i < length; i++)
+ {
+ gchar *value;
+
+ value = g_key_file_parse_boolean_as_value (key_file, list[i]);
+
+ g_string_append (value_list, value);
+ g_string_append_c (value_list, key_file->list_separator);
+
+ g_free (value);
+ }
+
+ g_key_file_set_value (key_file, group_name, key, value_list->str);
+ g_string_free (value_list, TRUE);
+}
+
+/**
+ * g_key_file_get_integer:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as an
+ * integer.
+ *
+ * If @key cannot be found then 0 is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
+ * with @key cannot be interpreted as an integer then 0 is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as an integer, or
+ * 0 if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gint
+g_key_file_get_integer (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GError *key_file_error;
+ gchar *value;
+ gint int_value;
+
+ g_return_val_if_fail (key_file != NULL, -1);
+ g_return_val_if_fail (group_name != NULL, -1);
+ g_return_val_if_fail (key != NULL, -1);
+
+ key_file_error = NULL;
+
+ value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return 0;
+ }
+
+ int_value = g_key_file_parse_value_as_integer (key_file, value,
+ &key_file_error);
+ g_free (value);
+
+ if (key_file_error)
+ {
+ if (g_error_matches (key_file_error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains key '%s' in group '%s' "
+ "which has value that cannot be interpreted."), key,
+ group_name);
+ g_error_free (key_file_error);
+ }
+ else
+ g_propagate_error (error, key_file_error);
+ }
+
+ return int_value;
+}
+
+/**
+ * g_key_file_set_integer:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an integer value
+ *
+ * Associates a new integer value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_integer (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gint value)
+{
+ gchar *result;
+
+ g_return_if_fail (key_file != NULL);
+
+ result = g_key_file_parse_integer_as_value (key_file, value);
+ g_key_file_set_value (key_file, group_name, key, result);
+ g_free (result);
+}
+
+/**
+ * g_key_file_get_integer_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of integers returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * integers.
+ *
+ * If @key cannot be found then %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
+ * with @key cannot be interpreted as integers then %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a list of
+ * integers, or %NULL if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gint *
+g_key_file_get_integer_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ gchar **values;
+ gint *int_values;
+ gsize i, num_ints;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ if (length)
+ *length = 0;
+
+ values = g_key_file_get_string_list (key_file, group_name, key,
+ &num_ints, &key_file_error);
+
+ if (key_file_error)
+ g_propagate_error (error, key_file_error);
+
+ if (!values)
+ return NULL;
+
+ int_values = g_new (gint, num_ints);
+
+ for (i = 0; i < num_ints; i++)
+ {
+ int_values[i] = g_key_file_parse_value_as_integer (key_file,
+ values[i],
+ &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ g_strfreev (values);
+ g_free (int_values);
+
+ return NULL;
+ }
+ }
+ g_strfreev (values);
+
+ if (length)
+ *length = num_ints;
+
+ return int_values;
+}
+
+/**
+ * g_key_file_set_integer_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of integer values
+ * @length: number of integer values in @list
+ *
+ * Associates a list of integer values with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_integer_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gint list[],
+ gsize length)
+{
+ GString *values;
+ gsize i;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (list != NULL);
+
+ values = g_string_sized_new (length * 16);
+ for (i = 0; i < length; i++)
+ {
+ gchar *value;
+
+ value = g_key_file_parse_integer_as_value (key_file, list[i]);
+
+ g_string_append (values, value);
+ g_string_append_c (values, key_file->list_separator);
+
+ g_free (value);
+ }
+
+ g_key_file_set_value (key_file, group_name, key, values->str);
+ g_string_free (values, TRUE);
+}
+
+/**
+ * g_key_file_get_double:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as a
+ * double. If @group_name is %NULL, the start_group is used.
+ *
+ * If @key cannot be found then 0.0 is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
+ * with @key cannot be interpreted as a double then 0.0 is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as a double, or
+ * 0.0 if the key was not found or could not be parsed.
+ *
+ * Since: 2.12
+ **/
+gdouble
+g_key_file_get_double (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GError *key_file_error;
+ gchar *value;
+ gdouble double_value;
+
+ g_return_val_if_fail (key_file != NULL, -1);
+ g_return_val_if_fail (group_name != NULL, -1);
+ g_return_val_if_fail (key != NULL, -1);
+
+ key_file_error = NULL;
+
+ value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ return 0;
+ }
+
+ double_value = g_key_file_parse_value_as_double (key_file, value,
+ &key_file_error);
+ g_free (value);
+
+ if (key_file_error)
+ {
+ if (g_error_matches (key_file_error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE))
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains key '%s' in group '%s' "
+ "which has value that cannot be interpreted."), key,
+ group_name);
+ g_error_free (key_file_error);
+ }
+ else
+ g_propagate_error (error, key_file_error);
+ }
+
+ return double_value;
+}
+
+/**
+ * g_key_file_set_double:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an double value
+ *
+ * Associates a new double value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.12
+ **/
+void
+g_key_file_set_double (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gdouble value)
+{
+ gchar result[G_ASCII_DTOSTR_BUF_SIZE];
+
+ g_return_if_fail (key_file != NULL);
+
+ g_ascii_dtostr (result, sizeof (result), value);
+ g_key_file_set_value (key_file, group_name, key, result);
+}
+
+/**
+ * g_key_file_get_double_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of doubles returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * doubles.
+ *
+ * If @key cannot be found then %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
+ * with @key cannot be interpreted as doubles then %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a list of
+ * doubles, or %NULL if the key was not found or could not be parsed.
+ *
+ * Since: 2.12
+ **/
+gdouble *
+g_key_file_get_double_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error)
+{
+ GError *key_file_error = NULL;
+ gchar **values;
+ gdouble *double_values;
+ gsize i, num_doubles;
+
+ g_return_val_if_fail (key_file != NULL, NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ if (length)
+ *length = 0;
+
+ values = g_key_file_get_string_list (key_file, group_name, key,
+ &num_doubles, &key_file_error);
+
+ if (key_file_error)
+ g_propagate_error (error, key_file_error);
+
+ if (!values)
+ return NULL;
+
+ double_values = g_new (gdouble, num_doubles);
+
+ for (i = 0; i < num_doubles; i++)
+ {
+ double_values[i] = g_key_file_parse_value_as_double (key_file,
+ values[i],
+ &key_file_error);
+
+ if (key_file_error)
+ {
+ g_propagate_error (error, key_file_error);
+ g_strfreev (values);
+ g_free (double_values);
+
+ return NULL;
+ }
+ }
+ g_strfreev (values);
+
+ if (length)
+ *length = num_doubles;
+
+ return double_values;
+}
+
+/**
+ * g_key_file_set_double_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of double values
+ * @length: number of double values in @list
+ *
+ * Associates a list of double values with @key under
+ * @group_name. If @key cannot be found then it is created.
+ *
+ * Since: 2.12
+ **/
+void
+g_key_file_set_double_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gdouble list[],
+ gsize length)
+{
+ GString *values;
+ gsize i;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (list != NULL);
+
+ values = g_string_sized_new (length * 16);
+ for (i = 0; i < length; i++)
+ {
+ gchar result[G_ASCII_DTOSTR_BUF_SIZE];
+
+ g_ascii_dtostr( result, sizeof (result), list[i] );
+
+ g_string_append (values, result);
+ g_string_append_c (values, key_file->list_separator);
+ }
+
+ g_key_file_set_value (key_file, group_name, key, values->str);
+ g_string_free (values, TRUE);
+}
+
+static gboolean
+g_key_file_set_key_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *comment,
+ GError **error)
+{
+ GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
+ GList *key_node, *comment_node, *tmp;
+
+ group = g_key_file_lookup_group (key_file, group_name);
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+
+ return FALSE;
+ }
+
+ /* First find the key the comments are supposed to be
+ * associated with
+ */
+ key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
+
+ if (key_node == NULL)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+ _("Key file does not have key '%s' in group '%s'"),
+ key, group->name);
+ return FALSE;
+ }
+
+ /* Then find all the comments already associated with the
+ * key and free them
+ */
+ tmp = key_node->next;
+ while (tmp != NULL)
+ {
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (pair->key != NULL)
+ break;
+
+ comment_node = tmp;
+ tmp = tmp->next;
+ g_key_file_remove_key_value_pair_node (key_file, group,
+ comment_node);
+ }
+
+ if (comment == NULL)
+ return TRUE;
+
+ /* Now we can add our new comment
+ */
+ pair = g_slice_new (GKeyFileKeyValuePair);
+ pair->key = NULL;
+ pair->value = g_key_file_parse_comment_as_value (key_file, comment);
+
+ key_node = g_list_insert (key_node, pair, 1);
+
+ return TRUE;
+}
+
+static gboolean
+g_key_file_set_group_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *comment,
+ GError **error)
+{
+ GKeyFileGroup *group;
+
+ g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE);
+
+ group = g_key_file_lookup_group (key_file, group_name);
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+
+ return FALSE;
+ }
+
+ /* First remove any existing comment
+ */
+ if (group->comment)
+ {
+ g_key_file_key_value_pair_free (group->comment);
+ group->comment = NULL;
+ }
+
+ if (comment == NULL)
+ return TRUE;
+
+ /* Now we can add our new comment
+ */
+ group->comment = g_slice_new (GKeyFileKeyValuePair);
+ group->comment->key = NULL;
+ group->comment->value = g_key_file_parse_comment_as_value (key_file, comment);
+
+ return TRUE;
+}
+
+static gboolean
+g_key_file_set_top_comment (GKeyFile *key_file,
+ const gchar *comment,
+ GError **error)
+{
+ GList *group_node;
+ GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
+
+ /* The last group in the list should be the top (comments only)
+ * group in the file
+ */
+ g_warn_if_fail (key_file->groups != NULL);
+ group_node = g_list_last (key_file->groups);
+ group = (GKeyFileGroup *) group_node->data;
+ g_warn_if_fail (group->name == NULL);
+
+ /* Note all keys must be comments at the top of
+ * the file, so we can just free it all.
+ */
+ if (group->key_value_pairs != NULL)
+ {
+ g_list_foreach (group->key_value_pairs,
+ (GFunc) g_key_file_key_value_pair_free,
+ NULL);
+ g_list_free (group->key_value_pairs);
+ group->key_value_pairs = NULL;
+ }
+
+ if (comment == NULL)
+ return TRUE;
+
+ pair = g_slice_new (GKeyFileKeyValuePair);
+ pair->key = NULL;
+ pair->value = g_key_file_parse_comment_as_value (key_file, comment);
+
+ group->key_value_pairs =
+ g_list_prepend (group->key_value_pairs, pair);
+
+ return TRUE;
+}
+
+/**
+ * g_key_file_set_comment:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name, or %NULL
+ * @key: a key
+ * @comment: a comment
+ * @error: return location for a #GError
+ *
+ * Places a comment above @key from @group_name.
+ * If @key is %NULL then @comment will be written above @group_name.
+ * If both @key and @group_name are %NULL, then @comment will be
+ * written above the first group in the file.
+ *
+ * Returns: %TRUE if the comment was written, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_set_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *comment,
+ GError **error)
+{
+ g_return_val_if_fail (key_file != NULL, FALSE);
+
+ if (group_name != NULL && key != NULL)
+ {
+ if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error))
+ return FALSE;
+ }
+ else if (group_name != NULL)
+ {
+ if (!g_key_file_set_group_comment (key_file, group_name, comment, error))
+ return FALSE;
+ }
+ else
+ {
+ if (!g_key_file_set_top_comment (key_file, comment, error))
+ return FALSE;
+ }
+
+ if (comment != NULL)
+ key_file->approximate_size += strlen (comment);
+
+ return TRUE;
+}
+
+static gchar *
+g_key_file_get_key_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
+ GList *key_node, *tmp;
+ GString *string;
+ gchar *comment;
+
+ g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL);
+
+ group = g_key_file_lookup_group (key_file, group_name);
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+
+ return NULL;
+ }
+
+ /* First find the key the comments are supposed to be
+ * associated with
+ */
+ key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
+
+ if (key_node == NULL)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+ _("Key file does not have key '%s' in group '%s'"),
+ key, group->name);
+ return NULL;
+ }
+
+ string = NULL;
+
+ /* Then find all the comments already associated with the
+ * key and concatentate them.
+ */
+ tmp = key_node->next;
+ if (!key_node->next)
+ return NULL;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+ if (pair->key != NULL)
+ return NULL;
+
+ while (tmp->next)
+ {
+ pair = (GKeyFileKeyValuePair *) tmp->next->data;
+
+ if (pair->key != NULL)
+ break;
+
+ tmp = tmp->next;
+ }
+
+ while (tmp != key_node)
+ {
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (string == NULL)
+ string = g_string_sized_new (512);
+
+ comment = g_key_file_parse_value_as_comment (key_file, pair->value);
+ g_string_append (string, comment);
+ g_free (comment);
+
+ tmp = tmp->prev;
+ }
+
+ if (string != NULL)
+ {
+ comment = string->str;
+ g_string_free (string, FALSE);
+ }
+ else
+ comment = NULL;
+
+ return comment;
+}
+
+static gchar *
+get_group_comment (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ GError **error)
+{
+ GString *string;
+ GList *tmp;
+ gchar *comment;
+
+ string = NULL;
+
+ tmp = group->key_value_pairs;
+ while (tmp)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (pair->key != NULL)
+ {
+ tmp = tmp->prev;
+ break;
+ }
+
+ if (tmp->next == NULL)
+ break;
+
+ tmp = tmp->next;
+ }
+
+ while (tmp != NULL)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (string == NULL)
+ string = g_string_sized_new (512);
+
+ comment = g_key_file_parse_value_as_comment (key_file, pair->value);
+ g_string_append (string, comment);
+ g_free (comment);
+
+ tmp = tmp->prev;
+ }
+
+ if (string != NULL)
+ return g_string_free (string, FALSE);
+
+ return NULL;
+}
+
+static gchar *
+g_key_file_get_group_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ GError **error)
+{
+ GList *group_node;
+ GKeyFileGroup *group;
+
+ group = g_key_file_lookup_group (key_file, group_name);
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+
+ return NULL;
+ }
+
+ if (group->comment)
+ return g_strdup (group->comment->value);
+
+ group_node = g_key_file_lookup_group_node (key_file, group_name);
+ group_node = group_node->next;
+ group = (GKeyFileGroup *)group_node->data;
+ return get_group_comment (key_file, group, error);
+}
+
+static gchar *
+g_key_file_get_top_comment (GKeyFile *key_file,
+ GError **error)
+{
+ GList *group_node;
+ GKeyFileGroup *group;
+
+ /* The last group in the list should be the top (comments only)
+ * group in the file
+ */
+ g_warn_if_fail (key_file->groups != NULL);
+ group_node = g_list_last (key_file->groups);
+ group = (GKeyFileGroup *) group_node->data;
+ g_warn_if_fail (group->name == NULL);
+
+ return get_group_comment (key_file, group, error);
+}
+
+/**
+ * g_key_file_get_comment:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name, or %NULL
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Retrieves a comment above @key from @group_name.
+ * If @key is %NULL then @comment will be read from above
+ * @group_name. If both @key and @group_name are %NULL, then
+ * @comment will be read from above the first group in the file.
+ *
+ * Returns: a comment that should be freed with g_free()
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ g_return_val_if_fail (key_file != NULL, NULL);
+
+ if (group_name != NULL && key != NULL)
+ return g_key_file_get_key_comment (key_file, group_name, key, error);
+ else if (group_name != NULL)
+ return g_key_file_get_group_comment (key_file, group_name, error);
+ else
+ return g_key_file_get_top_comment (key_file, error);
+}
+
+/**
+ * g_key_file_remove_comment:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name, or %NULL
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Removes a comment above @key from @group_name.
+ * If @key is %NULL then @comment will be removed above @group_name.
+ * If both @key and @group_name are %NULL, then @comment will
+ * be removed above the first group in the file.
+ *
+ * Returns: %TRUE if the comment was removed, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+
+gboolean
+g_key_file_remove_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ g_return_val_if_fail (key_file != NULL, FALSE);
+
+ if (group_name != NULL && key != NULL)
+ return g_key_file_set_key_comment (key_file, group_name, key, NULL, error);
+ else if (group_name != NULL)
+ return g_key_file_set_group_comment (key_file, group_name, NULL, error);
+ else
+ return g_key_file_set_top_comment (key_file, NULL, error);
+}
+
+/**
+ * g_key_file_has_group:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ *
+ * Looks whether the key file has the group @group_name.
+ *
+ * Return value: %TRUE if @group_name is a part of @key_file, %FALSE
+ * otherwise.
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_has_group (GKeyFile *key_file,
+ const gchar *group_name)
+{
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (group_name != NULL, FALSE);
+
+ return g_key_file_lookup_group (key_file, group_name) != NULL;
+}
+
+/**
+ * g_key_file_has_key:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key name
+ * @error: return location for a #GError
+ *
+ * Looks whether the key file has the key @key in the group
+ * @group_name.
+ *
+ * Return value: %TRUE if @key is a part of @group_name, %FALSE
+ * otherwise.
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_has_key (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GKeyFileKeyValuePair *pair;
+ GKeyFileGroup *group;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (group_name != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ group = g_key_file_lookup_group (key_file, group_name);
+
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+
+ return FALSE;
+ }
+
+ pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+ return pair != NULL;
+}
+
+static void
+g_key_file_add_group (GKeyFile *key_file,
+ const gchar *group_name)
+{
+ GKeyFileGroup *group;
+
+ g_return_if_fail (key_file != NULL);
+ g_return_if_fail (g_key_file_is_group_name (group_name));
+
+ group = g_key_file_lookup_group (key_file, group_name);
+ if (group != NULL)
+ {
+ key_file->current_group = group;
+ return;
+ }
+
+ group = g_slice_new0 (GKeyFileGroup);
+ group->name = g_strdup (group_name);
+ group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
+ key_file->groups = g_list_prepend (key_file->groups, group);
+ key_file->approximate_size += strlen (group_name) + 3;
+ key_file->current_group = group;
+
+ if (key_file->start_group == NULL)
+ key_file->start_group = group;
+
+ g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group);
+}
+
+static void
+g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair)
+{
+ if (pair != NULL)
+ {
+ g_free (pair->key);
+ g_free (pair->value);
+ g_slice_free (GKeyFileKeyValuePair, pair);
+ }
+}
+
+/* Be careful not to call this function on a node with data in the
+ * lookup map without removing it from the lookup map, first.
+ *
+ * Some current cases where this warning is not a concern are
+ * when:
+ * - the node being removed is a comment node
+ * - the entire lookup map is getting destroyed soon after
+ * anyway.
+ */
+static void
+g_key_file_remove_key_value_pair_node (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ GList *pair_node)
+{
+
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) pair_node->data;
+
+ group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node);
+
+ if (pair->key != NULL)
+ key_file->approximate_size -= strlen (pair->key) + 1;
+
+ g_warn_if_fail (pair->value != NULL);
+ key_file->approximate_size -= strlen (pair->value);
+
+ g_key_file_key_value_pair_free (pair);
+
+ g_list_free_1 (pair_node);
+}
+
+static void
+g_key_file_remove_group_node (GKeyFile *key_file,
+ GList *group_node)
+{
+ GKeyFileGroup *group;
+ GList *tmp;
+
+ group = (GKeyFileGroup *) group_node->data;
+
+ if (group->name)
+ g_hash_table_remove (key_file->group_hash, group->name);
+
+ /* If the current group gets deleted make the current group the last
+ * added group.
+ */
+ if (key_file->current_group == group)
+ {
+ /* groups should always contain at least the top comment group,
+ * unless g_key_file_clear has been called
+ */
+ if (key_file->groups)
+ key_file->current_group = (GKeyFileGroup *) key_file->groups->data;
+ else
+ key_file->current_group = NULL;
+ }
+
+ /* If the start group gets deleted make the start group the first
+ * added group.
+ */
+ if (key_file->start_group == group)
+ {
+ tmp = g_list_last (key_file->groups);
+ while (tmp != NULL)
+ {
+ if (tmp != group_node &&
+ ((GKeyFileGroup *) tmp->data)->name != NULL)
+ break;
+
+ tmp = tmp->prev;
+ }
+
+ if (tmp)
+ key_file->start_group = (GKeyFileGroup *) tmp->data;
+ else
+ key_file->start_group = NULL;
+ }
+
+ key_file->groups = g_list_remove_link (key_file->groups, group_node);
+
+ if (group->name != NULL)
+ key_file->approximate_size -= strlen (group->name) + 3;
+
+ tmp = group->key_value_pairs;
+ while (tmp != NULL)
+ {
+ GList *pair_node;
+
+ pair_node = tmp;
+ tmp = tmp->next;
+ g_key_file_remove_key_value_pair_node (key_file, group, pair_node);
+ }
+
+ g_warn_if_fail (group->key_value_pairs == NULL);
+
+ if (group->lookup_map)
+ {
+ g_hash_table_destroy (group->lookup_map);
+ group->lookup_map = NULL;
+ }
+
+ g_free ((gchar *) group->name);
+ g_slice_free (GKeyFileGroup, group);
+ g_list_free_1 (group_node);
+}
+
+/**
+ * g_key_file_remove_group:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @error: return location for a #GError or %NULL
+ *
+ * Removes the specified group, @group_name,
+ * from the key file.
+ *
+ * Returns: %TRUE if the group was removed, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_remove_group (GKeyFile *key_file,
+ const gchar *group_name,
+ GError **error)
+{
+ GList *group_node;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (group_name != NULL, FALSE);
+
+ group_node = g_key_file_lookup_group_node (key_file, group_name);
+
+ if (!group_node)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name);
+ return FALSE;
+ }
+
+ g_key_file_remove_group_node (key_file, group_node);
+
+ return TRUE;
+}
+
+static void
+g_key_file_add_key (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ const gchar *key,
+ const gchar *value)
+{
+ GKeyFileKeyValuePair *pair;
+
+ pair = g_slice_new (GKeyFileKeyValuePair);
+ pair->key = g_strdup (key);
+ pair->value = g_strdup (value);
+
+ g_hash_table_replace (group->lookup_map, pair->key, pair);
+ group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
+ group->has_trailing_blank_line = FALSE;
+ key_file->approximate_size += strlen (key) + strlen (value) + 2;
+}
+
+/**
+ * g_key_file_remove_key:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key name to remove
+ * @error: return location for a #GError or %NULL
+ *
+ * Removes @key in @group_name from the key file.
+ *
+ * Returns: %TRUE if the key was removed, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_remove_key (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error)
+{
+ GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
+
+ g_return_val_if_fail (key_file != NULL, FALSE);
+ g_return_val_if_fail (group_name != NULL, FALSE);
+ g_return_val_if_fail (key != NULL, FALSE);
+
+ pair = NULL;
+
+ group = g_key_file_lookup_group (key_file, group_name);
+ if (!group)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name ? group_name : "(null)");
+ return FALSE;
+ }
+
+ pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+ if (!pair)
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+ _("Key file does not have key '%s' in group '%s'"),
+ key, group->name);
+ return FALSE;
+ }
+
+ key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2;
+
+ group->key_value_pairs = g_list_remove (group->key_value_pairs, pair);
+ g_hash_table_remove (group->lookup_map, pair->key);
+ g_key_file_key_value_pair_free (pair);
+
+ return TRUE;
+}
+
+static GList *
+g_key_file_lookup_group_node (GKeyFile *key_file,
+ const gchar *group_name)
+{
+ GKeyFileGroup *group;
+ GList *tmp;
+
+ for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
+ {
+ group = (GKeyFileGroup *) tmp->data;
+
+ if (group && group->name && strcmp (group->name, group_name) == 0)
+ break;
+ }
+
+ return tmp;
+}
+
+static GKeyFileGroup *
+g_key_file_lookup_group (GKeyFile *key_file,
+ const gchar *group_name)
+{
+ return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name);
+}
+
+static GList *
+g_key_file_lookup_key_value_pair_node (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ const gchar *key)
+{
+ GList *key_node;
+
+ for (key_node = group->key_value_pairs;
+ key_node != NULL;
+ key_node = key_node->next)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) key_node->data;
+
+ if (pair->key && strcmp (pair->key, key) == 0)
+ break;
+ }
+
+ return key_node;
+}
+
+static GKeyFileKeyValuePair *
+g_key_file_lookup_key_value_pair (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ const gchar *key)
+{
+ return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
+}
+
+/* Lines starting with # or consisting entirely of whitespace are merely
+ * recorded, not parsed. This function assumes all leading whitespace
+ * has been stripped.
+ */
+static gboolean
+g_key_file_line_is_comment (const gchar *line)
+{
+ return (*line == '#' || *line == '\0' || *line == '\n');
+}
+
+static gboolean
+g_key_file_is_group_name (const gchar *name)
+{
+ gchar *p, *q;
+
+ if (name == NULL)
+ return FALSE;
+
+ p = q = (gchar *) name;
+ while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
+ q = g_utf8_find_next_char (q, NULL);
+
+ if (*q != '\0' || q == p)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+g_key_file_is_key_name (const gchar *name)
+{
+ gchar *p, *q;
+
+ if (name == NULL)
+ return FALSE;
+
+ p = q = (gchar *) name;
+ /* We accept a little more than the desktop entry spec says,
+ * since gnome-vfs uses mime-types as keys in its cache.
+ */
+ while (*q && *q != '=' && *q != '[' && *q != ']')
+ q = g_utf8_find_next_char (q, NULL);
+
+ /* No empty keys, please */
+ if (q == p)
+ return FALSE;
+
+ /* We accept spaces in the middle of keys to not break
+ * existing apps, but we don't tolerate initial or final
+ * spaces, which would lead to silent corruption when
+ * rereading the file.
+ */
+ if (*p == ' ' || q[-1] == ' ')
+ return FALSE;
+
+ if (*q == '[')
+ {
+ q++;
+ while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
+ q = g_utf8_find_next_char (q, NULL);
+
+ if (*q != ']')
+ return FALSE;
+
+ q++;
+ }
+
+ if (*q != '\0')
+ return FALSE;
+
+ return TRUE;
+}
+
+/* A group in a key file is made up of a starting '[' followed by one
+ * or more letters making up the group name followed by ']'.
+ */
+static gboolean
+g_key_file_line_is_group (const gchar *line)
+{
+ gchar *p;
+
+ p = (gchar *) line;
+ if (*p != '[')
+ return FALSE;
+
+ p++;
+
+ while (*p && *p != ']')
+ p = g_utf8_find_next_char (p, NULL);
+
+ if (*p != ']')
+ return FALSE;
+
+ /* silently accept whitespace after the ] */
+ p = g_utf8_find_next_char (p, NULL);
+ while (*p == ' ' || *p == '\t')
+ p = g_utf8_find_next_char (p, NULL);
+
+ if (*p)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+g_key_file_line_is_key_value_pair (const gchar *line)
+{
+ gchar *p;
+
+ p = (gchar *) g_utf8_strchr (line, -1, '=');
+
+ if (!p)
+ return FALSE;
+
+ /* Key must be non-empty
+ */
+ if (*p == line[0])
+ return FALSE;
+
+ return TRUE;
+}
+
+static gchar *
+g_key_file_parse_value_as_string (GKeyFile *key_file,
+ const gchar *value,
+ GSList **pieces,
+ GError **error)
+{
+ gchar *string_value, *p, *q0, *q;
+
+ string_value = g_new (gchar, strlen (value) + 1);
+
+ p = (gchar *) value;
+ q0 = q = string_value;
+ while (*p)
+ {
+ if (*p == '\\')
+ {
+ p++;
+
+ switch (*p)
+ {
+ case 's':
+ *q = ' ';
+ break;
+
+ case 'n':
+ *q = '\n';
+ break;
+
+ case 't':
+ *q = '\t';
+ break;
+
+ case 'r':
+ *q = '\r';
+ break;
+
+ case '\\':
+ *q = '\\';
+ break;
+
+ case '\0':
+ g_set_error_literal (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains escape character "
+ "at end of line"));
+ break;
+
+ default:
+ if (pieces && *p == key_file->list_separator)
+ *q = key_file->list_separator;
+ else
+ {
+ *q++ = '\\';
+ *q = *p;
+
+ if (*error == NULL)
+ {
+ gchar sequence[3];
+
+ sequence[0] = '\\';
+ sequence[1] = *p;
+ sequence[2] = '\0';
+
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains invalid escape "
+ "sequence '%s'"), sequence);
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ *q = *p;
+ if (pieces && (*p == key_file->list_separator))
+ {
+ *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
+ q0 = q + 1;
+ }
+ }
+
+ if (*p == '\0')
+ break;
+
+ q++;
+ p++;
+ }
+
+ *q = '\0';
+ if (pieces)
+ {
+ if (q0 < q)
+ *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
+ *pieces = g_slist_reverse (*pieces);
+ }
+
+ return string_value;
+}
+
+static gchar *
+g_key_file_parse_string_as_value (GKeyFile *key_file,
+ const gchar *string,
+ gboolean escape_separator)
+{
+ gchar *value, *p, *q;
+ gsize length;
+ gboolean parsing_leading_space;
+
+ length = strlen (string) + 1;
+
+ /* Worst case would be that every character needs to be escaped.
+ * In other words every character turns to two characters
+ */
+ value = g_new (gchar, 2 * length);
+
+ p = (gchar *) string;
+ q = value;
+ parsing_leading_space = TRUE;
+ while (p < (string + length - 1))
+ {
+ gchar escaped_character[3] = { '\\', 0, 0 };
+
+ switch (*p)
+ {
+ case ' ':
+ if (parsing_leading_space)
+ {
+ escaped_character[1] = 's';
+ strcpy (q, escaped_character);
+ q += 2;
+ }
+ else
+ {
+ *q = *p;
+ q++;
+ }
+ break;
+ case '\t':
+ if (parsing_leading_space)
+ {
+ escaped_character[1] = 't';
+ strcpy (q, escaped_character);
+ q += 2;
+ }
+ else
+ {
+ *q = *p;
+ q++;
+ }
+ break;
+ case '\n':
+ escaped_character[1] = 'n';
+ strcpy (q, escaped_character);
+ q += 2;
+ break;
+ case '\r':
+ escaped_character[1] = 'r';
+ strcpy (q, escaped_character);
+ q += 2;
+ break;
+ case '\\':
+ escaped_character[1] = '\\';
+ strcpy (q, escaped_character);
+ q += 2;
+ parsing_leading_space = FALSE;
+ break;
+ default:
+ if (escape_separator && *p == key_file->list_separator)
+ {
+ escaped_character[1] = key_file->list_separator;
+ strcpy (q, escaped_character);
+ q += 2;
+ parsing_leading_space = TRUE;
+ }
+ else
+ {
+ *q = *p;
+ q++;
+ parsing_leading_space = FALSE;
+ }
+ break;
+ }
+ p++;
+ }
+ *q = '\0';
+
+ return value;
+}
+
+static gint
+g_key_file_parse_value_as_integer (GKeyFile *key_file,
+ const gchar *value,
+ GError **error)
+{
+ gchar *end_of_valid_int;
+ glong long_value;
+ gint int_value;
+
+ errno = 0;
+ long_value = strtol (value, &end_of_valid_int, 10);
+
+ if (*value == '\0' || *end_of_valid_int != '\0')
+ {
+ gchar *value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Value '%s' cannot be interpreted "
+ "as a number."), value_utf8);
+ g_free (value_utf8);
+
+ return 0;
+ }
+
+ int_value = long_value;
+ if (int_value != long_value || errno == ERANGE)
+ {
+ gchar *value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Integer value '%s' out of range"),
+ value_utf8);
+ g_free (value_utf8);
+
+ return 0;
+ }
+
+ return int_value;
+}
+
+static gchar *
+g_key_file_parse_integer_as_value (GKeyFile *key_file,
+ gint value)
+
+{
+ return g_strdup_printf ("%d", value);
+}
+
+static gdouble
+g_key_file_parse_value_as_double (GKeyFile *key_file,
+ const gchar *value,
+ GError **error)
+{
+ gchar *end_of_valid_d;
+ gdouble double_value = 0;
+
+ double_value = g_ascii_strtod (value, &end_of_valid_d);
+
+ if (*end_of_valid_d != '\0' || end_of_valid_d == value)
+ {
+ gchar *value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Value '%s' cannot be interpreted "
+ "as a float number."),
+ value_utf8);
+ g_free (value_utf8);
+ }
+
+ return double_value;
+}
+
+static gboolean
+g_key_file_parse_value_as_boolean (GKeyFile *key_file,
+ const gchar *value,
+ GError **error)
+{
+ gchar *value_utf8;
+
+ if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
+ return TRUE;
+ else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
+ return FALSE;
+
+ value_utf8 = _g_utf8_make_valid (value);
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Value '%s' cannot be interpreted "
+ "as a boolean."), value_utf8);
+ g_free (value_utf8);
+
+ return FALSE;
+}
+
+static gchar *
+g_key_file_parse_boolean_as_value (GKeyFile *key_file,
+ gboolean value)
+{
+ if (value)
+ return g_strdup ("true");
+ else
+ return g_strdup ("false");
+}
+
+static gchar *
+g_key_file_parse_value_as_comment (GKeyFile *key_file,
+ const gchar *value)
+{
+ GString *string;
+ gchar **lines;
+ gsize i;
+
+ string = g_string_sized_new (512);
+
+ lines = g_strsplit (value, "\n", 0);
+
+ for (i = 0; lines[i] != NULL; i++)
+ {
+ if (lines[i][0] != '#')
+ g_string_append_printf (string, "%s\n", lines[i]);
+ else
+ g_string_append_printf (string, "%s\n", lines[i] + 1);
+ }
+ g_strfreev (lines);
+
+ return g_string_free (string, FALSE);
+}
+
+static gchar *
+g_key_file_parse_comment_as_value (GKeyFile *key_file,
+ const gchar *comment)
+{
+ GString *string;
+ gchar **lines;
+ gsize i;
+
+ string = g_string_sized_new (512);
+
+ lines = g_strsplit (comment, "\n", 0);
+
+ for (i = 0; lines[i] != NULL; i++)
+ g_string_append_printf (string, "#%s%s", lines[i],
+ lines[i + 1] == NULL? "" : "\n");
+ g_strfreev (lines);
+
+ return g_string_free (string, FALSE);
+}
+
+#define __G_KEY_FILE_C__
+#include "galiasdef.c"
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/gkeyfile.h b/desmume/src/windows/glib-2.20.1/build/glib/gkeyfile.h
new file mode 100644
index 000000000..b19124c35
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/gkeyfile.h
@@ -0,0 +1,250 @@
+/* gkeyfile.h - desktop entry file parser
+ *
+ * Copyright 2004 Red Hat, Inc.
+ *
+ * Ray Strode
+ *
+ * GLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with GLib; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#ifndef __G_KEY_FILE_H__
+#define __G_KEY_FILE_H__
+
+#include
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+ G_KEY_FILE_ERROR_PARSE,
+ G_KEY_FILE_ERROR_NOT_FOUND,
+ G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ G_KEY_FILE_ERROR_INVALID_VALUE
+} GKeyFileError;
+
+#define G_KEY_FILE_ERROR g_key_file_error_quark()
+
+GQuark g_key_file_error_quark (void);
+
+typedef struct _GKeyFile GKeyFile;
+
+typedef enum
+{
+ G_KEY_FILE_NONE = 0,
+ G_KEY_FILE_KEEP_COMMENTS = 1 << 0,
+ G_KEY_FILE_KEEP_TRANSLATIONS = 1 << 1
+} GKeyFileFlags;
+
+GKeyFile *g_key_file_new (void);
+void g_key_file_free (GKeyFile *key_file);
+void g_key_file_set_list_separator (GKeyFile *key_file,
+ gchar separator);
+gboolean g_key_file_load_from_file (GKeyFile *key_file,
+ const gchar *file,
+ GKeyFileFlags flags,
+ GError **error);
+gboolean g_key_file_load_from_data (GKeyFile *key_file,
+ const gchar *data,
+ gsize length,
+ GKeyFileFlags flags,
+ GError **error);
+gboolean g_key_file_load_from_dirs (GKeyFile *key_file,
+ const gchar *file,
+ const gchar **search_dirs,
+ gchar **full_path,
+ GKeyFileFlags flags,
+ GError **error);
+gboolean g_key_file_load_from_data_dirs (GKeyFile *key_file,
+ const gchar *file,
+ gchar **full_path,
+ GKeyFileFlags flags,
+ GError **error);
+gchar *g_key_file_to_data (GKeyFile *key_file,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+gchar *g_key_file_get_start_group (GKeyFile *key_file) G_GNUC_MALLOC;
+gchar **g_key_file_get_groups (GKeyFile *key_file,
+ gsize *length) G_GNUC_MALLOC;
+gchar **g_key_file_get_keys (GKeyFile *key_file,
+ const gchar *group_name,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+gboolean g_key_file_has_group (GKeyFile *key_file,
+ const gchar *group_name);
+gboolean g_key_file_has_key (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error);
+gchar *g_key_file_get_value (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_value (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *value);
+gchar *g_key_file_get_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *string);
+gchar *g_key_file_get_locale_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_locale_string (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ const gchar *string);
+gboolean g_key_file_get_boolean (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error);
+void g_key_file_set_boolean (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gboolean value);
+gint g_key_file_get_integer (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error);
+void g_key_file_set_integer (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gint value);
+gdouble g_key_file_get_double (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error);
+void g_key_file_set_double (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gdouble value);
+gchar **g_key_file_get_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar * const list[],
+ gsize length);
+gchar **g_key_file_get_locale_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_locale_string_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *locale,
+ const gchar * const list[],
+ gsize length);
+gboolean *g_key_file_get_boolean_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_boolean_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gboolean list[],
+ gsize length);
+gint *g_key_file_get_integer_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_double_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gdouble list[],
+ gsize length);
+gdouble *g_key_file_get_double_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gsize *length,
+ GError **error) G_GNUC_MALLOC;
+void g_key_file_set_integer_list (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ gint list[],
+ gsize length);
+gboolean g_key_file_set_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ const gchar *comment,
+ GError **error);
+gchar *g_key_file_get_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error) G_GNUC_MALLOC;
+
+gboolean g_key_file_remove_comment (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error);
+gboolean g_key_file_remove_key (GKeyFile *key_file,
+ const gchar *group_name,
+ const gchar *key,
+ GError **error);
+gboolean g_key_file_remove_group (GKeyFile *key_file,
+ const gchar *group_name,
+ GError **error);
+
+/* Defines for handling freedesktop.org Desktop files */
+#define G_KEY_FILE_DESKTOP_GROUP "Desktop Entry"
+
+#define G_KEY_FILE_DESKTOP_KEY_TYPE "Type"
+#define G_KEY_FILE_DESKTOP_KEY_VERSION "Version"
+#define G_KEY_FILE_DESKTOP_KEY_NAME "Name"
+#define G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME "GenericName"
+#define G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY "NoDisplay"
+#define G_KEY_FILE_DESKTOP_KEY_COMMENT "Comment"
+#define G_KEY_FILE_DESKTOP_KEY_ICON "Icon"
+#define G_KEY_FILE_DESKTOP_KEY_HIDDEN "Hidden"
+#define G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN "OnlyShowIn"
+#define G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN "NotShowIn"
+#define G_KEY_FILE_DESKTOP_KEY_TRY_EXEC "TryExec"
+#define G_KEY_FILE_DESKTOP_KEY_EXEC "Exec"
+#define G_KEY_FILE_DESKTOP_KEY_PATH "Path"
+#define G_KEY_FILE_DESKTOP_KEY_TERMINAL "Terminal"
+#define G_KEY_FILE_DESKTOP_KEY_MIME_TYPE "MimeType"
+#define G_KEY_FILE_DESKTOP_KEY_CATEGORIES "Categories"
+#define G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY "StartupNotify"
+#define G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS "StartupWMClass"
+#define G_KEY_FILE_DESKTOP_KEY_URL "URL"
+
+#define G_KEY_FILE_DESKTOP_TYPE_APPLICATION "Application"
+#define G_KEY_FILE_DESKTOP_TYPE_LINK "Link"
+#define G_KEY_FILE_DESKTOP_TYPE_DIRECTORY "Directory"
+
+G_END_DECLS
+
+#endif /* __G_KEY_FILE_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/glib-object.h b/desmume/src/windows/glib-2.20.1/build/glib/glib-object.h
new file mode 100644
index 000000000..8687ef1f2
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/glib-object.h
@@ -0,0 +1,41 @@
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __GLIB_GOBJECT_H__
+#define __GLIB_GOBJECT_H__
+
+#define __GLIB_GOBJECT_H_INSIDE__
+
+/* topmost include file for GObject header files */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#undef __GLIB_GOBJECT_H_INSIDE__
+
+#endif /* __GLIB_GOBJECT_H__ */
diff --git a/desmume/src/windows/glib-2.20.1/build/glib/glib.h b/desmume/src/windows/glib-2.20.1/build/glib/glib.h
new file mode 100644
index 000000000..000d41768
--- /dev/null
+++ b/desmume/src/windows/glib-2.20.1/build/glib/glib.h
@@ -0,0 +1,93 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __G_LIB_H__
+#define __G_LIB_H__
+
+#define __GLIB_H_INSIDE__
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include