Made plugins and stuff use .ini files; added MooPluginLoader
parent
a739f67bc3
commit
0cc33c80e3
|
@ -18,8 +18,9 @@ mooedit_include_headers = \
|
|||
moolangmgr.h \
|
||||
moolinemark.h \
|
||||
moolineview.h \
|
||||
mooplugin-macro.h \
|
||||
mooplugin.h \
|
||||
mooplugin-loader.h \
|
||||
mooplugin-macro.h \
|
||||
mootextbuffer.h \
|
||||
mootextiter.h \
|
||||
mootextpopup.h \
|
||||
|
@ -88,6 +89,7 @@ mooedit_sources = \
|
|||
moolinemark.c \
|
||||
moolineview.c \
|
||||
mooplugin.c \
|
||||
mooplugin-loader.c \
|
||||
mootextbox.c \
|
||||
mootextbtree.c \
|
||||
mootextbuffer.c \
|
||||
|
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
* mooplugin-loader.c
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "mooedit/mooplugin-loader.h"
|
||||
#include "mooedit/mooplugin.h"
|
||||
#include "moopython/mooplugin-python.h"
|
||||
#include "mooutils/mooutils-misc.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define GROUP_MODULE "module"
|
||||
#define GROUP_PLUGIN "plugin"
|
||||
#define KEY_LOADER "type"
|
||||
#define KEY_FILE "file"
|
||||
#define KEY_ID "id"
|
||||
#define KEY_NAME "name"
|
||||
#define KEY_DESCRIPTION "description"
|
||||
#define KEY_AUTHOR "author"
|
||||
#define KEY_VERSION "version"
|
||||
#define KEY_LANGS "langs"
|
||||
#define KEY_ENABLED "enabled"
|
||||
#define KEY_VISIBLE "visible"
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *loader;
|
||||
char *file;
|
||||
char *plugin_id;
|
||||
MooPluginInfo *plugin_info;
|
||||
MooPluginParams *plugin_params;
|
||||
} ModuleInfo;
|
||||
|
||||
|
||||
static GHashTable *registered_loaders;
|
||||
static void init_loaders (void);
|
||||
GType _moo_c_plugin_loader_get_type (void);
|
||||
|
||||
|
||||
typedef MooPluginLoader MooCPluginLoader;
|
||||
typedef MooPluginLoaderClass MooCPluginLoaderClass;
|
||||
|
||||
G_DEFINE_TYPE (MooPluginLoader, moo_plugin_loader, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE (MooCPluginLoader, _moo_c_plugin_loader, MOO_TYPE_PLUGIN_LOADER)
|
||||
|
||||
|
||||
static void
|
||||
moo_plugin_loader_init (G_GNUC_UNUSED MooPluginLoader *loader)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_plugin_loader_class_init (G_GNUC_UNUSED MooPluginLoaderClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static MooPluginLoader *
|
||||
moo_plugin_loader_lookup (const char *id)
|
||||
{
|
||||
g_return_val_if_fail (id != NULL, NULL);
|
||||
init_loaders ();
|
||||
return g_hash_table_lookup (registered_loaders, id);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_plugin_loader_add (MooPluginLoader *loader,
|
||||
const char *type)
|
||||
{
|
||||
g_return_if_fail (MOO_IS_PLUGIN_LOADER (loader));
|
||||
g_return_if_fail (type != NULL);
|
||||
g_return_if_fail (registered_loaders != NULL);
|
||||
|
||||
g_hash_table_insert (registered_loaders, g_strdup (type), g_object_ref (loader));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_plugin_loader_register (MooPluginLoader *loader,
|
||||
const char *type)
|
||||
{
|
||||
g_return_if_fail (MOO_IS_PLUGIN_LOADER (loader));
|
||||
g_return_if_fail (type != NULL);
|
||||
init_loaders ();
|
||||
moo_plugin_loader_add (loader, type);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_plugin_loader_load (MooPluginLoader *loader,
|
||||
ModuleInfo *module_info,
|
||||
const char *ini_file)
|
||||
{
|
||||
if (module_info->plugin_id)
|
||||
{
|
||||
g_return_if_fail (MOO_PLUGIN_LOADER_GET_CLASS(loader)->load_plugin != NULL);
|
||||
MOO_PLUGIN_LOADER_GET_CLASS(loader)->load_plugin (loader,
|
||||
module_info->file,
|
||||
module_info->plugin_id,
|
||||
module_info->plugin_info,
|
||||
module_info->plugin_params,
|
||||
ini_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_return_if_fail (MOO_PLUGIN_LOADER_GET_CLASS(loader)->load_module != NULL);
|
||||
MOO_PLUGIN_LOADER_GET_CLASS(loader)->load_module (loader, module_info->file, ini_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
parse_plugin_info (GKeyFile *key_file,
|
||||
const char *plugin_id,
|
||||
MooPluginInfo **info_p,
|
||||
MooPluginParams **params_p)
|
||||
{
|
||||
MooPluginInfo *info;
|
||||
MooPluginParams *params;
|
||||
char *name;
|
||||
char *description;
|
||||
char *author;
|
||||
char *version;
|
||||
char *langs;
|
||||
gboolean enabled = TRUE;
|
||||
gboolean visible = TRUE;
|
||||
|
||||
name = g_key_file_get_string (key_file, GROUP_PLUGIN, KEY_NAME, NULL);
|
||||
description = g_key_file_get_string (key_file, GROUP_PLUGIN, KEY_DESCRIPTION, NULL);
|
||||
author = g_key_file_get_string (key_file, GROUP_PLUGIN, KEY_AUTHOR, NULL);
|
||||
version = g_key_file_get_string (key_file, GROUP_PLUGIN, KEY_VERSION, NULL);
|
||||
langs = g_key_file_get_string (key_file, GROUP_PLUGIN, KEY_LANGS, NULL);
|
||||
|
||||
if (g_key_file_has_key (key_file, GROUP_PLUGIN, KEY_ENABLED, NULL))
|
||||
enabled = g_key_file_get_boolean (key_file, GROUP_PLUGIN, KEY_ENABLED, NULL);
|
||||
if (g_key_file_has_key (key_file, GROUP_PLUGIN, KEY_VISIBLE, NULL))
|
||||
visible = g_key_file_get_boolean (key_file, GROUP_PLUGIN, KEY_VISIBLE, NULL);
|
||||
|
||||
info = moo_plugin_info_new (name ? name : plugin_id,
|
||||
description ? description : "",
|
||||
author ? author : "",
|
||||
version ? version : "",
|
||||
langs);
|
||||
params = moo_plugin_params_new (enabled, visible);
|
||||
|
||||
*info_p = info;
|
||||
*params_p = params;
|
||||
|
||||
g_free (name);
|
||||
g_free (description);
|
||||
g_free (author);
|
||||
g_free (version);
|
||||
g_free (langs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
check_version (const char *version,
|
||||
const char *ini_file_path)
|
||||
{
|
||||
char *dot;
|
||||
char *end = NULL;
|
||||
long major, minor;
|
||||
|
||||
dot = strchr (version, '.');
|
||||
|
||||
if (!dot || dot == version)
|
||||
goto invalid;
|
||||
|
||||
major = strtol (version, &end, 10);
|
||||
|
||||
if (end != dot)
|
||||
goto invalid;
|
||||
|
||||
minor = strtol (dot + 1, &end, 10);
|
||||
|
||||
if (*end != 0)
|
||||
goto invalid;
|
||||
|
||||
if (major != MOO_VERSION_MAJOR || minor > MOO_VERSION_MINOR)
|
||||
{
|
||||
g_warning ("module version %s is not compatible with current version %d.%d",
|
||||
version, MOO_VERSION_MAJOR, MOO_VERSION_MINOR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
invalid:
|
||||
g_warning ("invalid module version '%s' in file '%s'",
|
||||
version, ini_file_path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
parse_ini_file (const char *dir,
|
||||
const char *ini_file,
|
||||
ModuleInfo *module_info)
|
||||
{
|
||||
GKeyFile *key_file;
|
||||
GError *error = NULL;
|
||||
char *ini_file_path;
|
||||
gboolean success = FALSE;
|
||||
char *file = NULL, *loader = NULL, *id = NULL, *version = NULL;
|
||||
MooPluginInfo *info = NULL;
|
||||
MooPluginParams *params = NULL;
|
||||
|
||||
ini_file_path = g_build_filename (dir, ini_file, NULL);
|
||||
key_file = g_key_file_new ();
|
||||
|
||||
if (!g_key_file_load_from_file (key_file, ini_file_path, 0, &error))
|
||||
{
|
||||
g_warning ("error parsing plugin ini file '%s': %s", ini_file_path, error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!g_key_file_has_group (key_file, GROUP_MODULE))
|
||||
{
|
||||
g_warning ("plugin ini file '%s' does not have '" GROUP_MODULE "' group", ini_file_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(version = g_key_file_get_string (key_file, GROUP_MODULE, KEY_VERSION, &error)))
|
||||
{
|
||||
g_warning ("plugin ini file '%s' does not specify version of module system", ini_file_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!check_version (version, ini_file_path))
|
||||
goto out;
|
||||
|
||||
if (!(loader = g_key_file_get_string (key_file, GROUP_MODULE, KEY_LOADER, &error)))
|
||||
{
|
||||
g_warning ("plugin ini file '%s' does not specify module type", ini_file_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(file = g_key_file_get_string (key_file, GROUP_MODULE, KEY_FILE, &error)))
|
||||
{
|
||||
g_warning ("plugin ini file '%s' does not specify module file", ini_file_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!g_path_is_absolute (file))
|
||||
{
|
||||
char *tmp = file;
|
||||
file = g_build_filename (dir, file, NULL);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
if (g_key_file_has_group (key_file, GROUP_PLUGIN))
|
||||
{
|
||||
if (!(id = g_key_file_get_string (key_file, GROUP_PLUGIN, KEY_ID, NULL)))
|
||||
{
|
||||
g_warning ("plugin ini file '%s' does not specify plugin id", ini_file_path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!parse_plugin_info (key_file, id, &info, ¶ms))
|
||||
goto out;
|
||||
}
|
||||
|
||||
module_info->loader = loader;
|
||||
module_info->file = g_build_path (dir, file, NULL);
|
||||
module_info->plugin_id = id;
|
||||
module_info->plugin_info = info;
|
||||
module_info->plugin_params = params;
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (error)
|
||||
g_error_free (error);
|
||||
g_free (ini_file_path);
|
||||
g_key_file_free (key_file);
|
||||
g_free (file);
|
||||
g_free (version);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
g_free (loader);
|
||||
g_free (id);
|
||||
moo_plugin_info_free (info);
|
||||
moo_plugin_params_free (params);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
module_info_destroy (ModuleInfo *module_info)
|
||||
{
|
||||
g_free (module_info->loader);
|
||||
g_free (module_info->file);
|
||||
g_free (module_info->plugin_id);
|
||||
moo_plugin_info_free (module_info->plugin_info);
|
||||
moo_plugin_params_free (module_info->plugin_params);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_moo_plugin_load (const char *dir,
|
||||
const char *ini_file)
|
||||
{
|
||||
ModuleInfo module_info;
|
||||
MooPluginLoader *loader;
|
||||
char *ini_file_path;
|
||||
|
||||
g_return_if_fail (dir != NULL && ini_file != NULL);
|
||||
|
||||
if (!parse_ini_file (dir, ini_file, &module_info))
|
||||
return;
|
||||
|
||||
loader = moo_plugin_loader_lookup (module_info.loader);
|
||||
|
||||
if (!loader)
|
||||
{
|
||||
/* XXX */
|
||||
g_warning ("unknown module type '%s' in file '%s'", module_info.loader, ini_file);
|
||||
module_info_destroy (&module_info);
|
||||
return;
|
||||
}
|
||||
|
||||
ini_file_path = g_build_filename (dir, ini_file, NULL);
|
||||
moo_plugin_loader_load (loader, &module_info, ini_file_path);
|
||||
|
||||
g_free (ini_file_path);
|
||||
module_info_destroy (&module_info);
|
||||
}
|
||||
|
||||
|
||||
static GModule *
|
||||
module_open (const char *path)
|
||||
{
|
||||
GModule *module;
|
||||
|
||||
_moo_disable_win32_error_message ();
|
||||
module = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
_moo_enable_win32_error_message ();
|
||||
|
||||
if (!module)
|
||||
g_warning ("could not open module '%s': %s", path, g_module_error ());
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load_c_module (G_GNUC_UNUSED MooPluginLoader *loader,
|
||||
const char *module_file,
|
||||
G_GNUC_UNUSED const char *ini_file)
|
||||
{
|
||||
MooModuleInitFunc init_func;
|
||||
GModule *module;
|
||||
|
||||
module = module_open (module_file);
|
||||
|
||||
if (!module)
|
||||
return;
|
||||
|
||||
if (g_module_symbol (module, MOO_MODULE_INIT_FUNC_NAME,
|
||||
(gpointer*) &init_func) &&
|
||||
init_func ())
|
||||
{
|
||||
g_module_make_resident (module);
|
||||
}
|
||||
|
||||
g_module_close (module);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load_c_plugin (G_GNUC_UNUSED MooPluginLoader *loader,
|
||||
const char *plugin_file,
|
||||
const char *plugin_id,
|
||||
MooPluginInfo *info,
|
||||
MooPluginParams *params,
|
||||
G_GNUC_UNUSED const char *ini_file)
|
||||
{
|
||||
MooPluginModuleInitFunc init_func;
|
||||
GModule *module;
|
||||
GType type = 0;
|
||||
|
||||
module = module_open (plugin_file);
|
||||
|
||||
if (!module)
|
||||
return;
|
||||
|
||||
if (!g_module_symbol (module, MOO_PLUGIN_INIT_FUNC_NAME, (gpointer*) &init_func))
|
||||
{
|
||||
g_module_close (module);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!init_func (&type))
|
||||
{
|
||||
g_module_close (module);
|
||||
return;
|
||||
}
|
||||
|
||||
g_return_if_fail (g_type_is_a (type, MOO_TYPE_PLUGIN));
|
||||
|
||||
if (!moo_plugin_register (plugin_id, type, info, params))
|
||||
{
|
||||
g_module_close (module);
|
||||
return;
|
||||
}
|
||||
|
||||
g_module_make_resident (module);
|
||||
g_module_close (module);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_c_plugin_loader_class_init (MooPluginLoaderClass *klass)
|
||||
{
|
||||
klass->load_module = load_c_module;
|
||||
klass->load_plugin = load_c_plugin;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_c_plugin_loader_init (G_GNUC_UNUSED MooPluginLoader *loader)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_loaders (void)
|
||||
{
|
||||
MooPluginLoader *loader;
|
||||
|
||||
if (registered_loaders)
|
||||
return;
|
||||
|
||||
registered_loaders = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, g_object_unref);
|
||||
|
||||
loader = g_object_new (_moo_c_plugin_loader_get_type (), NULL);
|
||||
moo_plugin_loader_add (loader, "C");
|
||||
g_object_unref (loader);
|
||||
|
||||
#ifdef MOO_USE_PYGTK
|
||||
loader = _moo_python_get_plugin_loader ();
|
||||
moo_plugin_loader_add (loader, MOO_PYTHON_PLUGIN_LOADER_ID);
|
||||
g_object_unref (loader);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* mooplugin-loader.h
|
||||
*
|
||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef __MOO_PLUGIN_LOADER_H__
|
||||
#define __MOO_PLUGIN_LOADER_H__
|
||||
|
||||
#include <mooedit/mooplugin.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define MOO_TYPE_PLUGIN_LOADER (moo_plugin_loader_get_type ())
|
||||
#define MOO_PLUGIN_LOADER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_PLUGIN_LOADER, MooPluginLoader))
|
||||
#define MOO_PLUGIN_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_PLUGIN_LOADER, MooPluginLoaderClass))
|
||||
#define MOO_IS_PLUGIN_LOADER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOO_TYPE_PLUGIN_LOADER))
|
||||
#define MOO_IS_PLUGIN_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_PLUGIN_LOADER))
|
||||
#define MOO_PLUGIN_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_PLUGIN_LOADER, MooPluginLoaderClass))
|
||||
|
||||
typedef struct _MooPluginLoadInfo MooPluginLoadInfo;
|
||||
typedef struct _MooPluginLoader MooPluginLoader;
|
||||
typedef struct _MooPluginLoaderClass MooPluginLoaderClass;
|
||||
|
||||
struct _MooPluginLoader
|
||||
{
|
||||
GObject base;
|
||||
};
|
||||
|
||||
struct _MooPluginLoaderClass
|
||||
{
|
||||
GObjectClass base_class;
|
||||
|
||||
void (*load_module) (MooPluginLoader *loader,
|
||||
const char *module_file,
|
||||
const char *ini_file);
|
||||
|
||||
void (*load_plugin) (MooPluginLoader *loader,
|
||||
const char *plugin_file,
|
||||
const char *plugin_id,
|
||||
MooPluginInfo *info,
|
||||
MooPluginParams *params,
|
||||
const char *ini_file);
|
||||
};
|
||||
|
||||
|
||||
GType moo_plugin_loader_get_type (void) G_GNUC_CONST;
|
||||
void moo_plugin_loader_register (MooPluginLoader *loader,
|
||||
const char *type);
|
||||
|
||||
void _moo_plugin_load (const char *dir,
|
||||
const char *ini_file);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MOO_PLUGIN_LOADER_H__ */
|
|
@ -17,25 +17,21 @@
|
|||
#include <mooedit/mooplugin.h>
|
||||
|
||||
|
||||
#define MOO_MODULE_CHECK_VERSION() \
|
||||
G_STMT_START { \
|
||||
if (!moo_module_check_version (MOO_MODULE_VERSION_MAJOR, \
|
||||
MOO_MODULE_VERSION_MINOR)) \
|
||||
return FALSE; \
|
||||
} G_STMT_END
|
||||
|
||||
|
||||
#define MOO_PLUGIN_INIT_FUNC_DECL \
|
||||
G_MODULE_EXPORT gboolean \
|
||||
MOO_PLUGIN_INIT_FUNC (void)
|
||||
MOO_PLUGIN_INIT_FUNC (GType *type)
|
||||
|
||||
#define MOO_MODULE_INIT_FUNC_DECL \
|
||||
G_MODULE_EXPORT gboolean \
|
||||
MOO_MODULE_INIT_FUNC (void)
|
||||
|
||||
|
||||
#define MOO_PLUGIN_DEFINE_INFO(plugin_name__,id__,name__, \
|
||||
#define MOO_PLUGIN_DEFINE_INFO(plugin_name__,name__, \
|
||||
description__,author__,version__, \
|
||||
langs__) \
|
||||
\
|
||||
static const MooPluginInfo plugin_name__##_plugin_info = \
|
||||
{(char*) id__, (char*) name__, (char*) description__, \
|
||||
{(char*) name__, (char*) description__, \
|
||||
(char*) author__, (char*) version__, (char*) langs__};
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#endif
|
||||
|
||||
#include "mooedit/mooplugin.h"
|
||||
#include "mooedit/mooplugin-loader.h"
|
||||
#include "mooedit/moopluginprefs-glade.h"
|
||||
#include "mooedit/plugins/mooeditplugins.h"
|
||||
#include "moopython/mooplugin-python.h"
|
||||
|
@ -203,7 +204,8 @@ moo_plugin_class_init (MooPluginClass *klass)
|
|||
|
||||
|
||||
gboolean
|
||||
moo_plugin_register (GType type,
|
||||
moo_plugin_register (const char *id,
|
||||
GType type,
|
||||
const MooPluginInfo *info,
|
||||
const MooPluginParams *params)
|
||||
{
|
||||
|
@ -212,6 +214,9 @@ moo_plugin_register (GType type,
|
|||
char *prefs_key;
|
||||
GSList *l, *windows;
|
||||
|
||||
g_return_val_if_fail (id != NULL && id[0] != 0, FALSE);
|
||||
g_return_val_if_fail (g_utf8_validate (id, -1, NULL), FALSE);
|
||||
|
||||
g_return_val_if_fail (g_type_is_a (type, MOO_TYPE_PLUGIN), FALSE);
|
||||
|
||||
klass = g_type_class_ref (type);
|
||||
|
@ -232,6 +237,7 @@ moo_plugin_register (GType type,
|
|||
}
|
||||
|
||||
plugin = g_object_new (type, NULL);
|
||||
plugin->id = g_strdup (id);
|
||||
plugin->info = moo_plugin_info_copy ((MooPluginInfo*) info);
|
||||
plugin->params = params ? moo_plugin_params_copy ((MooPluginParams*) params) :
|
||||
moo_plugin_params_new (TRUE, TRUE);
|
||||
|
@ -668,8 +674,7 @@ moo_doc_plugin_lookup (const char *plugin_id,
|
|||
static gboolean
|
||||
plugin_info_check (const MooPluginInfo *info)
|
||||
{
|
||||
return info && info->id && info->id[0] &&
|
||||
g_utf8_validate (info->id, -1, NULL) &&
|
||||
return info &&
|
||||
info->name && g_utf8_validate (info->name, -1, NULL) &&
|
||||
info->description && g_utf8_validate (info->description, -1, NULL);
|
||||
}
|
||||
|
@ -805,8 +810,8 @@ gboolean
|
|||
moo_module_check_version (guint major,
|
||||
guint minor)
|
||||
{
|
||||
return major == MOO_MODULE_VERSION_MAJOR &&
|
||||
minor <= MOO_MODULE_VERSION_MINOR;
|
||||
return major == MOO_VERSION_MAJOR &&
|
||||
minor <= MOO_VERSION_MINOR;
|
||||
}
|
||||
|
||||
|
||||
|
@ -835,7 +840,6 @@ moo_plugin_##what (MooPlugin *plugin) \
|
|||
return plugin->info->what; \
|
||||
}
|
||||
|
||||
DEFINE_GETTER(id)
|
||||
DEFINE_GETTER(name)
|
||||
DEFINE_GETTER(description)
|
||||
DEFINE_GETTER(version)
|
||||
|
@ -843,36 +847,14 @@ DEFINE_GETTER(author)
|
|||
|
||||
#undef DEFINE_GETTER
|
||||
|
||||
|
||||
static gboolean
|
||||
moo_plugin_read_module (GModule *module,
|
||||
const char *name)
|
||||
const char *
|
||||
moo_plugin_id (MooPlugin *plugin)
|
||||
{
|
||||
MooPluginModuleInitFunc init_func;
|
||||
|
||||
g_return_val_if_fail (module != NULL, FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
|
||||
if (!g_module_symbol (module, MOO_PLUGIN_INIT_FUNC_NAME,
|
||||
(gpointer*) &init_func))
|
||||
return FALSE;
|
||||
|
||||
return init_func ();
|
||||
g_return_val_if_fail (MOO_IS_PLUGIN (plugin), NULL);
|
||||
return plugin->id;
|
||||
}
|
||||
|
||||
|
||||
static GModule *
|
||||
module_open (const char *path)
|
||||
{
|
||||
GModule *module;
|
||||
|
||||
_moo_disable_win32_error_message ();
|
||||
module = g_module_open (path, G_MODULE_BIND_LOCAL);
|
||||
_moo_enable_win32_error_message ();
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
static void
|
||||
moo_plugin_read_dir (const char *path)
|
||||
{
|
||||
|
@ -888,30 +870,12 @@ moo_plugin_read_dir (const char *path)
|
|||
|
||||
while ((name = g_dir_read_name (dir)))
|
||||
{
|
||||
char *module_path, *prefix, *suffix;
|
||||
GModule *module;
|
||||
|
||||
if (!g_str_has_suffix (name, "." G_MODULE_SUFFIX))
|
||||
continue;
|
||||
|
||||
suffix = g_strrstr (name, "." G_MODULE_SUFFIX);
|
||||
prefix = g_strndup (name, suffix - name);
|
||||
|
||||
module_path = g_build_filename (path, name, NULL);
|
||||
module = module_open (module_path);
|
||||
|
||||
if (module)
|
||||
if (g_str_has_suffix (name, ".ini"))
|
||||
{
|
||||
if (!moo_plugin_read_module (module, prefix))
|
||||
g_module_close (module);
|
||||
char *tmp = g_strdup (name);
|
||||
_moo_plugin_load (path, tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("%s: %s", G_STRLOC, g_module_error ());
|
||||
}
|
||||
|
||||
g_free (prefix);
|
||||
g_free (module_path);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
|
@ -937,9 +901,6 @@ moo_plugin_init_builtin (void)
|
|||
#endif
|
||||
_moo_active_strings_plugin_init ();
|
||||
_moo_completion_plugin_init ();
|
||||
#ifdef MOO_USE_PYGTK
|
||||
_moo_python_plugin_init ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1150,8 +1111,7 @@ moo_plugin_set_win_plugin_type (MooPlugin *plugin,
|
|||
|
||||
|
||||
MooPluginInfo *
|
||||
moo_plugin_info_new (const char *id,
|
||||
const char *name,
|
||||
moo_plugin_info_new (const char *name,
|
||||
const char *description,
|
||||
const char *author,
|
||||
const char *version,
|
||||
|
@ -1159,10 +1119,9 @@ moo_plugin_info_new (const char *id,
|
|||
{
|
||||
MooPluginInfo *info;
|
||||
|
||||
g_return_val_if_fail (id && name, NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
info = g_new0 (MooPluginInfo, 1);
|
||||
info->id = g_strdup (id);
|
||||
info->name = g_strdup (name);
|
||||
info->description = description ? g_strdup (description) : g_strdup ("");
|
||||
info->author = author ? g_strdup (author) : g_strdup ("");
|
||||
|
@ -1177,7 +1136,7 @@ MooPluginInfo *
|
|||
moo_plugin_info_copy (MooPluginInfo *info)
|
||||
{
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
return moo_plugin_info_new (info->id, info->name, info->description,
|
||||
return moo_plugin_info_new (info->name, info->description,
|
||||
info->author, info->version, info->langs);
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1146,6 @@ moo_plugin_info_free (MooPluginInfo *info)
|
|||
{
|
||||
if (info)
|
||||
{
|
||||
g_free (info->id);
|
||||
g_free (info->name);
|
||||
g_free (info->description);
|
||||
g_free (info->author);
|
||||
|
|
|
@ -21,11 +21,10 @@ G_BEGIN_DECLS
|
|||
#define MOO_PLUGIN_PREFS_ROOT "Plugins"
|
||||
#define MOO_PLUGIN_DIR_BASENAME "plugins"
|
||||
|
||||
#define MOO_MODULE_VERSION_MAJOR 2
|
||||
#define MOO_MODULE_VERSION_MINOR 0
|
||||
|
||||
#define MOO_PLUGIN_INIT_FUNC moo_module_init
|
||||
#define MOO_PLUGIN_INIT_FUNC_NAME "moo_module_init"
|
||||
#define MOO_PLUGIN_INIT_FUNC moo_plugin_module_init
|
||||
#define MOO_PLUGIN_INIT_FUNC_NAME "moo_plugin_module_init"
|
||||
#define MOO_MODULE_INIT_FUNC moo_module_init
|
||||
#define MOO_MODULE_INIT_FUNC_NAME "moo_module_init"
|
||||
|
||||
#define MOO_TYPE_PLUGIN (moo_plugin_get_type ())
|
||||
#define MOO_PLUGIN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_PLUGIN, MooPlugin))
|
||||
|
@ -63,7 +62,8 @@ typedef struct _MooDocPluginClass MooDocPluginClass;
|
|||
typedef struct _MooPluginMeth MooPluginMeth;
|
||||
|
||||
|
||||
typedef gboolean (*MooPluginModuleInitFunc) (void);
|
||||
typedef gboolean (*MooModuleInitFunc) (void);
|
||||
typedef gboolean (*MooPluginModuleInitFunc) (GType *type);
|
||||
|
||||
typedef gboolean (*MooPluginInitFunc) (MooPlugin *plugin);
|
||||
typedef void (*MooPluginDeinitFunc) (MooPlugin *plugin);
|
||||
|
@ -104,13 +104,10 @@ struct _MooPluginParams
|
|||
|
||||
struct _MooPluginInfo
|
||||
{
|
||||
char *id;
|
||||
|
||||
char *name;
|
||||
char *description;
|
||||
char *author;
|
||||
char *version;
|
||||
|
||||
char *langs;
|
||||
};
|
||||
|
||||
|
@ -120,6 +117,7 @@ struct _MooPlugin
|
|||
|
||||
gboolean initialized;
|
||||
|
||||
char *id;
|
||||
GQuark id_quark;
|
||||
MooPluginInfo *info;
|
||||
MooPluginParams *params;
|
||||
|
@ -183,7 +181,8 @@ GType moo_plugin_params_get_type (void) G_GNUC_CONST;
|
|||
gboolean moo_module_check_version (guint major,
|
||||
guint minor);
|
||||
|
||||
gboolean moo_plugin_register (GType type,
|
||||
gboolean moo_plugin_register (const char *id,
|
||||
GType type,
|
||||
const MooPluginInfo *info,
|
||||
const MooPluginParams *params);
|
||||
void moo_plugin_unregister (GType type);
|
||||
|
@ -222,8 +221,7 @@ void moo_plugin_set_doc_plugin_type (MooPlugin *plugin,
|
|||
void moo_plugin_set_win_plugin_type (MooPlugin *plugin,
|
||||
GType type);
|
||||
|
||||
MooPluginInfo *moo_plugin_info_new (const char *id,
|
||||
const char *name,
|
||||
MooPluginInfo *moo_plugin_info_new (const char *name,
|
||||
const char *description,
|
||||
const char *author,
|
||||
const char *version,
|
||||
|
|
|
@ -1146,7 +1146,7 @@ _as_plugin_save_config (MooConfig *config,
|
|||
}
|
||||
|
||||
|
||||
MOO_PLUGIN_DEFINE_INFO (as, AS_PLUGIN_ID,
|
||||
MOO_PLUGIN_DEFINE_INFO (as,
|
||||
"Active Strings", "Very active",
|
||||
"Yevgen Muntyan <muntyan@tamu.edu>",
|
||||
MOO_VERSION, NULL);
|
||||
|
@ -1160,7 +1160,8 @@ MOO_PLUGIN_DEFINE_FULL (AS, as,
|
|||
gboolean
|
||||
_moo_active_strings_plugin_init (void)
|
||||
{
|
||||
MOO_MODULE_CHECK_VERSION ();
|
||||
return moo_plugin_register (as_plugin_get_type (),
|
||||
&as_plugin_info, NULL);
|
||||
return moo_plugin_register (AS_PLUGIN_ID,
|
||||
as_plugin_get_type (),
|
||||
&as_plugin_info,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ cmpl_plugin_deinit (CmplPlugin *plugin)
|
|||
}
|
||||
|
||||
|
||||
MOO_PLUGIN_DEFINE_INFO (cmpl, CMPL_PLUGIN_ID,
|
||||
MOO_PLUGIN_DEFINE_INFO (cmpl,
|
||||
"Completion", "Makes it complete",
|
||||
"Yevgen Muntyan <muntyan@tamu.edu>",
|
||||
MOO_VERSION, NULL)
|
||||
|
@ -87,7 +87,8 @@ MOO_PLUGIN_DEFINE_FULL (Cmpl, cmpl,
|
|||
gboolean
|
||||
_moo_completion_plugin_init (void)
|
||||
{
|
||||
MOO_MODULE_CHECK_VERSION ();
|
||||
return moo_plugin_register (cmpl_plugin_get_type (),
|
||||
&cmpl_plugin_info, NULL);
|
||||
return moo_plugin_register (CMPL_PLUGIN_ID,
|
||||
cmpl_plugin_get_type (),
|
||||
&cmpl_plugin_info,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -1361,7 +1361,7 @@ _moo_file_selector_update_tools (MooPlugin *plugin)
|
|||
}
|
||||
|
||||
|
||||
MOO_PLUGIN_DEFINE_INFO (file_selector, MOO_FILE_SELECTOR_PLUGIN_ID,
|
||||
MOO_PLUGIN_DEFINE_INFO (file_selector,
|
||||
"File Selector", "File selector pane for editor window",
|
||||
"Yevgen Muntyan <muntyan@tamu.edu>",
|
||||
MOO_VERSION, NULL);
|
||||
|
@ -1387,9 +1387,10 @@ _moo_file_selector_plugin_init (void)
|
|||
{
|
||||
GType ptype = file_selector_plugin_get_type ();
|
||||
|
||||
MOO_MODULE_CHECK_VERSION ();
|
||||
|
||||
if (!moo_plugin_register (ptype, &file_selector_plugin_info, NULL))
|
||||
if (!moo_plugin_register (MOO_FILE_SELECTOR_PLUGIN_ID,
|
||||
ptype,
|
||||
&file_selector_plugin_info,
|
||||
NULL))
|
||||
return FALSE;
|
||||
|
||||
moo_plugin_method_new ("get-widget", ptype,
|
||||
|
|
|
@ -887,7 +887,7 @@ output_activate (WindowStuff *stuff,
|
|||
}
|
||||
|
||||
|
||||
MOO_PLUGIN_DEFINE_INFO (find, FIND_PLUGIN_ID,
|
||||
MOO_PLUGIN_DEFINE_INFO (find,
|
||||
"Find", "Finds everything",
|
||||
"Yevgen Muntyan <muntyan@tamu.edu>",
|
||||
MOO_VERSION, NULL);
|
||||
|
@ -903,7 +903,8 @@ MOO_PLUGIN_DEFINE_FULL (Find, find,
|
|||
gboolean
|
||||
_moo_find_plugin_init (void)
|
||||
{
|
||||
MOO_MODULE_CHECK_VERSION ();
|
||||
return moo_plugin_register (find_plugin_get_type (),
|
||||
&find_plugin_info, NULL);
|
||||
return moo_plugin_register (FIND_PLUGIN_ID,
|
||||
find_plugin_get_type (),
|
||||
&find_plugin_info,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "mooutils/moopython.h"
|
||||
#include "mooutils/mooutils-misc.h"
|
||||
#include "moopython/pygtk/moo-pygtk.h"
|
||||
#include "mooedit/mooplugin-macro.h"
|
||||
#include "mooedit/mooplugin-loader.h"
|
||||
|
||||
#define PLUGIN_SUFFIX ".py"
|
||||
#define LIBDIR "lib"
|
||||
|
@ -242,119 +242,119 @@ moo_python_api_init (void)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_python_plugin_read_file (const char *path)
|
||||
{
|
||||
PyObject *mod, *code;
|
||||
char *modname = NULL, *content = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
if (!g_file_get_contents (path, &content, NULL, &error))
|
||||
{
|
||||
g_warning ("%s: could not read plugin file", G_STRLOC);
|
||||
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
modname = g_strdup_printf ("moo_plugin_%08x%08x", g_random_int (), g_random_int ());
|
||||
code = Py_CompileString (content, path, Py_file_input);
|
||||
|
||||
if (!code)
|
||||
{
|
||||
PyErr_Print ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
mod = PyImport_ExecCodeModule (modname, code);
|
||||
Py_DECREF (code);
|
||||
|
||||
if (!mod)
|
||||
{
|
||||
PyErr_Print ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
Py_DECREF (mod);
|
||||
|
||||
out:
|
||||
g_free (content);
|
||||
g_free (modname);
|
||||
}
|
||||
// static void
|
||||
// moo_python_plugin_read_file (const char *path)
|
||||
// {
|
||||
// PyObject *mod, *code;
|
||||
// char *modname = NULL, *content = NULL;
|
||||
// GError *error = NULL;
|
||||
//
|
||||
// g_return_if_fail (path != NULL);
|
||||
//
|
||||
// if (!g_file_get_contents (path, &content, NULL, &error))
|
||||
// {
|
||||
// g_warning ("%s: could not read plugin file", G_STRLOC);
|
||||
// g_warning ("%s: %s", G_STRLOC, error->message);
|
||||
// g_error_free (error);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// modname = g_strdup_printf ("moo_plugin_%08x%08x", g_random_int (), g_random_int ());
|
||||
// code = Py_CompileString (content, path, Py_file_input);
|
||||
//
|
||||
// if (!code)
|
||||
// {
|
||||
// PyErr_Print ();
|
||||
// goto out;
|
||||
// }
|
||||
//
|
||||
// mod = PyImport_ExecCodeModule (modname, code);
|
||||
// Py_DECREF (code);
|
||||
//
|
||||
// if (!mod)
|
||||
// {
|
||||
// PyErr_Print ();
|
||||
// goto out;
|
||||
// }
|
||||
//
|
||||
// Py_DECREF (mod);
|
||||
//
|
||||
// out:
|
||||
// g_free (content);
|
||||
// g_free (modname);
|
||||
// }
|
||||
|
||||
|
||||
static void
|
||||
moo_python_plugin_read_dir (const char *path)
|
||||
{
|
||||
GDir *dir;
|
||||
const char *name;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
|
||||
dir = g_dir_open (path, 0, NULL);
|
||||
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
while ((name = g_dir_read_name (dir)))
|
||||
{
|
||||
char *file_path, *prefix, *suffix;
|
||||
|
||||
if (!g_str_has_suffix (name, PLUGIN_SUFFIX))
|
||||
continue;
|
||||
|
||||
suffix = g_strrstr (name, PLUGIN_SUFFIX);
|
||||
prefix = g_strndup (name, suffix - name);
|
||||
|
||||
file_path = g_build_filename (path, name, NULL);
|
||||
|
||||
/* don't try broken links */
|
||||
if (g_file_test (file_path, G_FILE_TEST_EXISTS))
|
||||
moo_python_plugin_read_file (file_path);
|
||||
|
||||
g_free (prefix);
|
||||
g_free (file_path);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
}
|
||||
// static void
|
||||
// moo_python_plugin_read_dir (const char *path)
|
||||
// {
|
||||
// GDir *dir;
|
||||
// const char *name;
|
||||
//
|
||||
// g_return_if_fail (path != NULL);
|
||||
//
|
||||
// dir = g_dir_open (path, 0, NULL);
|
||||
//
|
||||
// if (!dir)
|
||||
// return;
|
||||
//
|
||||
// while ((name = g_dir_read_name (dir)))
|
||||
// {
|
||||
// char *file_path, *prefix, *suffix;
|
||||
//
|
||||
// if (!g_str_has_suffix (name, PLUGIN_SUFFIX))
|
||||
// continue;
|
||||
//
|
||||
// suffix = g_strrstr (name, PLUGIN_SUFFIX);
|
||||
// prefix = g_strndup (name, suffix - name);
|
||||
//
|
||||
// file_path = g_build_filename (path, name, NULL);
|
||||
//
|
||||
// /* don't try broken links */
|
||||
// if (g_file_test (file_path, G_FILE_TEST_EXISTS))
|
||||
// moo_python_plugin_read_file (file_path);
|
||||
//
|
||||
// g_free (prefix);
|
||||
// g_free (file_path);
|
||||
// }
|
||||
//
|
||||
// g_dir_close (dir);
|
||||
// }
|
||||
|
||||
|
||||
static void
|
||||
moo_python_plugin_read_dirs (void)
|
||||
{
|
||||
char **d;
|
||||
char **dirs = moo_plugin_get_dirs ();
|
||||
PyObject *sys = NULL, *path = NULL;
|
||||
|
||||
sys = PyImport_ImportModule ((char*) "sys");
|
||||
|
||||
if (sys)
|
||||
path = PyObject_GetAttrString (sys, (char*) "path");
|
||||
|
||||
if (!path || !PyList_Check (path))
|
||||
{
|
||||
g_critical ("%s: oops", G_STRLOC);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (d = dirs; d && *d; ++d)
|
||||
{
|
||||
char *libdir = g_build_filename (*d, LIBDIR, NULL);
|
||||
PyObject *s = PyString_FromString (libdir);
|
||||
PyList_Append (path, s);
|
||||
Py_XDECREF (s);
|
||||
g_free (libdir);
|
||||
}
|
||||
}
|
||||
|
||||
for (d = dirs; d && *d; ++d)
|
||||
moo_python_plugin_read_dir (*d);
|
||||
|
||||
g_strfreev (dirs);
|
||||
}
|
||||
// static void
|
||||
// moo_python_plugin_read_dirs (void)
|
||||
// {
|
||||
// char **d;
|
||||
// char **dirs = moo_plugin_get_dirs ();
|
||||
// PyObject *sys = NULL, *path = NULL;
|
||||
//
|
||||
// sys = PyImport_ImportModule ((char*) "sys");
|
||||
//
|
||||
// if (sys)
|
||||
// path = PyObject_GetAttrString (sys, (char*) "path");
|
||||
//
|
||||
// if (!path || !PyList_Check (path))
|
||||
// {
|
||||
// g_critical ("%s: oops", G_STRLOC);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// for (d = dirs; d && *d; ++d)
|
||||
// {
|
||||
// char *libdir = g_build_filename (*d, LIBDIR, NULL);
|
||||
// PyObject *s = PyString_FromString (libdir);
|
||||
// PyList_Append (path, s);
|
||||
// Py_XDECREF (s);
|
||||
// g_free (libdir);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (d = dirs; d && *d; ++d)
|
||||
// moo_python_plugin_read_dir (*d);
|
||||
//
|
||||
// g_strfreev (dirs);
|
||||
// }
|
||||
|
||||
|
||||
static gboolean
|
||||
|
@ -374,10 +374,10 @@ init_moo_pygtk (void)
|
|||
}
|
||||
|
||||
|
||||
gboolean
|
||||
_moo_python_plugin_init (void)
|
||||
static gboolean
|
||||
moo_python_stuff_init (void)
|
||||
{
|
||||
if (!in_moo_module)
|
||||
if (!in_moo_module && !main_mod)
|
||||
{
|
||||
if (!moo_python_api_init ())
|
||||
return FALSE;
|
||||
|
@ -396,7 +396,22 @@ _moo_python_plugin_init (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
moo_python_plugin_read_dirs ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
_moo_python_plugin_init (void)
|
||||
{
|
||||
MooPluginLoader *loader;
|
||||
|
||||
if (!moo_python_stuff_init ())
|
||||
return FALSE;
|
||||
|
||||
loader = _moo_python_get_plugin_loader ();
|
||||
moo_plugin_loader_register (loader, MOO_PYTHON_PLUGIN_LOADER_ID);
|
||||
g_object_unref (loader);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -411,11 +426,9 @@ _moo_python_plugin_deinit (void)
|
|||
|
||||
|
||||
#ifdef MOO_PYTHON_PLUGIN
|
||||
MOO_PLUGIN_INIT_FUNC_DECL;
|
||||
MOO_PLUGIN_INIT_FUNC_DECL
|
||||
MOO_MODULE_INIT_FUNC_DECL;
|
||||
MOO_MODULE_INIT_FUNC_DECL
|
||||
{
|
||||
MOO_MODULE_CHECK_VERSION ();
|
||||
|
||||
return !moo_python_running () &&
|
||||
_moo_python_plugin_init ();
|
||||
}
|
||||
|
@ -433,3 +446,179 @@ void initmoo (void)
|
|||
_moo_pygtk_init ();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Python plugin loader
|
||||
*/
|
||||
|
||||
GType _moo_python_plugin_loader_get_type (void);
|
||||
typedef MooPluginLoader MooPythonPluginLoader;
|
||||
typedef MooPluginLoaderClass MooPythonPluginLoaderClass;
|
||||
G_DEFINE_TYPE (MooPythonPluginLoader, _moo_python_plugin_loader, MOO_TYPE_PLUGIN_LOADER)
|
||||
|
||||
|
||||
// static gboolean
|
||||
// push_path_dir (const char *filename)
|
||||
// {
|
||||
// PyObject *sys = NULL, *path = NULL;
|
||||
// char *dirname;
|
||||
//
|
||||
// /* XXX encoding */
|
||||
// dirname = g_path_get_dirname (filename);
|
||||
// g_return_val_if_fail (dirname != NULL, FALSE);
|
||||
//
|
||||
// sys = PyImport_ImportModule ((char*) "sys");
|
||||
//
|
||||
// if (sys)
|
||||
// path = PyObject_GetAttrString (sys, (char*) "path");
|
||||
//
|
||||
// if (!path || !PyList_Check (path))
|
||||
// {
|
||||
// g_critical ("%s: oops", G_STRLOC);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// for (d = dirs; d && *d; ++d)
|
||||
// {
|
||||
// char *libdir = g_build_filename (*d, LIBDIR, NULL);
|
||||
// PyObject *s = PyString_FromString (libdir);
|
||||
// PyList_Append (path, s);
|
||||
// Py_XDECREF (s);
|
||||
// g_free (libdir);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (d = dirs; d && *d; ++d)
|
||||
// moo_python_plugin_read_dir (*d);
|
||||
//
|
||||
// g_strfreev (dirs);
|
||||
// }
|
||||
|
||||
|
||||
static PyObject *
|
||||
load_file (const char *path)
|
||||
{
|
||||
PyObject *mod = NULL;
|
||||
PyObject *code;
|
||||
char *modname = NULL, *content = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
|
||||
if (!moo_python_stuff_init ())
|
||||
return NULL;
|
||||
|
||||
if (!g_file_get_contents (path, &content, NULL, &error))
|
||||
{
|
||||
g_warning ("could not read file '%s': %s", path, error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modname = g_strdup_printf ("moo_module_%08x", g_random_int ());
|
||||
code = Py_CompileString (content, path, Py_file_input);
|
||||
|
||||
if (!code)
|
||||
{
|
||||
PyErr_Print ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
mod = PyImport_ExecCodeModule (modname, code);
|
||||
Py_DECREF (code);
|
||||
|
||||
if (!mod)
|
||||
{
|
||||
PyErr_Print ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (content);
|
||||
g_free (modname);
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load_python_module (G_GNUC_UNUSED MooPluginLoader *loader,
|
||||
const char *module_file,
|
||||
G_GNUC_UNUSED const char *ini_file)
|
||||
{
|
||||
Py_XDECREF (load_file (module_file));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load_python_plugin (G_GNUC_UNUSED MooPluginLoader *loader,
|
||||
const char *plugin_file,
|
||||
const char *plugin_id,
|
||||
MooPluginInfo *info,
|
||||
MooPluginParams *params,
|
||||
G_GNUC_UNUSED const char *ini_file)
|
||||
{
|
||||
PyObject *mod;
|
||||
PyObject *py_plugin_type;
|
||||
GType plugin_type;
|
||||
|
||||
if (!(mod = load_file (plugin_file)))
|
||||
return;
|
||||
|
||||
py_plugin_type = PyObject_GetAttrString (mod, (char*) "__plugin__");
|
||||
|
||||
if (!py_plugin_type)
|
||||
{
|
||||
g_warning ("file %s doesn't define __plugin__ attribute",
|
||||
plugin_file);
|
||||
}
|
||||
else if (py_plugin_type == Py_None)
|
||||
{
|
||||
/* it's fine, ignore */
|
||||
}
|
||||
else if (!PyType_Check (py_plugin_type))
|
||||
{
|
||||
g_warning ("__plugin__ attribute in file %s is not a type",
|
||||
plugin_file);
|
||||
}
|
||||
else if (!(plugin_type = pyg_type_from_object (py_plugin_type)))
|
||||
{
|
||||
g_warning ("__plugin__ attribute in file %s is not a valid type",
|
||||
plugin_file);
|
||||
PyErr_Clear ();
|
||||
}
|
||||
else if (!g_type_is_a (plugin_type, MOO_TYPE_PLUGIN))
|
||||
{
|
||||
g_warning ("__plugin__ attribute in file %s is not a MooPlugin subclass",
|
||||
plugin_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_plugin_register (plugin_id, plugin_type, info, params);
|
||||
}
|
||||
|
||||
Py_XDECREF (py_plugin_type);
|
||||
Py_XDECREF (mod);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_python_plugin_loader_class_init (MooPluginLoaderClass *klass)
|
||||
{
|
||||
klass->load_module = load_python_module;
|
||||
klass->load_plugin = load_python_plugin;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_moo_python_plugin_loader_init (G_GNUC_UNUSED MooPluginLoader *loader)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
gpointer
|
||||
_moo_python_get_plugin_loader (void)
|
||||
{
|
||||
return g_object_new (_moo_python_plugin_loader_get_type (), NULL);
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
gboolean _moo_python_plugin_init (void);
|
||||
void _moo_python_plugin_deinit (void);
|
||||
#define MOO_PYTHON_PLUGIN_LOADER_ID "Python"
|
||||
gpointer _moo_python_get_plugin_loader (void);
|
||||
gboolean _moo_python_plugin_init (void);
|
||||
void _moo_python_plugin_deinit (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -4,6 +4,7 @@ moopython_pluginsdir = $(MOO_LIB_DIR)/plugins
|
|||
moopython_plugins_libdir = $(MOO_LIB_DIR)/plugins/lib
|
||||
|
||||
moopython_plugins_DATA = \
|
||||
console.ini \
|
||||
console.py \
|
||||
python.py
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
[module]
|
||||
type = Python
|
||||
file = console.py
|
||||
version = 0.7
|
||||
|
||||
[plugin]
|
||||
id = Console
|
||||
name = Console
|
||||
description = Console
|
||||
author = Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
version = 3.1415926
|
|
@ -61,12 +61,9 @@ class WinPlugin(moo.edit.WinPlugin):
|
|||
self.window.remove_pane(CONSOLE_PLUGIN_ID)
|
||||
|
||||
|
||||
if os.name == 'posix' and moo.edit.module_check_version(2, 0):
|
||||
if os.name == 'posix':
|
||||
gobject.type_register(Plugin)
|
||||
gobject.type_register(WinPlugin)
|
||||
|
||||
info = moo.edit.PluginInfo(CONSOLE_PLUGIN_ID, "Console",
|
||||
description="Console",
|
||||
author="Yevgen Muntyan <muntyan@math.tamu.edu>",
|
||||
version="3.1415926")
|
||||
moo.edit.plugin_register(Plugin, info)
|
||||
__plugin__ = Plugin
|
||||
else:
|
||||
__plugin__ = None
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
(gtype-id "MOO_TYPE_PLUGIN")
|
||||
(fields
|
||||
'("gboolean" "initialized")
|
||||
'("char*" "id")
|
||||
'("MooPluginInfo*" "info")
|
||||
'("MooPluginParams*" "params")
|
||||
'("GSList*" "docs")
|
||||
|
@ -43,7 +44,6 @@
|
|||
(copy-func "moo_plugin_info_copy")
|
||||
(release-func "moo_plugin_info_free")
|
||||
(fields
|
||||
'("char*" "id")
|
||||
'("char*" "name")
|
||||
'("char*" "description")
|
||||
'("char*" "author")
|
||||
|
@ -260,7 +260,6 @@
|
|||
(is-constructor-of "MooPluginInfo")
|
||||
(return-type "MooPluginInfo*")
|
||||
(parameters
|
||||
'("const-char*" "id")
|
||||
'("const-char*" "name")
|
||||
'("const-char*" "author" (null-ok) (default "NULL"))
|
||||
'("const-char*" "description" (null-ok) (default "NULL"))
|
||||
|
@ -284,6 +283,7 @@
|
|||
(c-name "moo_plugin_register")
|
||||
(return-type "gboolean")
|
||||
(parameters
|
||||
'("const-char*" "id")
|
||||
'("GType" "type")
|
||||
'("MooPluginInfo*" "info")
|
||||
'("MooPluginParams*" "params" (null-ok) (default "NULL"))
|
||||
|
|
Loading…
Reference in New Issue