summaryrefslogtreecommitdiff
path: root/src/if_python.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/if_python.c')
-rw-r--r--src/if_python.c141
1 files changed, 133 insertions, 8 deletions
diff --git a/src/if_python.c b/src/if_python.c
index 518b4e3f1..09b3ca5d2 100644
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -24,9 +24,9 @@
/* uncomment this if used with the debug version of python.
* Checked on 2.7.4. */
/* #define Py_DEBUG */
-/* Note: most of time you can add -DPy_DEBUG to CFLAGS in place of uncommenting
+/* Note: most of time you can add -DPy_DEBUG to CFLAGS in place of uncommenting
*/
-/* uncomment this if used with the debug version of python, but without its
+/* uncomment this if used with the debug version of python, but without its
* allocator */
/* #define Py_DEBUG_NO_PYMALLOC */
@@ -168,6 +168,7 @@ struct PyMethodDef { Py_ssize_t a; };
# define PyErr_SetNone dll_PyErr_SetNone
# define PyErr_SetString dll_PyErr_SetString
# define PyErr_SetObject dll_PyErr_SetObject
+# define PyErr_ExceptionMatches dll_PyErr_ExceptionMatches
# define PyEval_InitThreads dll_PyEval_InitThreads
# define PyEval_RestoreThread dll_PyEval_RestoreThread
# define PyEval_SaveThread dll_PyEval_SaveThread
@@ -184,6 +185,7 @@ struct PyMethodDef { Py_ssize_t a; };
# define PyLong_Type (*dll_PyLong_Type)
# define PyList_GetItem dll_PyList_GetItem
# define PyList_Append dll_PyList_Append
+# define PyList_Insert dll_PyList_Insert
# define PyList_New dll_PyList_New
# define PyList_SetItem dll_PyList_SetItem
# define PyList_Size dll_PyList_Size
@@ -233,6 +235,7 @@ struct PyMethodDef { Py_ssize_t a; };
# define PyFloat_Type (*dll_PyFloat_Type)
# define PyImport_AddModule (*dll_PyImport_AddModule)
# define PySys_SetObject dll_PySys_SetObject
+# define PySys_GetObject dll_PySys_GetObject
# define PySys_SetArgv dll_PySys_SetArgv
# define PyType_Type (*dll_PyType_Type)
# define PyType_Ready (*dll_PyType_Ready)
@@ -305,6 +308,7 @@ static PyObject*(*dll_PyErr_Occurred)(void);
static void(*dll_PyErr_SetNone)(PyObject *);
static void(*dll_PyErr_SetString)(PyObject *, const char *);
static void(*dll_PyErr_SetObject)(PyObject *, PyObject *);
+static int(*dll_PyErr_ExceptionMatches)(PyObject *);
static void(*dll_PyEval_InitThreads)(void);
static void(*dll_PyEval_RestoreThread)(PyThreadState *);
static PyThreadState*(*dll_PyEval_SaveThread)(void);
@@ -320,7 +324,8 @@ static PyTypeObject* dll_PyBool_Type;
static PyTypeObject* dll_PyInt_Type;
static PyTypeObject* dll_PyLong_Type;
static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
-static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
+static int(*dll_PyList_Append)(PyObject *, PyObject *);
+static int(*dll_PyList_Insert)(PyObject *, int, PyObject *);
static PyObject*(*dll_PyList_New)(PyInt size);
static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
static PyInt(*dll_PyList_Size)(PyObject *);
@@ -366,6 +371,7 @@ static double(*dll_PyFloat_AsDouble)(PyObject *);
static PyObject*(*dll_PyFloat_FromDouble)(double);
static PyTypeObject* dll_PyFloat_Type;
static int(*dll_PySys_SetObject)(char *, PyObject *);
+static PyObject *(*dll_PySys_GetObject)(char *);
static int(*dll_PySys_SetArgv)(int, char **);
static PyTypeObject* dll_PyType_Type;
static int (*dll_PyType_Ready)(PyTypeObject *type);
@@ -431,6 +437,7 @@ static PyObject *imp_PyExc_KeyboardInterrupt;
static PyObject *imp_PyExc_TypeError;
static PyObject *imp_PyExc_ValueError;
static PyObject *imp_PyExc_RuntimeError;
+static PyObject *imp_PyExc_ImportError;
# define PyExc_AttributeError imp_PyExc_AttributeError
# define PyExc_IndexError imp_PyExc_IndexError
@@ -439,6 +446,7 @@ static PyObject *imp_PyExc_RuntimeError;
# define PyExc_TypeError imp_PyExc_TypeError
# define PyExc_ValueError imp_PyExc_ValueError
# define PyExc_RuntimeError imp_PyExc_RuntimeError
+# define PyExc_ImportError imp_PyExc_ImportError
/*
* Table of name to function pointer of python.
@@ -471,6 +479,7 @@ static struct
{"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone},
{"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString},
{"PyErr_SetObject", (PYTHON_PROC*)&dll_PyErr_SetObject},
+ {"PyErr_ExceptionMatches", (PYTHON_PROC*)&dll_PyErr_ExceptionMatches},
{"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads},
{"PyEval_RestoreThread", (PYTHON_PROC*)&dll_PyEval_RestoreThread},
{"PyEval_SaveThread", (PYTHON_PROC*)&dll_PyEval_SaveThread},
@@ -487,6 +496,7 @@ static struct
{"PyLong_Type", (PYTHON_PROC*)&dll_PyLong_Type},
{"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
{"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append},
+ {"PyList_Insert", (PYTHON_PROC*)&dll_PyList_Insert},
{"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
{"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
{"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
@@ -532,6 +542,7 @@ static struct
{"PyFloat_FromDouble", (PYTHON_PROC*)&dll_PyFloat_FromDouble},
{"PyImport_AddModule", (PYTHON_PROC*)&dll_PyImport_AddModule},
{"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
+ {"PySys_GetObject", (PYTHON_PROC*)&dll_PySys_GetObject},
{"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
{"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
{"PyType_Ready", (PYTHON_PROC*)&dll_PyType_Ready},
@@ -706,6 +717,7 @@ get_exceptions(void)
imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
+ imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
Py_XINCREF(imp_PyExc_AttributeError);
Py_XINCREF(imp_PyExc_IndexError);
Py_XINCREF(imp_PyExc_KeyError);
@@ -713,6 +725,7 @@ get_exceptions(void)
Py_XINCREF(imp_PyExc_TypeError);
Py_XINCREF(imp_PyExc_ValueError);
Py_XINCREF(imp_PyExc_RuntimeError);
+ Py_XINCREF(imp_PyExc_ImportError);
Py_XDECREF(exmod);
}
#endif /* DYNAMIC_PYTHON */
@@ -735,6 +748,10 @@ static PyObject *DictionaryGetattr(PyObject *, char*);
static PyObject *ListGetattr(PyObject *, char *);
static PyObject *FunctionGetattr(PyObject *, char *);
+static PyObject *LoaderLoadModule(PyObject *, PyObject *);
+static PyObject *FinderFindModule(PyObject *, PyObject *);
+static PyObject *VimPathHook(PyObject *, PyObject *);
+
#ifndef Py_VISIT
# define Py_VISIT(obj) visit(obj, arg)
#endif
@@ -1359,11 +1376,112 @@ python_tabpage_free(tabpage_T *tab)
}
#endif
+ static PyObject *
+LoaderLoadModule(PyObject *self, PyObject *args)
+{
+ char *fullname;
+ PyObject *path;
+ PyObject *meta_path;
+ PyObject *path_hooks;
+ PyObject *new_path;
+ PyObject *r;
+ PyObject *new_list;
+
+ if (!PyArg_ParseTuple(args, "s", &fullname))
+ return NULL;
+
+ if (!(new_path = Vim_GetPaths(self)))
+ return NULL;
+
+ if (!(new_list = PyList_New(0)))
+ return NULL;
+
+#define GET_SYS_OBJECT(objstr, obj) \
+ obj = PySys_GetObject(objstr); \
+ PyErr_Clear(); \
+ Py_XINCREF(obj);
+
+ GET_SYS_OBJECT("meta_path", meta_path);
+ if (PySys_SetObject("meta_path", new_list))
+ {
+ Py_XDECREF(meta_path);
+ Py_DECREF(new_list);
+ return NULL;
+ }
+ Py_DECREF(new_list); /* Now it becomes a reference borrowed from
+ sys.meta_path */
+
+#define RESTORE_SYS_OBJECT(objstr, obj) \
+ if (obj) \
+ { \
+ PySys_SetObject(objstr, obj); \
+ Py_DECREF(obj); \
+ }
+
+ GET_SYS_OBJECT("path_hooks", path_hooks);
+ if (PySys_SetObject("path_hooks", new_list))
+ {
+ RESTORE_SYS_OBJECT("meta_path", meta_path);
+ Py_XDECREF(path_hooks);
+ return NULL;
+ }
+
+ GET_SYS_OBJECT("path", path);
+ if (PySys_SetObject("path", new_path))
+ {
+ RESTORE_SYS_OBJECT("meta_path", meta_path);
+ RESTORE_SYS_OBJECT("path_hooks", path_hooks);
+ Py_XDECREF(path);
+ return NULL;
+ }
+ Py_DECREF(new_path);
+
+ r = PyImport_ImportModule(fullname);
+
+ RESTORE_SYS_OBJECT("meta_path", meta_path);
+ RESTORE_SYS_OBJECT("path_hooks", path_hooks);
+ RESTORE_SYS_OBJECT("path", path);
+
+ if (PyErr_Occurred())
+ {
+ Py_XDECREF(r);
+ return NULL;
+ }
+
+ return r;
+}
+
+ static PyObject *
+FinderFindModule(PyObject *self UNUSED, PyObject *args UNUSED)
+{
+ /*
+ * Don't bother actually finding the module, it is delegated to the "loader"
+ * object (which is basically the same object: vim module).
+ */
+ Py_INCREF(vim_module);
+ return vim_module;
+}
+
+ static PyObject *
+VimPathHook(PyObject *self UNUSED, PyObject *args)
+{
+ char *path;
+
+ if (PyArg_ParseTuple(args, "s", &path)
+ && STRCMP(path, vim_special_path) == 0)
+ {
+ Py_INCREF(vim_module);
+ return vim_module;
+ }
+
+ PyErr_Clear();
+ PyErr_SetNone(PyExc_ImportError);
+ return NULL;
+}
+
static int
PythonMod_Init(void)
{
- PyObject *mod;
-
/* The special value is removed from sys.path in Python_Init(). */
static char *(argv[2]) = {"/must>not&exist/foo", NULL};
@@ -1373,10 +1491,17 @@ PythonMod_Init(void)
/* Set sys.argv[] to avoid a crash in warn(). */
PySys_SetArgv(1, argv);
- mod = Py_InitModule4("vim", VimMethods, (char *)NULL, (PyObject *)NULL,
- PYTHON_API_VERSION);
+ vim_module = Py_InitModule4("vim", VimMethods, (char *)NULL,
+ (PyObject *)NULL, PYTHON_API_VERSION);
+
+ if (populate_module(vim_module, PyModule_AddObject,
+ PyObject_GetAttrString))
+ return -1;
+
+ if (init_sys_path())
+ return -1;
- return populate_module(mod, PyModule_AddObject, PyObject_GetAttrString);
+ return 0;
}
/*************************************************************************