2006-05-06 10:08:47 -07:00
|
|
|
/*
|
2005-11-05 20:49:00 -08:00
|
|
|
* mooplugin-python.c
|
2005-11-05 07:32:04 -08:00
|
|
|
*
|
2006-02-23 06:03:17 -08:00
|
|
|
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
2005-11-05 07:32:04 -08:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2005-11-05 20:49:00 -08:00
|
|
|
#include <Python.h>
|
|
|
|
#define NO_IMPORT_PYGOBJECT
|
|
|
|
#include "pygobject.h"
|
|
|
|
|
2005-11-05 07:32:04 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
2005-11-05 20:49:00 -08:00
|
|
|
|
|
|
|
#include "moopython/mooplugin-python.h"
|
2005-12-23 06:30:26 -08:00
|
|
|
#include "moopython/moopython-utils.h"
|
2005-12-23 06:32:32 -08:00
|
|
|
#include "mooutils/moopython.h"
|
2006-05-06 10:08:47 -07:00
|
|
|
#include "mooutils/mooutils-misc.h"
|
2005-12-23 06:31:22 -08:00
|
|
|
#include "moopython/pygtk/moo-pygtk.h"
|
2005-11-05 20:49:00 -08:00
|
|
|
#include "mooedit/mooplugin-macro.h"
|
|
|
|
|
|
|
|
#define PLUGIN_SUFFIX ".py"
|
2006-03-15 00:16:42 -08:00
|
|
|
#define LIBDIR "lib"
|
2005-11-05 07:32:04 -08:00
|
|
|
|
2005-11-07 00:36:04 -08:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
static PyObject *main_mod;
|
2005-11-07 00:36:04 -08:00
|
|
|
|
2005-11-05 07:32:04 -08:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
static MooPyObject*
|
2006-03-14 12:59:07 -08:00
|
|
|
run_simple_string (const char *str)
|
2005-11-05 07:32:04 -08:00
|
|
|
{
|
2005-12-23 06:31:22 -08:00
|
|
|
PyObject *dict;
|
|
|
|
g_return_val_if_fail (str != NULL, NULL);
|
|
|
|
dict = PyModule_GetDict (main_mod);
|
|
|
|
return (MooPyObject*) PyRun_String (str, Py_file_input, dict, dict);
|
|
|
|
}
|
|
|
|
|
2005-11-05 20:49:00 -08:00
|
|
|
|
2006-03-14 12:59:07 -08:00
|
|
|
static MooPyObject*
|
|
|
|
run_string (const char *str,
|
|
|
|
MooPyObject *locals,
|
|
|
|
MooPyObject *globals)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (str != NULL, NULL);
|
|
|
|
g_return_val_if_fail (locals != NULL, NULL);
|
|
|
|
g_return_val_if_fail (globals != NULL, NULL);
|
|
|
|
return (MooPyObject*) PyRun_String (str, Py_file_input,
|
|
|
|
(PyObject*) locals,
|
|
|
|
(PyObject*) globals);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
static MooPyObject*
|
|
|
|
run_file (gpointer fp,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
PyObject *dict;
|
|
|
|
g_return_val_if_fail (fp != NULL && filename != NULL, NULL);
|
|
|
|
dict = PyModule_GetDict (main_mod);
|
|
|
|
return (MooPyObject*) PyRun_File (fp, filename, Py_file_input, dict, dict);
|
|
|
|
}
|
2005-11-05 20:49:00 -08:00
|
|
|
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
static MooPyObject*
|
|
|
|
incref (MooPyObject *obj)
|
|
|
|
{
|
|
|
|
if (obj)
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
2005-12-23 06:31:22 -08:00
|
|
|
Py_INCREF ((PyObject*) obj);
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
return obj;
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
static void
|
|
|
|
decref (MooPyObject *obj)
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
2005-12-23 06:31:22 -08:00
|
|
|
if (obj)
|
|
|
|
{
|
|
|
|
Py_DECREF ((PyObject*) obj);
|
|
|
|
}
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-14 12:59:07 -08:00
|
|
|
static MooPyObject *
|
|
|
|
py_object_from_gobject (gpointer gobj)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (!gobj || G_IS_OBJECT (gobj), NULL);
|
2006-04-07 22:39:13 -07:00
|
|
|
return (MooPyObject*) pygobject_new (gobj);
|
2006-03-14 12:59:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MooPyObject *
|
|
|
|
dict_get_item (MooPyObject *dict,
|
|
|
|
const char *key)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (dict != NULL, NULL);
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
|
|
return (MooPyObject*) PyDict_GetItemString ((PyObject*) dict, (char*) key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
dict_set_item (MooPyObject *dict,
|
|
|
|
const char *key,
|
|
|
|
MooPyObject *val)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (dict != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (key != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (val != NULL, FALSE);
|
|
|
|
|
|
|
|
if (PyDict_SetItemString ((PyObject*) dict, (char*) key, (PyObject*) val))
|
|
|
|
{
|
|
|
|
PyErr_Print ();
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
dict_del_item (MooPyObject *dict,
|
|
|
|
const char *key)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (dict != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (key != NULL, FALSE);
|
|
|
|
|
|
|
|
if (PyDict_DelItemString ((PyObject*) dict, (char*) key))
|
|
|
|
{
|
|
|
|
PyErr_Print ();
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MooPyObject *
|
|
|
|
get_script_dict (const char *name)
|
|
|
|
{
|
|
|
|
PyObject *dict, *builtins;
|
|
|
|
|
|
|
|
builtins = PyImport_ImportModule ((char*) "__builtin__");
|
|
|
|
g_return_val_if_fail (builtins != NULL, NULL);
|
|
|
|
|
|
|
|
dict = PyDict_New ();
|
|
|
|
PyDict_SetItemString (dict, (char*) "__builtins__", builtins);
|
|
|
|
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
PyObject *py_name = PyString_FromString (name);
|
|
|
|
PyDict_SetItemString (dict, (char*) "__name__", py_name);
|
|
|
|
Py_XDECREF (py_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_XDECREF (builtins);
|
|
|
|
return (MooPyObject*) dict;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-15 00:16:42 -08:00
|
|
|
static void
|
|
|
|
err_print (void)
|
|
|
|
{
|
|
|
|
PyErr_Print ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-15 13:21:48 -08:00
|
|
|
static char *
|
|
|
|
get_info (void)
|
|
|
|
{
|
|
|
|
return g_strdup_printf ("%s %s", Py_GetVersion (), Py_GetPlatform ());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
static gboolean
|
|
|
|
moo_python_api_init (void)
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
2006-04-15 18:36:36 -07:00
|
|
|
static int argc;
|
|
|
|
static char **argv;
|
|
|
|
|
2005-12-23 06:34:18 -08:00
|
|
|
static MooPyAPI api = {
|
2005-12-23 06:31:22 -08:00
|
|
|
incref, decref, err_print,
|
2006-06-03 00:26:41 -07:00
|
|
|
get_info,
|
2006-03-14 12:59:07 -08:00
|
|
|
run_simple_string, run_string, run_file,
|
|
|
|
py_object_from_gobject,
|
|
|
|
get_script_dict,
|
|
|
|
dict_get_item, dict_set_item, dict_del_item
|
2005-12-23 06:31:22 -08:00
|
|
|
};
|
2005-11-05 07:32:04 -08:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
g_return_val_if_fail (!moo_python_running(), FALSE);
|
2005-12-23 06:32:32 -08:00
|
|
|
|
2005-12-23 06:34:18 -08:00
|
|
|
if (!moo_python_init (MOO_PY_API_VERSION, &api))
|
|
|
|
{
|
|
|
|
g_warning ("%s: oops", G_STRLOC);
|
2005-12-23 06:32:32 -08:00
|
|
|
return FALSE;
|
2005-12-23 06:34:18 -08:00
|
|
|
}
|
2005-11-05 20:49:00 -08:00
|
|
|
|
2006-03-13 03:52:54 -08:00
|
|
|
g_assert (moo_python_running ());
|
2006-03-15 00:16:42 -08:00
|
|
|
|
2006-04-15 18:36:36 -07:00
|
|
|
if (!argv)
|
|
|
|
{
|
|
|
|
argc = 1;
|
|
|
|
argv = g_new0 (char*, 2);
|
|
|
|
argv[0] = g_strdup ("");
|
|
|
|
}
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
Py_Initialize ();
|
2006-04-15 18:36:36 -07:00
|
|
|
/* pygtk wants sys.argv */
|
|
|
|
PySys_SetArgv (argc, argv);
|
|
|
|
|
2006-03-15 00:16:42 -08:00
|
|
|
moo_py_init_print_funcs ();
|
2005-12-23 06:31:22 -08:00
|
|
|
|
|
|
|
main_mod = PyImport_AddModule ((char*)"__main__");
|
|
|
|
|
2006-03-15 00:16:42 -08:00
|
|
|
if (!main_mod)
|
|
|
|
{
|
|
|
|
g_warning ("%s: could not import __main__", G_STRLOC);
|
|
|
|
PyErr_Print ();
|
|
|
|
moo_python_init (MOO_PY_API_VERSION, NULL);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_XINCREF ((PyObject*) main_mod);
|
2005-12-23 06:31:22 -08:00
|
|
|
return TRUE;
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2005-11-15 11:52:02 -08:00
|
|
|
moo_python_plugin_read_file (const char *path)
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
2005-11-06 19:44:09 -08:00
|
|
|
PyObject *mod, *code;
|
|
|
|
char *modname = NULL, *content = NULL;
|
|
|
|
GError *error = NULL;
|
2005-11-05 20:49:00 -08:00
|
|
|
|
|
|
|
g_return_if_fail (path != NULL);
|
|
|
|
|
2005-11-06 19:44:09 -08:00
|
|
|
if (!g_file_get_contents (path, &content, NULL, &error))
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
2005-11-06 19:44:09 -08:00
|
|
|
g_warning ("%s: could not read plugin file", G_STRLOC);
|
|
|
|
g_warning ("%s: %s", G_STRLOC, error->message);
|
|
|
|
g_error_free (error);
|
2005-11-05 20:49:00 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-11-06 19:44:09 -08:00
|
|
|
modname = g_strdup_printf ("moo_plugin_%08x%08x", g_random_int (), g_random_int ());
|
|
|
|
code = Py_CompileString (content, path, Py_file_input);
|
2005-11-05 20:49:00 -08:00
|
|
|
|
2005-11-06 19:44:09 -08:00
|
|
|
if (!code)
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
2005-11-06 19:44:09 -08:00
|
|
|
PyErr_Print ();
|
|
|
|
goto out;
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
2005-11-06 19:44:09 -08:00
|
|
|
|
|
|
|
mod = PyImport_ExecCodeModule (modname, code);
|
|
|
|
Py_DECREF (code);
|
|
|
|
|
|
|
|
if (!mod)
|
2005-11-05 20:49:00 -08:00
|
|
|
{
|
|
|
|
PyErr_Print ();
|
2005-11-06 19:44:09 -08:00
|
|
|
goto out;
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
2005-11-06 19:44:09 -08:00
|
|
|
|
|
|
|
Py_DECREF (mod);
|
|
|
|
|
|
|
|
out:
|
|
|
|
g_free (content);
|
|
|
|
g_free (modname);
|
2005-11-05 07:32:04 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2006-03-15 00:16:42 -08:00
|
|
|
moo_python_plugin_read_dir (const char *path)
|
2005-11-05 07:32:04 -08:00
|
|
|
{
|
2005-11-05 20:49:00 -08:00
|
|
|
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);
|
2006-04-13 00:27:56 -07:00
|
|
|
|
|
|
|
/* don't try broken links */
|
|
|
|
if (g_file_test (file_path, G_FILE_TEST_EXISTS))
|
|
|
|
moo_python_plugin_read_file (file_path);
|
2005-11-05 20:49:00 -08:00
|
|
|
|
|
|
|
g_free (prefix);
|
|
|
|
g_free (file_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_dir_close (dir);
|
2005-11-05 07:32:04 -08:00
|
|
|
}
|
|
|
|
|
2005-11-05 20:49:00 -08:00
|
|
|
|
2005-11-05 07:32:04 -08:00
|
|
|
static void
|
2006-03-15 00:16:42 -08:00
|
|
|
moo_python_plugin_read_dirs (void)
|
2005-11-05 07:32:04 -08:00
|
|
|
{
|
2005-12-23 06:31:22 -08:00
|
|
|
char **d;
|
2006-04-05 23:16:29 -07:00
|
|
|
char **dirs = moo_plugin_get_dirs ();
|
2006-03-15 00:16:42 -08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2005-11-05 07:32:04 -08:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
for (d = dirs; d && *d; ++d)
|
|
|
|
moo_python_plugin_read_dir (*d);
|
2005-11-05 07:32:04 -08:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
g_strfreev (dirs);
|
2005-11-05 20:49:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
gboolean
|
|
|
|
_moo_python_plugin_init (void)
|
2005-11-07 00:36:04 -08:00
|
|
|
{
|
2005-12-23 06:31:22 -08:00
|
|
|
if (!moo_python_api_init ())
|
|
|
|
return FALSE;
|
2005-11-07 00:36:04 -08:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
if (!_moo_pygtk_init ())
|
2005-12-23 06:34:18 -08:00
|
|
|
{
|
|
|
|
PyErr_Print ();
|
2006-03-15 00:16:42 -08:00
|
|
|
moo_python_init (MOO_PY_API_VERSION, NULL);
|
2005-12-23 06:31:22 -08:00
|
|
|
return FALSE;
|
2005-12-23 06:34:18 -08:00
|
|
|
}
|
2005-11-07 00:36:04 -08:00
|
|
|
|
2006-05-09 13:13:10 -07:00
|
|
|
#ifdef pyg_disable_warning_redirections
|
|
|
|
pyg_disable_warning_redirections ();
|
2006-05-07 01:01:37 -07:00
|
|
|
#else
|
2006-05-06 10:08:47 -07:00
|
|
|
moo_reset_log_func ();
|
2006-05-07 01:01:37 -07:00
|
|
|
#endif
|
2006-05-06 10:08:47 -07:00
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
moo_python_plugin_read_dirs ();
|
|
|
|
return TRUE;
|
2005-11-15 13:08:06 -08:00
|
|
|
}
|
|
|
|
|
2005-12-23 06:31:22 -08:00
|
|
|
|
2006-06-09 14:19:25 -07:00
|
|
|
void
|
|
|
|
_moo_python_plugin_deinit (void)
|
|
|
|
{
|
|
|
|
Py_XDECREF (main_mod);
|
|
|
|
main_mod = NULL;
|
|
|
|
moo_python_init (MOO_PY_API_VERSION, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-23 06:34:18 -08:00
|
|
|
#ifdef MOO_PYTHON_PLUGIN
|
2006-05-10 14:32:41 -07:00
|
|
|
MOO_PLUGIN_INIT_FUNC_DECL;
|
2006-04-20 15:57:53 -07:00
|
|
|
MOO_PLUGIN_INIT_FUNC_DECL
|
2005-12-23 06:34:18 -08:00
|
|
|
{
|
2006-05-29 00:43:09 -07:00
|
|
|
MOO_MODULE_CHECK_VERSION ();
|
|
|
|
|
|
|
|
return !moo_python_running () &&
|
|
|
|
_moo_python_plugin_init ();
|
2005-12-23 06:34:18 -08:00
|
|
|
}
|
|
|
|
#endif
|