1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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
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.
69 #include "anjuta-c-module.h"
71 #include <libanjuta/interfaces/ianjuta-plugin-factory.h>
75 #define ANJUTA_PLUGIN_REGISTRATION "anjuta_glue_register_components"
78 *---------------------------------------------------------------------------*/
80 struct _AnjutaCModuleClass
82 GTypeModuleClass parent
;
91 IAnjutaPluginFactoryError error
;
94 typedef void (*AnjutaRegisterFunc
) (GTypeModule
*);
96 G_DEFINE_TYPE (AnjutaCModule
, anjuta_c_module
, G_TYPE_TYPE_MODULE
)
99 *---------------------------------------------------------------------------*/
101 /* GTypeModule functions
102 *---------------------------------------------------------------------------*/
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
;
123 module
->error
= IANJUTA_PLUGIN_FACTORY_INVALID_MODULE
;
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
);
136 /* Register all types */
138 module
->error
= IANJUTA_PLUGIN_FACTORY_OK
;
144 anjuta_c_module_unload (GTypeModule
*gmodule
)
146 AnjutaCModule
*module
= ANJUTA_C_MODULE (gmodule
);
148 g_module_close (module
->library
);
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
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
);
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
;
182 anjuta_c_module_init (AnjutaCModule
*module
)
184 module
->full_name
= NULL
;
185 module
->error
= IANJUTA_PLUGIN_FACTORY_OK
;
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
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
:
209 case IANJUTA_PLUGIN_FACTORY_MISSING_MODULE
:
210 g_set_error (err
, IANJUTA_PLUGIN_FACTORY_ERROR
,
212 _("Unable to find plugin module %s"), module
->full_name
);
214 case IANJUTA_PLUGIN_FACTORY_INVALID_MODULE
:
215 g_set_error (err
, IANJUTA_PLUGIN_FACTORY_ERROR
,
217 "%s", g_module_error());
219 case IANJUTA_PLUGIN_FACTORY_MISSING_FUNCTION
:
220 g_set_error (err
, IANJUTA_PLUGIN_FACTORY_ERROR
,
222 _("Unable to find plugin registration function %s in module %s"),
223 ANJUTA_PLUGIN_REGISTRATION
, module
->full_name
);
226 g_set_error (err
, IANJUTA_PLUGIN_FACTORY_ERROR
,
228 _("Unknown error in module %s"), module
->full_name
);
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.
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
);