Python scripting

This commit is contained in:
Yevgen Muntyan 2010-11-01 02:47:01 -07:00
parent 0441281cd3
commit 851aa7c29c
25 changed files with 990 additions and 437 deletions

View File

@ -25,11 +25,11 @@
#include "mooapp-info.h"
#include "mooappabout.h"
#include "mooscript/lua/moolua.h"
#include "mooscript/python/moopython.h"
#include "mooedit/mooeditprefs.h"
#include "mooedit/mooeditor.h"
#include "mooedit/mooplugin.h"
#include "mooutils/mooprefsdialog.h"
#include "mooutils/moopython.h"
#include "marshals.h"
#include "mooutils/mooappinput.h"
#include "mooutils/moodialogs.h"
@ -476,8 +476,10 @@ moo_app_get_instance (void)
}
#define SCRIPT_PREFIX_LUA "lua-script:"
#define SCRIPT_PREFIX_LUA_FILE "lua-file:"
#define SCRIPT_PREFIX_LUA "lua:"
#define SCRIPT_PREFIX_LUA_FILE "luaf:"
#define SCRIPT_PREFIX_PYTHON "py:"
#define SCRIPT_PREFIX_PYTHON_FILE "pyf:"
void
moo_app_run_script (MooApp *app,
@ -490,6 +492,10 @@ moo_app_run_script (MooApp *app,
medit_lua_run_string (script + strlen (SCRIPT_PREFIX_LUA));
else if (g_str_has_prefix (script, SCRIPT_PREFIX_LUA_FILE))
medit_lua_run_file (script + strlen (SCRIPT_PREFIX_LUA_FILE));
else if (g_str_has_prefix (script, SCRIPT_PREFIX_PYTHON))
moo_python_run_string (script + strlen (SCRIPT_PREFIX_PYTHON));
else if (g_str_has_prefix (script, SCRIPT_PREFIX_PYTHON_FILE))
moo_python_run_file (script + strlen (SCRIPT_PREFIX_PYTHON_FILE));
else
medit_lua_run_string (script);
}

View File

@ -46,15 +46,6 @@ static gpointer credits_dialog;
#define MOO_TYPE_HTML GTK_TYPE_TEXT_VIEW
#endif
static char *
get_python_info (void)
{
if (!moo_python_running ())
return NULL;
return moo_python_get_info ();
}
static void
set_translator_credits (CreditsDialogXml *gxml)
{
@ -255,18 +246,6 @@ moo_app_get_system_info (MooApp *app)
GTK_MINOR_VERSION,
GTK_MICRO_VERSION);
if (moo_python_running ())
{
g_string_append (text, "Python support: yes\n");
string = get_python_info ();
g_string_append_printf (text, "Python: %s\n", string ? string : "None");
g_free (string);
}
else
{
g_string_append (text, "Python support: no\n");
}
g_string_append_printf (text, "libxml2: %s\n", LIBXML_DOTTED_VERSION);
g_string_append (text, "Data dirs: ");

View File

@ -28,7 +28,6 @@
#include <windows.h>
#endif
#include "mooutils/moopython.h"
#include <errno.h>
#include <gtk/gtk.h>

View File

@ -950,11 +950,6 @@ moo_plugin_shutdown (void)
list = g_slist_delete_link (list, list);
}
/* XXX */
#if 0 && defined(MOO_USE_PYTHON)
_moo_python_plugin_deinit ();
#endif
plugin_store->dirs_read = FALSE;
plugin_store->editor = NULL;

View File

@ -42,3 +42,4 @@ mooscript/mooscript.stamp: $(MOO_SCRIPT_PARSER_FILES) mooscript/mooscript.xml
endif
include mooscript/lua/Makefile.incl
include mooscript/python/Makefile.incl

View File

@ -12,6 +12,12 @@ private:
String m_message;
public:
Result() NOTHROW
: m_success(true)
, m_message()
{
}
Result(bool success, const String &message = "unknown error") NOTHROW
: m_success(success)
, m_message(message)

View File

@ -38,7 +38,6 @@ mom_signal_editor_save_before (MooEdit *doc, GFile *file, const char *encoding)
return false;
ArgArray args;
args.append(HObject(editor));
args.append(HObject(*Document::wrap(doc)));
args.append(String(path));
args.append(String(encoding));

View File

@ -30,6 +30,9 @@ public:
class ArgArray : public VariantArray
{
public:
ArgArray() {}
ArgArray(const VariantArray &ar) : VariantArray(ar) {}
};
class VariantDict : public moo::Dict<String, Variant>

View File

@ -72,6 +72,8 @@
<signal name='document-save-before'>
<param name='doc' type='Document'/>
<param name='path' type='string'/>
<param name='encoding' type='string'/>
</signal>
<signal name='document-save-after'>
<param name='doc' type='Document'/>

View File

@ -0,0 +1,33 @@
moo_sources += \
mooscript/python/moopython.h \
mooscript/python/moopython.cpp
built_moo_sources += \
mooscript/python/moopython-init.h \
mooscript/python/moopython-init-script.h
EXTRA_DIST += \
mooscript/python/moopython-init.py \
mooscript/python/moopython-init-script.py
mooscript/python/moopython-init.h: mooscript/python/moopython-init.py
$(AM_V_at)$(MKDIR_P) mooscript/python
$(AM_V_GEN)$(PYTHON) $(top_srcdir)/tools/xml2h.py $(srcdir)/mooscript/python/moopython-init.py \
mooscript/python/moopython-init.h.tmp MOO_PYTHON_INIT \
&& mv mooscript/python/moopython-init.h.tmp mooscript/python/moopython-init.h
mooscript/python/moopython-init-script.h: mooscript/python/moopython-init-script.py
$(AM_V_at)$(MKDIR_P) mooscript/python
$(AM_V_GEN)$(PYTHON) $(top_srcdir)/tools/xml2h.py $(srcdir)/mooscript/python/moopython-init-script.py \
mooscript/python/moopython-init-script.h.tmp MOO_PYTHON_INIT_SCRIPT \
&& mv mooscript/python/moopython-init-script.h.tmp mooscript/python/moopython-init-script.h
pythondir = $(MOO_DATA_DIR)/python
EXTRA_DIST += mooscript/python/moo
install-data-local: install-python-moo
uninstall-local: uninstall-python-moo
install-python-moo:
$(MKDIR_P) $(DESTDIR)$(pythondir)/moo
cd $(srcdir) && $(INSTALL_DATA) mooscript/python/moo/*.py $(DESTDIR)$(pythondir)/moo/
uninstall-python-moo:
rm -f $(DESTDIR)$(pythondir)/moo/*.py $(DESTDIR)$(pythondir)/moo/*.pyc

View File

View File

@ -0,0 +1,128 @@
# -%- indent-width:4; use-tabs:no; strip: yes -%-
import _medit_raw
__all__ = ['Object', 'get_app_obj']
class Variant(object):
def __init__(self, value=None):
object.__init__(self)
self.p = _medit_raw.variant_new()
if value is None:
pass
elif isinstance(value, bool):
_medit_raw.variant_set_bool(self.p, value)
elif isinstance(value, int):
_medit_raw.variant_set_int(self.p, value)
elif isinstance(value, float):
_medit_raw.variant_set_double(self.p, value)
elif isinstance(value, str):
_medit_raw.variant_set_string(self.p, value)
elif isinstance(value, Object):
_medit_raw.variant_set_object(self.p, value._id())
elif isinstance(value, list):
va = VariantArray(value)
_medit_raw.variant_set_array(self.p, va.p)
elif isinstance(value, dict):
va = VariantDict(value)
_medit_raw.variant_set_dict(self.p, va.p)
else:
raise RuntimeError("don't know how to wrap value '%r'" % (value,))
def __del__(self):
if self.p:
_medit_raw.variant_free(self.p)
self.p = None
class VariantArray(object):
def __init__(self, items):
object.__init__(self)
self.p = None
v_items = [Variant(i) for i in items]
self.p = _medit_raw.variant_array_new()
for i in v_items:
_medit_raw.variant_array_append(self.p, i.p)
def __del__(self):
if self.p:
_medit_raw.variant_array_free(self.p)
self.p = None
class VariantDict(object):
def __init__(self, dic):
object.__init__(self)
self.p = None
v_dic = {}
for k in dic:
if not isinstance(k, str):
raise ValueError('dict key must be a string')
v_dic[k] = Variant(dic[k])
self.p = _medit_raw.variant_dict_new()
for k in v_dic:
_medit_raw.variant_dict_set(self.p, k, v_dic[k].p)
def __del__(self):
if self.p:
_medit_raw.variant_dict_free(self.p)
self.p = None
class Method(object):
def __init__(self, obj, meth):
object.__init__(self)
self.__obj = obj
self.__meth = meth
def __call__(self, *args):
args_v = VariantArray(args)
ret = eval(_medit_raw.call_method(self.__obj._id(), self.__meth, args_v.p))
if isinstance(ret, Exception):
raise ret
else:
return ret
class Object(object):
callbacks = {}
@classmethod
def _invoke_callback(cls, callback_id, retval_id, *args):
cb = cls.callbacks[callback_id]
ret = cb(*args)
ret_v = Variant(ret)
_medit_raw.push_retval(retval_id, ret_v.p)
def __init__(self, id):
object.__init__(self)
self.__id = id
def _id(self):
return self.__id
def connect_callback(self, sig, callback):
ret = eval(_medit_raw.connect_callback(self._id(), sig))
if isinstance(ret, Exception):
raise ret
Object.callbacks[ret] = callback
return ret
def disconnect_callback(self, callback_id):
ret = eval(_medit_raw.connect_callback(self._id(), sig))
if isinstance(ret, Exception):
raise ret
del Object.callbacks[callback_id]
def __str__(self):
return '<Object id=%d>' % (self._id(),)
def __repr__(self):
return '<Object id=%d>' % (self._id(),)
def __getattr__(self, attr):
return Method(self, attr)
_medit_raw.Object = Object
def get_app_obj():
return Object(_medit_raw.get_app_obj())
# print VariantArray([None, False, True, 1, 14, 3.34345, 'fgoo', get_app_obj(), [12,3,4], {'a':1}])
# print VariantDict({'a': [1,2,3]})

View File

@ -0,0 +1,3 @@
import moo._medit
app = moo._medit.get_app_obj()
editor = app.editor()

View File

@ -0,0 +1,14 @@
# continuation of __medit_init function
sys.path = [ctypes.c_char_p(addr).value for addr in reversed(path_entries)] + sys.path
_medit_raw = imp.new_module('_medit_raw')
sys.modules['_medit_raw'] = _medit_raw
for f in funcs:
setattr(_medit_raw, f, funcs[f])
import moo._medit
__medit_init()
del __medit_init

View File

@ -0,0 +1,675 @@
#include "moopython.h"
#include "mooscript/python/moopython-init.h"
#include "mooscript/python/moopython-init-script.h"
#include "mooscript/mooscript-api.h"
#include "mooutils/mooutils-misc.h"
using namespace mom;
typedef void (*Fn_Py_InitializeEx) (int initsigs);
typedef void (*Fn_Py_Finalize) (void);
typedef int (*Fn_PyRun_SimpleString) (const char *command);
typedef struct {
GModule *module;
gboolean initialized;
int ref_count;
gboolean py_initialized;
Fn_Py_InitializeEx pfn_Py_InitializeEx;
Fn_Py_Finalize pfn_Py_Finalize;
Fn_PyRun_SimpleString pfn_PyRun_SimpleString;
guint last_retval_id;
moo::Dict<guint, Variant> retvals;
} MooPythonModule;
static MooPythonModule moo_python_module;
static GModule *
find_python_dll (gboolean py3)
{
const char *python2_libs[] = {
#ifdef __WIN32__
"python27", "python26",
#else
"python2.7", "python2.6",
#endif
NULL
};
const char *python3_libs[] = {
#ifdef __WIN32__
"python35", "python34", "python33", "python32", "python31",
#else
"python3.5", "python34", "python33", "python32", "python31",
#endif
NULL
};
const char **libs, **p;
GModule *module = NULL;
if (py3)
libs = python3_libs;
else
libs = python2_libs;
for (p = libs; p && *p; ++p)
{
char *path = g_module_build_path (NULL, *p);
if (path)
module = g_module_open (path, G_MODULE_BIND_LAZY);
g_free (path);
if (module)
break;
}
return module;
}
static void encode_list (const VariantArray &list, GString *str);
static void encode_variant (const Variant &val, GString *str);
static void encode_string (const char *s, GString *str);
char *encode_error (const char *message)
{
GString *str = g_string_new ("RuntimeError(");
encode_string (message, str);
g_string_append (str, ")");
return g_string_free (str, FALSE);
}
static void
encode_string (const char *s, GString *str)
{
g_string_append_c (str, '"');
for ( ; *s; ++s)
{
if (g_ascii_isprint (*s))
g_string_append_c (str, *s);
else
g_string_append_printf (str, "\\x%x", (guint) (guchar) *s);
}
g_string_append_c (str, '"');
}
static void
encode_dict (const VariantDict &dict, GString *str)
{
g_string_append (str, "{");
for (moo::Dict<String, Variant>::const_iterator iter = dict.begin(); iter != dict.end(); ++iter)
{
if (iter != dict.begin())
g_string_append (str, ", ");
encode_string (iter.key(), str);
g_string_append (str, ": ");
encode_variant (iter.value(), str);
}
g_string_append (str, "}");
}
static void
encode_object (const HObject &h, GString *str)
{
g_string_append_printf (str, "_medit_raw.Object(%u)", h.id());
}
static void
encode_variant (const Variant &val, GString *str)
{
switch (val.vt())
{
case VtVoid:
g_string_append (str, "None");
break;
case VtBool:
g_string_append (str, val.value<VtBool>() ? "True" : "False");
break;
case VtIndex:
g_string_append_printf (str, "%d", val.value<VtIndex>().get());
break;
case VtInt:
g_string_append_printf (str, "%" G_GINT64_FORMAT, val.value<VtInt>());
break;
case VtDouble:
g_string_append_printf (str, "%f", val.value<VtDouble>());
break;
case VtString:
encode_string (val.value<VtString>(), str);
break;
case VtArray:
encode_list (val.value<VtArray>(), str);
break;
case VtArgs:
encode_list (val.value<VtArgs>(), str);
break;
case VtDict:
encode_dict (val.value<VtDict>(), str);
break;
case VtObject:
encode_object (val.value<VtObject>(), str);
break;
default:
moo_critical ("oops");
g_string_append (str, "None");
break;
}
}
static void
encode_list_elms (const VariantArray &list, GString *str)
{
for (int i = 0, c = list.size(); i < c; ++i)
{
if (i > 0)
g_string_append (str, ", ");
encode_variant (list[i], str);
}
}
static void
encode_list (const VariantArray &list, GString *str)
{
g_string_append (str, "[");
encode_list_elms (list, str);
g_string_append (str, "]");
}
static void
encode_args (const ArgArray &args, GString *str)
{
encode_list_elms (args, str);
}
static char *
encode_variant (const Variant &val)
{
GString *str = g_string_new (NULL);
encode_variant (val, str);
return g_string_free (str, FALSE);
}
#define CFUNC_PROTO_variant_new "ctypes.c_void_p"
static Variant *
cfunc_variant_new ()
{
return new Variant;
}
#define CFUNC_PROTO_variant_free "None, ctypes.c_void_p"
static void
cfunc_variant_free (Variant *var)
{
delete var;
}
#define CFUNC_PROTO_variant_set_bool "None, ctypes.c_void_p, ctypes.c_int"
static void
cfunc_variant_set_bool (Variant *var, int val)
{
var->setValue(bool(val));
}
#define CFUNC_PROTO_variant_set_int "None, ctypes.c_void_p, ctypes.c_longlong"
static void
cfunc_variant_set_int (Variant *var, gint64 val)
{
var->setValue(val);
}
#define CFUNC_PROTO_variant_set_double "None, ctypes.c_void_p, ctypes.c_double"
static void
cfunc_variant_set_double (Variant *var, double val)
{
var->setValue(val);
}
#define CFUNC_PROTO_variant_set_string "None, ctypes.c_void_p, ctypes.c_char_p"
static void
cfunc_variant_set_string (Variant *var, const char *val)
{
var->setValue(String(val));
}
#define CFUNC_PROTO_variant_set_array "None, ctypes.c_void_p, ctypes.c_void_p"
static void
cfunc_variant_set_array (Variant *var, const VariantArray *val)
{
var->setValue(*val);
}
#define CFUNC_PROTO_variant_set_dict "None, ctypes.c_void_p, ctypes.c_void_p"
static void
cfunc_variant_set_dict (Variant *var, const VariantDict *val)
{
var->setValue(*val);
}
#define CFUNC_PROTO_variant_set_object "None, ctypes.c_void_p, ctypes.c_uint"
static void
cfunc_variant_set_object (Variant *var, guint val)
{
var->setValue(HObject(val));
}
#define CFUNC_PROTO_variant_array_new "ctypes.c_void_p"
static VariantArray *
cfunc_variant_array_new ()
{
return new VariantArray;
}
#define CFUNC_PROTO_variant_array_free "None, ctypes.c_void_p"
static void
cfunc_variant_array_free (VariantArray *ar)
{
delete ar;
}
#define CFUNC_PROTO_variant_array_append "None, ctypes.c_void_p, ctypes.c_void_p"
static void
cfunc_variant_array_append (VariantArray *ar, const Variant *val)
{
ar->append(*val);
}
#define CFUNC_PROTO_variant_dict_new "ctypes.c_void_p"
static VariantDict *
cfunc_variant_dict_new ()
{
return new VariantDict;
}
#define CFUNC_PROTO_variant_dict_free "None, ctypes.c_void_p"
static void
cfunc_variant_dict_free (VariantDict *dict)
{
delete dict;
}
#define CFUNC_PROTO_variant_dict_set "None, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p"
static void
cfunc_variant_dict_set (VariantDict *dict, const char *key, const Variant *val)
{
(*dict)[key] = *val;
}
#define CFUNC_PROTO_free "None, ctypes.c_char_p"
static void
cfunc_free (char *p)
{
g_free (p);
}
#define CFUNC_PROTO_get_app_obj "ctypes.c_uint"
static guint
cfunc_get_app_obj (void)
{
return Script::get_app_obj().id();
}
#define CFUNC_PROTO_push_retval "None, ctypes.c_uint, ctypes.c_void_p"
static void
cfunc_push_retval (guint id, const Variant *value)
{
moo_return_if_fail (value != 0);
if (moo_python_module.retvals.contains(id))
{
moo_critical ("oops");
return;
}
moo_python_module.retvals[id] = *value;
}
#define CFUNC_PROTO_call_method "ctypes.c_char_p, ctypes.c_uint, ctypes.c_char_p, ctypes.c_void_p"
static char *
cfunc_call_method (guint obj_id, const char *method, const VariantArray *argsv)
{
ArgArray args (argsv ? *argsv : VariantArray ());
Variant ret;
moo_python_ref ();
Result r = Script::call_method (HObject (obj_id), method, args, ret);
moo_python_unref ();
if (r.succeeded ())
return encode_variant (ret);
else
return encode_error (r.message ());
}
struct MooPythonCallback : public Callback
{
gulong id;
Variant run(const ArgArray &args)
{
guint retval_id = ++moo_python_module.last_retval_id;
GString *str = g_string_new (NULL);
g_string_append_printf (str, "import _medit_raw\n_medit_raw.Object._invoke_callback(%lu, %u, ", id, retval_id);
encode_args (args, str);
g_string_append (str, ")\n");
// g_print ("%s", str->str);
int result = moo_python_module.pfn_PyRun_SimpleString (str->str);
g_string_free (str, TRUE);
if (result != 0)
{
moo_message ("error in PyRun_SimpleString");
return Variant();
}
else if (!moo_python_module.retvals.contains(retval_id))
{
moo_critical ("oops");
return Variant();
}
else
{
Variant v = moo_python_module.retvals[retval_id];
moo_python_module.retvals.erase(retval_id);
return v;
}
}
void on_connect()
{
}
void on_disconnect()
{
}
};
#define CFUNC_PROTO_connect_callback "ctypes.c_char_p, ctypes.c_uint, ctypes.c_char_p"
static char *
cfunc_connect_callback (guint obj_id, const char *sig)
{
moo::SharedPtr<MooPythonCallback> cb (new MooPythonCallback);
gulong id;
Result r = Script::connect_callback (HObject (obj_id), sig, cb, id);
if (!r.succeeded ())
return encode_error (r.message ());
cb->id = id;
return g_strdup_printf ("%lu", id);
}
#define CFUNC_PROTO_disconnect_callback "ctypes.c_char_p, ctypes.c_uint, ctypes.c_uint"
static char *
cfunc_disconnect_callback (guint obj_id, guint callback_id)
{
Result r = Script::disconnect_callback (HObject (obj_id), callback_id);
if (!r.succeeded ())
return encode_error (r.message ());
else
return g_strdup ("None");
}
static gboolean
moo_python_init_impl (void)
{
GString *init_script = NULL;
char **dirs = NULL;
gpointer p;
if (moo_python_module.initialized)
{
if (moo_python_module.module != NULL)
{
moo_python_module.ref_count++;
return TRUE;
}
else
{
return FALSE;
}
}
moo_python_module.initialized = TRUE;
moo_python_module.module = find_python_dll (FALSE);
if (!moo_python_module.module)
{
moo_message ("python module not found");
goto error;
}
if (g_module_symbol (moo_python_module.module, "Py_InitializeEx", &p))
moo_python_module.pfn_Py_InitializeEx = (Fn_Py_InitializeEx) p;
if (g_module_symbol (moo_python_module.module, "Py_Finalize", &p))
moo_python_module.pfn_Py_Finalize = (Fn_Py_Finalize) p;
if (g_module_symbol (moo_python_module.module, "PyRun_SimpleString", &p))
moo_python_module.pfn_PyRun_SimpleString = (Fn_PyRun_SimpleString) p;
if (!moo_python_module.pfn_Py_InitializeEx)
{
moo_message ("Py_InitializeEx not found");
goto error;
}
if (!moo_python_module.pfn_PyRun_SimpleString)
{
moo_message ("PyRun_SimpleString not found");
goto error;
}
if (!moo_python_module.pfn_Py_Finalize)
{
moo_message ("Py_Finalize not found");
goto error;
}
moo_python_module.pfn_Py_InitializeEx (0);
moo_python_module.py_initialized = TRUE;
#define FUNC_ENTRY(func) " " #func "=ctypes.CFUNCTYPE(" CFUNC_PROTO_##func ")(%" G_GUINT64_FORMAT "),\n"
init_script = g_string_new (
"def __medit_init():\n"
" import ctypes\n"
" import sys\n"
" import imp\n"
);
g_string_append_printf (init_script,
" funcs = dict(\n"
FUNC_ENTRY(free)
FUNC_ENTRY(get_app_obj)
FUNC_ENTRY(call_method)
FUNC_ENTRY(connect_callback)
FUNC_ENTRY(disconnect_callback)
FUNC_ENTRY(push_retval)
FUNC_ENTRY(variant_new)
FUNC_ENTRY(variant_free)
FUNC_ENTRY(variant_set_bool)
FUNC_ENTRY(variant_set_int)
FUNC_ENTRY(variant_set_double)
FUNC_ENTRY(variant_set_string)
FUNC_ENTRY(variant_set_array)
FUNC_ENTRY(variant_set_dict)
FUNC_ENTRY(variant_set_object)
FUNC_ENTRY(variant_array_new)
FUNC_ENTRY(variant_array_free)
FUNC_ENTRY(variant_array_append)
FUNC_ENTRY(variant_dict_new)
FUNC_ENTRY(variant_dict_free)
FUNC_ENTRY(variant_dict_set)
" )\n",
(guint64) cfunc_free,
(guint64) cfunc_get_app_obj,
(guint64) cfunc_call_method,
(guint64) cfunc_connect_callback,
(guint64) cfunc_disconnect_callback,
(guint64) cfunc_push_retval,
(guint64) cfunc_variant_new,
(guint64) cfunc_variant_free,
(guint64) cfunc_variant_set_bool,
(guint64) cfunc_variant_set_int,
(guint64) cfunc_variant_set_double,
(guint64) cfunc_variant_set_string,
(guint64) cfunc_variant_set_array,
(guint64) cfunc_variant_set_dict,
(guint64) cfunc_variant_set_object,
(guint64) cfunc_variant_array_new,
(guint64) cfunc_variant_array_free,
(guint64) cfunc_variant_array_append,
(guint64) cfunc_variant_dict_new,
(guint64) cfunc_variant_dict_free,
(guint64) cfunc_variant_dict_set
);
g_string_append (init_script, " path_entries = [");
dirs = moo_get_data_subdirs ("python");
for (char **p = dirs; p && *p; ++p)
g_string_append_printf (init_script, "%" G_GUINT64_FORMAT ", ", (guint64) *p);
g_string_append (init_script, "]\n");
g_string_append (init_script, MOO_PYTHON_INIT);
// g_print ("%s\n", init_script->str);
if (moo_python_module.pfn_PyRun_SimpleString (init_script->str) != 0)
{
moo_message ("error in PyRun_SimpleString");
goto error;
}
if (dirs)
g_strfreev (dirs);
if (init_script)
g_string_free (init_script, TRUE);
moo_python_module.ref_count = 1;
return TRUE;
error:
if (moo_python_module.py_initialized)
{
moo_python_module.pfn_Py_Finalize ();
moo_python_module.py_initialized = FALSE;
}
if (moo_python_module.module)
{
g_module_close (moo_python_module.module);
moo_python_module.module = NULL;
}
if (dirs)
g_strfreev (dirs);
if (init_script)
g_string_free (init_script, TRUE);
return FALSE;
}
static void
moo_python_deinit_impl (void)
{
if (!moo_python_module.initialized)
return;
g_assert (moo_python_module.ref_count == 0);
if (moo_python_module.py_initialized)
{
moo_python_module.pfn_Py_Finalize ();
moo_python_module.py_initialized = FALSE;
}
if (moo_python_module.module)
{
g_module_close (moo_python_module.module);
moo_python_module.module = NULL;
}
}
extern "C" gboolean
moo_python_init (void)
{
return moo_python_init_impl ();
}
extern "C" void
moo_python_deinit (void)
{
moo_python_unref ();
}
extern "C" gboolean
moo_python_ref (void)
{
return moo_python_init_impl ();
}
extern "C" void
moo_python_unref (void)
{
moo_return_if_fail (moo_python_module.ref_count > 0);
if (!--moo_python_module.ref_count)
moo_python_deinit_impl ();
}
extern "C" gboolean
moo_python_run_string_full (const char *prefix,
const char *string)
{
GString *script;
gboolean ret = TRUE;
moo_return_val_if_fail (string != NULL, FALSE);
if (!moo_python_ref ())
return FALSE;
script = g_string_new (MOO_PYTHON_INIT_SCRIPT);
if (prefix && *prefix)
g_string_append (script, prefix);
if (string && *string)
g_string_append (script, string);
if (moo_python_module.pfn_PyRun_SimpleString (script->str) != 0)
{
moo_message ("error in PyRun_SimpleString");
ret = FALSE;
}
moo_python_unref ();
g_string_free (script, TRUE);
return ret;
}
extern "C" gboolean
moo_python_run_string (const char *string)
{
moo_return_val_if_fail (string != NULL, FALSE);
return moo_python_run_string_full (NULL, string);
}
extern "C" gboolean
moo_python_run_file (const char *filename)
{
char *content = NULL;
GError *error = NULL;
gboolean ret;
moo_return_val_if_fail (filename != NULL, FALSE);
if (!g_file_get_contents (filename, &content, NULL, &error))
{
moo_warning ("could not read file '%s': %s", filename, error->message);
g_error_free (error);
return FALSE;
}
ret = moo_python_run_string (content);
g_free (content);
return ret;
}

View File

@ -0,0 +1,35 @@
/*
* moopython.h
*
* Copyright (C) 2004-2010 by Yevgen Muntyan <emuntyan@sourceforge.net>
*
* This file is part of medit. medit 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MOO_PYTHON_H
#define MOO_PYTHON_H
#include <glib.h>
G_BEGIN_DECLS
gboolean moo_python_init (void);
void moo_python_deinit (void);
gboolean moo_python_ref (void);
void moo_python_unref (void);
gboolean moo_python_run_string (const char *string);
gboolean moo_python_run_file (const char *filename);
gboolean moo_python_run_string_full (const char *prefix,
const char *string);
G_END_DECLS
#endif /* MOO_PYTHON_H */

View File

@ -97,7 +97,6 @@ moo_sources += \
mooutils/mooprefsdialog.h \
mooutils/mooprefspage.c \
mooutils/mooprefspage.h \
mooutils/moopython.h \
mooutils/moospawn.c \
mooutils/moospawn.h \
mooutils/moostat.h \
@ -114,7 +113,6 @@ moo_sources += \
mooutils/mooutils-file.c \
mooutils/mooutils-file.h \
mooutils/mooutils-file-private.h\
mooutils/mooutils-fli.c \
mooutils/mooutils-fs.c \
mooutils/mooutils-fs.h \
mooutils/mooutils-gobject-private.h \

View File

@ -1,158 +0,0 @@
/*
* moopython.h
*
* Copyright (C) 2004-2008 by Yevgen Muntyan <muntyan@tamu.edu>
*
* This file is part of medit. medit 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MOO_PYTHON_H
#define MOO_PYTHON_H
#include <glib.h>
G_BEGIN_DECLS
#define MOO_PY_API_VERSION 95
typedef struct MooPyAPI MooPyAPI;
typedef struct MooPyObject MooPyObject;
typedef struct MooPyMethodDef MooPyMethodDef;
typedef MooPyObject* (*MooPyCFunction) (MooPyObject*, MooPyObject*);
enum {
MOO_PY_METH_VARARGS = 1 << 0,
MOO_PY_METH_KEYWORDS = 1 << 1,
MOO_PY_METH_NOARGS = 1 << 2,
MOO_PY_METH_O = 1 << 3,
MOO_PY_METH_CLASS = 1 << 4,
MOO_PY_METH_STATIC = 1 << 5
};
enum {
MOO_PY_RUNTIME_ERROR,
MOO_PY_TYPE_ERROR,
MOO_PY_VALUE_ERROR,
MOO_PY_NOT_IMPLEMENTED_ERROR
};
struct MooPyMethodDef {
const char *ml_name;
MooPyCFunction ml_meth;
int ml_flags;
const char *ml_doc;
};
struct MooPyAPI {
MooPyObject *py_none;
MooPyObject *py_true;
MooPyObject *py_false;
MooPyObject* (*incref) (MooPyObject *obj);
void (*decref) (MooPyObject *obj);
char* (*get_info) (void);
MooPyObject* (*run_simple_string) (const char *str);
MooPyObject* (*run_string) (const char *str,
MooPyObject *globals,
MooPyObject *locals);
MooPyObject* (*run_file) (void *fp,
const char *filename,
MooPyObject *globals,
MooPyObject *locals);
MooPyObject* (*run_code) (const char *str,
MooPyObject *globals,
MooPyObject *locals);
MooPyObject* (*create_script_dict) (const char *name);
MooPyObject* (*py_object_from_gobject) (gpointer gobj);
gpointer (*gobject_from_py_object) (MooPyObject *pyobj);
MooPyObject* (*dict_get_item) (MooPyObject *dict,
const char *key);
gboolean (*dict_set_item) (MooPyObject *dict,
const char *key,
MooPyObject *val);
gboolean (*dict_del_item) (MooPyObject *dict,
const char *key);
MooPyObject* (*import_exec) (const char *name,
const char *string);
void (*set_error) (int type,
const char *format,
...) G_GNUC_PRINTF(2,3);
void (*py_err_print) (void);
MooPyObject* (*py_object_call_method) (MooPyObject *object,
const char *method,
const char *format,
...);
MooPyObject* (*py_object_call_function) (MooPyObject *callable,
const char *format,
...);
MooPyObject* (*py_c_function_new) (MooPyMethodDef *meth,
MooPyObject *self);
int (*py_module_add_object) (MooPyObject *mod,
const char *name,
MooPyObject *obj);
gboolean (*py_arg_parse_tuple) (MooPyObject *args,
const char *format,
...);
GSList *_free_list;
};
MooPyAPI *moo_py_api_ (void);
gboolean moo_python_init (guint version,
MooPyAPI *api);
void moo_python_add_data (gpointer data,
GDestroyNotify destroy);
MooPyObject *moo_Py_INCREF (MooPyObject *obj);
void moo_Py_DECREF (MooPyObject *obj);
#define moo_python_running() (moo_py_api_() != NULL)
#define moo_python_get_info moo_py_api_()->get_info
#define moo_python_run_simple_string moo_py_api_()->run_simple_string
#define moo_python_run_string moo_py_api_()->run_string
#define moo_python_run_file moo_py_api_()->run_file
#define moo_python_run_code moo_py_api_()->run_code
#define moo_python_create_script_dict moo_py_api_()->create_script_dict
#define moo_py_dict_get_item moo_py_api_()->dict_get_item
#define moo_py_dict_set_item moo_py_api_()->dict_set_item
#define moo_py_dict_del_item moo_py_api_()->dict_del_item
#define moo_py_import_exec moo_py_api_()->import_exec
#define moo_py_object_from_gobject moo_py_api_()->py_object_from_gobject
#define moo_gobject_from_py_object moo_py_api_()->gobject_from_py_object
#define moo_py_set_error moo_py_api_()->set_error
#define moo_PyErr_Print moo_py_api_()->py_err_print
#define moo_PyObject_CallMethod moo_py_api_()->py_object_call_method
#define moo_PyObject_CallFunction moo_py_api_()->py_object_call_function
#define moo_PyCFunction_New moo_py_api_()->py_c_function_new
#define moo_PyModule_AddObject moo_py_api_()->py_module_add_object
#define moo_PyArg_ParseTuple moo_py_api_()->py_arg_parse_tuple
#define moo_Py_None moo_py_api_()->py_none
#define moo_Py_True moo_py_api_()->py_true
#define moo_Py_False moo_py_api_()->py_false
G_END_DECLS
#endif /* MOO_PYTHON_H */

View File

@ -1,106 +0,0 @@
/*
* mooutils-fli.c
*
* Copyright (C) 2004-2008 by Yevgen Muntyan <muntyan@tamu.edu>
*
* This file is part of medit. medit 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mooutils/moopython.h"
/**
* Python
*/
typedef struct {
gpointer data;
GDestroyNotify destroy;
} Data;
static MooPyAPI *moo_py_api_var = NULL;
MooPyAPI *
moo_py_api_ (void)
{
return moo_py_api_var;
}
void
moo_python_add_data (gpointer data,
GDestroyNotify destroy)
{
Data *d;
g_return_if_fail (moo_py_api_var != NULL);
g_return_if_fail (destroy != NULL);
d = g_new (Data, 1);
d->data = data;
d->destroy = destroy;
moo_py_api_var->_free_list = g_slist_prepend (moo_py_api_var->_free_list, d);
}
static void
data_free (Data *d)
{
if (d)
{
d->destroy (d->data);
g_free (d);
}
}
gboolean
moo_python_init (guint version,
MooPyAPI *api)
{
if (version != MOO_PY_API_VERSION)
return FALSE;
g_return_val_if_fail (!moo_py_api_var || !api, FALSE);
if (moo_py_api_var)
{
g_slist_foreach (moo_py_api_var->_free_list, (GFunc) data_free, NULL);
g_slist_free (moo_py_api_var->_free_list);
}
moo_py_api_var = api;
if (moo_py_api_var)
moo_py_api_var->_free_list = NULL;
return TRUE;
}
MooPyObject *
moo_Py_INCREF (MooPyObject *obj)
{
g_return_val_if_fail (moo_python_running (), obj);
if (obj)
moo_py_api_var->incref (obj);
return obj;
}
void
moo_Py_DECREF (MooPyObject *obj)
{
g_return_if_fail (moo_python_running ());
if (obj)
moo_py_api_var->decref (obj);
}

View File

@ -9,7 +9,7 @@ plugins_sources += \
plugins/moofilelist.c \
plugins/moofind.c \
plugins/mooluaplugin.cpp \
plugins/moopython.c
plugins/moopythonplugin.c
EXTRA_DIST += \
plugins/glade/moofileselector-prefs.glade \
@ -23,12 +23,6 @@ built_plugins_sources += \
moofind-gxml.h \
moogrep-gxml.h
EXTRA_DIST += plugins/moopython.py
built_plugins_sources += plugins/moopython-py.h
plugins/moopython-py.h: plugins/moopython.py $(top_srcdir)/tools/xml2h.py
$(AM_V_at)$(MKDIR_P) plugins
$(AM_V_GEN)$(PYTHON) $(top_srcdir)/tools/xml2h.py $< $@.tmp MOO_PYTHON_PY && mv $@.tmp $@
EXTRA_DIST += plugins/lua-module-setup.lua
built_plugins_sources += lua-module-setup.h
lua-module-setup.h: plugins/lua-module-setup.lua $(top_srcdir)/tools/xml2h.py

View File

@ -15,14 +15,14 @@
#include <config.h>
#include "mooeditplugins.h"
#include "mooutils/mooutils-misc.h"
void
moo_plugin_init_builtin (void)
{
const char *v = g_getenv ("MOO_DISABLE_PYTHON");
if (!v || !*v)
if (!moo_getenv_bool ("MOO_DISABLE_PYTHON"))
_moo_python_plugin_init ();
if (0)
if (!moo_getenv_bool ("MOO_DISABLE_LUA"))
_moo_lua_plugin_init ();
_moo_file_selector_plugin_init ();
_moo_file_list_plugin_init ();

View File

@ -1,127 +0,0 @@
/*
* moopython.c
*
* Copyright (C) 2004-2010 by Yevgen Muntyan <emuntyan@sourceforge.net>
*
* This file is part of medit. medit 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "mooeditplugins.h"
#include "mooedit/mooplugin-macro.h"
#include "mooutils/mooi18n.h"
#include "mooutils/mooutils-messages.h"
#include "plugins/moopython-py.h"
#define MOO_PYTHON_PLUGIN_ID "MooPython"
typedef void (*Fn_Py_InitializeEx) (int initsigs);
typedef void (*Fn_Py_Finalize) (void);
typedef int (*Fn_PyRun_SimpleString) (const char *command);
typedef struct {
Fn_Py_InitializeEx pfn_Py_InitializeEx;
Fn_Py_Finalize pfn_Py_Finalize;
Fn_PyRun_SimpleString pfn_PyRun_SimpleString;
} MooPythonAPI;
typedef struct {
MooPlugin parent;
GModule *module;
MooPythonAPI api;
} MooPythonPlugin;
static GModule *
find_python_dll (void)
{
GModule *module = NULL;
char *path = g_module_build_path (NULL, "python2.6");
if (path)
module = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
g_free (path);
return module;
}
static gboolean
moo_python_plugin_init (MooPythonPlugin *plugin)
{
plugin->module = find_python_dll ();
if (!plugin->module)
{
moo_message ("python module not found");
return FALSE;
}
gpointer p;
if (g_module_symbol (plugin->module, "Py_InitializeEx", &p))
plugin->api.pfn_Py_InitializeEx = p;
if (g_module_symbol (plugin->module, "Py_Finalize", &p))
plugin->api.pfn_Py_Finalize = p;
if (g_module_symbol (plugin->module, "PyRun_SimpleString", &p))
plugin->api.pfn_PyRun_SimpleString = p;
if (!plugin->api.pfn_Py_InitializeEx)
{
moo_message ("Py_InitializeEx not found");
return FALSE;
}
if (!plugin->api.pfn_PyRun_SimpleString)
{
moo_message ("PyRun_SimpleString not found");
return FALSE;
}
if (!plugin->api.pfn_Py_Finalize)
{
moo_message ("PyRun_SimpleString not found");
return FALSE;
}
plugin->api.pfn_Py_InitializeEx (0);
if (plugin->api.pfn_PyRun_SimpleString (MOO_PYTHON_PY) != 0)
{
plugin->api.pfn_Py_Finalize ();
moo_message ("error in PyRun_SimpleString");
return FALSE;
}
return TRUE;
}
static void
moo_python_plugin_deinit (MooPythonPlugin *plugin)
{
if (plugin->api.pfn_Py_Finalize)
plugin->api.pfn_Py_Finalize ();
if (plugin->module)
g_module_close (plugin->module);
plugin->module = NULL;
}
MOO_PLUGIN_DEFINE_INFO (moo_python,
N_("Python"), N_("Python support"),
"Yevgen Muntyan <" MOO_EMAIL ">",
MOO_VERSION, NULL)
MOO_PLUGIN_DEFINE (MooPython, moo_python,
NULL, NULL, NULL, NULL, NULL,
0, 0)
gboolean
_moo_python_plugin_init (void)
{
MooPluginParams params = { TRUE, TRUE };
return moo_plugin_register (MOO_PYTHON_PLUGIN_ID,
moo_python_plugin_get_type (),
&moo_python_plugin_info,
&params);
}

View File

@ -1,2 +0,0 @@
# bootstrap script for medit python scripting

View File

@ -0,0 +1,76 @@
/*
* moopythonplugin.c
*
* Copyright (C) 2004-2010 by Yevgen Muntyan <emuntyan@sourceforge.net>
*
* This file is part of medit. medit 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with medit. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "mooeditplugins.h"
#include "mooedit/mooplugin-macro.h"
#include "mooedit/mooplugin-loader.h"
#include "mooutils/mooi18n.h"
#include "mooutils/mooutils-messages.h"
#include "mooutils/moolist.h"
#include "mooscript/python/moopython.h"
#define MOO_PYTHON_PLUGIN_ID "MooPython"
typedef struct {
MooPlugin parent;
} MooPythonPlugin;
static gboolean
moo_python_plugin_init (G_GNUC_UNUSED MooPythonPlugin *plugin)
{
if (!moo_python_init ())
return FALSE;
return TRUE;
}
static void
moo_python_plugin_deinit (G_GNUC_UNUSED MooPythonPlugin *plugin)
{
moo_python_deinit ();
}
static void
load_python_module (const char *module_file,
G_GNUC_UNUSED const char *ini_file,
G_GNUC_UNUSED gpointer data)
{
if (moo_plugin_lookup (MOO_PYTHON_PLUGIN_ID))
moo_python_run_file (module_file);
}
MOO_PLUGIN_DEFINE_INFO (moo_python,
N_("Python"), N_("Python support"),
"Yevgen Muntyan <" MOO_EMAIL ">",
MOO_VERSION, NULL)
MOO_PLUGIN_DEFINE (MooPython, moo_python,
NULL, NULL, NULL, NULL, NULL,
0, 0)
gboolean
_moo_python_plugin_init (void)
{
MooPluginLoader loader = { load_python_module, NULL, NULL };
moo_plugin_loader_register (&loader, "Python");
MooPluginParams params = { TRUE, TRUE };
return moo_plugin_register (MOO_PYTHON_PLUGIN_ID,
moo_python_plugin_get_type (),
&moo_python_plugin_info,
&params);
}

View File

@ -60,7 +60,7 @@ moo/plugins/moofileselector.c
moo/plugins/moofileselector-prefs.c
moo/plugins/moofind.c
moo/plugins/mooluaplugin.cpp
moo/plugins/moopython.c
moo/plugins/moopythonplugin.c
moo/plugins/usertools/exe/moocommand-exe.c
moo/plugins/usertools/filters.xml
moo/plugins/usertools/glade/mooedittools-exe.glade