1 /* module-test.c - test program for GMODULE 2 * Copyright (C) 1998 Tim Janik 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20 /* 21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS 22 * file for a list of people on the GLib Team. See the ChangeLog 23 * files for a list of changes. These files are distributed with 24 * GLib at ftp://ftp.gtk.org/pub/gtk/. 25 */ 26 27 #undef G_DISABLE_ASSERT 28 #undef G_LOG_DOMAIN 29 30 #include <gmodule.h> 31 #include <string.h> 32 33 gchar* global_state; 34 35 G_MODULE_EXPORT void 36 g_clash_func (void) 37 { 38 global_state = "global clash"; 39 } 40 41 typedef void (*SimpleFunc) (void); 42 typedef void (*GModuleFunc) (GModule *); 43 44 static gchar **gplugin_a_state; 45 static gchar **gplugin_b_state; 46 47 static void 48 compare (const gchar *desc, const gchar *expected, const gchar *found) 49 { 50 if (!expected && !found) 51 return; 52 53 if (expected && found && strcmp (expected, found) == 0) 54 return; 55 56 g_error ("error: %s state should have been \"%s\", but is \"%s\"", 57 desc, expected ? expected : "NULL", found ? found : "NULL"); 58 } 59 60 static void 61 test_states (const gchar *global, const gchar *gplugin_a, 62 const gchar *gplugin_b) 63 { 64 compare ("global", global, global_state); 65 compare ("Plugin A", gplugin_a, *gplugin_a_state); 66 compare ("Plugin B", gplugin_b, *gplugin_b_state); 67 68 global_state = *gplugin_a_state = *gplugin_b_state = NULL; 69 } 70 71 static SimpleFunc plugin_clash_func = NULL; 72 73 int 74 main (int arg, 75 char *argv[]) 76 { 77 GModule *module_self, *module_a, *module_b; 78 gchar *dir; 79 gchar *plugin_a, *plugin_b; 80 SimpleFunc f_a, f_b, f_self; 81 GModuleFunc gmod_f; 82 83 if (!g_module_supported ()) 84 g_error ("dynamic modules not supported"); 85 86 dir = g_get_current_dir (); 87 88 plugin_a = g_strconcat (dir, G_DIR_SEPARATOR_S "libmoduletestplugin_a", 89 NULL); 90 plugin_b = g_strconcat (dir, G_DIR_SEPARATOR_S "libmoduletestplugin_b", 91 NULL); 92 93 g_free (dir); 94 95 /* module handles */ 96 97 module_self = g_module_open (NULL, G_MODULE_BIND_LAZY); 98 if (!module_self) 99 g_error ("error: %s", g_module_error ()); 100 101 if (!g_module_symbol (module_self, "g_module_close", (gpointer *) &f_self)) 102 g_error ("error: %s", g_module_error ()); 103 104 module_a = g_module_open (plugin_a, G_MODULE_BIND_LAZY); 105 if (!module_a) 106 g_error ("error: %s", g_module_error ()); 107 108 module_b = g_module_open (plugin_b, G_MODULE_BIND_LAZY); 109 if (!module_b) 110 g_error ("error: %s", g_module_error ()); 111 112 /* get plugin state vars */ 113 114 if (!g_module_symbol (module_a, "gplugin_a_state", 115 (gpointer *) &gplugin_a_state)) 116 g_error ("error: %s", g_module_error ()); 117 118 if (!g_module_symbol (module_b, "gplugin_b_state", 119 (gpointer *) &gplugin_b_state)) 120 g_error ("error: %s", g_module_error ()); 121 test_states (NULL, NULL, "check-init"); 122 123 /* get plugin specific symbols and call them 124 */ 125 if (!g_module_symbol (module_a, "gplugin_a_func", (gpointer *) &f_a)) 126 g_error ("error: %s", g_module_error ()); 127 test_states (NULL, NULL, NULL); 128 129 if (!g_module_symbol (module_b, "gplugin_b_func", (gpointer *) &f_b)) 130 g_error ("error: %s", g_module_error ()); 131 test_states (NULL, NULL, NULL); 132 133 f_a (); 134 test_states (NULL, "Hello world", NULL); 135 136 f_b (); 137 test_states (NULL, NULL, "Hello world"); 138 139 /* get and call globally clashing functions 140 */ 141 142 if (!g_module_symbol (module_self, "g_clash_func", (gpointer *) &f_self)) 143 g_error ("error: %s", g_module_error ()); 144 test_states (NULL, NULL, NULL); 145 146 if (!g_module_symbol (module_a, "g_clash_func", (gpointer *) &f_a)) 147 g_error ("error: %s", g_module_error ()); 148 test_states (NULL, NULL, NULL); 149 150 if (!g_module_symbol (module_b, "g_clash_func", (gpointer *) &f_b)) 151 g_error ("error: %s", g_module_error ()); 152 test_states (NULL, NULL, NULL); 153 154 f_self (); 155 test_states ("global clash", NULL, NULL); 156 157 f_a (); 158 test_states (NULL, "global clash", NULL); 159 160 f_b (); 161 test_states (NULL, NULL, "global clash"); 162 163 /* get and call clashing plugin functions */ 164 165 if (!g_module_symbol (module_a, "gplugin_clash_func", (gpointer *) &f_a)) 166 g_error ("error: %s", g_module_error ()); 167 test_states (NULL, NULL, NULL); 168 169 if (!g_module_symbol (module_b, "gplugin_clash_func", (gpointer *) &f_b)) 170 g_error ("error: %s", g_module_error ()); 171 test_states (NULL, NULL, NULL); 172 173 plugin_clash_func = f_a; 174 plugin_clash_func (); 175 test_states (NULL, "plugin clash", NULL); 176 177 plugin_clash_func = f_b; 178 plugin_clash_func (); 179 test_states (NULL, NULL, "plugin clash"); 180 181 /* call gmodule function from A */ 182 183 if (!g_module_symbol (module_a, "gplugin_a_module_func", (gpointer *) &gmod_f)) 184 g_error ("error: %s", g_module_error ()); 185 test_states (NULL, NULL, NULL); 186 187 gmod_f (module_b); 188 test_states (NULL, NULL, "BOOH"); 189 190 gmod_f (module_a); 191 test_states (NULL, "BOOH", NULL); 192 193 /* unload plugins */ 194 195 if (!g_module_close (module_a)) 196 g_error ("error: %s", g_module_error ()); 197 198 if (!g_module_close (module_b)) 199 g_error ("error: %s", g_module_error ()); 200 201 return 0; 202 } 203