symbol-db: project's progress bar fixed.
[anjuta.git] / libanjuta / anjuta-c-module.c
blob31e85a7cb40f6b1171002c21074f0ec807db107e
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 anjuta-c-module.c
4 Copyright (C) 2007 Sébastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /**
22 * SECTION:anjuta-c-module
23 * @title: AnjutaCModule
24 * @short_description: Anjuta C module
25 * @see_also: #AnjutaCPluginFactory
26 * @include: libanjuta/anjuta-c-module.h
28 * A module is the part of the plugin containing the code. For machine code
29 * compiled from C sources by example, it is a shared library and contained in
30 * a .so file on Linux. GLib provides a portable way to load dynamically such
31 * code with #GModule objects.
33 * In GLib you can register a dynamic type which means that you links a GLib
34 * type with a module. When the type is used for the first time the module is
35 * loaded. When the type is not used anymore, the module is unloaded. Most of
36 * the code necessary to do this is already written in GLib #GTypeModule object
37 * except the load and unload function.
39 * #AnjutaCModule is used only by a #AnjutaCPluginFactory. It derives from
40 * #GTypeModule and implements the load and unload function using a #GModule
41 * object for a module written in C.
43 * Anjuta plugin types are not registered before loading the module.
44 * The loading of the module is done explicitly and types are registered just
45 * after in a function included in the plugin. This function is named
46 * anjuta_glue_register_components and has a #GTypeModule as argument.
47 * The plugin must registers at the least the plugin type dynamically. It can
48 * register other types, but this is currently not used.
50 * After loading a module one or more plugin objects will be created using the
51 * name of the plugin type which has just been registered. The module
52 * will stay loaded while at least one plugin object is present. If all
53 * plugins objects are destroyed the unload function will be called and the
54 * module can be unloaded and removed from memory.
56 * It could be useful that some modules stay in memory even if there is no
57 * object using it. A typical example is if some plugin code or some code of
58 * a library used by a plugin registers a GLib type statically. GLib types can
59 * be registered statically at run time but cannot be unregistered later.
60 * The code (or rather the data used in the registration) must stay in the
61 * memory even if the type is not used. In order to avoid this, you must
62 * register every type dynamically. You could have other situations where a
63 * module cannot be unloaded. By default, Anjuta plugin modules are not
64 * unloaded unless it is explicitly allowed.
67 #include "config.h"
69 #include "anjuta-c-module.h"
71 #include <libanjuta/interfaces/ianjuta-plugin-factory.h>
73 #include <gmodule.h>
75 #define ANJUTA_PLUGIN_REGISTRATION "anjuta_glue_register_components"
77 /* Types
78 *---------------------------------------------------------------------------*/
80 struct _AnjutaCModuleClass
82 GTypeModuleClass parent;
85 struct _AnjutaCModule
87 GTypeModule parent;
89 GModule *library;
90 gchar *full_name;
91 IAnjutaPluginFactoryError error;
94 typedef void (*AnjutaRegisterFunc) (GTypeModule *);
96 G_DEFINE_TYPE (AnjutaCModule, anjuta_c_module, G_TYPE_TYPE_MODULE)
98 /* Private functions
99 *---------------------------------------------------------------------------*/
101 /* GTypeModule functions
102 *---------------------------------------------------------------------------*/
104 static gboolean
105 anjuta_c_module_load (GTypeModule *gmodule)
107 AnjutaCModule *module = ANJUTA_C_MODULE (gmodule);
108 AnjutaRegisterFunc func;
110 g_return_val_if_fail (module->full_name != NULL, FALSE);
112 /* Load the module and register the plugins */
113 module->library = g_module_open (module->full_name, 0);
115 if (module->library == NULL)
117 if (!g_file_test (module->full_name, G_FILE_TEST_IS_REGULAR))
119 module->error = IANJUTA_PLUGIN_FACTORY_MISSING_MODULE;
121 else
123 module->error = IANJUTA_PLUGIN_FACTORY_INVALID_MODULE;
125 return FALSE;
128 if (!g_module_symbol (module->library, ANJUTA_PLUGIN_REGISTRATION, (gpointer *)(gpointer)&func))
130 module->error = IANJUTA_PLUGIN_FACTORY_MISSING_FUNCTION;
131 g_module_close (module->library);
133 return FALSE;
136 /* Register all types */
137 (* func) (gmodule);
138 module->error = IANJUTA_PLUGIN_FACTORY_OK;
140 return TRUE;
143 static void
144 anjuta_c_module_unload (GTypeModule *gmodule)
146 AnjutaCModule *module = ANJUTA_C_MODULE (gmodule);
148 g_module_close (module->library);
151 /* GObject functions
152 *---------------------------------------------------------------------------*/
154 /* finalize is the last destruction step. It must free all memory allocated
155 * with instance_init. It is called only one time just before releasing all
156 * memory */
158 static void
159 anjuta_c_module_finalize (GObject *object)
161 AnjutaCModule* module = ANJUTA_C_MODULE (object);
163 g_free (module->full_name);
165 G_OBJECT_CLASS (anjuta_c_module_parent_class)->finalize (object);
169 static void
170 anjuta_c_module_class_init (AnjutaCModuleClass *klass)
172 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
173 GTypeModuleClass *gmodule_class = (GTypeModuleClass *)klass;
175 gobject_class->finalize = anjuta_c_module_finalize;
177 gmodule_class->load = anjuta_c_module_load;
178 gmodule_class->unload = anjuta_c_module_unload;
181 static void
182 anjuta_c_module_init (AnjutaCModule *module)
184 module->full_name = NULL;
185 module->error = IANJUTA_PLUGIN_FACTORY_OK;
188 /* Public functions
189 *---------------------------------------------------------------------------*/
192 * anjuta_c_module_get_last_error:
193 * @module: AnjutaCModule object
194 * @err: return location for a GError
196 * Receives the error that occured when the module was loaded
198 * Returns: TRUE if there was an Error, FALSE otherwise
200 gboolean
201 anjuta_c_module_get_last_error (AnjutaCModule *module, GError** err)
203 g_return_val_if_fail (module->full_name != NULL, FALSE);
205 switch (module->error)
207 case IANJUTA_PLUGIN_FACTORY_OK:
208 return FALSE;
209 case IANJUTA_PLUGIN_FACTORY_MISSING_MODULE:
210 g_set_error (err, IANJUTA_PLUGIN_FACTORY_ERROR,
211 module->error,
212 _("Unable to find plugin module %s"), module->full_name);
213 return TRUE;
214 case IANJUTA_PLUGIN_FACTORY_INVALID_MODULE:
215 g_set_error (err, IANJUTA_PLUGIN_FACTORY_ERROR,
216 module->error,
217 "%s", g_module_error());
218 return TRUE;
219 case IANJUTA_PLUGIN_FACTORY_MISSING_FUNCTION:
220 g_set_error (err, IANJUTA_PLUGIN_FACTORY_ERROR,
221 module->error,
222 _("Unable to find plugin registration function %s in module %s"),
223 ANJUTA_PLUGIN_REGISTRATION, module->full_name);
224 return TRUE;
225 default:
226 g_set_error (err, IANJUTA_PLUGIN_FACTORY_ERROR,
227 module->error,
228 _("Unknown error in module %s"), module->full_name);
229 return TRUE;
233 /* Creation and Destruction
234 *---------------------------------------------------------------------------*/
237 * anjuta_c_module_new:
238 * @path: The full path of the module
239 * @name: The name of the module
241 * Create a new #AnjutaCModule object.
243 * Return value: a new #AnjutaCModule object.
245 AnjutaCModule*
246 anjuta_c_module_new (const gchar *path, const char *name)
248 AnjutaCModule *module;
250 module = g_object_new (ANJUTA_TYPE_C_MODULE, NULL);
251 module->full_name = g_module_build_path (path, name);
252 g_type_module_set_name (G_TYPE_MODULE (module), module->full_name);
254 return module;