LCOV - code coverage report
Current view: top level - glib/gobject - gtypemodule.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 120 169 71.0 %
Date: 2024-05-21 07:38:11 Functions: 14 17 82.4 %
Branches: 35 62 56.5 %

           Branch data     Line data    Source code
       1                 :            : /* GObject - GLib Type, Object, Parameter and Signal Library
       2                 :            :  * Copyright (C) 2000 Red Hat, Inc.
       3                 :            :  *
       4                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       5                 :            :  *
       6                 :            :  * This library is free software; you can redistribute it and/or
       7                 :            :  * modify it under the terms of the GNU Lesser General Public
       8                 :            :  * License as published by the Free Software Foundation; either
       9                 :            :  * version 2.1 of the License, or (at your option) any later version.
      10                 :            :  *
      11                 :            :  * This library 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 GNU
      14                 :            :  * Lesser General Public License for more details.
      15                 :            :  *
      16                 :            :  * You should have received a copy of the GNU Lesser General Public
      17                 :            :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      18                 :            :  */
      19                 :            : 
      20                 :            : #include "config.h"
      21                 :            : 
      22                 :            : #include <stdlib.h>
      23                 :            : 
      24                 :            : #include "gtypeplugin.h"
      25                 :            : #include "gtypemodule.h"
      26                 :            : 
      27                 :            : 
      28                 :            : /**
      29                 :            :  * GTypeModule:
      30                 :            :  * @name: the name of the module
      31                 :            :  *
      32                 :            :  * `GTypeModule` provides a simple implementation of the `GTypePlugin`
      33                 :            :  * interface.
      34                 :            :  *
      35                 :            :  * The model of `GTypeModule` is a dynamically loaded module which
      36                 :            :  * implements some number of types and interface implementations.
      37                 :            :  *
      38                 :            :  * When the module is loaded, it registers its types and interfaces
      39                 :            :  * using [method@GObject.TypeModule.register_type] and
      40                 :            :  * [method@GObject.TypeModule.add_interface].
      41                 :            :  * As long as any instances of these types and interface implementations
      42                 :            :  * are in use, the module is kept loaded. When the types and interfaces
      43                 :            :  * are gone, the module may be unloaded. If the types and interfaces
      44                 :            :  * become used again, the module will be reloaded. Note that the last
      45                 :            :  * reference cannot be released from within the module code, since that
      46                 :            :  * would lead to the caller's code being unloaded before `g_object_unref()`
      47                 :            :  * returns to it.
      48                 :            :  *
      49                 :            :  * Keeping track of whether the module should be loaded or not is done by
      50                 :            :  * using a use count - it starts at zero, and whenever it is greater than
      51                 :            :  * zero, the module is loaded. The use count is maintained internally by
      52                 :            :  * the type system, but also can be explicitly controlled by
      53                 :            :  * [method@GObject.TypeModule.use] and [method@GObject.TypeModule.unuse].
      54                 :            :  * Typically, when loading a module for the first type, `g_type_module_use()`
      55                 :            :  * will be used to load it so that it can initialize its types. At some later
      56                 :            :  * point, when the module no longer needs to be loaded except for the type
      57                 :            :  * implementations it contains, `g_type_module_unuse()` is called.
      58                 :            :  *
      59                 :            :  * `GTypeModule` does not actually provide any implementation of module
      60                 :            :  * loading and unloading. To create a particular module type you must
      61                 :            :  * derive from `GTypeModule` and implement the load and unload functions
      62                 :            :  * in `GTypeModuleClass`.
      63                 :            :  */
      64                 :            : 
      65                 :            : typedef struct _ModuleTypeInfo ModuleTypeInfo;
      66                 :            : typedef struct _ModuleInterfaceInfo ModuleInterfaceInfo;
      67                 :            : 
      68                 :            : struct _ModuleTypeInfo 
      69                 :            : {
      70                 :            :   gboolean  loaded;
      71                 :            :   GType     type;
      72                 :            :   GType     parent_type;
      73                 :            :   GTypeInfo info;
      74                 :            : };
      75                 :            : 
      76                 :            : struct _ModuleInterfaceInfo 
      77                 :            : {
      78                 :            :   gboolean       loaded;
      79                 :            :   GType          instance_type;
      80                 :            :   GType          interface_type;
      81                 :            :   GInterfaceInfo info;
      82                 :            : };
      83                 :            : 
      84                 :            : static void g_type_module_use_plugin              (GTypePlugin     *plugin);
      85                 :            : static void g_type_module_complete_type_info      (GTypePlugin     *plugin,
      86                 :            :                                                    GType            g_type,
      87                 :            :                                                    GTypeInfo       *info,
      88                 :            :                                                    GTypeValueTable *value_table);
      89                 :            : static void g_type_module_complete_interface_info (GTypePlugin     *plugin,
      90                 :            :                                                    GType            instance_type,
      91                 :            :                                                    GType            interface_type,
      92                 :            :                                                    GInterfaceInfo  *info);
      93                 :            :  
      94                 :            : static gpointer parent_class = NULL;
      95                 :            : 
      96                 :            : static void
      97                 :          2 : g_type_module_dispose (GObject *object)
      98                 :            : {
      99                 :          2 :   GTypeModule *module = G_TYPE_MODULE (object);
     100                 :            :   
     101   [ +  -  -  + ]:          2 :   if (module->type_infos || module->interface_infos)
     102                 :            :     {
     103                 :          0 :       g_critical (G_STRLOC ": unsolicitated invocation of g_object_run_dispose() on GTypeModule");
     104                 :            : 
     105                 :          0 :       g_object_ref (object);
     106                 :            :     }
     107                 :            : 
     108                 :          2 :   G_OBJECT_CLASS (parent_class)->dispose (object);
     109                 :          2 : }
     110                 :            : 
     111                 :            : static void
     112                 :          2 : g_type_module_finalize (GObject *object)
     113                 :            : {
     114                 :          2 :   GTypeModule *module = G_TYPE_MODULE (object);
     115                 :            : 
     116                 :          2 :   g_free (module->name);
     117                 :            : 
     118                 :            :   /* in case a subclass does not chain-up to parent in dispose() */
     119                 :          2 :   g_assert (module->type_infos == NULL);
     120                 :          2 :   g_assert (module->interface_infos == NULL);
     121                 :            : 
     122                 :          2 :   G_OBJECT_CLASS (parent_class)->finalize (object);
     123                 :          2 : }
     124                 :            : 
     125                 :            : static void
     126                 :         11 : g_type_module_class_init (GTypeModuleClass *class)
     127                 :            : {
     128                 :         11 :   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
     129                 :            : 
     130                 :         11 :   parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
     131                 :            :   
     132                 :         11 :   gobject_class->dispose = g_type_module_dispose;
     133                 :         11 :   gobject_class->finalize = g_type_module_finalize;
     134                 :         11 : }
     135                 :            : 
     136                 :            : static void
     137                 :         11 : g_type_module_iface_init (GTypePluginClass *iface)
     138                 :            : {
     139                 :         11 :   iface->use_plugin = g_type_module_use_plugin;
     140                 :         11 :   iface->unuse_plugin = (void (*) (GTypePlugin *))g_type_module_unuse;
     141                 :         11 :   iface->complete_type_info = g_type_module_complete_type_info;
     142                 :         11 :   iface->complete_interface_info = g_type_module_complete_interface_info;
     143                 :         11 : }
     144                 :            : 
     145                 :            : GType
     146                 :         75 : g_type_module_get_type (void)
     147                 :            : {
     148                 :            :   static GType type_module_type = 0;
     149                 :            : 
     150         [ +  + ]:         75 :   if (!type_module_type)
     151                 :            :     {
     152                 :         11 :       const GTypeInfo type_module_info = {
     153                 :            :         sizeof (GTypeModuleClass),
     154                 :            :         NULL,           /* base_init */
     155                 :            :         NULL,           /* base_finalize */
     156                 :            :         (GClassInitFunc) g_type_module_class_init,
     157                 :            :         NULL,           /* class_finalize */
     158                 :            :         NULL,           /* class_data */
     159                 :            :         sizeof (GTypeModule),
     160                 :            :         0,              /* n_preallocs */
     161                 :            :         NULL,           /* instance_init */
     162                 :            :         NULL,           /* value_table */
     163                 :            :       };
     164                 :         11 :       const GInterfaceInfo iface_info = {
     165                 :            :         (GInterfaceInitFunc) g_type_module_iface_init,
     166                 :            :         NULL,               /* interface_finalize */
     167                 :            :         NULL,               /* interface_data */
     168                 :            :       };
     169                 :            : 
     170                 :         11 :       type_module_type = g_type_register_static (G_TYPE_OBJECT, g_intern_static_string ("GTypeModule"), &type_module_info, G_TYPE_FLAG_ABSTRACT);
     171                 :            : 
     172                 :         11 :       g_type_add_interface_static (type_module_type, G_TYPE_TYPE_PLUGIN, &iface_info);
     173                 :            :     }
     174                 :            :   
     175                 :         75 :   return type_module_type;
     176                 :            : }
     177                 :            : 
     178                 :            : /**
     179                 :            :  * g_type_module_set_name:
     180                 :            :  * @module: a #GTypeModule.
     181                 :            :  * @name: a human-readable name to use in error messages.
     182                 :            :  * 
     183                 :            :  * Sets the name for a #GTypeModule 
     184                 :            :  */
     185                 :            : void
     186                 :          0 : g_type_module_set_name (GTypeModule  *module,
     187                 :            :                         const gchar  *name)
     188                 :            : {
     189                 :          0 :   g_return_if_fail (G_IS_TYPE_MODULE (module));
     190                 :            : 
     191                 :          0 :   g_free (module->name);
     192                 :          0 :   module->name = g_strdup (name);
     193                 :            : }
     194                 :            : 
     195                 :            : static ModuleTypeInfo *
     196                 :          8 : g_type_module_find_type_info (GTypeModule *module,
     197                 :            :                               GType        type)
     198                 :            : {
     199                 :          8 :   GSList *tmp_list = module->type_infos;
     200         [ +  - ]:          8 :   while (tmp_list)
     201                 :            :     {
     202                 :          8 :       ModuleTypeInfo *type_info = tmp_list->data;
     203         [ +  - ]:          8 :       if (type_info->type == type)
     204                 :          8 :         return type_info;
     205                 :            :       
     206                 :          0 :       tmp_list = tmp_list->next;
     207                 :            :     }
     208                 :            : 
     209                 :          0 :   return NULL;
     210                 :            : }
     211                 :            : 
     212                 :            : static ModuleInterfaceInfo *
     213                 :          4 : g_type_module_find_interface_info (GTypeModule *module,
     214                 :            :                                    GType        instance_type,
     215                 :            :                                    GType        interface_type)
     216                 :            : {
     217                 :          4 :   GSList *tmp_list = module->interface_infos;
     218         [ +  - ]:          4 :   while (tmp_list)
     219                 :            :     {
     220                 :          4 :       ModuleInterfaceInfo *interface_info = tmp_list->data;
     221         [ +  - ]:          4 :       if (interface_info->instance_type == instance_type &&
     222         [ +  - ]:          4 :           interface_info->interface_type == interface_type)
     223                 :          4 :         return interface_info;
     224                 :            :       
     225                 :          0 :       tmp_list = tmp_list->next;
     226                 :            :     }
     227                 :            : 
     228                 :          0 :   return NULL;
     229                 :            : }
     230                 :            : 
     231                 :            : /**
     232                 :            :  * g_type_module_use:
     233                 :            :  * @module: a #GTypeModule
     234                 :            :  * 
     235                 :            :  * Increases the use count of a #GTypeModule by one. If the
     236                 :            :  * use count was zero before, the plugin will be loaded.
     237                 :            :  * If loading the plugin fails, the use count is reset to 
     238                 :            :  * its prior value. 
     239                 :            :  * 
     240                 :            :  * Returns: %FALSE if the plugin needed to be loaded and
     241                 :            :  *  loading the plugin failed.
     242                 :            :  */
     243                 :            : gboolean
     244                 :         14 : g_type_module_use (GTypeModule *module)
     245                 :            : {
     246                 :         14 :   g_return_val_if_fail (G_IS_TYPE_MODULE (module), FALSE);
     247                 :            : 
     248                 :         14 :   module->use_count++;
     249         [ +  + ]:         14 :   if (module->use_count == 1)
     250                 :            :     {
     251                 :            :       GSList *tmp_list;
     252                 :            :       
     253         [ -  + ]:         12 :       if (!G_TYPE_MODULE_GET_CLASS (module)->load (module))
     254                 :            :         {
     255                 :          0 :           module->use_count--;
     256                 :          0 :           return FALSE;
     257                 :            :         }
     258                 :            : 
     259                 :         12 :       tmp_list = module->type_infos;
     260         [ +  + ]:         20 :       while (tmp_list)
     261                 :            :         {
     262                 :          8 :           ModuleTypeInfo *type_info = tmp_list->data;
     263         [ -  + ]:          8 :           if (!type_info->loaded)
     264                 :            :             {
     265         [ #  # ]:          0 :               g_critical ("plugin '%s' failed to register type '%s'",
     266                 :            :                           module->name ? module->name : "(unknown)",
     267                 :            :                           g_type_name (type_info->type));
     268                 :          0 :               module->use_count--;
     269                 :          0 :               return FALSE;
     270                 :            :             }
     271                 :            :           
     272                 :          8 :           tmp_list = tmp_list->next;
     273                 :            :         }
     274                 :            :     }
     275                 :            :  
     276                 :         14 :   return TRUE;
     277                 :            : }
     278                 :            : 
     279                 :            : /**
     280                 :            :  * g_type_module_unuse:
     281                 :            :  * @module: a #GTypeModule
     282                 :            :  *
     283                 :            :  * Decreases the use count of a #GTypeModule by one. If the
     284                 :            :  * result is zero, the module will be unloaded. (However, the
     285                 :            :  * #GTypeModule will not be freed, and types associated with the
     286                 :            :  * #GTypeModule are not unregistered. Once a #GTypeModule is
     287                 :            :  * initialized, it must exist forever.)
     288                 :            :  */
     289                 :            : void
     290                 :          8 : g_type_module_unuse (GTypeModule *module)
     291                 :            : {
     292                 :          8 :   g_return_if_fail (G_IS_TYPE_MODULE (module));
     293                 :          8 :   g_return_if_fail (module->use_count > 0);
     294                 :            : 
     295                 :          8 :   module->use_count--;
     296                 :            : 
     297         [ +  - ]:          8 :   if (module->use_count == 0)
     298                 :            :     {
     299                 :            :       GSList *tmp_list;
     300                 :            : 
     301                 :          8 :       G_TYPE_MODULE_GET_CLASS (module)->unload (module);
     302                 :            : 
     303                 :          8 :       tmp_list = module->type_infos;
     304         [ +  + ]:         12 :       while (tmp_list)
     305                 :            :         {
     306                 :          4 :           ModuleTypeInfo *type_info = tmp_list->data;
     307                 :          4 :           type_info->loaded = FALSE;
     308                 :            : 
     309                 :          4 :           tmp_list = tmp_list->next;
     310                 :            :         }
     311                 :            :     }
     312                 :            : }
     313                 :            :         
     314                 :            : static void
     315                 :          6 : g_type_module_use_plugin (GTypePlugin *plugin)
     316                 :            : {
     317                 :          6 :   GTypeModule *module = G_TYPE_MODULE (plugin);
     318                 :            : 
     319         [ -  + ]:          6 :   if (!g_type_module_use (module))
     320                 :            :     {
     321         [ #  # ]:          0 :       g_error ("Fatal error - Could not reload previously loaded plugin '%s'",
     322                 :            :                 module->name ? module->name : "(unknown)");
     323                 :            :     }
     324                 :          6 : }
     325                 :            : 
     326                 :            : static void
     327                 :          4 : g_type_module_complete_type_info (GTypePlugin     *plugin,
     328                 :            :                                   GType            g_type,
     329                 :            :                                   GTypeInfo       *info,
     330                 :            :                                   GTypeValueTable *value_table)
     331                 :            : {
     332                 :          4 :   GTypeModule *module = G_TYPE_MODULE (plugin);
     333                 :          4 :   ModuleTypeInfo *module_type_info = g_type_module_find_type_info (module, g_type);
     334                 :            : 
     335                 :          4 :   *info = module_type_info->info;
     336                 :            :   
     337         [ -  + ]:          4 :   if (module_type_info->info.value_table)
     338                 :          0 :     *value_table = *module_type_info->info.value_table;
     339                 :          4 : }
     340                 :            : 
     341                 :            : static void 
     342                 :          2 : g_type_module_complete_interface_info (GTypePlugin    *plugin,
     343                 :            :                                        GType           instance_type,
     344                 :            :                                        GType           interface_type,
     345                 :            :                                        GInterfaceInfo *info)
     346                 :            : {
     347                 :          2 :   GTypeModule *module = G_TYPE_MODULE (plugin);
     348                 :          2 :   ModuleInterfaceInfo *module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
     349                 :            : 
     350                 :          2 :   *info = module_interface_info->info;
     351                 :          2 : }
     352                 :            : 
     353                 :            : /**
     354                 :            :  * g_type_module_register_type:
     355                 :            :  * @module: (nullable): a #GTypeModule
     356                 :            :  * @parent_type: the type for the parent class
     357                 :            :  * @type_name: name for the type
     358                 :            :  * @type_info: type information structure
     359                 :            :  * @flags: flags field providing details about the type
     360                 :            :  *
     361                 :            :  * Looks up or registers a type that is implemented with a particular
     362                 :            :  * type plugin. If a type with name @type_name was previously registered,
     363                 :            :  * the #GType identifier for the type is returned, otherwise the type
     364                 :            :  * is newly registered, and the resulting #GType identifier returned.
     365                 :            :  *
     366                 :            :  * When reregistering a type (typically because a module is unloaded
     367                 :            :  * then reloaded, and reinitialized), @module and @parent_type must
     368                 :            :  * be the same as they were previously.
     369                 :            :  *
     370                 :            :  * As long as any instances of the type exist, the type plugin will
     371                 :            :  * not be unloaded.
     372                 :            :  *
     373                 :            :  * Since 2.56 if @module is %NULL this will call g_type_register_static()
     374                 :            :  * instead. This can be used when making a static build of the module.
     375                 :            :  *
     376                 :            :  * Returns: the new or existing type ID
     377                 :            :  */
     378                 :            : GType
     379                 :          8 : g_type_module_register_type (GTypeModule     *module,
     380                 :            :                              GType            parent_type,
     381                 :            :                              const gchar     *type_name,
     382                 :            :                              const GTypeInfo *type_info,
     383                 :            :                              GTypeFlags       flags)
     384                 :            : {
     385                 :          8 :   ModuleTypeInfo *module_type_info = NULL;
     386                 :            :   GType type;
     387                 :            :   
     388                 :          8 :   g_return_val_if_fail (type_name != NULL, 0);
     389                 :          8 :   g_return_val_if_fail (type_info != NULL, 0);
     390                 :            : 
     391         [ -  + ]:          8 :   if (module == NULL)
     392                 :            :     {
     393                 :            :       /* Cannot pass type_info directly to g_type_register_static() here because
     394                 :            :        * it has class_finalize != NULL and that's forbidden for static types */
     395                 :          0 :       return g_type_register_static_simple (parent_type,
     396                 :            :                                             type_name,
     397                 :          0 :                                             type_info->class_size,
     398                 :          0 :                                             type_info->class_init,
     399                 :          0 :                                             type_info->instance_size,
     400                 :          0 :                                             type_info->instance_init,
     401                 :            :                                             flags);
     402                 :            :     }
     403                 :            : 
     404                 :          8 :   type = g_type_from_name (type_name);
     405         [ +  + ]:          8 :   if (type)
     406                 :            :     {
     407                 :          4 :       GTypePlugin *old_plugin = g_type_get_plugin (type);
     408                 :            : 
     409         [ -  + ]:          4 :       if (old_plugin != G_TYPE_PLUGIN (module))
     410                 :            :         {
     411                 :          0 :           g_critical ("Two different plugins tried to register '%s'.", type_name);
     412                 :          0 :           return 0;
     413                 :            :         }
     414                 :            :     }
     415                 :            : 
     416         [ +  + ]:          8 :   if (type)
     417                 :            :     {
     418                 :          4 :       module_type_info = g_type_module_find_type_info (module, type);
     419                 :            : 
     420         [ -  + ]:          4 :       if (module_type_info->parent_type != parent_type)
     421                 :            :         {
     422                 :          0 :           const gchar *parent_type_name = g_type_name (parent_type);
     423                 :            :           
     424         [ #  # ]:          0 :           g_critical ("Type '%s' recreated with different parent type."
     425                 :            :                       "(was '%s', now '%s')", type_name,
     426                 :            :                       g_type_name (module_type_info->parent_type),
     427                 :            :                       parent_type_name ? parent_type_name : "(unknown)");
     428                 :          0 :           return 0;
     429                 :            :         }
     430                 :            : 
     431         [ -  + ]:          4 :       if (module_type_info->info.value_table)
     432                 :          0 :         g_free ((GTypeValueTable *) module_type_info->info.value_table);
     433                 :            :     }
     434                 :            :   else
     435                 :            :     {
     436                 :          4 :       module_type_info = g_new (ModuleTypeInfo, 1);
     437                 :            :       
     438                 :          4 :       module_type_info->parent_type = parent_type;
     439                 :          4 :       module_type_info->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (module), flags);
     440                 :            :       
     441                 :          4 :       module->type_infos = g_slist_prepend (module->type_infos, module_type_info);
     442                 :            :     }
     443                 :            : 
     444                 :          8 :   module_type_info->loaded = TRUE;
     445                 :          8 :   module_type_info->info = *type_info;
     446         [ -  + ]:          8 :   if (type_info->value_table)
     447                 :          0 :     module_type_info->info.value_table = g_memdup2 (type_info->value_table,
     448                 :            :                                                    sizeof (GTypeValueTable));
     449                 :            : 
     450                 :          8 :   return module_type_info->type;
     451                 :            : }
     452                 :            : 
     453                 :            : /**
     454                 :            :  * g_type_module_add_interface:
     455                 :            :  * @module: (nullable): a #GTypeModule
     456                 :            :  * @instance_type: type to which to add the interface.
     457                 :            :  * @interface_type: interface type to add
     458                 :            :  * @interface_info: type information structure
     459                 :            :  *
     460                 :            :  * Registers an additional interface for a type, whose interface lives
     461                 :            :  * in the given type plugin. If the interface was already registered
     462                 :            :  * for the type in this plugin, nothing will be done.
     463                 :            :  *
     464                 :            :  * As long as any instances of the type exist, the type plugin will
     465                 :            :  * not be unloaded.
     466                 :            :  *
     467                 :            :  * Since 2.56 if @module is %NULL this will call g_type_add_interface_static()
     468                 :            :  * instead. This can be used when making a static build of the module.
     469                 :            :  */
     470                 :            : void
     471                 :          4 : g_type_module_add_interface (GTypeModule          *module,
     472                 :            :                              GType                 instance_type,
     473                 :            :                              GType                 interface_type,
     474                 :            :                              const GInterfaceInfo *interface_info)
     475                 :            : {
     476                 :          4 :   ModuleInterfaceInfo *module_interface_info = NULL;
     477                 :            : 
     478                 :          4 :   g_return_if_fail (interface_info != NULL);
     479                 :            : 
     480         [ -  + ]:          4 :   if (module == NULL)
     481                 :            :     {
     482                 :          0 :       g_type_add_interface_static (instance_type, interface_type, interface_info);
     483                 :          0 :       return;
     484                 :            :     }
     485                 :            : 
     486   [ +  -  +  + ]:          4 :   if (g_type_is_a (instance_type, interface_type))
     487                 :          2 :     {
     488                 :          2 :       GTypePlugin *old_plugin = g_type_interface_get_plugin (instance_type,
     489                 :            :                                                              interface_type);
     490                 :            : 
     491         [ -  + ]:          2 :       if (!old_plugin)
     492                 :            :         {
     493                 :          0 :           g_critical ("Interface '%s' for '%s' was previously registered statically or for a parent type.",
     494                 :            :                       g_type_name (interface_type), g_type_name (instance_type));
     495                 :          0 :           return;
     496                 :            :         }
     497         [ -  + ]:          2 :       else if (old_plugin != G_TYPE_PLUGIN (module))
     498                 :            :         {
     499                 :          0 :           g_critical ("Two different plugins tried to register interface '%s' for '%s'.",
     500                 :            :                       g_type_name (interface_type), g_type_name (instance_type));
     501                 :          0 :           return;
     502                 :            :         }
     503                 :            :       
     504                 :          2 :       module_interface_info = g_type_module_find_interface_info (module, instance_type, interface_type);
     505                 :            : 
     506                 :          2 :       g_assert (module_interface_info);
     507                 :            :     }
     508                 :            :   else
     509                 :            :     {
     510                 :          2 :       module_interface_info = g_new (ModuleInterfaceInfo, 1);
     511                 :            :       
     512                 :          2 :       module_interface_info->instance_type = instance_type;
     513                 :          2 :       module_interface_info->interface_type = interface_type;
     514                 :            :       
     515                 :          2 :       g_type_add_interface_dynamic (instance_type, interface_type, G_TYPE_PLUGIN (module));
     516                 :            :       
     517                 :          2 :       module->interface_infos = g_slist_prepend (module->interface_infos, module_interface_info);
     518                 :            :     }
     519                 :            :   
     520                 :          4 :   module_interface_info->loaded = TRUE;
     521                 :          4 :   module_interface_info->info = *interface_info;
     522                 :            : }
     523                 :            : 
     524                 :            : /**
     525                 :            :  * g_type_module_register_enum:
     526                 :            :  * @module: (nullable): a #GTypeModule
     527                 :            :  * @name: name for the type
     528                 :            :  * @const_static_values: an array of #GEnumValue structs for the
     529                 :            :  *                       possible enumeration values. The array is
     530                 :            :  *                       terminated by a struct with all members being
     531                 :            :  *                       0.
     532                 :            :  *
     533                 :            :  * Looks up or registers an enumeration that is implemented with a particular
     534                 :            :  * type plugin. If a type with name @type_name was previously registered,
     535                 :            :  * the #GType identifier for the type is returned, otherwise the type
     536                 :            :  * is newly registered, and the resulting #GType identifier returned.
     537                 :            :  *
     538                 :            :  * As long as any instances of the type exist, the type plugin will
     539                 :            :  * not be unloaded.
     540                 :            :  *
     541                 :            :  * Since 2.56 if @module is %NULL this will call g_type_register_static()
     542                 :            :  * instead. This can be used when making a static build of the module.
     543                 :            :  *
     544                 :            :  * Since: 2.6
     545                 :            :  *
     546                 :            :  * Returns: the new or existing type ID
     547                 :            :  */
     548                 :            : GType
     549                 :          0 : g_type_module_register_enum (GTypeModule      *module,
     550                 :            :                              const gchar      *name,
     551                 :            :                              const GEnumValue *const_static_values)
     552                 :            : {
     553                 :          0 :   GTypeInfo enum_type_info = { 0, };
     554                 :            : 
     555                 :          0 :   g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0);
     556                 :          0 :   g_return_val_if_fail (name != NULL, 0);
     557                 :          0 :   g_return_val_if_fail (const_static_values != NULL, 0);
     558                 :            : 
     559                 :          0 :   g_enum_complete_type_info (G_TYPE_ENUM,
     560                 :            :                              &enum_type_info, const_static_values);
     561                 :            : 
     562                 :          0 :   return g_type_module_register_type (G_TYPE_MODULE (module),
     563                 :            :                                       G_TYPE_ENUM, name, &enum_type_info, 0);
     564                 :            : }
     565                 :            : 
     566                 :            : /**
     567                 :            :  * g_type_module_register_flags:
     568                 :            :  * @module: (nullable): a #GTypeModule
     569                 :            :  * @name: name for the type
     570                 :            :  * @const_static_values: an array of #GFlagsValue structs for the
     571                 :            :  *                       possible flags values. The array is
     572                 :            :  *                       terminated by a struct with all members being
     573                 :            :  *                       0.
     574                 :            :  *
     575                 :            :  * Looks up or registers a flags type that is implemented with a particular
     576                 :            :  * type plugin. If a type with name @type_name was previously registered,
     577                 :            :  * the #GType identifier for the type is returned, otherwise the type
     578                 :            :  * is newly registered, and the resulting #GType identifier returned.
     579                 :            :  *
     580                 :            :  * As long as any instances of the type exist, the type plugin will
     581                 :            :  * not be unloaded.
     582                 :            :  *
     583                 :            :  * Since 2.56 if @module is %NULL this will call g_type_register_static()
     584                 :            :  * instead. This can be used when making a static build of the module.
     585                 :            :  *
     586                 :            :  * Since: 2.6
     587                 :            :  *
     588                 :            :  * Returns: the new or existing type ID
     589                 :            :  */
     590                 :            : GType
     591                 :          0 : g_type_module_register_flags (GTypeModule      *module,
     592                 :            :                              const gchar       *name,
     593                 :            :                              const GFlagsValue *const_static_values)
     594                 :            : {
     595                 :          0 :   GTypeInfo flags_type_info = { 0, };
     596                 :            : 
     597                 :          0 :   g_return_val_if_fail (module == NULL || G_IS_TYPE_MODULE (module), 0);
     598                 :          0 :   g_return_val_if_fail (name != NULL, 0);
     599                 :          0 :   g_return_val_if_fail (const_static_values != NULL, 0);
     600                 :            : 
     601                 :          0 :   g_flags_complete_type_info (G_TYPE_FLAGS,
     602                 :            :                              &flags_type_info, const_static_values);
     603                 :            : 
     604                 :          0 :   return g_type_module_register_type (G_TYPE_MODULE (module),
     605                 :            :                                       G_TYPE_FLAGS, name, &flags_type_info, 0);
     606                 :            : }

Generated by: LCOV version 1.14