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 | return 0; |
---|
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 | } |
---|