blob: b2c2ba3bac5bab9a930cef014d28f75074be16c5 [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
25// uncomment this if used with the debug version of python
26// #define Py_DEBUG
27
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 Moolenaarbd5e15f2010-07-17 21:19:38 +020077#if defined(DYNAMIC_PYTHON3)
78
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020079#ifndef WIN3264
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020080#include <dlfcn.h>
81#define FARPROC void*
82#define HINSTANCE void*
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020083#define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020084#define close_dll dlclose
85#define symbol_from_dll dlsym
86#else
87#define load_dll LoadLibrary
88#define close_dll FreeLibrary
89#define symbol_from_dll GetProcAddress
90#endif
91/*
92 * Wrapper defines
93 */
94#undef PyArg_Parse
95# define PyArg_Parse py3_PyArg_Parse
96#undef PyArg_ParseTuple
97# define PyArg_ParseTuple py3_PyArg_ParseTuple
98# define PyDict_SetItemString py3_PyDict_SetItemString
99# define PyErr_BadArgument py3_PyErr_BadArgument
100# define PyErr_Clear py3_PyErr_Clear
101# define PyErr_NoMemory py3_PyErr_NoMemory
102# define PyErr_Occurred py3_PyErr_Occurred
103# define PyErr_SetNone py3_PyErr_SetNone
104# define PyErr_SetString py3_PyErr_SetString
105# define PyEval_InitThreads py3_PyEval_InitThreads
106# define PyEval_RestoreThread py3_PyEval_RestoreThread
107# define PyEval_SaveThread py3_PyEval_SaveThread
108# define PyGILState_Ensure py3_PyGILState_Ensure
109# define PyGILState_Release py3_PyGILState_Release
110# define PyLong_AsLong py3_PyLong_AsLong
111# define PyLong_FromLong py3_PyLong_FromLong
112# define PyList_GetItem py3_PyList_GetItem
113# define PyList_Append py3_PyList_Append
114# define PyList_New py3_PyList_New
115# define PyList_SetItem py3_PyList_SetItem
116# define PyList_Size py3_PyList_Size
117# define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
118# define PyImport_ImportModule py3_PyImport_ImportModule
119# define PyObject_Init py3__PyObject_Init
120# define PyDict_New py3_PyDict_New
121# define PyDict_GetItemString py3_PyDict_GetItemString
122# define PyModule_GetDict py3_PyModule_GetDict
123#undef PyRun_SimpleString
124# define PyRun_SimpleString py3_PyRun_SimpleString
125# define PySys_SetObject py3_PySys_SetObject
126# define PySys_SetArgv py3_PySys_SetArgv
127# define PyType_Type (*py3_PyType_Type)
128# define PyType_Ready py3_PyType_Ready
129#undef Py_BuildValue
130# define Py_BuildValue py3_Py_BuildValue
131# define Py_Initialize py3_Py_Initialize
132# define Py_Finalize py3_Py_Finalize
133# define Py_IsInitialized py3_Py_IsInitialized
134# define _Py_NoneStruct (*py3__Py_NoneStruct)
135# define PyModule_AddObject py3_PyModule_AddObject
136# define PyImport_AppendInittab py3_PyImport_AppendInittab
137# define _PyUnicode_AsString py3__PyUnicode_AsString
138# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
139# define PySlice_Type (*py3_PySlice_Type)
140#ifdef Py_DEBUG
141 # define _Py_NegativeRefcount py3__Py_NegativeRefcount
142 # define _Py_RefTotal (*py3__Py_RefTotal)
143 # define _Py_Dealloc py3__Py_Dealloc
144 # define _PyObject_DebugMalloc py3__PyObject_DebugMalloc
145 # define _PyObject_DebugFree py3__PyObject_DebugFree
146#else
147 # define PyObject_Malloc py3_PyObject_Malloc
148 # define PyObject_Free py3_PyObject_Free
149#endif
150# define PyType_GenericAlloc py3_PyType_GenericAlloc
151# define PyType_GenericNew py3_PyType_GenericNew
152# define PyModule_Create2 py3_PyModule_Create2
153#undef PyUnicode_FromString
154# define PyUnicode_FromString py3_PyUnicode_FromString
155#undef PyUnicode_FromStringAndSize
156# define PyUnicode_FromStringAndSize py3_PyUnicode_FromStringAndSize
157
158#ifdef Py_DEBUG
159#undef PyObject_NEW
160#define PyObject_NEW(type, typeobj) \
161( (type *) PyObject_Init( \
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200162 (PyObject *) _PyObject_DebugMalloc( _PyObject_SIZE(typeobj) ), (typeobj)) )
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200163#endif
164/*
165 * Pointers for dynamic link
166 */
167static int (*py3_PySys_SetArgv)(int, wchar_t **);
168static void (*py3_Py_Initialize)(void);
169static PyObject* (*py3_PyList_New)(Py_ssize_t size);
170static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
171static void (*py3_PyGILState_Release)(PyGILState_STATE);
172static int (*py3_PySys_SetObject)(char *, PyObject *);
173static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
174static Py_ssize_t (*py3_PyList_Size)(PyObject *);
175static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200176 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200177static PyObject* (*py3_PyErr_NoMemory)(void);
178static void (*py3_Py_Finalize)(void);
179static void (*py3_PyErr_SetString)(PyObject *, const char *);
180static int (*py3_PyRun_SimpleString)(char *);
181static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
182static PyObject* (*py3_PyImport_ImportModule)(const char *);
183static int (*py3_PyErr_BadArgument)(void);
184static PyTypeObject* py3_PyType_Type;
185static PyObject* (*py3_PyErr_Occurred)(void);
186static PyObject* (*py3_PyModule_GetDict)(PyObject *);
187static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *);
188static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
189static PyObject* (*py3_PyLong_FromLong)(long);
190static PyObject* (*py3_PyDict_New)(void);
191static PyObject* (*py3_Py_BuildValue)(char *, ...);
192static int (*py3_PyType_Ready)(PyTypeObject *type);
193static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
194static PyObject* (*py3_PyUnicode_FromString)(const char *u);
195static PyObject* (*py3_PyUnicode_FromStringAndSize)(const char *u, Py_ssize_t size);
196static long (*py3_PyLong_AsLong)(PyObject *);
197static void (*py3_PyErr_SetNone)(PyObject *);
198static void (*py3_PyEval_InitThreads)(void);
199static void(*py3_PyEval_RestoreThread)(PyThreadState *);
200static PyThreadState*(*py3_PyEval_SaveThread)(void);
201static int (*py3_PyArg_Parse)(PyObject *, char *, ...);
202static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...);
203static int (*py3_Py_IsInitialized)(void);
204static void (*py3_PyErr_Clear)(void);
205static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
206static PyObject* py3__Py_NoneStruct;
207static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o);
208static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void));
209static char* (*py3__PyUnicode_AsString)(PyObject *unicode);
210static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
211static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
212static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
213static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
214static PyTypeObject* py3_PySlice_Type;
215#ifdef Py_DEBUG
216 static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
217 static Py_ssize_t* py3__Py_RefTotal;
218 static void (*py3__Py_Dealloc)(PyObject *obj);
219 static void (*py3__PyObject_DebugFree)(void*);
220 static void* (*py3__PyObject_DebugMalloc)(size_t);
221#else
222 static void (*py3_PyObject_Free)(void*);
223 static void* (*py3_PyObject_Malloc)(size_t);
224#endif
225
226static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
227
228/* Imported exception objects */
229static PyObject *p3imp_PyExc_AttributeError;
230static PyObject *p3imp_PyExc_IndexError;
231static PyObject *p3imp_PyExc_KeyboardInterrupt;
232static PyObject *p3imp_PyExc_TypeError;
233static PyObject *p3imp_PyExc_ValueError;
234
235# define PyExc_AttributeError p3imp_PyExc_AttributeError
236# define PyExc_IndexError p3imp_PyExc_IndexError
237# define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt
238# define PyExc_TypeError p3imp_PyExc_TypeError
239# define PyExc_ValueError p3imp_PyExc_ValueError
240
241/*
242 * Table of name to function pointer of python.
243 */
244# define PYTHON_PROC FARPROC
245static struct
246{
247 char *name;
248 PYTHON_PROC *ptr;
249} py3_funcname_table[] =
250{
251 {"PySys_SetArgv", (PYTHON_PROC*)&py3_PySys_SetArgv},
252 {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize},
253 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
254 {"PyList_New", (PYTHON_PROC*)&py3_PyList_New},
255 {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
256 {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
257 {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
258 {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
259 {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
260 {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx},
261 {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory},
262 {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
263 {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
264 {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
265 {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
266 {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
267 {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument},
268 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
269 {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred},
270 {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict},
271 {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem},
272 {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString},
273 {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
274 {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
275 {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue},
276 {"PyType_Ready", (PYTHON_PROC*)&py3_PyType_Ready},
277 {"PyDict_SetItemString", (PYTHON_PROC*)&py3_PyDict_SetItemString},
278 {"PyLong_AsLong", (PYTHON_PROC*)&py3_PyLong_AsLong},
279 {"PyErr_SetNone", (PYTHON_PROC*)&py3_PyErr_SetNone},
280 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads},
281 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread},
282 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
283 {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse},
284 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
285 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
286 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
287 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
288 {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
289 {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject},
290 {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab},
291 {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString},
292 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
293 {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
294 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
295 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
296 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
297#ifdef Py_DEBUG
298 {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
299 {"_Py_RefTotal", (PYTHON_PROC*)&py3__Py_RefTotal},
300 {"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
301 {"_PyObject_DebugFree", (PYTHON_PROC*)&py3__PyObject_DebugFree},
302 {"_PyObject_DebugMalloc", (PYTHON_PROC*)&py3__PyObject_DebugMalloc},
303#else
304 {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
305 {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
306#endif
307 {"", NULL},
308};
309
310/*
311 * Free python.dll
312 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200313 static void
314end_dynamic_python3(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200315{
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200316 if (hinstPy3 != 0)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200317 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200318 close_dll(hinstPy3);
319 hinstPy3 = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200320 }
321}
322
323/*
324 * Load library and get all pointers.
325 * Parameter 'libname' provides name of DLL.
326 * Return OK or FAIL.
327 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200328 static int
329py3_runtime_link_init(char *libname, int verbose)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200330{
331 int i;
Bram Moolenaar69154f22010-07-18 21:42:34 +0200332 void *ucs_from_string, *ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200333
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200334#if defined(UNIX) && defined(FEAT_PYTHON)
335 /* Can't have Python and Python3 loaded at the same time, it may cause a
336 * crash. */
337 if (python_loaded())
338 {
339 EMSG(_("E999: Python: Cannot use :py and :py3 in one session"));
340 return FAIL;
341 }
342#endif
343
344 if (hinstPy3 != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200345 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200346 hinstPy3 = load_dll(libname);
347
348 if (!hinstPy3)
349 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200350 if (verbose)
351 EMSG2(_(e_loadlib), libname);
352 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200353 }
354
355 for (i = 0; py3_funcname_table[i].ptr; ++i)
356 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200357 if ((*py3_funcname_table[i].ptr = symbol_from_dll(hinstPy3,
358 py3_funcname_table[i].name)) == NULL)
359 {
360 close_dll(hinstPy3);
361 hinstPy3 = 0;
362 if (verbose)
363 EMSG2(_(e_loadfunc), py3_funcname_table[i].name);
364 return FAIL;
365 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200366 }
367
Bram Moolenaar69154f22010-07-18 21:42:34 +0200368 /* Load unicode functions separately as only the ucs2 or the ucs4 functions
369 * will be present in the library. */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200370 ucs_from_string = symbol_from_dll(hinstPy3, "PyUnicodeUCS2_FromString");
371 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200372 "PyUnicodeUCS2_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200373 if (!ucs_from_string || !ucs_from_string_and_size)
374 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200375 ucs_from_string = symbol_from_dll(hinstPy3,
376 "PyUnicodeUCS4_FromString");
377 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
378 "PyUnicodeUCS4_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200379 }
380 if (ucs_from_string && ucs_from_string_and_size)
381 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200382 py3_PyUnicode_FromString = ucs_from_string;
383 py3_PyUnicode_FromStringAndSize = ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200384 }
385 else
386 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200387 close_dll(hinstPy3);
388 hinstPy3 = 0;
389 if (verbose)
390 EMSG2(_(e_loadfunc), "PyUnicode_UCSX_*");
391 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200392 }
393
394 return OK;
395}
396
397/*
398 * If python is enabled (there is installed python on Windows system) return
399 * TRUE, else FALSE.
400 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200401 int
402python3_enabled(int verbose)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200403{
404 return py3_runtime_link_init(DYNAMIC_PYTHON3_DLL, verbose) == OK;
405}
406
407/* Load the standard Python exceptions - don't import the symbols from the
408 * DLL, as this can cause errors (importing data symbols is not reliable).
409 */
410static void get_py3_exceptions __ARGS((void));
411
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200412 static void
413get_py3_exceptions()
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200414{
415 PyObject *exmod = PyImport_ImportModule("builtins");
416 PyObject *exdict = PyModule_GetDict(exmod);
417 p3imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
418 p3imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
419 p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
420 p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
421 p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
422 Py_XINCREF(p3imp_PyExc_AttributeError);
423 Py_XINCREF(p3imp_PyExc_IndexError);
424 Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
425 Py_XINCREF(p3imp_PyExc_TypeError);
426 Py_XINCREF(p3imp_PyExc_ValueError);
427 Py_XDECREF(exmod);
428}
429#endif /* DYNAMIC_PYTHON3 */
430
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200431static PyObject *BufferNew (buf_T *);
432static PyObject *WindowNew(win_T *);
433static PyObject *LineToString(const char *);
434
435static PyTypeObject RangeType;
436
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200437/*
438 * Include the code shared with if_python.c
439 */
440#include "if_py_both.h"
441
442 static void
443call_PyObject_Free(void *p)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200444{
445#ifdef Py_DEBUG
446 _PyObject_DebugFree(p);
447#else
448 PyObject_Free(p);
449#endif
450}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200451
452 static PyObject *
453call_PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200454{
455 return PyType_GenericNew(type,args,kwds);
456}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200457
458 static PyObject *
459call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200460{
461 return PyType_GenericAlloc(type,nitems);
462}
463
464/******************************************************
465 * Internal function prototypes.
466 */
467
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200468static Py_ssize_t RangeStart;
469static Py_ssize_t RangeEnd;
470
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200471static int PythonIO_Init(void);
472static void PythonIO_Fini(void);
Bram Moolenaar69154f22010-07-18 21:42:34 +0200473PyMODINIT_FUNC Py3Init_vim(void);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200474
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200475/******************************************************
476 * 1. Python interpreter main program.
477 */
478
479static int py3initialised = 0;
480
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200481static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
482
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200483 void
484python3_end()
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200485{
486 static int recurse = 0;
487
488 /* If a crash occurs while doing this, don't try again. */
489 if (recurse != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200490 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200491
492 ++recurse;
493
494#ifdef DYNAMIC_PYTHON3
495 if (hinstPy3)
496#endif
497 if (Py_IsInitialized())
498 {
499 // acquire lock before finalizing
500 pygilstate = PyGILState_Ensure();
501
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200502 PythonIO_Fini();
503 Py_Finalize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200504 }
505
506#ifdef DYNAMIC_PYTHON3
507 end_dynamic_python3();
508#endif
509
510 --recurse;
511}
512
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200513#if (defined(DYNAMIC_PYTHON) && defined(FEAT_PYTHON)) || defined(PROTO)
514 int
515python3_loaded()
516{
517 return (hinstPy3 != 0);
518}
519#endif
520
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200521 static int
522Python3_Init(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200523{
524 if (!py3initialised)
525 {
526#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200527 if (!python3_enabled(TRUE))
528 {
529 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
530 goto fail;
531 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200532#endif
533
534 init_structs();
535
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200536 /* initialise threads */
537 PyEval_InitThreads();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200538
539#if !defined(MACOS) || defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200540 Py_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200541#else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200542 PyMac_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200543#endif
544
545#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200546 get_py3_exceptions();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200547#endif
548
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200549 if (PythonIO_Init())
550 goto fail;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200551
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200552 PyImport_AppendInittab("vim", Py3Init_vim);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200553
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200554 /* Remove the element from sys.path that was added because of our
555 * argv[0] value in Py3Init_vim(). Previously we used an empty
556 * string, but dependinding on the OS we then get an empty entry or
557 * the current directory in sys.path. */
558 PyRun_SimpleString("import sys; sys.path = list(filter(lambda x: x != '/must>not&exist', sys.path))");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200559
560 // lock is created and acquired in PyEval_InitThreads() and thread
561 // state is created in Py_Initialize()
562 // there _PyGILState_NoteThreadState() also sets gilcounter to 1
563 // (python must have threads enabled!)
564 // so the following does both: unlock GIL and save thread state in TLS
565 // without deleting thread state
566 PyGILState_Release(pygilstate);
567
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200568 py3initialised = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200569 }
570
571 return 0;
572
573fail:
574 /* We call PythonIO_Flush() here to print any Python errors.
575 * This is OK, as it is possible to call this function even
576 * if PythonIO_Init() has not completed successfully (it will
577 * not do anything in this case).
578 */
579 PythonIO_Flush();
580 return -1;
581}
582
583/*
584 * External interface
585 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200586 static void
587DoPy3Command(exarg_T *eap, const char *cmd)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200588{
589#if defined(MACOS) && !defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200590 GrafPtr oldPort;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200591#endif
592#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200593 char *saved_locale;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200594#endif
595
596#if defined(MACOS) && !defined(MACOS_X_UNIX)
597 GetPort(&oldPort);
598 /* Check if the Python library is available */
599 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200600 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200601#endif
602 if (Python3_Init())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200603 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200604
605 RangeStart = eap->line1;
606 RangeEnd = eap->line2;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200607 Python_Release_Vim(); /* leave vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200608
609#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
610 /* Python only works properly when the LC_NUMERIC locale is "C". */
611 saved_locale = setlocale(LC_NUMERIC, NULL);
612 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200613 saved_locale = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200614 else
615 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200616 /* Need to make a copy, value may change when setting new locale. */
617 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
618 (void)setlocale(LC_NUMERIC, "C");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200619 }
620#endif
621
622 pygilstate = PyGILState_Ensure();
623
624 PyRun_SimpleString((char *)(cmd));
625
626 PyGILState_Release(pygilstate);
627
628#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
629 if (saved_locale != NULL)
630 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200631 (void)setlocale(LC_NUMERIC, saved_locale);
632 vim_free(saved_locale);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200633 }
634#endif
635
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200636 Python_Lock_Vim(); /* enter vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200637 PythonIO_Flush();
638#if defined(MACOS) && !defined(MACOS_X_UNIX)
639 SetPort(oldPort);
640#endif
641
642theend:
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200643 return; /* keeps lint happy */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200644}
645
646/*
Bram Moolenaar368373e2010-07-19 20:46:22 +0200647 * ":py3"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200648 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200649 void
650ex_py3(exarg_T *eap)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200651{
652 char_u *script;
653
654 script = script_get(eap, eap->arg);
655 if (!eap->skip)
656 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200657 if (script == NULL)
658 DoPy3Command(eap, (char *)eap->arg);
659 else
660 DoPy3Command(eap, (char *)script);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200661 }
662 vim_free(script);
663}
664
665#define BUFFER_SIZE 2048
666
667/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200668 * ":py3file"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200669 */
670 void
671ex_py3file(exarg_T *eap)
672{
673 static char buffer[BUFFER_SIZE];
674 const char *file;
675 char *p;
676 int i;
677
678 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
679 * stdio file pointer, but Vim and the Python DLL are compiled with
680 * different options under Windows, meaning that stdio pointers aren't
681 * compatible between the two. Yuk.
682 *
683 * construct: exec(compile(open('a_filename').read(), 'a_filename', 'exec'))
684 *
685 * We need to escape any backslashes or single quotes in the file name, so that
686 * Python won't mangle the file name.
687 */
688
689 strcpy(buffer, "exec(compile(open('");
690 p = buffer + 19; /* size of "exec(compile(open('" */
691
692 for (i=0; i<2; ++i)
693 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200694 file = (char *)eap->arg;
695 while (*file && p < buffer + (BUFFER_SIZE - 3))
696 {
697 if (*file == '\\' || *file == '\'')
698 *p++ = '\\';
699 *p++ = *file++;
700 }
701 /* If we didn't finish the file name, we hit a buffer overflow */
702 if (*file != '\0')
703 return;
704 if (i==0)
705 {
706 strcpy(p,"').read(),'");
707 p += 11;
708 }
709 else
710 {
711 strcpy(p,"','exec'))");
712 p += 10;
713 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200714 }
715
716
717 /* Execute the file */
718 DoPy3Command(eap, buffer);
719}
720
721/******************************************************
722 * 2. Python output stream: writes output via [e]msg().
723 */
724
725/* Implementation functions
726 */
727
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200728 static PyObject *
729OutputGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200730{
731 char *name = "";
732 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200733 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200734
735 if (strcmp(name, "softspace") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200736 return PyLong_FromLong(((OutputObject *)(self))->softspace);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200737
738 return PyObject_GenericGetAttr(self, nameobj);
739}
740
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200741 static int
742OutputSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
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 (val == NULL) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200749 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
750 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200751 }
752
753 if (strcmp(name, "softspace") == 0)
754 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200755 if (!PyLong_Check(val)) {
756 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
757 return -1;
758 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200759
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200760 ((OutputObject *)(self))->softspace = PyLong_AsLong(val);
761 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200762 }
763
764 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
765 return -1;
766}
767
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200768/***************/
769
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200770 static int
771PythonIO_Init(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200772{
773 PyType_Ready(&OutputType);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200774 return PythonIO_Init_io();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200775}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200776
777 static void
778PythonIO_Fini(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200779{
780 PySys_SetObject("stdout", NULL);
781 PySys_SetObject("stderr", NULL);
782}
783
784/******************************************************
785 * 3. Implementation of the Vim module for Python
786 */
787
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200788/* Window type - Implementation functions
789 * --------------------------------------
790 */
791
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200792#define WindowType_Check(obj) ((obj)->ob_base.ob_type == &WindowType)
793
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200794/* Buffer type - Implementation functions
795 * --------------------------------------
796 */
797
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200798#define BufferType_Check(obj) ((obj)->ob_base.ob_type == &BufferType)
799
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200800static Py_ssize_t BufferLength(PyObject *);
801static PyObject *BufferItem(PyObject *, Py_ssize_t);
802static Py_ssize_t BufferAsItem(PyObject *, Py_ssize_t, PyObject *);
803static PyObject* BufferSubscript(PyObject *self, PyObject* idx);
804
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200805
806/* Line range type - Implementation functions
807 * --------------------------------------
808 */
809
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200810#define RangeType_Check(obj) ((obj)->ob_base.ob_type == &RangeType)
811
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200812static PyObject* RangeSubscript(PyObject *self, PyObject* idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200813static Py_ssize_t RangeAsItem(PyObject *, Py_ssize_t, PyObject *);
814
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200815/* Current objects type - Implementation functions
816 * -----------------------------------------------
817 */
818
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200819static PySequenceMethods BufferAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200820 (lenfunc) BufferLength, /* sq_length, len(x) */
821 (binaryfunc) 0, /* sq_concat, x+y */
822 (ssizeargfunc) 0, /* sq_repeat, x*n */
823 (ssizeargfunc) BufferItem, /* sq_item, x[i] */
824 0, /* was_sq_slice, x[i:j] */
825 (ssizeobjargproc) BufferAsItem, /* sq_ass_item, x[i]=v */
826 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200827 0, /* sq_contains */
828 0, /* sq_inplace_concat */
829 0, /* sq_inplace_repeat */
830};
831
832PyMappingMethods BufferAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200833 /* mp_length */ (lenfunc)BufferLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200834 /* mp_subscript */ (binaryfunc)BufferSubscript,
835 /* mp_ass_subscript */ (objobjargproc)0,
836};
837
838
839/* Buffer object - Definitions
840 */
841
842static PyTypeObject BufferType;
843
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200844 static PyObject *
845BufferNew(buf_T *buf)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200846{
847 /* We need to handle deletion of buffers underneath us.
848 * If we add a "b_python3_ref" field to the buf_T structure,
849 * then we can get at it in buf_freeall() in vim. We then
850 * need to create only ONE Python object per buffer - if
851 * we try to create a second, just INCREF the existing one
852 * and return it. The (single) Python object referring to
853 * the buffer is stored in "b_python3_ref".
854 * Question: what to do on a buf_freeall(). We'll probably
855 * have to either delete the Python object (DECREF it to
856 * zero - a bad idea, as it leaves dangling refs!) or
857 * set the buf_T * value to an invalid value (-1?), which
858 * means we need checks in all access functions... Bah.
859 */
860
861 BufferObject *self;
862
863 if (buf->b_python3_ref != NULL)
864 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200865 self = buf->b_python3_ref;
866 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200867 }
868 else
869 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200870 self = PyObject_NEW(BufferObject, &BufferType);
871 buf->b_python3_ref = self;
872 if (self == NULL)
873 return NULL;
874 self->buf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200875 }
876
877 return (PyObject *)(self);
878}
879
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200880 static void
881BufferDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200882{
883 BufferObject *this = (BufferObject *)(self);
884
885 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200886 this->buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200887}
888
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200889 static PyObject *
890BufferGetattro(PyObject *self, PyObject*nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200891{
892 BufferObject *this = (BufferObject *)(self);
893
894 char *name = "";
895 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200896 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200897
898 if (CheckBuffer(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200899 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200900
901 if (strcmp(name, "name") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200902 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200903 else if (strcmp(name, "number") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200904 return Py_BuildValue("n", this->buf->b_fnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200905 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200906 return Py_BuildValue("[ss]", "name", "number");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200907 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200908 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200909}
910
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200911 static PyObject *
912BufferRepr(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200913{
914 static char repr[100];
915 BufferObject *this = (BufferObject *)(self);
916
917 if (this->buf == INVALID_BUFFER_VALUE)
918 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200919 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
920 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200921 }
922 else
923 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200924 char *name = (char *)this->buf->b_fname;
925 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200926
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200927 if (name == NULL)
928 name = "";
929 len = strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200930
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200931 if (len > 35)
932 name = name + (35 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200933
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200934 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200935
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200936 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200937 }
938}
939
940/******************/
941
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200942 static Py_ssize_t
943BufferLength(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200944{
945 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200946 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200947
948 return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
949}
950
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200951 static PyObject *
952BufferItem(PyObject *self, Py_ssize_t n)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200953{
954 return RBItem((BufferObject *)(self), n, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200955 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200956}
957
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200958 static PyObject *
959BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
960{
961 return RBSlice((BufferObject *)(self), lo, hi, 1,
962 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
963}
964
965 static Py_ssize_t
966BufferAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200967{
968 return RBAsItem((BufferObject *)(self), n, val, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200969 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
970 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200971}
972
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200973
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200974 static PyObject *
975BufferSubscript(PyObject *self, PyObject* idx)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200976{
977 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200978 long _idx = PyLong_AsLong(idx);
979 return BufferItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200980 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200981 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200982
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200983 if (PySlice_GetIndicesEx((PySliceObject *)idx,
984 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
985 &start, &stop,
986 &step, &slicelen) < 0) {
987 return NULL;
988 }
989 return BufferSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200990 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200991 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
992 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200993 }
994}
995
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200996static PySequenceMethods RangeAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200997 (lenfunc) RangeLength, /* sq_length, len(x) */
998 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
999 (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
1000 (ssizeargfunc) RangeItem, /* sq_item, x[i] */
1001 0, /* was_sq_slice, x[i:j] */
1002 (ssizeobjargproc) RangeAsItem, /* sq_as_item, x[i]=v */
1003 0, /* sq_ass_slice, x[i:j]=v */
1004 0, /* sq_contains */
1005 0, /* sq_inplace_concat */
1006 0, /* sq_inplace_repeat */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001007};
1008
1009PyMappingMethods RangeAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001010 /* mp_length */ (lenfunc)RangeLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001011 /* mp_subscript */ (binaryfunc)RangeSubscript,
1012 /* mp_ass_subscript */ (objobjargproc)0,
1013};
1014
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001015/* Line range object - Implementation
1016 */
1017
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001018 static void
1019RangeDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001020{
1021 Py_DECREF(((RangeObject *)(self))->buf);
1022}
1023
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001024 static PyObject *
1025RangeGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001026{
1027 char *name = "";
1028 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001029 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001030
1031 if (strcmp(name, "start") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001032 return Py_BuildValue("n", ((RangeObject *)(self))->start - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001033 else if (strcmp(name, "end") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001034 return Py_BuildValue("n", ((RangeObject *)(self))->end - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001035 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001036 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001037}
1038
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001039/****************/
1040
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001041 static Py_ssize_t
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001042RangeAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001043{
1044 return RBAsItem(((RangeObject *)(self))->buf, n, val,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001045 ((RangeObject *)(self))->start,
1046 ((RangeObject *)(self))->end,
1047 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001048}
1049
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001050 static PyObject *
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001051RangeSubscript(PyObject *self, PyObject* idx)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001052{
1053 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001054 long _idx = PyLong_AsLong(idx);
1055 return RangeItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001056 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001057 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001058
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001059 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1060 ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
1061 &start, &stop,
1062 &step, &slicelen) < 0) {
1063 return NULL;
1064 }
1065 return RangeSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001066 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001067 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1068 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001069 }
1070}
1071
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001072/* Buffer list object - Definitions
1073 */
1074
1075typedef struct
1076{
1077 PyObject_HEAD
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001078} BufListObject;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001079
1080static PySequenceMethods BufListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001081 (lenfunc) BufListLength, /* sq_length, len(x) */
1082 (binaryfunc) 0, /* sq_concat, x+y */
1083 (ssizeargfunc) 0, /* sq_repeat, x*n */
1084 (ssizeargfunc) BufListItem, /* sq_item, x[i] */
1085 0, /* was_sq_slice, x[i:j] */
1086 (ssizeobjargproc) 0, /* sq_as_item, x[i]=v */
1087 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001088 0, /* sq_contains */
1089 0, /* sq_inplace_concat */
1090 0, /* sq_inplace_repeat */
1091};
1092
1093static PyTypeObject BufListType;
1094
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001095/* Window object - Definitions
1096 */
1097
1098static struct PyMethodDef WindowMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001099 /* name, function, calling, documentation */
1100 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001101};
1102
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001103static PyTypeObject WindowType;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001104
1105/* Window object - Implementation
1106 */
1107
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001108 static PyObject *
1109WindowNew(win_T *win)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001110{
1111 /* We need to handle deletion of windows underneath us.
1112 * If we add a "w_python3_ref" field to the win_T structure,
1113 * then we can get at it in win_free() in vim. We then
1114 * need to create only ONE Python object per window - if
1115 * we try to create a second, just INCREF the existing one
1116 * and return it. The (single) Python object referring to
1117 * the window is stored in "w_python3_ref".
1118 * On a win_free() we set the Python object's win_T* field
1119 * to an invalid value. We trap all uses of a window
1120 * object, and reject them if the win_T* field is invalid.
1121 */
1122
1123 WindowObject *self;
1124
1125 if (win->w_python3_ref)
1126 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001127 self = win->w_python3_ref;
1128 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001129 }
1130 else
1131 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001132 self = PyObject_NEW(WindowObject, &WindowType);
1133 if (self == NULL)
1134 return NULL;
1135 self->win = win;
1136 win->w_python3_ref = self;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001137 }
1138
1139 return (PyObject *)(self);
1140}
1141
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001142 static void
1143WindowDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001144{
1145 WindowObject *this = (WindowObject *)(self);
1146
1147 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001148 this->win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001149}
1150
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001151 static PyObject *
1152WindowGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001153{
1154 WindowObject *this = (WindowObject *)(self);
1155
1156 char *name = "";
1157 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001158 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001159
1160
1161 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001162 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001163
1164 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001165 return (PyObject *)BufferNew(this->win->w_buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001166 else if (strcmp(name, "cursor") == 0)
1167 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001168 pos_T *pos = &this->win->w_cursor;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001169
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001170 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001171 }
1172 else if (strcmp(name, "height") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001173 return Py_BuildValue("l", (long)(this->win->w_height));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001174#ifdef FEAT_VERTSPLIT
1175 else if (strcmp(name, "width") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001176 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001177#endif
1178 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001179 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001180 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001181 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001182}
1183
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001184 static int
1185WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001186{
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001187 char *name = "";
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001188
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001189 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001190 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001191
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001192 return WindowSetattr(self, name, val);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001193}
1194
1195/* Window list object - Definitions
1196 */
1197
1198typedef struct
1199{
1200 PyObject_HEAD
1201}
1202WinListObject;
1203
1204static PySequenceMethods WinListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001205 (lenfunc) WinListLength, /* sq_length, len(x) */
1206 (binaryfunc) 0, /* sq_concat, x+y */
1207 (ssizeargfunc) 0, /* sq_repeat, x*n */
1208 (ssizeargfunc) WinListItem, /* sq_item, x[i] */
1209 0, /* sq_slice, x[i:j] */
1210 (ssizeobjargproc)0, /* sq_as_item, x[i]=v */
1211 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001212 0, /* sq_contains */
1213 0, /* sq_inplace_concat */
1214 0, /* sq_inplace_repeat */
1215};
1216
1217static PyTypeObject WinListType;
1218
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001219/* Current items object - Definitions
1220 */
1221
1222typedef struct
1223{
1224 PyObject_HEAD
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001225} CurrentObject;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001226
1227static PyTypeObject CurrentType;
1228
1229/* Current items object - Implementation
1230 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001231 static PyObject *
1232CurrentGetattro(PyObject *self UNUSED, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001233{
1234 char *name = "";
1235 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001236 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001237
1238 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001239 return (PyObject *)BufferNew(curbuf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001240 else if (strcmp(name, "window") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001241 return (PyObject *)WindowNew(curwin);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001242 else if (strcmp(name, "line") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001243 return GetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001244 else if (strcmp(name, "range") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001245 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001246 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001247 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001248 else
1249 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001250 PyErr_SetString(PyExc_AttributeError, name);
1251 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001252 }
1253}
1254
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001255 static int
1256CurrentSetattro(PyObject *self UNUSED, PyObject *nameobj, PyObject *value)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001257{
1258 char *name = "";
1259 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001260 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001261
1262 if (strcmp(name, "line") == 0)
1263 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001264 if (SetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum, value, NULL) == FAIL)
1265 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001266
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001267 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001268 }
1269 else
1270 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001271 PyErr_SetString(PyExc_AttributeError, name);
1272 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001273 }
1274}
1275
1276/* External interface
1277 */
1278
1279 void
1280python3_buffer_free(buf_T *buf)
1281{
1282 if (buf->b_python3_ref != NULL)
1283 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001284 BufferObject *bp = buf->b_python3_ref;
1285 bp->buf = INVALID_BUFFER_VALUE;
1286 buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001287 }
1288}
1289
1290#if defined(FEAT_WINDOWS) || defined(PROTO)
1291 void
1292python3_window_free(win_T *win)
1293{
1294 if (win->w_python3_ref != NULL)
1295 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001296 WindowObject *wp = win->w_python3_ref;
1297 wp->win = INVALID_WINDOW_VALUE;
1298 win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001299 }
1300}
1301#endif
1302
1303static BufListObject TheBufferList =
1304{
1305 PyObject_HEAD_INIT(&BufListType)
1306};
1307
1308static WinListObject TheWindowList =
1309{
1310 PyObject_HEAD_INIT(&WinListType)
1311};
1312
1313static CurrentObject TheCurrent =
1314{
1315 PyObject_HEAD_INIT(&CurrentType)
1316};
1317
1318PyDoc_STRVAR(vim_module_doc,"vim python interface\n");
1319
1320static struct PyModuleDef vimmodule;
1321
Bram Moolenaar69154f22010-07-18 21:42:34 +02001322#ifndef PROTO
1323PyMODINIT_FUNC Py3Init_vim(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001324{
1325 PyObject *mod;
1326 /* The special value is removed from sys.path in Python3_Init(). */
1327 static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
1328
1329 PyType_Ready(&BufferType);
1330 PyType_Ready(&RangeType);
1331 PyType_Ready(&WindowType);
1332 PyType_Ready(&BufListType);
1333 PyType_Ready(&WinListType);
1334 PyType_Ready(&CurrentType);
1335
1336 /* Set sys.argv[] to avoid a crash in warn(). */
1337 PySys_SetArgv(1, argv);
1338
1339 mod = PyModule_Create(&vimmodule);
1340
1341 VimError = Py_BuildValue("s", "vim.error");
1342
1343 PyModule_AddObject(mod, "error", VimError);
1344 Py_INCREF((PyObject *)(void *)&TheBufferList);
1345 PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
1346 Py_INCREF((PyObject *)(void *)&TheCurrent);
1347 PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
1348 Py_INCREF((PyObject *)(void *)&TheWindowList);
1349 PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
1350
1351 if (PyErr_Occurred())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001352 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001353
1354 return mod;
1355}
Bram Moolenaar69154f22010-07-18 21:42:34 +02001356#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001357
1358/*************************************************************************
1359 * 4. Utility functions for handling the interface between Vim and Python.
1360 */
1361
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001362/* Convert a Vim line into a Python string.
1363 * All internal newlines are replaced by null characters.
1364 *
1365 * On errors, the Python exception data is set, and NULL is returned.
1366 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001367 static PyObject *
1368LineToString(const char *str)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001369{
1370 PyObject *result;
1371 Py_ssize_t len = strlen(str);
1372 char *tmp,*p;
1373
1374 tmp = (char *)alloc((unsigned)(len+1));
1375 p = tmp;
1376 if (p == NULL)
1377 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001378 PyErr_NoMemory();
1379 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001380 }
1381
1382 while (*str)
1383 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001384 if (*str == '\n')
1385 *p = '\0';
1386 else
1387 *p = *str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001388
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001389 ++p;
1390 ++str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001391 }
1392 *p = '\0';
1393
1394 result = PyUnicode_FromStringAndSize(tmp, len);
1395
1396 vim_free(tmp);
1397 return result;
1398}
1399
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001400 static void
1401init_structs(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001402{
1403 vim_memset(&OutputType, 0, sizeof(OutputType));
1404 OutputType.tp_name = "vim.message";
1405 OutputType.tp_basicsize = sizeof(OutputObject);
1406 OutputType.tp_getattro = OutputGetattro;
1407 OutputType.tp_setattro = OutputSetattro;
1408 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
1409 OutputType.tp_doc = "vim message object";
1410 OutputType.tp_methods = OutputMethods;
1411 OutputType.tp_alloc = call_PyType_GenericAlloc;
1412 OutputType.tp_new = call_PyType_GenericNew;
1413 OutputType.tp_free = call_PyObject_Free;
1414
1415 vim_memset(&BufferType, 0, sizeof(BufferType));
1416 BufferType.tp_name = "vim.buffer";
1417 BufferType.tp_basicsize = sizeof(BufferType);
1418 BufferType.tp_dealloc = BufferDestructor;
1419 BufferType.tp_repr = BufferRepr;
1420 BufferType.tp_as_sequence = &BufferAsSeq;
1421 BufferType.tp_as_mapping = &BufferAsMapping;
1422 BufferType.tp_getattro = BufferGetattro;
1423 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
1424 BufferType.tp_doc = "vim buffer object";
1425 BufferType.tp_methods = BufferMethods;
1426 BufferType.tp_alloc = call_PyType_GenericAlloc;
1427 BufferType.tp_new = call_PyType_GenericNew;
1428 BufferType.tp_free = call_PyObject_Free;
1429
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001430 vim_memset(&WindowType, 0, sizeof(WindowType));
1431 WindowType.tp_name = "vim.window";
1432 WindowType.tp_basicsize = sizeof(WindowObject);
1433 WindowType.tp_dealloc = WindowDestructor;
1434 WindowType.tp_repr = WindowRepr;
1435 WindowType.tp_getattro = WindowGetattro;
1436 WindowType.tp_setattro = WindowSetattro;
1437 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
1438 WindowType.tp_doc = "vim Window object";
1439 WindowType.tp_methods = WindowMethods;
1440 WindowType.tp_alloc = call_PyType_GenericAlloc;
1441 WindowType.tp_new = call_PyType_GenericNew;
1442 WindowType.tp_free = call_PyObject_Free;
1443
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001444 vim_memset(&BufListType, 0, sizeof(BufListType));
1445 BufListType.tp_name = "vim.bufferlist";
1446 BufListType.tp_basicsize = sizeof(BufListObject);
1447 BufListType.tp_as_sequence = &BufListAsSeq;
1448 BufListType.tp_flags = Py_TPFLAGS_DEFAULT;
1449 BufferType.tp_doc = "vim buffer list";
1450
1451 vim_memset(&WinListType, 0, sizeof(WinListType));
1452 WinListType.tp_name = "vim.windowlist";
1453 WinListType.tp_basicsize = sizeof(WinListType);
1454 WinListType.tp_as_sequence = &WinListAsSeq;
1455 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
1456 WinListType.tp_doc = "vim window list";
1457
1458 vim_memset(&RangeType, 0, sizeof(RangeType));
1459 RangeType.tp_name = "vim.range";
1460 RangeType.tp_basicsize = sizeof(RangeObject);
1461 RangeType.tp_dealloc = RangeDestructor;
1462 RangeType.tp_repr = RangeRepr;
1463 RangeType.tp_as_sequence = &RangeAsSeq;
1464 RangeType.tp_as_mapping = &RangeAsMapping;
1465 RangeType.tp_getattro = RangeGetattro;
1466 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
1467 RangeType.tp_doc = "vim Range object";
1468 RangeType.tp_methods = RangeMethods;
1469 RangeType.tp_alloc = call_PyType_GenericAlloc;
1470 RangeType.tp_new = call_PyType_GenericNew;
1471 RangeType.tp_free = call_PyObject_Free;
1472
1473 vim_memset(&CurrentType, 0, sizeof(CurrentType));
1474 CurrentType.tp_name = "vim.currentdata";
1475 CurrentType.tp_basicsize = sizeof(CurrentObject);
1476 CurrentType.tp_getattro = CurrentGetattro;
1477 CurrentType.tp_setattro = CurrentSetattro;
1478 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
1479 CurrentType.tp_doc = "vim current object";
1480
1481 vim_memset(&vimmodule, 0, sizeof(vimmodule));
1482 vimmodule.m_name = "vim";
1483 vimmodule.m_doc = vim_module_doc;
1484 vimmodule.m_size = -1;
1485 vimmodule.m_methods = VimMethods;
1486}