Determine the suffix of the shared librarries for this system. This is
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Determine the suffix of the shared librarries for
this system. This is done analogous to
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
"sl", "dll", or (most often) "so".
* tests/Makefile.am, tests/module-test.c,
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
Added new testcase for gmodule. This is mostly copied from
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
some tests that verbose, not to say loquacious...)
* gmodule.c: Make g_module_open more tolerant wrt to the module
name. First it tries to open the module as named, if that fails,
it checks, whether it is a libtool archive and parses it, if that
fails it appends the systems shared library suffix
(i.e. ".so") (if not already found) and tries again and if that
fails it tries to append the ".la" libtool suffix (if not already
found) and parses it.
* gmodule.c: Lock recursive mutex during most module functions for
safety.
* gmodule-dl.c: Return an error from _g_module_symbol only, if
dlerror says so. All other functions return an error as well, if
dlerror returns NULL.
* testgmodule.c: Thanks to the above change the #ifdefs have
vanished.
* glib/glib-sections.txt: Added G_MODULE_SUFFIX.
* glib/tmpl/modules.sgml: Updated.
2000-12-22 14:44:25 +01:00
|
|
|
/* module-test.c - test program for GMODULE
|
|
|
|
* 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/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <gmodule.h>
|
Changes for 64-bit cleanliness, loosely based on patch from Mark Murnane.
Wed Jun 20 12:00:54 2001 Owen Taylor <otaylor@redhat.com>
Changes for 64-bit cleanliness, loosely based on patch
from Mark Murnane.
* gconvert.c (g_convert/g_convert_with_fallback): Remove
workarounds for since-fixed GNU libc bugs. Minor
doc fix.
* gconvert.[ch]: Change gint to gsize/gssize as
appropriate.
* gconvert.c (g_locale/filename_to/from_utf8): Fix incorrect
computation of bytes_read / bytes_written.
* gfileutils.[ch] (g_file_get_contents): Make length
out parameter 'gsize *len'.
* ghook.c (g_hook_compare_ids): Don't compare a
and b as 'a - b'.
* gmacros.h (GSIZE_TO_POINTER): Add GPOINTER_TO_SIZE,
GSIZE_TO_POINTER.
* gmain.c (g_timeout_prepare): Rewrite to avoid
overflows. (Fixes bug when system clock skews
backwards more than 24 days.)
* gmarkup.[ch]: Make lengths passed to callbacks
gsize, length for g_markup_parse-context_parse(),
g_markup_escape_text() gssize.
* gmessages.[ch] (g_printf_string_upper_bound): Change
return value to gsize.
* gmessages.c (printf_string_upper_bound): Remove
a ridiculous use of 'inline' on a 300 line function.
* gstring.[ch]: Represent size of string as a gsize,
not gint. Make parameters to functions take gsize,
or gssize where -1 is allowed.
* gstring.c (g_string_erase): Make
g_string_erase (string, pos, -1) a synonym for
g_string_truncate for consistency with other G*
APIs.
* gstrfuncs.[ch]: Make all functions taking a string
length, take a gsize, or gssize if -1 is allowed.
(g_strstr_len, g_strrstr_len). Also fix some boundary
conditions in g_str[r]str[_len].
* gutf8.c tests/unicode-encoding.c: Make parameters that
are byte lengths gsize, gssize as appropriate. Make
character offsets, other counts, glong.
* gasyncqueue.c gcompletion.c
timeloop.c timeloop-basic.c gutils.c gspawn.c.
Small 64 bit cleanliness fixups.
* glist.c (g_list_sort2, g_list_sort_real): Fix functions
that should have been static.
* gdate.c (g_date_fill_parse_tokens): Fix extra
declaration that was shadowing another.
* tests/module-test.c: Include string.h
Mon Jun 18 15:43:29 2001 Owen Taylor <otaylor@redhat.com>
* gutf8.c (g_get_charset): Make argument
G_CONST_RETURN char **.
2001-06-23 15:55:09 +02:00
|
|
|
#include <string.h>
|
Determine the suffix of the shared librarries for this system. This is
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in: Determine the suffix of the shared librarries for
this system. This is done analogous to
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
"sl", "dll", or (most often) "so".
* tests/Makefile.am, tests/module-test.c,
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
Added new testcase for gmodule. This is mostly copied from
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
some tests that verbose, not to say loquacious...)
* gmodule.c: Make g_module_open more tolerant wrt to the module
name. First it tries to open the module as named, if that fails,
it checks, whether it is a libtool archive and parses it, if that
fails it appends the systems shared library suffix
(i.e. ".so") (if not already found) and tries again and if that
fails it tries to append the ".la" libtool suffix (if not already
found) and parses it.
* gmodule.c: Lock recursive mutex during most module functions for
safety.
* gmodule-dl.c: Return an error from _g_module_symbol only, if
dlerror says so. All other functions return an error as well, if
dlerror returns NULL.
* testgmodule.c: Thanks to the above change the #ifdefs have
vanished.
* glib/glib-sections.txt: Added G_MODULE_SUFFIX.
* glib/tmpl/modules.sgml: Updated.
2000-12-22 14:44:25 +01:00
|
|
|
|
|
|
|
gchar* global_state;
|
|
|
|
|
|
|
|
G_MODULE_EXPORT void
|
|
|
|
g_clash_func (void)
|
|
|
|
{
|
|
|
|
global_state = "global clash";
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef void (*SimpleFunc) (void);
|
|
|
|
typedef void (*GModuleFunc) (GModule *);
|
|
|
|
|
|
|
|
static gchar **gplugin_a_state;
|
|
|
|
static gchar **gplugin_b_state;
|
|
|
|
|
|
|
|
static void
|
|
|
|
compare (const gchar *desc, const gchar *expected, const gchar *found)
|
|
|
|
{
|
|
|
|
if (!expected && !found)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (expected && found && strcmp (expected, found) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
g_error ("error: %s state should have been \"%s\", but is \"%s\"",
|
|
|
|
desc, expected ? expected : "NULL", found ? found : "NULL");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_states (const gchar *global, const gchar *gplugin_a,
|
|
|
|
const gchar *gplugin_b)
|
|
|
|
{
|
|
|
|
compare ("global", global, global_state);
|
|
|
|
compare ("Plugin A", gplugin_a, *gplugin_a_state);
|
|
|
|
compare ("Plugin B", gplugin_b, *gplugin_b_state);
|
|
|
|
|
|
|
|
global_state = *gplugin_a_state = *gplugin_b_state = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static SimpleFunc plugin_clash_func = NULL;
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int arg,
|
|
|
|
char *argv[])
|
|
|
|
{
|
|
|
|
GModule *module_self, *module_a, *module_b;
|
|
|
|
gchar *dir;
|
|
|
|
gchar *plugin_a, *plugin_b;
|
|
|
|
SimpleFunc f_a, f_b, f_self;
|
|
|
|
GModuleFunc gmod_f;
|
|
|
|
|
|
|
|
if (!g_module_supported ())
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
dir = g_get_current_dir ();
|
|
|
|
|
|
|
|
plugin_a = g_strconcat (dir, G_DIR_SEPARATOR_S "libmoduletestplugin_a",
|
|
|
|
NULL);
|
|
|
|
plugin_b = g_strconcat (dir, G_DIR_SEPARATOR_S "libmoduletestplugin_b",
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_free (dir);
|
|
|
|
|
|
|
|
/* module handles */
|
|
|
|
|
|
|
|
module_self = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
|
|
|
if (!module_self)
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_self, "g_module_close", (gpointer) &f_self))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
module_a = g_module_open (plugin_a, G_MODULE_BIND_LAZY);
|
|
|
|
if (!module_a)
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
module_b = g_module_open (plugin_b, G_MODULE_BIND_LAZY);
|
|
|
|
if (!module_b)
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
/* get plugin state vars */
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_a, "gplugin_a_state",
|
|
|
|
(gpointer) &gplugin_a_state))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_b, "gplugin_b_state",
|
|
|
|
(gpointer) &gplugin_b_state))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, "check-init");
|
|
|
|
|
|
|
|
/* get plugin specific symbols and call them
|
|
|
|
*/
|
|
|
|
if (!g_module_symbol (module_a, "gplugin_a_func", (gpointer) &f_a))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_b, "gplugin_b_func", (gpointer) &f_b))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
f_a ();
|
|
|
|
test_states (NULL, "Hello world", NULL);
|
|
|
|
|
|
|
|
f_b ();
|
|
|
|
test_states (NULL, NULL, "Hello world");
|
|
|
|
|
|
|
|
/* get and call globally clashing functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_self, "g_clash_func", (gpointer) &f_self))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_a, "g_clash_func", (gpointer) &f_a))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_b, "g_clash_func", (gpointer) &f_b))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
f_self ();
|
|
|
|
test_states ("global clash", NULL, NULL);
|
|
|
|
|
|
|
|
f_a ();
|
|
|
|
test_states (NULL, "global clash", NULL);
|
|
|
|
|
|
|
|
f_b ();
|
|
|
|
test_states (NULL, NULL, "global clash");
|
|
|
|
|
|
|
|
/* get and call clashing plugin functions */
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_a, "gplugin_clash_func", (gpointer) &f_a))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_b, "gplugin_clash_func", (gpointer) &f_b))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
plugin_clash_func = f_a;
|
|
|
|
plugin_clash_func ();
|
|
|
|
test_states (NULL, "plugin clash", NULL);
|
|
|
|
|
|
|
|
plugin_clash_func = f_b;
|
|
|
|
plugin_clash_func ();
|
|
|
|
test_states (NULL, NULL, "plugin clash");
|
|
|
|
|
|
|
|
/* call gmodule function from A */
|
|
|
|
|
|
|
|
if (!g_module_symbol (module_a, "gplugin_a_module_func", (gpointer) &gmod_f))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
test_states (NULL, NULL, NULL);
|
|
|
|
|
|
|
|
gmod_f (module_b);
|
|
|
|
test_states (NULL, NULL, "BOOH");
|
|
|
|
|
|
|
|
gmod_f (module_a);
|
|
|
|
test_states (NULL, "BOOH", NULL);
|
|
|
|
|
|
|
|
/* unload plugins */
|
|
|
|
|
|
|
|
if (!g_module_close (module_a))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
if (!g_module_close (module_b))
|
|
|
|
g_error ("error: %s", g_module_error ());
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|