Made plugins and stuff use .ini files; added MooPluginLoader

master
Yevgen Muntyan 2006-08-03 14:26:08 -05:00
parent a739f67bc3
commit 0cc33c80e3
16 changed files with 923 additions and 232 deletions

View File

@ -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 \

View File

@ -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, &params))
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
}

View File

@ -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__ */

View File

@ -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__};

View File

@ -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);

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"))