<commit_before>/*
 * peas-object-module.c
 * This file is part of libpeas
 *
 * Copyright (C) 2003 <NAME>
 * Copyright (C) 2003-2004 <NAME>
 * Copyright (C) 2005-2007 <NAME>
 * Copyright (C) 2008 <NAME>
 * Copyright (C) 2010 <NAME>
 *
 * libpeas is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * libpeas is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 */

#include "config.h"

#include <string.h>

#include "peas-object-module.h"
#include "peas-plugin-loader.h"

/**
 * SECTION:peas-object-module
 * @short_description: Type module which allows extension registration.
 *
 * #PeasObjectModule is a subclass of #GTypeModule which allows registration
 * of extensions.  It will be used by C extensions implementors to register
 * extension implementations from within the peas_register_types module
 * function.
 *
 * Since libpeas 1.22, @extension_type can be an Abstract #GType
 * and not just an Interface #GType.
 **/

typedef void (*PeasObjectModuleRegisterFunc) (PeasObjectModule *module);

enum {
  PROP_0,
  PROP_MODULE_NAME,
  PROP_PATH,
  PROP_SYMBOL,
  PROP_RESIDENT,
  PROP_LOCAL_LINKAGE,
  N_PROPERTIES
};

static GParamSpec *properties[N_PROPERTIES] = { NULL };

typedef struct {
  GType exten_type;
  PeasFactoryFunc func;
  gpointer user_data;
  GDestroyNotify destroy_func;
} ExtensionImplementation;

struct _PeasObjectModulePrivate {
  GModule *library;

  PeasObjectModuleRegisterFunc register_func;
  GArray *implementations;

  gchar *path;
  gchar *module_name;
  gchar *symbol;

  guint resident : 1;
  guint local_linkage : 1;
};

G_DEFINE_TYPE_WITH_PRIVATE (PeasObjectModule,
                            peas_object_module,
                            G_TYPE_TYPE_MODULE)

#define GET_PRIV(o) \
  (peas_object_module_get_instance_private (o))

#define TYPE_MISSING_PLUGIN_INFO_PROPERTY (G_TYPE_FLAG_RESERVED_ID_BIT)

static const gchar *intern_plugin_info = NULL;

static gboolean
peas_object_module_load (GTypeModule *gmodule)
{
  PeasObjectModule *module = PEAS_OBJECT_MODULE (gmodule);
  PeasObjectModulePrivate *priv = GET_PRIV (module);

  g_return_val_if_fail (priv->module_name != NULL, FALSE);

  if (priv->path == NULL)
    {
      g_return_val_if_fail (priv->resident, FALSE);
      g_return_val_if_fail (!priv->local_linkage, FALSE);

      priv->library = g_module_open (NULL, 0);
    }
  else
    {
      gchar *path;
      GModuleFlags flags = 0;

      path = g_module_build_path (priv->path, priv->module_name);

      /* g_module_build_path() will add G_MODULE_SUFFIX to the path,
       * however g_module_open() will only try to load the libtool archive
       * if there is no suffix specified. So we remove G_MODULE_SUFFIX here
       * which allows uninstalled builds to load plugins as well, as there
       * is only the .la file in the build directory.
       */
      if (G_MODULE_SUFFIX[0] != '\0' && g_str_has_suffix (path, "." G_MODULE_SUFFIX))
        path[strlen (path) - strlen (G_MODULE_SUFFIX) - 1] = '\0';

      if (priv->local_linkage)
        flags = G_MODULE_BIND_LOCAL;

      /* Bind symbols immediately to avoid errors long after loading */
      priv->library = g_module_open (path, flags);
      g_free (path);
    }

  if (priv->library == NULL)
    {
      g_warning ("Failed to load module '%s': %s",
                 priv->module_name, g_module_error ());

      return FALSE;
    }

  /* Extract the required symbol from the library */
  if (!g_module_symbol (priv->library, priv->symbol,
                        (gpointer) &priv->register_func))
    {
      g_warning ("Failed to get '%s' for module '%s': %s",
                 priv->symbol, priv->module_name, g_module_error ());
      g_module_close (priv->library);
<commit_msg>peas-object-module.c: Add fallback module search for Windows<commit_after>/*
 * peas-object-module.c
 * This file is part of libpeas
 *
 * Copyright (C) 2003 <NAME>
 * Copyright (C) 2003-2004 <NAME>
 * Copyright (C) 2005-2007 <NAME>
 * Copyright (C) 2008 <NAME>
 * Copyright (C) 2010 <NAME>
 *
 * libpeas is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * libpeas is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
 */

#include "config.h"

#include <string.h>

#include "peas-object-module.h"
#include "peas-plugin-loader.h"

/**
 * SECTION:peas-object-module
 * @short_description: Type module which allows extension registration.
 *
 * #PeasObjectModule is a subclass of #GTypeModule which allows registration
 * of extensions.  It will be used by C extensions implementors to register
 * extension implementations from within the peas_register_types module
 * function.
 *
 * Since libpeas 1.22, @extension_type can be an Abstract #GType
 * and not just an Interface #GType.
 **/

typedef void (*PeasObjectModuleRegisterFunc) (PeasObjectModule *module);

enum {
  PROP_0,
  PROP_MODULE_NAME,
  PROP_PATH,
  PROP_SYMBOL,
  PROP_RESIDENT,
  PROP_LOCAL_LINKAGE,
  N_PROPERTIES
};

static GParamSpec *properties[N_PROPERTIES] = { NULL };

typedef struct {
  GType exten_type;
  PeasFactoryFunc func;
  gpointer user_data;
  GDestroyNotify destroy_func;
} ExtensionImplementation;

struct _PeasObjectModulePrivate {
  GModule *library;

  PeasObjectModuleRegisterFunc register_func;
  GArray *implementations;

  gchar *path;
  gchar *module_name;
  gchar *symbol;

  guint resident : 1;
  guint local_linkage : 1;
};

G_DEFINE_TYPE_WITH_PRIVATE (PeasObjectModule,
                            peas_object_module,
                            G_TYPE_TYPE_MODULE)

#define GET_PRIV(o) \
  (peas_object_module_get_instance_private (o))

#define TYPE_MISSING_PLUGIN_INFO_PROPERTY (G_TYPE_FLAG_RESERVED_ID_BIT)

static const gchar *intern_plugin_info = NULL;

static gboolean
peas_object_module_load (GTypeModule *gmodule)
{
  PeasObjectModule *module = PEAS_OBJECT_MODULE (gmodule);
  PeasObjectModulePrivate *priv = GET_PRIV (module);

  g_return_val_if_fail (priv->module_name != NULL, FALSE);

  if (priv->path == NULL)
    {
      g_return_val_if_fail (priv->resident, FALSE);
      g_return_val_if_fail (!priv->local_linkage, FALSE);

      priv->library = g_module_open (NULL, 0);
    }
  else
    {
      gchar *path;
      GModuleFlags flags = 0;
      gchar *fallback_path = NULL;

#ifdef G_OS_WIN32
      if (!g_str_has_suffix (priv->module_name, "." G_MODULE_SUFFIX))
        {
          /* On Windows, g_module_build_path() will add a "lib" prefix,
           * to the module_name unless a ".dll" suffix is appended to the
           * module_name. So, we also try to look for a DLL whose filename
           * is the module name in the case that lib<module_name>.dll is
           * not found, as it is commonly the case on Meson builds and
           * also likely in other cases.
           */
          gchar *mod_file = g_strconcat (priv->module_name, "." G_MODULE_SUFFIX, NULL);
          fallback_path = g_module_build_path (priv->path, mod_file);
          g_free (mod_file);
        }
#endif

      /* g_module_build_path() will add G_MODULE_SUFFIX to the path,
       * however g_module_open() will only try to load the libtool archive
       * if there is no suffix specified. So we remove G_MODULE_SUFFIX here
       * which allows uninstalled builds to load plugins as well, as there
       * is only the .la file in the build directory.
       */
      path = g_module_build_path (priv->path, priv->module_name);

      if (G_MODULE_SUFFIX[0] != '\0' && g_str_has_suffix (path, "." G_MODULE_SUFFIX))
        path[strlen (path) - strlen (G_MODULE_SUFFIX) - 1] = '\0';

      if (priv->local_linkage)
        flags = G_MODULE_BIND_LOCAL;

      /* Bind symbols immediately to avoid errors long after loading */
      priv->library = g_module_open (path, flags);

      /* Windows case if lib<module_name>.dll cannot be found */
      if (fallback_path != NULL)
        {
          if (priv->library == NULL)
            priv->library = g_module_open (fallback_path, flags);

          g_free (fallback_path);
        }

      g_free (path);
    }

  if (priv->library == NULL)
    {
      g_warning ("Failed to load module '%s': %s",
                 priv->module_name, g_module_error ());

      return FALSE;
    }

  /* Extract the required symbol from the library */
  if (!g_module_symbol (priv->library, priv->symbol,
                        (gpointer) &priv->register_func))
    {
      g_warning ("Failed to get '%s' for module '%s': %s",
                 priv->symbol, priv->module_name, g_module_error ());
      g_module_close (priv->library);

{'fraction_non_alphanumeric': 0.09239971125090234, 'fraction_numerical': 0.011137465195421265, 'mean_word_length': 3.194636678200692, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5189263', 'n_tokens_mistral': 3139, 'n_tokens_neox': 2988, 'n_words': 958}