blob: 1121802b50ecf8b2b19ccb952101a59aa1f4df97 [file] [log] [blame]
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9/*
10 * Python extensions by Paul Moore.
11 * Changes for Unix by David Leonard.
12 *
13 * This consists of four parts:
14 * 1. Python interpreter main program
15 * 2. Python output stream: writes output via [e]msg().
16 * 3. Implementation of the Vim module for Python
17 * 4. Utility functions for handling the interface between Vim and Python.
18 */
19
20/*
21 * Roland Puntaier 2009/sept/16:
22 * Adaptations to support both python3.x and python2.x
23 */
24
Bram Moolenaar0c1f3f42011-02-25 15:18:50 +010025/* uncomment this if used with the debug version of python */
26/* #define Py_DEBUG */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020027
28#include "vim.h"
29
30#include <limits.h>
31
32/* Python.h defines _POSIX_THREADS itself (if needed) */
33#ifdef _POSIX_THREADS
34# undef _POSIX_THREADS
35#endif
36
Bram Moolenaard68554d2010-07-25 13:43:20 +020037#if defined(_WIN32) && defined(HAVE_FCNTL_H)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020038# undef HAVE_FCNTL_H
39#endif
40
41#ifdef _DEBUG
42# undef _DEBUG
43#endif
44
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020045#define PY_SSIZE_T_CLEAN
46
47#ifdef F_BLANK
48# undef F_BLANK
49#endif
50
Bram Moolenaar6df6f472010-07-18 18:04:50 +020051#ifdef HAVE_STDARG_H
52# undef HAVE_STDARG_H /* Python's config.h defines it as well. */
53#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020054#ifdef _POSIX_C_SOURCE /* defined in feature.h */
55# undef _POSIX_C_SOURCE
56#endif
Bram Moolenaar6df6f472010-07-18 18:04:50 +020057#ifdef _XOPEN_SOURCE
58# undef _XOPEN_SOURCE /* pyconfig.h defines it as well. */
59#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020060
61#include <Python.h>
62#if defined(MACOS) && !defined(MACOS_X_UNIX)
63# include "macglue.h"
64# include <CodeFragments.h>
65#endif
66#undef main /* Defined in python.h - aargh */
67#undef HAVE_FCNTL_H /* Clash with os_win32.h */
68
69static void init_structs(void);
70
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020071#define PyInt Py_ssize_t
Bram Moolenaarca8a4df2010-07-31 19:54:14 +020072#define PyString_Check(obj) PyUnicode_Check(obj)
73#define PyString_AsString(obj) _PyUnicode_AsString(obj)
74#define PyString_Size(obj) PyUnicode_GET_SIZE(obj)
75#define PyString_FromString(repr) PyUnicode_FromString(repr)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020076
Bram Moolenaar0c1f3f42011-02-25 15:18:50 +010077#if defined(DYNAMIC_PYTHON3) || defined(PROTO)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020078
Bram Moolenaarb61f95c2010-08-09 22:06:13 +020079# ifndef WIN3264
80# include <dlfcn.h>
81# define FARPROC void*
82# define HINSTANCE void*
Bram Moolenaar644d37b2010-11-16 19:26:02 +010083# if defined(PY_NO_RTLD_GLOBAL) && defined(PY3_NO_RTLD_GLOBAL)
Bram Moolenaarb61f95c2010-08-09 22:06:13 +020084# define load_dll(n) dlopen((n), RTLD_LAZY)
85# else
86# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
87# endif
88# define close_dll dlclose
89# define symbol_from_dll dlsym
90# else
Bram Moolenaarebbcb822010-10-23 14:02:54 +020091# define load_dll vimLoadLib
Bram Moolenaarb61f95c2010-08-09 22:06:13 +020092# define close_dll FreeLibrary
93# define symbol_from_dll GetProcAddress
94# endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020095/*
96 * Wrapper defines
97 */
Bram Moolenaarb61f95c2010-08-09 22:06:13 +020098# undef PyArg_Parse
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020099# define PyArg_Parse py3_PyArg_Parse
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200100# undef PyArg_ParseTuple
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200101# define PyArg_ParseTuple py3_PyArg_ParseTuple
102# define PyDict_SetItemString py3_PyDict_SetItemString
103# define PyErr_BadArgument py3_PyErr_BadArgument
104# define PyErr_Clear py3_PyErr_Clear
105# define PyErr_NoMemory py3_PyErr_NoMemory
106# define PyErr_Occurred py3_PyErr_Occurred
107# define PyErr_SetNone py3_PyErr_SetNone
108# define PyErr_SetString py3_PyErr_SetString
109# define PyEval_InitThreads py3_PyEval_InitThreads
110# define PyEval_RestoreThread py3_PyEval_RestoreThread
111# define PyEval_SaveThread py3_PyEval_SaveThread
112# define PyGILState_Ensure py3_PyGILState_Ensure
113# define PyGILState_Release py3_PyGILState_Release
114# define PyLong_AsLong py3_PyLong_AsLong
115# define PyLong_FromLong py3_PyLong_FromLong
116# define PyList_GetItem py3_PyList_GetItem
117# define PyList_Append py3_PyList_Append
118# define PyList_New py3_PyList_New
119# define PyList_SetItem py3_PyList_SetItem
120# define PyList_Size py3_PyList_Size
121# define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
122# define PyImport_ImportModule py3_PyImport_ImportModule
123# define PyObject_Init py3__PyObject_Init
124# define PyDict_New py3_PyDict_New
125# define PyDict_GetItemString py3_PyDict_GetItemString
126# define PyModule_GetDict py3_PyModule_GetDict
127#undef PyRun_SimpleString
128# define PyRun_SimpleString py3_PyRun_SimpleString
129# define PySys_SetObject py3_PySys_SetObject
130# define PySys_SetArgv py3_PySys_SetArgv
131# define PyType_Type (*py3_PyType_Type)
132# define PyType_Ready py3_PyType_Ready
133#undef Py_BuildValue
134# define Py_BuildValue py3_Py_BuildValue
Bram Moolenaar644d37b2010-11-16 19:26:02 +0100135# define Py_SetPythonHome py3_Py_SetPythonHome
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200136# define Py_Initialize py3_Py_Initialize
137# define Py_Finalize py3_Py_Finalize
138# define Py_IsInitialized py3_Py_IsInitialized
139# define _Py_NoneStruct (*py3__Py_NoneStruct)
140# define PyModule_AddObject py3_PyModule_AddObject
141# define PyImport_AppendInittab py3_PyImport_AppendInittab
142# define _PyUnicode_AsString py3__PyUnicode_AsString
143# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
144# define PySlice_Type (*py3_PySlice_Type)
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200145# ifdef Py_DEBUG
146# define _Py_NegativeRefcount py3__Py_NegativeRefcount
147# define _Py_RefTotal (*py3__Py_RefTotal)
148# define _Py_Dealloc py3__Py_Dealloc
149# define _PyObject_DebugMalloc py3__PyObject_DebugMalloc
150# define _PyObject_DebugFree py3__PyObject_DebugFree
151# else
152# define PyObject_Malloc py3_PyObject_Malloc
153# define PyObject_Free py3_PyObject_Free
154# endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200155# define PyType_GenericAlloc py3_PyType_GenericAlloc
156# define PyType_GenericNew py3_PyType_GenericNew
157# define PyModule_Create2 py3_PyModule_Create2
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200158# undef PyUnicode_FromString
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200159# define PyUnicode_FromString py3_PyUnicode_FromString
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200160# undef PyUnicode_FromStringAndSize
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200161# define PyUnicode_FromStringAndSize py3_PyUnicode_FromStringAndSize
162
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200163# ifdef Py_DEBUG
164# undef PyObject_NEW
165# define PyObject_NEW(type, typeobj) \
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200166( (type *) PyObject_Init( \
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200167 (PyObject *) _PyObject_DebugMalloc( _PyObject_SIZE(typeobj) ), (typeobj)) )
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200168# endif
169
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200170/*
171 * Pointers for dynamic link
172 */
173static int (*py3_PySys_SetArgv)(int, wchar_t **);
Bram Moolenaar644d37b2010-11-16 19:26:02 +0100174static void (*py3_Py_SetPythonHome)(wchar_t *home);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200175static void (*py3_Py_Initialize)(void);
176static PyObject* (*py3_PyList_New)(Py_ssize_t size);
177static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
178static void (*py3_PyGILState_Release)(PyGILState_STATE);
179static int (*py3_PySys_SetObject)(char *, PyObject *);
180static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
181static Py_ssize_t (*py3_PyList_Size)(PyObject *);
182static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200183 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200184static PyObject* (*py3_PyErr_NoMemory)(void);
185static void (*py3_Py_Finalize)(void);
186static void (*py3_PyErr_SetString)(PyObject *, const char *);
187static int (*py3_PyRun_SimpleString)(char *);
188static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
189static PyObject* (*py3_PyImport_ImportModule)(const char *);
190static int (*py3_PyErr_BadArgument)(void);
191static PyTypeObject* py3_PyType_Type;
192static PyObject* (*py3_PyErr_Occurred)(void);
193static PyObject* (*py3_PyModule_GetDict)(PyObject *);
194static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *);
195static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
196static PyObject* (*py3_PyLong_FromLong)(long);
197static PyObject* (*py3_PyDict_New)(void);
198static PyObject* (*py3_Py_BuildValue)(char *, ...);
199static int (*py3_PyType_Ready)(PyTypeObject *type);
200static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
201static PyObject* (*py3_PyUnicode_FromString)(const char *u);
202static PyObject* (*py3_PyUnicode_FromStringAndSize)(const char *u, Py_ssize_t size);
203static long (*py3_PyLong_AsLong)(PyObject *);
204static void (*py3_PyErr_SetNone)(PyObject *);
205static void (*py3_PyEval_InitThreads)(void);
206static void(*py3_PyEval_RestoreThread)(PyThreadState *);
207static PyThreadState*(*py3_PyEval_SaveThread)(void);
208static int (*py3_PyArg_Parse)(PyObject *, char *, ...);
209static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...);
210static int (*py3_Py_IsInitialized)(void);
211static void (*py3_PyErr_Clear)(void);
212static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
213static PyObject* py3__Py_NoneStruct;
214static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o);
215static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void));
216static char* (*py3__PyUnicode_AsString)(PyObject *unicode);
217static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
218static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
219static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
220static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
221static PyTypeObject* py3_PySlice_Type;
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200222# ifdef Py_DEBUG
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200223 static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
224 static Py_ssize_t* py3__Py_RefTotal;
225 static void (*py3__Py_Dealloc)(PyObject *obj);
226 static void (*py3__PyObject_DebugFree)(void*);
227 static void* (*py3__PyObject_DebugMalloc)(size_t);
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200228# else
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200229 static void (*py3_PyObject_Free)(void*);
230 static void* (*py3_PyObject_Malloc)(size_t);
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200231# endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200232
233static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
234
235/* Imported exception objects */
236static PyObject *p3imp_PyExc_AttributeError;
237static PyObject *p3imp_PyExc_IndexError;
238static PyObject *p3imp_PyExc_KeyboardInterrupt;
239static PyObject *p3imp_PyExc_TypeError;
240static PyObject *p3imp_PyExc_ValueError;
241
242# define PyExc_AttributeError p3imp_PyExc_AttributeError
243# define PyExc_IndexError p3imp_PyExc_IndexError
244# define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt
245# define PyExc_TypeError p3imp_PyExc_TypeError
246# define PyExc_ValueError p3imp_PyExc_ValueError
247
248/*
249 * Table of name to function pointer of python.
250 */
251# define PYTHON_PROC FARPROC
252static struct
253{
254 char *name;
255 PYTHON_PROC *ptr;
256} py3_funcname_table[] =
257{
258 {"PySys_SetArgv", (PYTHON_PROC*)&py3_PySys_SetArgv},
Bram Moolenaar644d37b2010-11-16 19:26:02 +0100259 {"Py_SetPythonHome", (PYTHON_PROC*)&py3_Py_SetPythonHome},
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200260 {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize},
261 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
262 {"PyList_New", (PYTHON_PROC*)&py3_PyList_New},
263 {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
264 {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
265 {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
266 {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
267 {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
268 {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx},
269 {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory},
270 {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
271 {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
272 {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
273 {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
274 {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
275 {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument},
276 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
277 {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred},
278 {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict},
279 {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem},
280 {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString},
281 {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
282 {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
283 {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue},
284 {"PyType_Ready", (PYTHON_PROC*)&py3_PyType_Ready},
285 {"PyDict_SetItemString", (PYTHON_PROC*)&py3_PyDict_SetItemString},
286 {"PyLong_AsLong", (PYTHON_PROC*)&py3_PyLong_AsLong},
287 {"PyErr_SetNone", (PYTHON_PROC*)&py3_PyErr_SetNone},
288 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads},
289 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread},
290 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
291 {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse},
292 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
293 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
294 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
295 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
296 {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
297 {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject},
298 {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab},
299 {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString},
300 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
301 {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
302 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
303 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
304 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200305# ifdef Py_DEBUG
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200306 {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
307 {"_Py_RefTotal", (PYTHON_PROC*)&py3__Py_RefTotal},
308 {"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
309 {"_PyObject_DebugFree", (PYTHON_PROC*)&py3__PyObject_DebugFree},
310 {"_PyObject_DebugMalloc", (PYTHON_PROC*)&py3__PyObject_DebugMalloc},
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200311# else
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200312 {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
313 {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200314# endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200315 {"", NULL},
316};
317
318/*
319 * Free python.dll
320 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200321 static void
322end_dynamic_python3(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200323{
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200324 if (hinstPy3 != 0)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200325 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200326 close_dll(hinstPy3);
327 hinstPy3 = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200328 }
329}
330
331/*
332 * Load library and get all pointers.
333 * Parameter 'libname' provides name of DLL.
334 * Return OK or FAIL.
335 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200336 static int
337py3_runtime_link_init(char *libname, int verbose)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200338{
339 int i;
Bram Moolenaar69154f22010-07-18 21:42:34 +0200340 void *ucs_from_string, *ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200341
Bram Moolenaar644d37b2010-11-16 19:26:02 +0100342# if !(defined(PY_NO_RTLD_GLOBAL) && defined(PY3_NO_RTLD_GLOBAL)) && defined(UNIX) && defined(FEAT_PYTHON)
Bram Moolenaarb744b2f2010-08-13 16:22:57 +0200343 /* Can't have Python and Python3 loaded at the same time.
344 * It cause a crash, because RTLD_GLOBAL is needed for
345 * standard C extension libraries of one or both python versions. */
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200346 if (python_loaded())
347 {
Bram Moolenaarb744b2f2010-08-13 16:22:57 +0200348 EMSG(_("E837: This Vim cannot execute :py3 after using :python"));
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200349 return FAIL;
350 }
Bram Moolenaarb61f95c2010-08-09 22:06:13 +0200351# endif
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200352
353 if (hinstPy3 != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200354 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200355 hinstPy3 = load_dll(libname);
356
357 if (!hinstPy3)
358 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200359 if (verbose)
360 EMSG2(_(e_loadlib), libname);
361 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200362 }
363
364 for (i = 0; py3_funcname_table[i].ptr; ++i)
365 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200366 if ((*py3_funcname_table[i].ptr = symbol_from_dll(hinstPy3,
367 py3_funcname_table[i].name)) == NULL)
368 {
369 close_dll(hinstPy3);
370 hinstPy3 = 0;
371 if (verbose)
372 EMSG2(_(e_loadfunc), py3_funcname_table[i].name);
373 return FAIL;
374 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200375 }
376
Bram Moolenaar69154f22010-07-18 21:42:34 +0200377 /* Load unicode functions separately as only the ucs2 or the ucs4 functions
378 * will be present in the library. */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200379 ucs_from_string = symbol_from_dll(hinstPy3, "PyUnicodeUCS2_FromString");
380 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200381 "PyUnicodeUCS2_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200382 if (!ucs_from_string || !ucs_from_string_and_size)
383 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200384 ucs_from_string = symbol_from_dll(hinstPy3,
385 "PyUnicodeUCS4_FromString");
386 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
387 "PyUnicodeUCS4_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200388 }
389 if (ucs_from_string && ucs_from_string_and_size)
390 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200391 py3_PyUnicode_FromString = ucs_from_string;
392 py3_PyUnicode_FromStringAndSize = ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200393 }
394 else
395 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200396 close_dll(hinstPy3);
397 hinstPy3 = 0;
398 if (verbose)
399 EMSG2(_(e_loadfunc), "PyUnicode_UCSX_*");
400 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200401 }
402
403 return OK;
404}
405
406/*
407 * If python is enabled (there is installed python on Windows system) return
408 * TRUE, else FALSE.
409 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200410 int
411python3_enabled(int verbose)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200412{
413 return py3_runtime_link_init(DYNAMIC_PYTHON3_DLL, verbose) == OK;
414}
415
416/* Load the standard Python exceptions - don't import the symbols from the
417 * DLL, as this can cause errors (importing data symbols is not reliable).
418 */
419static void get_py3_exceptions __ARGS((void));
420
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200421 static void
422get_py3_exceptions()
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200423{
424 PyObject *exmod = PyImport_ImportModule("builtins");
425 PyObject *exdict = PyModule_GetDict(exmod);
426 p3imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
427 p3imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
428 p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
429 p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
430 p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
431 Py_XINCREF(p3imp_PyExc_AttributeError);
432 Py_XINCREF(p3imp_PyExc_IndexError);
433 Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
434 Py_XINCREF(p3imp_PyExc_TypeError);
435 Py_XINCREF(p3imp_PyExc_ValueError);
436 Py_XDECREF(exmod);
437}
438#endif /* DYNAMIC_PYTHON3 */
439
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200440static PyObject *BufferNew (buf_T *);
441static PyObject *WindowNew(win_T *);
442static PyObject *LineToString(const char *);
443
444static PyTypeObject RangeType;
445
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200446/*
447 * Include the code shared with if_python.c
448 */
449#include "if_py_both.h"
450
451 static void
452call_PyObject_Free(void *p)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200453{
454#ifdef Py_DEBUG
455 _PyObject_DebugFree(p);
456#else
457 PyObject_Free(p);
458#endif
459}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200460
461 static PyObject *
462call_PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200463{
464 return PyType_GenericNew(type,args,kwds);
465}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200466
467 static PyObject *
468call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200469{
470 return PyType_GenericAlloc(type,nitems);
471}
472
473/******************************************************
474 * Internal function prototypes.
475 */
476
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200477static Py_ssize_t RangeStart;
478static Py_ssize_t RangeEnd;
479
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200480static int PythonIO_Init(void);
481static void PythonIO_Fini(void);
Bram Moolenaar69154f22010-07-18 21:42:34 +0200482PyMODINIT_FUNC Py3Init_vim(void);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200483
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200484/******************************************************
485 * 1. Python interpreter main program.
486 */
487
488static int py3initialised = 0;
489
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200490static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
491
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200492 void
493python3_end()
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200494{
495 static int recurse = 0;
496
497 /* If a crash occurs while doing this, don't try again. */
498 if (recurse != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200499 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200500
501 ++recurse;
502
503#ifdef DYNAMIC_PYTHON3
504 if (hinstPy3)
505#endif
506 if (Py_IsInitialized())
507 {
508 // acquire lock before finalizing
509 pygilstate = PyGILState_Ensure();
510
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200511 PythonIO_Fini();
512 Py_Finalize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200513 }
514
515#ifdef DYNAMIC_PYTHON3
516 end_dynamic_python3();
517#endif
518
519 --recurse;
520}
521
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200522#if (defined(DYNAMIC_PYTHON) && defined(FEAT_PYTHON)) || defined(PROTO)
523 int
524python3_loaded()
525{
526 return (hinstPy3 != 0);
527}
528#endif
529
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200530 static int
531Python3_Init(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200532{
533 if (!py3initialised)
534 {
535#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200536 if (!python3_enabled(TRUE))
537 {
538 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
539 goto fail;
540 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200541#endif
542
543 init_structs();
544
Bram Moolenaar644d37b2010-11-16 19:26:02 +0100545
546#ifdef PYTHON3_HOME
547 Py_SetPythonHome(PYTHON3_HOME);
548#endif
549
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200550#if !defined(MACOS) || defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200551 Py_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200552#else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200553 PyMac_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200554#endif
Bram Moolenaar456f2bb2011-06-12 21:37:13 +0200555 /* initialise threads, must be after Py_Initialize() */
556 PyEval_InitThreads();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200557
558#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200559 get_py3_exceptions();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200560#endif
561
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200562 if (PythonIO_Init())
563 goto fail;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200564
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200565 PyImport_AppendInittab("vim", Py3Init_vim);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200566
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200567 /* Remove the element from sys.path that was added because of our
568 * argv[0] value in Py3Init_vim(). Previously we used an empty
569 * string, but dependinding on the OS we then get an empty entry or
570 * the current directory in sys.path. */
571 PyRun_SimpleString("import sys; sys.path = list(filter(lambda x: x != '/must>not&exist', sys.path))");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200572
573 // lock is created and acquired in PyEval_InitThreads() and thread
574 // state is created in Py_Initialize()
575 // there _PyGILState_NoteThreadState() also sets gilcounter to 1
576 // (python must have threads enabled!)
577 // so the following does both: unlock GIL and save thread state in TLS
578 // without deleting thread state
579 PyGILState_Release(pygilstate);
580
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200581 py3initialised = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200582 }
583
584 return 0;
585
586fail:
587 /* We call PythonIO_Flush() here to print any Python errors.
588 * This is OK, as it is possible to call this function even
589 * if PythonIO_Init() has not completed successfully (it will
590 * not do anything in this case).
591 */
592 PythonIO_Flush();
593 return -1;
594}
595
596/*
597 * External interface
598 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200599 static void
600DoPy3Command(exarg_T *eap, const char *cmd)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200601{
602#if defined(MACOS) && !defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200603 GrafPtr oldPort;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200604#endif
605#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200606 char *saved_locale;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200607#endif
608
609#if defined(MACOS) && !defined(MACOS_X_UNIX)
610 GetPort(&oldPort);
611 /* Check if the Python library is available */
612 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200613 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200614#endif
615 if (Python3_Init())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200616 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200617
618 RangeStart = eap->line1;
619 RangeEnd = eap->line2;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200620 Python_Release_Vim(); /* leave vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200621
622#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
623 /* Python only works properly when the LC_NUMERIC locale is "C". */
624 saved_locale = setlocale(LC_NUMERIC, NULL);
625 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200626 saved_locale = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200627 else
628 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200629 /* Need to make a copy, value may change when setting new locale. */
630 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
631 (void)setlocale(LC_NUMERIC, "C");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200632 }
633#endif
634
635 pygilstate = PyGILState_Ensure();
636
637 PyRun_SimpleString((char *)(cmd));
638
639 PyGILState_Release(pygilstate);
640
641#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
642 if (saved_locale != NULL)
643 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200644 (void)setlocale(LC_NUMERIC, saved_locale);
645 vim_free(saved_locale);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200646 }
647#endif
648
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200649 Python_Lock_Vim(); /* enter vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200650 PythonIO_Flush();
651#if defined(MACOS) && !defined(MACOS_X_UNIX)
652 SetPort(oldPort);
653#endif
654
655theend:
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200656 return; /* keeps lint happy */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200657}
658
659/*
Bram Moolenaar368373e2010-07-19 20:46:22 +0200660 * ":py3"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200661 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200662 void
663ex_py3(exarg_T *eap)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200664{
665 char_u *script;
666
667 script = script_get(eap, eap->arg);
668 if (!eap->skip)
669 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200670 if (script == NULL)
671 DoPy3Command(eap, (char *)eap->arg);
672 else
673 DoPy3Command(eap, (char *)script);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200674 }
675 vim_free(script);
676}
677
678#define BUFFER_SIZE 2048
679
680/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200681 * ":py3file"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200682 */
683 void
684ex_py3file(exarg_T *eap)
685{
686 static char buffer[BUFFER_SIZE];
687 const char *file;
688 char *p;
689 int i;
690
691 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
692 * stdio file pointer, but Vim and the Python DLL are compiled with
693 * different options under Windows, meaning that stdio pointers aren't
694 * compatible between the two. Yuk.
695 *
696 * construct: exec(compile(open('a_filename').read(), 'a_filename', 'exec'))
697 *
698 * We need to escape any backslashes or single quotes in the file name, so that
699 * Python won't mangle the file name.
700 */
701
702 strcpy(buffer, "exec(compile(open('");
703 p = buffer + 19; /* size of "exec(compile(open('" */
704
705 for (i=0; i<2; ++i)
706 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200707 file = (char *)eap->arg;
708 while (*file && p < buffer + (BUFFER_SIZE - 3))
709 {
710 if (*file == '\\' || *file == '\'')
711 *p++ = '\\';
712 *p++ = *file++;
713 }
714 /* If we didn't finish the file name, we hit a buffer overflow */
715 if (*file != '\0')
716 return;
717 if (i==0)
718 {
719 strcpy(p,"').read(),'");
720 p += 11;
721 }
722 else
723 {
724 strcpy(p,"','exec'))");
725 p += 10;
726 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200727 }
728
729
730 /* Execute the file */
731 DoPy3Command(eap, buffer);
732}
733
734/******************************************************
735 * 2. Python output stream: writes output via [e]msg().
736 */
737
738/* Implementation functions
739 */
740
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200741 static PyObject *
742OutputGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200743{
744 char *name = "";
745 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200746 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200747
748 if (strcmp(name, "softspace") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200749 return PyLong_FromLong(((OutputObject *)(self))->softspace);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200750
751 return PyObject_GenericGetAttr(self, nameobj);
752}
753
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200754 static int
755OutputSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200756{
757 char *name = "";
758 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200759 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200760
761 if (val == NULL) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200762 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
763 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200764 }
765
766 if (strcmp(name, "softspace") == 0)
767 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200768 if (!PyLong_Check(val)) {
769 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
770 return -1;
771 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200772
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200773 ((OutputObject *)(self))->softspace = PyLong_AsLong(val);
774 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200775 }
776
777 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
778 return -1;
779}
780
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200781/***************/
782
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200783 static int
784PythonIO_Init(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200785{
786 PyType_Ready(&OutputType);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200787 return PythonIO_Init_io();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200788}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200789
790 static void
791PythonIO_Fini(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200792{
793 PySys_SetObject("stdout", NULL);
794 PySys_SetObject("stderr", NULL);
795}
796
797/******************************************************
798 * 3. Implementation of the Vim module for Python
799 */
800
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200801/* Window type - Implementation functions
802 * --------------------------------------
803 */
804
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200805#define WindowType_Check(obj) ((obj)->ob_base.ob_type == &WindowType)
806
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200807/* Buffer type - Implementation functions
808 * --------------------------------------
809 */
810
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200811#define BufferType_Check(obj) ((obj)->ob_base.ob_type == &BufferType)
812
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200813static Py_ssize_t BufferLength(PyObject *);
814static PyObject *BufferItem(PyObject *, Py_ssize_t);
815static Py_ssize_t BufferAsItem(PyObject *, Py_ssize_t, PyObject *);
816static PyObject* BufferSubscript(PyObject *self, PyObject* idx);
817
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200818
819/* Line range type - Implementation functions
820 * --------------------------------------
821 */
822
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200823#define RangeType_Check(obj) ((obj)->ob_base.ob_type == &RangeType)
824
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200825static PyObject* RangeSubscript(PyObject *self, PyObject* idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200826static Py_ssize_t RangeAsItem(PyObject *, Py_ssize_t, PyObject *);
827
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200828/* Current objects type - Implementation functions
829 * -----------------------------------------------
830 */
831
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200832static PySequenceMethods BufferAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200833 (lenfunc) BufferLength, /* sq_length, len(x) */
834 (binaryfunc) 0, /* sq_concat, x+y */
835 (ssizeargfunc) 0, /* sq_repeat, x*n */
836 (ssizeargfunc) BufferItem, /* sq_item, x[i] */
837 0, /* was_sq_slice, x[i:j] */
838 (ssizeobjargproc) BufferAsItem, /* sq_ass_item, x[i]=v */
839 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200840 0, /* sq_contains */
841 0, /* sq_inplace_concat */
842 0, /* sq_inplace_repeat */
843};
844
845PyMappingMethods BufferAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200846 /* mp_length */ (lenfunc)BufferLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200847 /* mp_subscript */ (binaryfunc)BufferSubscript,
848 /* mp_ass_subscript */ (objobjargproc)0,
849};
850
851
852/* Buffer object - Definitions
853 */
854
855static PyTypeObject BufferType;
856
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200857 static PyObject *
858BufferNew(buf_T *buf)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200859{
860 /* We need to handle deletion of buffers underneath us.
861 * If we add a "b_python3_ref" field to the buf_T structure,
862 * then we can get at it in buf_freeall() in vim. We then
863 * need to create only ONE Python object per buffer - if
864 * we try to create a second, just INCREF the existing one
865 * and return it. The (single) Python object referring to
866 * the buffer is stored in "b_python3_ref".
867 * Question: what to do on a buf_freeall(). We'll probably
868 * have to either delete the Python object (DECREF it to
869 * zero - a bad idea, as it leaves dangling refs!) or
870 * set the buf_T * value to an invalid value (-1?), which
871 * means we need checks in all access functions... Bah.
872 */
873
874 BufferObject *self;
875
876 if (buf->b_python3_ref != NULL)
877 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200878 self = buf->b_python3_ref;
879 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200880 }
881 else
882 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200883 self = PyObject_NEW(BufferObject, &BufferType);
884 buf->b_python3_ref = self;
885 if (self == NULL)
886 return NULL;
887 self->buf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200888 }
889
890 return (PyObject *)(self);
891}
892
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200893 static void
894BufferDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200895{
896 BufferObject *this = (BufferObject *)(self);
897
898 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200899 this->buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200900}
901
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200902 static PyObject *
903BufferGetattro(PyObject *self, PyObject*nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200904{
905 BufferObject *this = (BufferObject *)(self);
906
907 char *name = "";
908 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200909 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200910
911 if (CheckBuffer(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200912 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200913
914 if (strcmp(name, "name") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200915 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200916 else if (strcmp(name, "number") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200917 return Py_BuildValue("n", this->buf->b_fnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200918 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200919 return Py_BuildValue("[ss]", "name", "number");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200920 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200921 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200922}
923
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200924 static PyObject *
925BufferRepr(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200926{
927 static char repr[100];
928 BufferObject *this = (BufferObject *)(self);
929
930 if (this->buf == INVALID_BUFFER_VALUE)
931 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200932 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
933 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200934 }
935 else
936 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200937 char *name = (char *)this->buf->b_fname;
938 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200939
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200940 if (name == NULL)
941 name = "";
942 len = strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200943
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200944 if (len > 35)
945 name = name + (35 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200946
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200947 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200948
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200949 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200950 }
951}
952
953/******************/
954
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200955 static Py_ssize_t
956BufferLength(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200957{
958 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200959 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200960
961 return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
962}
963
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200964 static PyObject *
965BufferItem(PyObject *self, Py_ssize_t n)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200966{
967 return RBItem((BufferObject *)(self), n, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200968 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200969}
970
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200971 static PyObject *
972BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
973{
974 return RBSlice((BufferObject *)(self), lo, hi, 1,
975 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
976}
977
978 static Py_ssize_t
979BufferAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200980{
981 return RBAsItem((BufferObject *)(self), n, val, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200982 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
983 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200984}
985
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200986
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200987 static PyObject *
988BufferSubscript(PyObject *self, PyObject* idx)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200989{
990 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200991 long _idx = PyLong_AsLong(idx);
992 return BufferItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200993 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200994 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200995
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200996 if (PySlice_GetIndicesEx((PySliceObject *)idx,
997 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
998 &start, &stop,
999 &step, &slicelen) < 0) {
1000 return NULL;
1001 }
1002 return BufferSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001003 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001004 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1005 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001006 }
1007}
1008
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001009static PySequenceMethods RangeAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001010 (lenfunc) RangeLength, /* sq_length, len(x) */
1011 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
1012 (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
1013 (ssizeargfunc) RangeItem, /* sq_item, x[i] */
1014 0, /* was_sq_slice, x[i:j] */
1015 (ssizeobjargproc) RangeAsItem, /* sq_as_item, x[i]=v */
1016 0, /* sq_ass_slice, x[i:j]=v */
1017 0, /* sq_contains */
1018 0, /* sq_inplace_concat */
1019 0, /* sq_inplace_repeat */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001020};
1021
1022PyMappingMethods RangeAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001023 /* mp_length */ (lenfunc)RangeLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001024 /* mp_subscript */ (binaryfunc)RangeSubscript,
1025 /* mp_ass_subscript */ (objobjargproc)0,
1026};
1027
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001028/* Line range object - Implementation
1029 */
1030
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001031 static void
1032RangeDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001033{
1034 Py_DECREF(((RangeObject *)(self))->buf);
1035}
1036
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001037 static PyObject *
1038RangeGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001039{
1040 char *name = "";
1041 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001042 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001043
1044 if (strcmp(name, "start") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001045 return Py_BuildValue("n", ((RangeObject *)(self))->start - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001046 else if (strcmp(name, "end") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001047 return Py_BuildValue("n", ((RangeObject *)(self))->end - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001048 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001049 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001050}
1051
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001052/****************/
1053
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001054 static Py_ssize_t
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001055RangeAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001056{
1057 return RBAsItem(((RangeObject *)(self))->buf, n, val,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001058 ((RangeObject *)(self))->start,
1059 ((RangeObject *)(self))->end,
1060 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001061}
1062
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001063 static PyObject *
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001064RangeSubscript(PyObject *self, PyObject* idx)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001065{
1066 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001067 long _idx = PyLong_AsLong(idx);
1068 return RangeItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001069 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001070 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001071
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001072 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1073 ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
1074 &start, &stop,
1075 &step, &slicelen) < 0) {
1076 return NULL;
1077 }
1078 return RangeSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001079 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001080 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1081 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001082 }
1083}
1084
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001085/* Buffer list object - Definitions
1086 */
1087
1088typedef struct
1089{
1090 PyObject_HEAD
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001091} BufListObject;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001092
1093static PySequenceMethods BufListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001094 (lenfunc) BufListLength, /* sq_length, len(x) */
1095 (binaryfunc) 0, /* sq_concat, x+y */
1096 (ssizeargfunc) 0, /* sq_repeat, x*n */
1097 (ssizeargfunc) BufListItem, /* sq_item, x[i] */
1098 0, /* was_sq_slice, x[i:j] */
1099 (ssizeobjargproc) 0, /* sq_as_item, x[i]=v */
1100 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001101 0, /* sq_contains */
1102 0, /* sq_inplace_concat */
1103 0, /* sq_inplace_repeat */
1104};
1105
1106static PyTypeObject BufListType;
1107
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001108/* Window object - Definitions
1109 */
1110
1111static struct PyMethodDef WindowMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001112 /* name, function, calling, documentation */
1113 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001114};
1115
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001116static PyTypeObject WindowType;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001117
1118/* Window object - Implementation
1119 */
1120
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001121 static PyObject *
1122WindowNew(win_T *win)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001123{
1124 /* We need to handle deletion of windows underneath us.
1125 * If we add a "w_python3_ref" field to the win_T structure,
1126 * then we can get at it in win_free() in vim. We then
1127 * need to create only ONE Python object per window - if
1128 * we try to create a second, just INCREF the existing one
1129 * and return it. The (single) Python object referring to
1130 * the window is stored in "w_python3_ref".
1131 * On a win_free() we set the Python object's win_T* field
1132 * to an invalid value. We trap all uses of a window
1133 * object, and reject them if the win_T* field is invalid.
1134 */
1135
1136 WindowObject *self;
1137
1138 if (win->w_python3_ref)
1139 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001140 self = win->w_python3_ref;
1141 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001142 }
1143 else
1144 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001145 self = PyObject_NEW(WindowObject, &WindowType);
1146 if (self == NULL)
1147 return NULL;
1148 self->win = win;
1149 win->w_python3_ref = self;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001150 }
1151
1152 return (PyObject *)(self);
1153}
1154
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001155 static void
1156WindowDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001157{
1158 WindowObject *this = (WindowObject *)(self);
1159
1160 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001161 this->win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001162}
1163
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001164 static PyObject *
1165WindowGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001166{
1167 WindowObject *this = (WindowObject *)(self);
1168
1169 char *name = "";
1170 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001171 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001172
1173
1174 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001175 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001176
1177 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001178 return (PyObject *)BufferNew(this->win->w_buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001179 else if (strcmp(name, "cursor") == 0)
1180 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001181 pos_T *pos = &this->win->w_cursor;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001182
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001183 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001184 }
1185 else if (strcmp(name, "height") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001186 return Py_BuildValue("l", (long)(this->win->w_height));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001187#ifdef FEAT_VERTSPLIT
1188 else if (strcmp(name, "width") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001189 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001190#endif
1191 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001192 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001193 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001194 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001195}
1196
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001197 static int
1198WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001199{
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001200 char *name = "";
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001201
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001202 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001203 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001204
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001205 return WindowSetattr(self, name, val);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001206}
1207
1208/* Window list object - Definitions
1209 */
1210
1211typedef struct
1212{
1213 PyObject_HEAD
1214}
1215WinListObject;
1216
1217static PySequenceMethods WinListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001218 (lenfunc) WinListLength, /* sq_length, len(x) */
1219 (binaryfunc) 0, /* sq_concat, x+y */
1220 (ssizeargfunc) 0, /* sq_repeat, x*n */
1221 (ssizeargfunc) WinListItem, /* sq_item, x[i] */
1222 0, /* sq_slice, x[i:j] */
1223 (ssizeobjargproc)0, /* sq_as_item, x[i]=v */
1224 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001225 0, /* sq_contains */
1226 0, /* sq_inplace_concat */
1227 0, /* sq_inplace_repeat */
1228};
1229
1230static PyTypeObject WinListType;
1231
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001232/* Current items object - Definitions
1233 */
1234
1235typedef struct
1236{
1237 PyObject_HEAD
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001238} CurrentObject;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001239
1240static PyTypeObject CurrentType;
1241
1242/* Current items object - Implementation
1243 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001244 static PyObject *
1245CurrentGetattro(PyObject *self UNUSED, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001246{
1247 char *name = "";
1248 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001249 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001250
1251 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001252 return (PyObject *)BufferNew(curbuf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001253 else if (strcmp(name, "window") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001254 return (PyObject *)WindowNew(curwin);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001255 else if (strcmp(name, "line") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001256 return GetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001257 else if (strcmp(name, "range") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001258 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001259 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001260 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001261 else
1262 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001263 PyErr_SetString(PyExc_AttributeError, name);
1264 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001265 }
1266}
1267
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001268 static int
1269CurrentSetattro(PyObject *self UNUSED, PyObject *nameobj, PyObject *value)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001270{
1271 char *name = "";
1272 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001273 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001274
1275 if (strcmp(name, "line") == 0)
1276 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001277 if (SetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum, value, NULL) == FAIL)
1278 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001279
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001280 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001281 }
1282 else
1283 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001284 PyErr_SetString(PyExc_AttributeError, name);
1285 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001286 }
1287}
1288
1289/* External interface
1290 */
1291
1292 void
1293python3_buffer_free(buf_T *buf)
1294{
1295 if (buf->b_python3_ref != NULL)
1296 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001297 BufferObject *bp = buf->b_python3_ref;
1298 bp->buf = INVALID_BUFFER_VALUE;
1299 buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001300 }
1301}
1302
1303#if defined(FEAT_WINDOWS) || defined(PROTO)
1304 void
1305python3_window_free(win_T *win)
1306{
1307 if (win->w_python3_ref != NULL)
1308 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001309 WindowObject *wp = win->w_python3_ref;
1310 wp->win = INVALID_WINDOW_VALUE;
1311 win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001312 }
1313}
1314#endif
1315
1316static BufListObject TheBufferList =
1317{
1318 PyObject_HEAD_INIT(&BufListType)
1319};
1320
1321static WinListObject TheWindowList =
1322{
1323 PyObject_HEAD_INIT(&WinListType)
1324};
1325
1326static CurrentObject TheCurrent =
1327{
1328 PyObject_HEAD_INIT(&CurrentType)
1329};
1330
1331PyDoc_STRVAR(vim_module_doc,"vim python interface\n");
1332
1333static struct PyModuleDef vimmodule;
1334
Bram Moolenaar69154f22010-07-18 21:42:34 +02001335#ifndef PROTO
1336PyMODINIT_FUNC Py3Init_vim(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001337{
1338 PyObject *mod;
1339 /* The special value is removed from sys.path in Python3_Init(). */
1340 static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
1341
1342 PyType_Ready(&BufferType);
1343 PyType_Ready(&RangeType);
1344 PyType_Ready(&WindowType);
1345 PyType_Ready(&BufListType);
1346 PyType_Ready(&WinListType);
1347 PyType_Ready(&CurrentType);
1348
1349 /* Set sys.argv[] to avoid a crash in warn(). */
1350 PySys_SetArgv(1, argv);
1351
1352 mod = PyModule_Create(&vimmodule);
1353
1354 VimError = Py_BuildValue("s", "vim.error");
1355
1356 PyModule_AddObject(mod, "error", VimError);
1357 Py_INCREF((PyObject *)(void *)&TheBufferList);
1358 PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
1359 Py_INCREF((PyObject *)(void *)&TheCurrent);
1360 PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
1361 Py_INCREF((PyObject *)(void *)&TheWindowList);
1362 PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
1363
1364 if (PyErr_Occurred())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001365 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001366
1367 return mod;
1368}
Bram Moolenaar69154f22010-07-18 21:42:34 +02001369#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001370
1371/*************************************************************************
1372 * 4. Utility functions for handling the interface between Vim and Python.
1373 */
1374
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001375/* Convert a Vim line into a Python string.
1376 * All internal newlines are replaced by null characters.
1377 *
1378 * On errors, the Python exception data is set, and NULL is returned.
1379 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001380 static PyObject *
1381LineToString(const char *str)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001382{
1383 PyObject *result;
1384 Py_ssize_t len = strlen(str);
1385 char *tmp,*p;
1386
1387 tmp = (char *)alloc((unsigned)(len+1));
1388 p = tmp;
1389 if (p == NULL)
1390 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001391 PyErr_NoMemory();
1392 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001393 }
1394
1395 while (*str)
1396 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001397 if (*str == '\n')
1398 *p = '\0';
1399 else
1400 *p = *str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001401
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001402 ++p;
1403 ++str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001404 }
1405 *p = '\0';
1406
1407 result = PyUnicode_FromStringAndSize(tmp, len);
1408
1409 vim_free(tmp);
1410 return result;
1411}
1412
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001413 static void
1414init_structs(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001415{
1416 vim_memset(&OutputType, 0, sizeof(OutputType));
1417 OutputType.tp_name = "vim.message";
1418 OutputType.tp_basicsize = sizeof(OutputObject);
1419 OutputType.tp_getattro = OutputGetattro;
1420 OutputType.tp_setattro = OutputSetattro;
1421 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
1422 OutputType.tp_doc = "vim message object";
1423 OutputType.tp_methods = OutputMethods;
1424 OutputType.tp_alloc = call_PyType_GenericAlloc;
1425 OutputType.tp_new = call_PyType_GenericNew;
1426 OutputType.tp_free = call_PyObject_Free;
1427
1428 vim_memset(&BufferType, 0, sizeof(BufferType));
1429 BufferType.tp_name = "vim.buffer";
1430 BufferType.tp_basicsize = sizeof(BufferType);
1431 BufferType.tp_dealloc = BufferDestructor;
1432 BufferType.tp_repr = BufferRepr;
1433 BufferType.tp_as_sequence = &BufferAsSeq;
1434 BufferType.tp_as_mapping = &BufferAsMapping;
1435 BufferType.tp_getattro = BufferGetattro;
1436 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
1437 BufferType.tp_doc = "vim buffer object";
1438 BufferType.tp_methods = BufferMethods;
1439 BufferType.tp_alloc = call_PyType_GenericAlloc;
1440 BufferType.tp_new = call_PyType_GenericNew;
1441 BufferType.tp_free = call_PyObject_Free;
1442
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001443 vim_memset(&WindowType, 0, sizeof(WindowType));
1444 WindowType.tp_name = "vim.window";
1445 WindowType.tp_basicsize = sizeof(WindowObject);
1446 WindowType.tp_dealloc = WindowDestructor;
1447 WindowType.tp_repr = WindowRepr;
1448 WindowType.tp_getattro = WindowGetattro;
1449 WindowType.tp_setattro = WindowSetattro;
1450 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
1451 WindowType.tp_doc = "vim Window object";
1452 WindowType.tp_methods = WindowMethods;
1453 WindowType.tp_alloc = call_PyType_GenericAlloc;
1454 WindowType.tp_new = call_PyType_GenericNew;
1455 WindowType.tp_free = call_PyObject_Free;
1456
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001457 vim_memset(&BufListType, 0, sizeof(BufListType));
1458 BufListType.tp_name = "vim.bufferlist";
1459 BufListType.tp_basicsize = sizeof(BufListObject);
1460 BufListType.tp_as_sequence = &BufListAsSeq;
1461 BufListType.tp_flags = Py_TPFLAGS_DEFAULT;
1462 BufferType.tp_doc = "vim buffer list";
1463
1464 vim_memset(&WinListType, 0, sizeof(WinListType));
1465 WinListType.tp_name = "vim.windowlist";
1466 WinListType.tp_basicsize = sizeof(WinListType);
1467 WinListType.tp_as_sequence = &WinListAsSeq;
1468 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
1469 WinListType.tp_doc = "vim window list";
1470
1471 vim_memset(&RangeType, 0, sizeof(RangeType));
1472 RangeType.tp_name = "vim.range";
1473 RangeType.tp_basicsize = sizeof(RangeObject);
1474 RangeType.tp_dealloc = RangeDestructor;
1475 RangeType.tp_repr = RangeRepr;
1476 RangeType.tp_as_sequence = &RangeAsSeq;
1477 RangeType.tp_as_mapping = &RangeAsMapping;
1478 RangeType.tp_getattro = RangeGetattro;
1479 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
1480 RangeType.tp_doc = "vim Range object";
1481 RangeType.tp_methods = RangeMethods;
1482 RangeType.tp_alloc = call_PyType_GenericAlloc;
1483 RangeType.tp_new = call_PyType_GenericNew;
1484 RangeType.tp_free = call_PyObject_Free;
1485
1486 vim_memset(&CurrentType, 0, sizeof(CurrentType));
1487 CurrentType.tp_name = "vim.currentdata";
1488 CurrentType.tp_basicsize = sizeof(CurrentObject);
1489 CurrentType.tp_getattro = CurrentGetattro;
1490 CurrentType.tp_setattro = CurrentSetattro;
1491 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
1492 CurrentType.tp_doc = "vim current object";
1493
1494 vim_memset(&vimmodule, 0, sizeof(vimmodule));
1495 vimmodule.m_name = "vim";
1496 vimmodule.m_doc = vim_module_doc;
1497 vimmodule.m_size = -1;
1498 vimmodule.m_methods = VimMethods;
1499}