blob: 8958e0ae29dc3caa6d0973b7be9cfc0f15467037 [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
37#if defined(_WIN32) && defined (HAVE_FCNTL_H)
38# 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
71#if defined(DYNAMIC_PYTHON3)
72
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020073#ifndef WIN3264
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020074#include <dlfcn.h>
75#define FARPROC void*
76#define HINSTANCE void*
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020077#define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020078#define close_dll dlclose
79#define symbol_from_dll dlsym
80#else
81#define load_dll LoadLibrary
82#define close_dll FreeLibrary
83#define symbol_from_dll GetProcAddress
84#endif
85/*
86 * Wrapper defines
87 */
88#undef PyArg_Parse
89# define PyArg_Parse py3_PyArg_Parse
90#undef PyArg_ParseTuple
91# define PyArg_ParseTuple py3_PyArg_ParseTuple
92# define PyDict_SetItemString py3_PyDict_SetItemString
93# define PyErr_BadArgument py3_PyErr_BadArgument
94# define PyErr_Clear py3_PyErr_Clear
95# define PyErr_NoMemory py3_PyErr_NoMemory
96# define PyErr_Occurred py3_PyErr_Occurred
97# define PyErr_SetNone py3_PyErr_SetNone
98# define PyErr_SetString py3_PyErr_SetString
99# define PyEval_InitThreads py3_PyEval_InitThreads
100# define PyEval_RestoreThread py3_PyEval_RestoreThread
101# define PyEval_SaveThread py3_PyEval_SaveThread
102# define PyGILState_Ensure py3_PyGILState_Ensure
103# define PyGILState_Release py3_PyGILState_Release
104# define PyLong_AsLong py3_PyLong_AsLong
105# define PyLong_FromLong py3_PyLong_FromLong
106# define PyList_GetItem py3_PyList_GetItem
107# define PyList_Append py3_PyList_Append
108# define PyList_New py3_PyList_New
109# define PyList_SetItem py3_PyList_SetItem
110# define PyList_Size py3_PyList_Size
111# define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
112# define PyImport_ImportModule py3_PyImport_ImportModule
113# define PyObject_Init py3__PyObject_Init
114# define PyDict_New py3_PyDict_New
115# define PyDict_GetItemString py3_PyDict_GetItemString
116# define PyModule_GetDict py3_PyModule_GetDict
117#undef PyRun_SimpleString
118# define PyRun_SimpleString py3_PyRun_SimpleString
119# define PySys_SetObject py3_PySys_SetObject
120# define PySys_SetArgv py3_PySys_SetArgv
121# define PyType_Type (*py3_PyType_Type)
122# define PyType_Ready py3_PyType_Ready
123#undef Py_BuildValue
124# define Py_BuildValue py3_Py_BuildValue
125# define Py_Initialize py3_Py_Initialize
126# define Py_Finalize py3_Py_Finalize
127# define Py_IsInitialized py3_Py_IsInitialized
128# define _Py_NoneStruct (*py3__Py_NoneStruct)
129# define PyModule_AddObject py3_PyModule_AddObject
130# define PyImport_AppendInittab py3_PyImport_AppendInittab
131# define _PyUnicode_AsString py3__PyUnicode_AsString
132# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
133# define PySlice_Type (*py3_PySlice_Type)
134#ifdef Py_DEBUG
135 # define _Py_NegativeRefcount py3__Py_NegativeRefcount
136 # define _Py_RefTotal (*py3__Py_RefTotal)
137 # define _Py_Dealloc py3__Py_Dealloc
138 # define _PyObject_DebugMalloc py3__PyObject_DebugMalloc
139 # define _PyObject_DebugFree py3__PyObject_DebugFree
140#else
141 # define PyObject_Malloc py3_PyObject_Malloc
142 # define PyObject_Free py3_PyObject_Free
143#endif
144# define PyType_GenericAlloc py3_PyType_GenericAlloc
145# define PyType_GenericNew py3_PyType_GenericNew
146# define PyModule_Create2 py3_PyModule_Create2
147#undef PyUnicode_FromString
148# define PyUnicode_FromString py3_PyUnicode_FromString
149#undef PyUnicode_FromStringAndSize
150# define PyUnicode_FromStringAndSize py3_PyUnicode_FromStringAndSize
151
152#ifdef Py_DEBUG
153#undef PyObject_NEW
154#define PyObject_NEW(type, typeobj) \
155( (type *) PyObject_Init( \
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200156 (PyObject *) _PyObject_DebugMalloc( _PyObject_SIZE(typeobj) ), (typeobj)) )
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200157#endif
158/*
159 * Pointers for dynamic link
160 */
161static int (*py3_PySys_SetArgv)(int, wchar_t **);
162static void (*py3_Py_Initialize)(void);
163static PyObject* (*py3_PyList_New)(Py_ssize_t size);
164static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
165static void (*py3_PyGILState_Release)(PyGILState_STATE);
166static int (*py3_PySys_SetObject)(char *, PyObject *);
167static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
168static Py_ssize_t (*py3_PyList_Size)(PyObject *);
169static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200170 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200171static PyObject* (*py3_PyErr_NoMemory)(void);
172static void (*py3_Py_Finalize)(void);
173static void (*py3_PyErr_SetString)(PyObject *, const char *);
174static int (*py3_PyRun_SimpleString)(char *);
175static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
176static PyObject* (*py3_PyImport_ImportModule)(const char *);
177static int (*py3_PyErr_BadArgument)(void);
178static PyTypeObject* py3_PyType_Type;
179static PyObject* (*py3_PyErr_Occurred)(void);
180static PyObject* (*py3_PyModule_GetDict)(PyObject *);
181static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *);
182static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
183static PyObject* (*py3_PyLong_FromLong)(long);
184static PyObject* (*py3_PyDict_New)(void);
185static PyObject* (*py3_Py_BuildValue)(char *, ...);
186static int (*py3_PyType_Ready)(PyTypeObject *type);
187static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
188static PyObject* (*py3_PyUnicode_FromString)(const char *u);
189static PyObject* (*py3_PyUnicode_FromStringAndSize)(const char *u, Py_ssize_t size);
190static long (*py3_PyLong_AsLong)(PyObject *);
191static void (*py3_PyErr_SetNone)(PyObject *);
192static void (*py3_PyEval_InitThreads)(void);
193static void(*py3_PyEval_RestoreThread)(PyThreadState *);
194static PyThreadState*(*py3_PyEval_SaveThread)(void);
195static int (*py3_PyArg_Parse)(PyObject *, char *, ...);
196static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...);
197static int (*py3_Py_IsInitialized)(void);
198static void (*py3_PyErr_Clear)(void);
199static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
200static PyObject* py3__Py_NoneStruct;
201static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o);
202static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void));
203static char* (*py3__PyUnicode_AsString)(PyObject *unicode);
204static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
205static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
206static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
207static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
208static PyTypeObject* py3_PySlice_Type;
209#ifdef Py_DEBUG
210 static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
211 static Py_ssize_t* py3__Py_RefTotal;
212 static void (*py3__Py_Dealloc)(PyObject *obj);
213 static void (*py3__PyObject_DebugFree)(void*);
214 static void* (*py3__PyObject_DebugMalloc)(size_t);
215#else
216 static void (*py3_PyObject_Free)(void*);
217 static void* (*py3_PyObject_Malloc)(size_t);
218#endif
219
220static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
221
222/* Imported exception objects */
223static PyObject *p3imp_PyExc_AttributeError;
224static PyObject *p3imp_PyExc_IndexError;
225static PyObject *p3imp_PyExc_KeyboardInterrupt;
226static PyObject *p3imp_PyExc_TypeError;
227static PyObject *p3imp_PyExc_ValueError;
228
229# define PyExc_AttributeError p3imp_PyExc_AttributeError
230# define PyExc_IndexError p3imp_PyExc_IndexError
231# define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt
232# define PyExc_TypeError p3imp_PyExc_TypeError
233# define PyExc_ValueError p3imp_PyExc_ValueError
234
235/*
236 * Table of name to function pointer of python.
237 */
238# define PYTHON_PROC FARPROC
239static struct
240{
241 char *name;
242 PYTHON_PROC *ptr;
243} py3_funcname_table[] =
244{
245 {"PySys_SetArgv", (PYTHON_PROC*)&py3_PySys_SetArgv},
246 {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize},
247 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
248 {"PyList_New", (PYTHON_PROC*)&py3_PyList_New},
249 {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
250 {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
251 {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
252 {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
253 {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
254 {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx},
255 {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory},
256 {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
257 {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
258 {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
259 {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
260 {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
261 {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument},
262 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
263 {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred},
264 {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict},
265 {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem},
266 {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString},
267 {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
268 {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
269 {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue},
270 {"PyType_Ready", (PYTHON_PROC*)&py3_PyType_Ready},
271 {"PyDict_SetItemString", (PYTHON_PROC*)&py3_PyDict_SetItemString},
272 {"PyLong_AsLong", (PYTHON_PROC*)&py3_PyLong_AsLong},
273 {"PyErr_SetNone", (PYTHON_PROC*)&py3_PyErr_SetNone},
274 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads},
275 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread},
276 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
277 {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse},
278 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
279 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
280 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
281 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
282 {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
283 {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject},
284 {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab},
285 {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString},
286 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
287 {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
288 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
289 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
290 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
291#ifdef Py_DEBUG
292 {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
293 {"_Py_RefTotal", (PYTHON_PROC*)&py3__Py_RefTotal},
294 {"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
295 {"_PyObject_DebugFree", (PYTHON_PROC*)&py3__PyObject_DebugFree},
296 {"_PyObject_DebugMalloc", (PYTHON_PROC*)&py3__PyObject_DebugMalloc},
297#else
298 {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
299 {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
300#endif
301 {"", NULL},
302};
303
304/*
305 * Free python.dll
306 */
307static void end_dynamic_python3(void)
308{
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200309 if (hinstPy3 != 0)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200310 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200311 close_dll(hinstPy3);
312 hinstPy3 = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200313 }
314}
315
316/*
317 * Load library and get all pointers.
318 * Parameter 'libname' provides name of DLL.
319 * Return OK or FAIL.
320 */
321static int py3_runtime_link_init(char *libname, int verbose)
322{
323 int i;
Bram Moolenaar69154f22010-07-18 21:42:34 +0200324 void *ucs_from_string, *ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200325
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200326#if defined(UNIX) && defined(FEAT_PYTHON)
327 /* Can't have Python and Python3 loaded at the same time, it may cause a
328 * crash. */
329 if (python_loaded())
330 {
331 EMSG(_("E999: Python: Cannot use :py and :py3 in one session"));
332 return FAIL;
333 }
334#endif
335
336 if (hinstPy3 != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200337 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200338 hinstPy3 = load_dll(libname);
339
340 if (!hinstPy3)
341 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200342 if (verbose)
343 EMSG2(_(e_loadlib), libname);
344 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200345 }
346
347 for (i = 0; py3_funcname_table[i].ptr; ++i)
348 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200349 if ((*py3_funcname_table[i].ptr = symbol_from_dll(hinstPy3,
350 py3_funcname_table[i].name)) == NULL)
351 {
352 close_dll(hinstPy3);
353 hinstPy3 = 0;
354 if (verbose)
355 EMSG2(_(e_loadfunc), py3_funcname_table[i].name);
356 return FAIL;
357 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200358 }
359
Bram Moolenaar69154f22010-07-18 21:42:34 +0200360 /* Load unicode functions separately as only the ucs2 or the ucs4 functions
361 * will be present in the library. */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200362 ucs_from_string = symbol_from_dll(hinstPy3, "PyUnicodeUCS2_FromString");
363 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200364 "PyUnicodeUCS2_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200365 if (!ucs_from_string || !ucs_from_string_and_size)
366 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200367 ucs_from_string = symbol_from_dll(hinstPy3,
368 "PyUnicodeUCS4_FromString");
369 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
370 "PyUnicodeUCS4_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200371 }
372 if (ucs_from_string && ucs_from_string_and_size)
373 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200374 py3_PyUnicode_FromString = ucs_from_string;
375 py3_PyUnicode_FromStringAndSize = ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200376 }
377 else
378 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200379 close_dll(hinstPy3);
380 hinstPy3 = 0;
381 if (verbose)
382 EMSG2(_(e_loadfunc), "PyUnicode_UCSX_*");
383 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200384 }
385
386 return OK;
387}
388
389/*
390 * If python is enabled (there is installed python on Windows system) return
391 * TRUE, else FALSE.
392 */
393int python3_enabled(int verbose)
394{
395 return py3_runtime_link_init(DYNAMIC_PYTHON3_DLL, verbose) == OK;
396}
397
398/* Load the standard Python exceptions - don't import the symbols from the
399 * DLL, as this can cause errors (importing data symbols is not reliable).
400 */
401static void get_py3_exceptions __ARGS((void));
402
403static void get_py3_exceptions()
404{
405 PyObject *exmod = PyImport_ImportModule("builtins");
406 PyObject *exdict = PyModule_GetDict(exmod);
407 p3imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
408 p3imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
409 p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
410 p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
411 p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
412 Py_XINCREF(p3imp_PyExc_AttributeError);
413 Py_XINCREF(p3imp_PyExc_IndexError);
414 Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
415 Py_XINCREF(p3imp_PyExc_TypeError);
416 Py_XINCREF(p3imp_PyExc_ValueError);
417 Py_XDECREF(exmod);
418}
419#endif /* DYNAMIC_PYTHON3 */
420
421static void call_PyObject_Free(void *p)
422{
423#ifdef Py_DEBUG
424 _PyObject_DebugFree(p);
425#else
426 PyObject_Free(p);
427#endif
428}
429static PyObject* call_PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
430{
431 return PyType_GenericNew(type,args,kwds);
432}
433static PyObject* call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
434{
435 return PyType_GenericAlloc(type,nitems);
436}
437
438/******************************************************
439 * Internal function prototypes.
440 */
441
442static void DoPy3Command(exarg_T *, const char *);
443static Py_ssize_t RangeStart;
444static Py_ssize_t RangeEnd;
445
446static void PythonIO_Flush(void);
447static int PythonIO_Init(void);
448static void PythonIO_Fini(void);
Bram Moolenaar69154f22010-07-18 21:42:34 +0200449PyMODINIT_FUNC Py3Init_vim(void);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200450
451/* Utility functions for the vim/python interface
452 * ----------------------------------------------
453 */
454static PyObject *GetBufferLine(buf_T *, Py_ssize_t);
455
456static int SetBufferLine(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
457static int InsertBufferLines(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
458static PyObject *GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi);
459
460static PyObject *LineToString(const char *);
461static char *StringToLine(PyObject *);
462
463static int VimErrorCheck(void);
464
465#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
466
467/******************************************************
468 * 1. Python interpreter main program.
469 */
470
471static int py3initialised = 0;
472
473
474static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
475
476/*
477 * obtain a lock on the Vim data structures
478 */
479static void Python_Lock_Vim(void)
480{
481}
482
483/*
484 * release a lock on the Vim data structures
485 */
486static void Python_Release_Vim(void)
487{
488}
489
490void python3_end()
491{
492 static int recurse = 0;
493
494 /* If a crash occurs while doing this, don't try again. */
495 if (recurse != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200496 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200497
498 ++recurse;
499
500#ifdef DYNAMIC_PYTHON3
501 if (hinstPy3)
502#endif
503 if (Py_IsInitialized())
504 {
505 // acquire lock before finalizing
506 pygilstate = PyGILState_Ensure();
507
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200508 PythonIO_Fini();
509 Py_Finalize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200510 }
511
512#ifdef DYNAMIC_PYTHON3
513 end_dynamic_python3();
514#endif
515
516 --recurse;
517}
518
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200519#if (defined(DYNAMIC_PYTHON) && defined(FEAT_PYTHON)) || defined(PROTO)
520 int
521python3_loaded()
522{
523 return (hinstPy3 != 0);
524}
525#endif
526
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200527static int Python3_Init(void)
528{
529 if (!py3initialised)
530 {
531#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200532 if (!python3_enabled(TRUE))
533 {
534 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
535 goto fail;
536 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200537#endif
538
539 init_structs();
540
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200541 /* initialise threads */
542 PyEval_InitThreads();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200543
544#if !defined(MACOS) || defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200545 Py_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200546#else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200547 PyMac_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200548#endif
549
550#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200551 get_py3_exceptions();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200552#endif
553
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200554 if (PythonIO_Init())
555 goto fail;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200556
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200557 PyImport_AppendInittab("vim", Py3Init_vim);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200558
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200559 /* Remove the element from sys.path that was added because of our
560 * argv[0] value in Py3Init_vim(). Previously we used an empty
561 * string, but dependinding on the OS we then get an empty entry or
562 * the current directory in sys.path. */
563 PyRun_SimpleString("import sys; sys.path = list(filter(lambda x: x != '/must>not&exist', sys.path))");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200564
565 // lock is created and acquired in PyEval_InitThreads() and thread
566 // state is created in Py_Initialize()
567 // there _PyGILState_NoteThreadState() also sets gilcounter to 1
568 // (python must have threads enabled!)
569 // so the following does both: unlock GIL and save thread state in TLS
570 // without deleting thread state
571 PyGILState_Release(pygilstate);
572
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200573 py3initialised = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200574 }
575
576 return 0;
577
578fail:
579 /* We call PythonIO_Flush() here to print any Python errors.
580 * This is OK, as it is possible to call this function even
581 * if PythonIO_Init() has not completed successfully (it will
582 * not do anything in this case).
583 */
584 PythonIO_Flush();
585 return -1;
586}
587
588/*
589 * External interface
590 */
591static void DoPy3Command(exarg_T *eap, const char *cmd)
592{
593#if defined(MACOS) && !defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200594 GrafPtr oldPort;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200595#endif
596#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200597 char *saved_locale;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200598#endif
599
600#if defined(MACOS) && !defined(MACOS_X_UNIX)
601 GetPort(&oldPort);
602 /* Check if the Python library is available */
603 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200604 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200605#endif
606 if (Python3_Init())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200607 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200608
609 RangeStart = eap->line1;
610 RangeEnd = eap->line2;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200611 Python_Release_Vim(); /* leave vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200612
613#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
614 /* Python only works properly when the LC_NUMERIC locale is "C". */
615 saved_locale = setlocale(LC_NUMERIC, NULL);
616 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200617 saved_locale = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200618 else
619 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200620 /* Need to make a copy, value may change when setting new locale. */
621 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
622 (void)setlocale(LC_NUMERIC, "C");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200623 }
624#endif
625
626 pygilstate = PyGILState_Ensure();
627
628 PyRun_SimpleString((char *)(cmd));
629
630 PyGILState_Release(pygilstate);
631
632#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
633 if (saved_locale != NULL)
634 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200635 (void)setlocale(LC_NUMERIC, saved_locale);
636 vim_free(saved_locale);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200637 }
638#endif
639
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200640 Python_Lock_Vim(); /* enter vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200641 PythonIO_Flush();
642#if defined(MACOS) && !defined(MACOS_X_UNIX)
643 SetPort(oldPort);
644#endif
645
646theend:
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200647 return; /* keeps lint happy */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200648}
649
650/*
Bram Moolenaar368373e2010-07-19 20:46:22 +0200651 * ":py3"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200652 */
Bram Moolenaar368373e2010-07-19 20:46:22 +0200653void ex_py3(exarg_T *eap)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200654{
655 char_u *script;
656
657 script = script_get(eap, eap->arg);
658 if (!eap->skip)
659 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200660 if (script == NULL)
661 DoPy3Command(eap, (char *)eap->arg);
662 else
663 DoPy3Command(eap, (char *)script);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200664 }
665 vim_free(script);
666}
667
668#define BUFFER_SIZE 2048
669
670/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200671 * ":py3file"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200672 */
673 void
674ex_py3file(exarg_T *eap)
675{
676 static char buffer[BUFFER_SIZE];
677 const char *file;
678 char *p;
679 int i;
680
681 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
682 * stdio file pointer, but Vim and the Python DLL are compiled with
683 * different options under Windows, meaning that stdio pointers aren't
684 * compatible between the two. Yuk.
685 *
686 * construct: exec(compile(open('a_filename').read(), 'a_filename', 'exec'))
687 *
688 * We need to escape any backslashes or single quotes in the file name, so that
689 * Python won't mangle the file name.
690 */
691
692 strcpy(buffer, "exec(compile(open('");
693 p = buffer + 19; /* size of "exec(compile(open('" */
694
695 for (i=0; i<2; ++i)
696 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200697 file = (char *)eap->arg;
698 while (*file && p < buffer + (BUFFER_SIZE - 3))
699 {
700 if (*file == '\\' || *file == '\'')
701 *p++ = '\\';
702 *p++ = *file++;
703 }
704 /* If we didn't finish the file name, we hit a buffer overflow */
705 if (*file != '\0')
706 return;
707 if (i==0)
708 {
709 strcpy(p,"').read(),'");
710 p += 11;
711 }
712 else
713 {
714 strcpy(p,"','exec'))");
715 p += 10;
716 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200717 }
718
719
720 /* Execute the file */
721 DoPy3Command(eap, buffer);
722}
723
724/******************************************************
725 * 2. Python output stream: writes output via [e]msg().
726 */
727
728/* Implementation functions
729 */
730
731static PyObject *OutputGetattro(PyObject *, PyObject *);
732static int OutputSetattro(PyObject *, PyObject *, PyObject *);
733
734static PyObject *OutputWrite(PyObject *, PyObject *);
735static PyObject *OutputWritelines(PyObject *, PyObject *);
736
737typedef void (*writefn)(char_u *);
738static void writer(writefn fn, char_u *str, Py_ssize_t n);
739
740/* Output object definition
741 */
742
743typedef struct
744{
745 PyObject_HEAD
746 long softspace;
747 long error;
748} OutputObject;
749
750static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200751 /* name, function, calling, documentation */
752 {"write", OutputWrite, 1, "" },
753 {"writelines", OutputWritelines, 1, "" },
754 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200755};
756
757static PyTypeObject OutputType;
758
759/*************/
760
761static PyObject * OutputGetattro(PyObject *self, PyObject *nameobj)
762{
763 char *name = "";
764 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200765 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200766
767 if (strcmp(name, "softspace") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200768 return PyLong_FromLong(((OutputObject *)(self))->softspace);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200769
770 return PyObject_GenericGetAttr(self, nameobj);
771}
772
773static int OutputSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
774{
775 char *name = "";
776 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200777 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200778
779 if (val == NULL) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200780 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
781 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200782 }
783
784 if (strcmp(name, "softspace") == 0)
785 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200786 if (!PyLong_Check(val)) {
787 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
788 return -1;
789 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200790
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200791 ((OutputObject *)(self))->softspace = PyLong_AsLong(val);
792 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200793 }
794
795 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
796 return -1;
797}
798
799/*************/
800
801static PyObject * OutputWrite(PyObject *self, PyObject *args)
802{
803 int len;
804 char *str;
805 int error = ((OutputObject *)(self))->error;
806
807 if (!PyArg_ParseTuple(args, "s#", &str, &len))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200808 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200809
810 Py_BEGIN_ALLOW_THREADS
811 Python_Lock_Vim();
812 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
813 Python_Release_Vim();
814 Py_END_ALLOW_THREADS
815
816 Py_INCREF(Py_None);
817 return Py_None;
818}
819
820static PyObject * OutputWritelines(PyObject *self, PyObject *args)
821{
822 Py_ssize_t n;
823 Py_ssize_t i;
824 PyObject *list;
825 int error = ((OutputObject *)(self))->error;
826
827 if (!PyArg_ParseTuple(args, "O", &list))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200828 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200829 Py_INCREF(list);
830
831 if (!PyList_Check(list)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200832 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
833 Py_DECREF(list);
834 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200835 }
836
837 n = PyList_Size(list);
838
839 for (i = 0; i < n; ++i)
840 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200841 PyObject *line = PyList_GetItem(list, i);
842 char *str;
843 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200844
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200845 if (!PyArg_Parse(line, "s#", &str, &len)) {
846 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
847 Py_DECREF(list);
848 return NULL;
849 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200850
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200851 Py_BEGIN_ALLOW_THREADS
852 Python_Lock_Vim();
853 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
854 Python_Release_Vim();
855 Py_END_ALLOW_THREADS
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200856 }
857
858 Py_DECREF(list);
859 Py_INCREF(Py_None);
860 return Py_None;
861}
862
863/* Output buffer management
864 */
865
866static char_u *buffer = NULL;
867static Py_ssize_t buffer_len = 0;
868static Py_ssize_t buffer_size = 0;
869
870static writefn old_fn = NULL;
871
872static void buffer_ensure(Py_ssize_t n)
873{
874 Py_ssize_t new_size;
875 char_u *new_buffer;
876
877 if (n < buffer_size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200878 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200879
880 new_size = buffer_size;
881 while (new_size < n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200882 new_size += 80;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200883
884 if (new_size != buffer_size)
885 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200886 new_buffer = alloc((unsigned)new_size);
887 if (new_buffer == NULL)
888 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200889
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200890 if (buffer)
891 {
892 memcpy(new_buffer, buffer, buffer_len);
893 vim_free(buffer);
894 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200895
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200896 buffer = new_buffer;
897 buffer_size = new_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200898 }
899}
900
901static void PythonIO_Flush(void)
902{
903 if (old_fn && buffer_len)
904 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200905 buffer[buffer_len] = 0;
906 old_fn(buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200907 }
908
909 buffer_len = 0;
910}
911
912static void writer(writefn fn, char_u *str, Py_ssize_t n)
913{
914 char_u *ptr;
915
916 if (fn != old_fn && old_fn != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200917 PythonIO_Flush();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200918
919 old_fn = fn;
920
921 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
922 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200923 Py_ssize_t len = ptr - str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200924
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200925 buffer_ensure(buffer_len + len + 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200926
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200927 memcpy(buffer + buffer_len, str, len);
928 buffer_len += len;
929 buffer[buffer_len] = 0;
930 fn(buffer);
931 str = ptr + 1;
932 n -= len + 1;
933 buffer_len = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200934 }
935
936 /* Put the remaining text into the buffer for later printing */
937 buffer_ensure(buffer_len + n + 1);
938 memcpy(buffer + buffer_len, str, n);
939 buffer_len += n;
940}
941
942/***************/
943
944static OutputObject Output =
945{
946 PyObject_HEAD_INIT(&OutputType)
947 0,
948 0
949};
950
951static OutputObject Error =
952{
953 PyObject_HEAD_INIT(&OutputType)
954 0,
955 1
956};
957
958static int PythonIO_Init(void)
959{
960 PyType_Ready(&OutputType);
961
962 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
963 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
964
965 if (PyErr_Occurred())
966 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200967 EMSG(_("E264: Python: Error initialising I/O objects"));
968 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200969 }
970
971 return 0;
972}
973static void PythonIO_Fini(void)
974{
975 PySys_SetObject("stdout", NULL);
976 PySys_SetObject("stderr", NULL);
977}
978
979/******************************************************
980 * 3. Implementation of the Vim module for Python
981 */
982
983/* Vim module - Implementation functions
984 * -------------------------------------
985 */
986
987static PyObject *VimError;
988
989static PyObject *VimCommand(PyObject *, PyObject *);
990static PyObject *VimEval(PyObject *, PyObject *);
991
992/* Window type - Implementation functions
993 * --------------------------------------
994 */
995
996typedef struct
997{
998 PyObject_HEAD
999 win_T *win;
1000}
1001WindowObject;
1002
1003#define INVALID_WINDOW_VALUE ((win_T *)(-1))
1004
1005#define WindowType_Check(obj) ((obj)->ob_base.ob_type == &WindowType)
1006
1007static PyObject *WindowNew(win_T *);
1008
1009static void WindowDestructor(PyObject *);
1010static PyObject *WindowGetattro(PyObject *, PyObject *);
1011static int WindowSetattro(PyObject *, PyObject *, PyObject *);
1012static PyObject *WindowRepr(PyObject *);
1013
1014/* Buffer type - Implementation functions
1015 * --------------------------------------
1016 */
1017
1018typedef struct
1019{
1020 PyObject_HEAD
1021 buf_T *buf;
1022}
1023BufferObject;
1024
1025#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
1026
1027#define BufferType_Check(obj) ((obj)->ob_base.ob_type == &BufferType)
1028
1029static PyObject *BufferNew (buf_T *);
1030
1031static void BufferDestructor(PyObject *);
1032
1033static PyObject *BufferGetattro(PyObject *, PyObject*);
1034static PyObject *BufferRepr(PyObject *);
1035
1036static Py_ssize_t BufferLength(PyObject *);
1037static PyObject *BufferItem(PyObject *, Py_ssize_t);
1038static Py_ssize_t BufferAsItem(PyObject *, Py_ssize_t, PyObject *);
1039static PyObject* BufferSubscript(PyObject *self, PyObject* idx);
1040
1041static PyObject *BufferAppend(PyObject *, PyObject *);
1042static PyObject *BufferMark(PyObject *, PyObject *);
1043static PyObject *BufferRange(PyObject *, PyObject *);
1044
1045/* Line range type - Implementation functions
1046 * --------------------------------------
1047 */
1048
1049typedef struct
1050{
1051 PyObject_HEAD
1052 BufferObject *buf;
1053 Py_ssize_t start;
1054 Py_ssize_t end;
1055}
1056RangeObject;
1057
1058#define RangeType_Check(obj) ((obj)->ob_base.ob_type == &RangeType)
1059
1060static PyObject *RangeNew(buf_T *, Py_ssize_t, Py_ssize_t);
1061
1062static void RangeDestructor(PyObject *);
1063static PyObject *RangeGetattro(PyObject *, PyObject *);
1064static PyObject *RangeRepr(PyObject *);
1065static PyObject* RangeSubscript(PyObject *self, PyObject* idx);
1066
1067static Py_ssize_t RangeLength(PyObject *);
1068static PyObject *RangeItem(PyObject *, Py_ssize_t);
1069static Py_ssize_t RangeAsItem(PyObject *, Py_ssize_t, PyObject *);
1070
1071static PyObject *RangeAppend(PyObject *, PyObject *);
1072
1073/* Window list type - Implementation functions
1074 * -------------------------------------------
1075 */
1076
1077static Py_ssize_t WinListLength(PyObject *);
1078static PyObject *WinListItem(PyObject *, Py_ssize_t);
1079
1080/* Buffer list type - Implementation functions
1081 * -------------------------------------------
1082 */
1083
1084static Py_ssize_t BufListLength(PyObject *);
1085static PyObject *BufListItem(PyObject *, Py_ssize_t);
1086
1087/* Current objects type - Implementation functions
1088 * -----------------------------------------------
1089 */
1090
1091static PyObject *CurrentGetattro(PyObject *, PyObject *);
1092static int CurrentSetattro(PyObject *, PyObject *, PyObject *);
1093
1094/* Vim module - Definitions
1095 */
1096
1097static struct PyMethodDef VimMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001098 /* name, function, calling, documentation */
1099 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
1100 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
1101 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001102};
1103
1104/* Vim module - Implementation
1105 */
1106/*ARGSUSED*/
1107static PyObject * VimCommand(PyObject *self UNUSED, PyObject *args)
1108{
1109 char *cmd;
1110 PyObject *result;
1111
1112 if (!PyArg_ParseTuple(args, "s", &cmd))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001113 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001114
1115 PyErr_Clear();
1116
1117 Py_BEGIN_ALLOW_THREADS
1118 Python_Lock_Vim();
1119
1120 do_cmdline_cmd((char_u *)cmd);
1121 update_screen(VALID);
1122
1123 Python_Release_Vim();
1124 Py_END_ALLOW_THREADS
1125
1126 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001127 result = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001128 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001129 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001130
1131 Py_XINCREF(result);
1132 return result;
1133}
1134
1135#ifdef FEAT_EVAL
1136/*
1137 * Function to translate a typval_T into a PyObject; this will recursively
1138 * translate lists/dictionaries into their Python equivalents.
1139 *
1140 * The depth parameter is to avoid infinite recursion, set it to 1 when
1141 * you call VimToPython.
1142 */
1143static PyObject * VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
1144{
1145 PyObject *result;
1146 PyObject *newObj;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001147 char ptrBuf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001148
1149 /* Avoid infinite recursion */
1150 if (depth > 100)
1151 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001152 Py_INCREF(Py_None);
1153 result = Py_None;
1154 return result;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001155 }
1156
1157 /* Check if we run into a recursive loop. The item must be in lookupDict
1158 * then and we can use it again. */
1159 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001160 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001161 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001162 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
1163 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
1164 : (long_u)our_tv->vval.v_dict);
1165 result = PyDict_GetItemString(lookupDict, ptrBuf);
1166 if (result != NULL)
1167 {
1168 Py_INCREF(result);
1169 return result;
1170 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001171 }
1172
1173 if (our_tv->v_type == VAR_STRING)
1174 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001175 result = Py_BuildValue("s", our_tv->vval.v_string);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001176 }
1177 else if (our_tv->v_type == VAR_NUMBER)
1178 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001179 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001180
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001181 /* For backwards compatibility numbers are stored as strings. */
1182 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
1183 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001184 }
1185# ifdef FEAT_FLOAT
1186 else if (our_tv->v_type == VAR_FLOAT)
1187 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001188 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001189
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001190 sprintf(buf, "%f", our_tv->vval.v_float);
1191 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001192 }
1193# endif
1194 else if (our_tv->v_type == VAR_LIST)
1195 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001196 list_T *list = our_tv->vval.v_list;
1197 listitem_T *curr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001198
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001199 result = PyList_New(0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001200
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001201 if (list != NULL)
1202 {
1203 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001204
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001205 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
1206 {
1207 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
1208 PyList_Append(result, newObj);
1209 Py_DECREF(newObj);
1210 }
1211 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001212 }
1213 else if (our_tv->v_type == VAR_DICT)
1214 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001215 result = PyDict_New();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001216
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001217 if (our_tv->vval.v_dict != NULL)
1218 {
1219 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
1220 long_u t = ht->ht_used;
1221 hashitem_T *hi;
1222 dictitem_T *di;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001223
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001224 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001225
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001226 for (hi = ht->ht_array; t > 0; ++hi)
1227 {
1228 if (!HASHITEM_EMPTY(hi))
1229 {
1230 --t;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001231
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001232 di = dict_lookup(hi);
1233 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
1234 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
1235 Py_DECREF(newObj);
1236 }
1237 }
1238 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001239 }
1240 else
1241 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001242 Py_INCREF(Py_None);
1243 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001244 }
1245
1246 return result;
1247}
1248#endif
1249
1250/*ARGSUSED*/
1251static PyObject * VimEval(PyObject *self UNUSED, PyObject *args)
1252{
1253#ifdef FEAT_EVAL
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001254 char *expr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001255 typval_T *our_tv;
1256 PyObject *result;
1257 PyObject *lookup_dict;
1258
1259 if (!PyArg_ParseTuple(args, "s", &expr))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001260 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001261
1262 Py_BEGIN_ALLOW_THREADS
1263 Python_Lock_Vim();
1264 our_tv = eval_expr((char_u *)expr, NULL);
1265
1266 Python_Release_Vim();
1267 Py_END_ALLOW_THREADS
1268
1269 if (our_tv == NULL)
1270 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001271 PyErr_SetVim(_("invalid expression"));
1272 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001273 }
1274
1275 /* Convert the Vim type into a Python type. Create a dictionary that's
1276 * used to check for recursive loops. */
1277 lookup_dict = PyDict_New();
1278 result = VimToPython(our_tv, 1, lookup_dict);
1279 Py_DECREF(lookup_dict);
1280
1281
1282 Py_BEGIN_ALLOW_THREADS
1283 Python_Lock_Vim();
1284 free_tv(our_tv);
1285 Python_Release_Vim();
1286 Py_END_ALLOW_THREADS
1287
1288 return result;
1289#else
1290 PyErr_SetVim(_("expressions disabled at compile time"));
1291 return NULL;
1292#endif
1293}
1294
1295/* Common routines for buffers and line ranges
1296 * -------------------------------------------
1297 */
1298
1299static int CheckBuffer(BufferObject *this)
1300{
1301 if (this->buf == INVALID_BUFFER_VALUE)
1302 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001303 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1304 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001305 }
1306
1307 return 0;
1308}
1309
1310static PyObject * RBItem(BufferObject *self, Py_ssize_t n, Py_ssize_t start, Py_ssize_t end)
1311{
1312 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001313 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001314
1315 if (n < 0 || n > end - start)
1316 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001317 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1318 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001319 }
1320
1321 return GetBufferLine(self->buf, n+start);
1322}
1323
1324static Py_ssize_t RBAsItem(BufferObject *self, Py_ssize_t n, PyObject *val, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
1325{
1326 Py_ssize_t len_change;
1327
1328 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001329 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001330
1331 if (n < 0 || n > end - start)
1332 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001333 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1334 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001335 }
1336
1337 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001338 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001339
1340 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001341 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001342
1343 return 0;
1344}
1345
1346static PyObject * RBSlice(BufferObject *self, Py_ssize_t lo, Py_ssize_t hi, Py_ssize_t start, Py_ssize_t end)
1347{
1348 Py_ssize_t size;
1349
1350 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001351 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001352
1353 size = end - start + 1;
1354
1355 if (lo < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001356 lo = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001357 else if (lo > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001358 lo = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001359 if (hi < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001360 hi = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001361 if (hi < lo)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001362 hi = lo;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001363 else if (hi > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001364 hi = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001365
1366 return GetBufferLineList(self->buf, lo+start, hi+start);
1367}
1368
1369static PyObject * RBAppend(BufferObject *self, PyObject *args, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
1370{
1371 PyObject *lines;
1372 Py_ssize_t len_change;
1373 Py_ssize_t max;
1374 Py_ssize_t n;
1375
1376 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001377 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001378
1379 max = n = end - start + 1;
1380
1381 if (!PyArg_ParseTuple(args, "O|n" , &lines, &n))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001382 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001383
1384 if (n < 0 || n > max)
1385 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001386 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1387 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001388 }
1389
1390 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001391 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001392
1393 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001394 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001395
1396 Py_INCREF(Py_None);
1397 return Py_None;
1398}
1399
1400
1401static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001402 /* name, function, calling, documentation */
1403 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1404 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1405 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
1406 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001407};
1408
1409static PySequenceMethods BufferAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001410 (lenfunc) BufferLength, /* sq_length, len(x) */
1411 (binaryfunc) 0, /* sq_concat, x+y */
1412 (ssizeargfunc) 0, /* sq_repeat, x*n */
1413 (ssizeargfunc) BufferItem, /* sq_item, x[i] */
1414 0, /* was_sq_slice, x[i:j] */
1415 (ssizeobjargproc) BufferAsItem, /* sq_ass_item, x[i]=v */
1416 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001417 0, /* sq_contains */
1418 0, /* sq_inplace_concat */
1419 0, /* sq_inplace_repeat */
1420};
1421
1422PyMappingMethods BufferAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001423 /* mp_length */ (lenfunc)BufferLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001424 /* mp_subscript */ (binaryfunc)BufferSubscript,
1425 /* mp_ass_subscript */ (objobjargproc)0,
1426};
1427
1428
1429/* Buffer object - Definitions
1430 */
1431
1432static PyTypeObject BufferType;
1433
1434static PyObject * BufferNew(buf_T *buf)
1435{
1436 /* We need to handle deletion of buffers underneath us.
1437 * If we add a "b_python3_ref" field to the buf_T structure,
1438 * then we can get at it in buf_freeall() in vim. We then
1439 * need to create only ONE Python object per buffer - if
1440 * we try to create a second, just INCREF the existing one
1441 * and return it. The (single) Python object referring to
1442 * the buffer is stored in "b_python3_ref".
1443 * Question: what to do on a buf_freeall(). We'll probably
1444 * have to either delete the Python object (DECREF it to
1445 * zero - a bad idea, as it leaves dangling refs!) or
1446 * set the buf_T * value to an invalid value (-1?), which
1447 * means we need checks in all access functions... Bah.
1448 */
1449
1450 BufferObject *self;
1451
1452 if (buf->b_python3_ref != NULL)
1453 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001454 self = buf->b_python3_ref;
1455 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001456 }
1457 else
1458 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001459 self = PyObject_NEW(BufferObject, &BufferType);
1460 buf->b_python3_ref = self;
1461 if (self == NULL)
1462 return NULL;
1463 self->buf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001464 }
1465
1466 return (PyObject *)(self);
1467}
1468
1469static void BufferDestructor(PyObject *self)
1470{
1471 BufferObject *this = (BufferObject *)(self);
1472
1473 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001474 this->buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001475}
1476
1477static PyObject * BufferGetattro(PyObject *self, PyObject*nameobj)
1478{
1479 BufferObject *this = (BufferObject *)(self);
1480
1481 char *name = "";
1482 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001483 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001484
1485 if (CheckBuffer(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001486 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001487
1488 if (strcmp(name, "name") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001489 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001490 else if (strcmp(name, "number") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001491 return Py_BuildValue("n", this->buf->b_fnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001492 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001493 return Py_BuildValue("[ss]", "name", "number");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001494 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001495 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001496}
1497
1498static PyObject * BufferRepr(PyObject *self)
1499{
1500 static char repr[100];
1501 BufferObject *this = (BufferObject *)(self);
1502
1503 if (this->buf == INVALID_BUFFER_VALUE)
1504 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001505 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
1506 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001507 }
1508 else
1509 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001510 char *name = (char *)this->buf->b_fname;
1511 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001512
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001513 if (name == NULL)
1514 name = "";
1515 len = strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001516
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001517 if (len > 35)
1518 name = name + (35 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001519
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001520 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001521
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001522 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001523 }
1524}
1525
1526/******************/
1527
1528static Py_ssize_t BufferLength(PyObject *self)
1529{
1530 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001531 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001532
1533 return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
1534}
1535
1536static PyObject * BufferItem(PyObject *self, Py_ssize_t n)
1537{
1538 return RBItem((BufferObject *)(self), n, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001539 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001540}
1541
1542static Py_ssize_t BufferAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
1543{
1544 return RBAsItem((BufferObject *)(self), n, val, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001545 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1546 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001547}
1548
1549static PyObject * BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1550{
1551 return RBSlice((BufferObject *)(self), lo, hi, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001552 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001553}
1554
1555
1556static PyObject* BufferSubscript(PyObject *self, PyObject* idx)
1557{
1558 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001559 long _idx = PyLong_AsLong(idx);
1560 return BufferItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001561 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001562 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001563
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001564 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1565 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
1566 &start, &stop,
1567 &step, &slicelen) < 0) {
1568 return NULL;
1569 }
1570 return BufferSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001571 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001572 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1573 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001574 }
1575}
1576
1577static PyObject * BufferAppend(PyObject *self, PyObject *args)
1578{
1579 return RBAppend((BufferObject *)(self), args, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001580 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1581 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001582}
1583
1584static PyObject * BufferMark(PyObject *self, PyObject *args)
1585{
1586 pos_T *posp;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001587 char *pmark;//test
1588 char mark;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001589 buf_T *curbuf_save;
1590
1591 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001592 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001593
1594 if (!PyArg_ParseTuple(args, "s", &pmark))//test: "c"->"s"
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001595 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001596 mark = *pmark;//test
1597
1598 curbuf_save = curbuf;
1599 curbuf = ((BufferObject *)(self))->buf;
1600 posp = getmark(mark, FALSE);
1601 curbuf = curbuf_save;
1602
1603 if (posp == NULL)
1604 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001605 PyErr_SetVim(_("invalid mark name"));
1606 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001607 }
1608
1609 /* Ckeck for keyboard interrupt */
1610 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001611 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001612
1613 if (posp->lnum <= 0)
1614 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001615 /* Or raise an error? */
1616 Py_INCREF(Py_None);
1617 return Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001618 }
1619
1620 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1621}
1622
1623static PyObject * BufferRange(PyObject *self, PyObject *args)
1624{
1625 Py_ssize_t start;
1626 Py_ssize_t end;
1627
1628 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001629 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001630
1631 if (!PyArg_ParseTuple(args, "nn", &start, &end))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001632 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001633
1634 return RangeNew(((BufferObject *)(self))->buf, start, end);
1635}
1636
1637/* Line range object - Definitions
1638 */
1639
1640static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001641 /* name, function, calling, documentation */
1642 {"append", RangeAppend, 1, "Append data to the Vim range" },
1643 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001644};
1645
1646static PySequenceMethods RangeAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001647 (lenfunc) RangeLength, /* sq_length, len(x) */
1648 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
1649 (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
1650 (ssizeargfunc) RangeItem, /* sq_item, x[i] */
1651 0, /* was_sq_slice, x[i:j] */
1652 (ssizeobjargproc) RangeAsItem, /* sq_as_item, x[i]=v */
1653 0, /* sq_ass_slice, x[i:j]=v */
1654 0, /* sq_contains */
1655 0, /* sq_inplace_concat */
1656 0, /* sq_inplace_repeat */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001657};
1658
1659PyMappingMethods RangeAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001660 /* mp_length */ (lenfunc)RangeLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001661 /* mp_subscript */ (binaryfunc)RangeSubscript,
1662 /* mp_ass_subscript */ (objobjargproc)0,
1663};
1664
1665static PyTypeObject RangeType;
1666
1667/* Line range object - Implementation
1668 */
1669
1670static PyObject * RangeNew(buf_T *buf, Py_ssize_t start, Py_ssize_t end)
1671{
1672 BufferObject *bufr;
1673 RangeObject *self;
1674 self = PyObject_NEW(RangeObject, &RangeType);
1675 if (self == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001676 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001677
1678 bufr = (BufferObject *)BufferNew(buf);
1679 if (bufr == NULL)
1680 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001681 Py_DECREF(self);
1682 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001683 }
1684 Py_INCREF(bufr);
1685
1686 self->buf = bufr;
1687 self->start = start;
1688 self->end = end;
1689
1690 return (PyObject *)(self);
1691}
1692
1693static void RangeDestructor(PyObject *self)
1694{
1695 Py_DECREF(((RangeObject *)(self))->buf);
1696}
1697
1698static PyObject * RangeGetattro(PyObject *self, PyObject *nameobj)
1699{
1700 char *name = "";
1701 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001702 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001703
1704 if (strcmp(name, "start") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001705 return Py_BuildValue("n", ((RangeObject *)(self))->start - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001706 else if (strcmp(name, "end") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001707 return Py_BuildValue("n", ((RangeObject *)(self))->end - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001708 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001709 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001710}
1711
1712static PyObject * RangeRepr(PyObject *self)
1713{
1714 static char repr[100];
1715 RangeObject *this = (RangeObject *)(self);
1716
1717 if (this->buf->buf == INVALID_BUFFER_VALUE)
1718 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001719 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1720 (self));
1721 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001722 }
1723 else
1724 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001725 char *name = (char *)this->buf->buf->b_fname;
1726 int len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001727
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001728 if (name == NULL)
1729 name = "";
1730 len = (int)strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001731
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001732 if (len > 45)
1733 name = name + (45 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001734
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001735 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1736 len > 45 ? "..." : "", name,
1737 this->start, this->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001738
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001739 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001740 }
1741}
1742
1743/****************/
1744
1745static Py_ssize_t RangeLength(PyObject *self)
1746{
1747 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1748 if (CheckBuffer(((RangeObject *)(self))->buf))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001749 return -1; /* ??? */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001750
1751 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1752}
1753
1754static PyObject * RangeItem(PyObject *self, Py_ssize_t n)
1755{
1756 return RBItem(((RangeObject *)(self))->buf, n,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001757 ((RangeObject *)(self))->start,
1758 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001759}
1760
1761static Py_ssize_t RangeAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
1762{
1763 return RBAsItem(((RangeObject *)(self))->buf, n, val,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001764 ((RangeObject *)(self))->start,
1765 ((RangeObject *)(self))->end,
1766 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001767}
1768
1769static PyObject * RangeSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1770{
1771 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001772 ((RangeObject *)(self))->start,
1773 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001774}
1775
1776static PyObject* RangeSubscript(PyObject *self, PyObject* idx)
1777{
1778 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001779 long _idx = PyLong_AsLong(idx);
1780 return RangeItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001781 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001782 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001783
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001784 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1785 ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
1786 &start, &stop,
1787 &step, &slicelen) < 0) {
1788 return NULL;
1789 }
1790 return RangeSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001791 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001792 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1793 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001794 }
1795}
1796
1797static PyObject * RangeAppend(PyObject *self, PyObject *args)
1798{
1799 return RBAppend(((RangeObject *)(self))->buf, args,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001800 ((RangeObject *)(self))->start,
1801 ((RangeObject *)(self))->end,
1802 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001803}
1804
1805/* Buffer list object - Definitions
1806 */
1807
1808typedef struct
1809{
1810 PyObject_HEAD
1811}
1812BufListObject;
1813
1814static PySequenceMethods BufListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001815 (lenfunc) BufListLength, /* sq_length, len(x) */
1816 (binaryfunc) 0, /* sq_concat, x+y */
1817 (ssizeargfunc) 0, /* sq_repeat, x*n */
1818 (ssizeargfunc) BufListItem, /* sq_item, x[i] */
1819 0, /* was_sq_slice, x[i:j] */
1820 (ssizeobjargproc) 0, /* sq_as_item, x[i]=v */
1821 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001822 0, /* sq_contains */
1823 0, /* sq_inplace_concat */
1824 0, /* sq_inplace_repeat */
1825};
1826
1827static PyTypeObject BufListType;
1828
1829/* Buffer list object - Implementation
1830 */
1831
1832/*ARGSUSED*/
1833static Py_ssize_t BufListLength(PyObject *self UNUSED)
1834{
1835 buf_T *b = firstbuf;
1836 Py_ssize_t n = 0;
1837
1838 while (b)
1839 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001840 ++n;
1841 b = b->b_next;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001842 }
1843
1844 return n;
1845}
1846
1847/*ARGSUSED*/
1848static PyObject * BufListItem(PyObject *self UNUSED, Py_ssize_t n)
1849{
1850 buf_T *b;
1851
1852 for (b = firstbuf; b; b = b->b_next, --n)
1853 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001854 if (n == 0)
1855 return BufferNew(b);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001856 }
1857
1858 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1859 return NULL;
1860}
1861
1862/* Window object - Definitions
1863 */
1864
1865static struct PyMethodDef WindowMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001866 /* name, function, calling, documentation */
1867 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001868};
1869
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001870static PyTypeObject WindowType;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001871
1872/* Window object - Implementation
1873 */
1874
1875static PyObject * WindowNew(win_T *win)
1876{
1877 /* We need to handle deletion of windows underneath us.
1878 * If we add a "w_python3_ref" field to the win_T structure,
1879 * then we can get at it in win_free() in vim. We then
1880 * need to create only ONE Python object per window - if
1881 * we try to create a second, just INCREF the existing one
1882 * and return it. The (single) Python object referring to
1883 * the window is stored in "w_python3_ref".
1884 * On a win_free() we set the Python object's win_T* field
1885 * to an invalid value. We trap all uses of a window
1886 * object, and reject them if the win_T* field is invalid.
1887 */
1888
1889 WindowObject *self;
1890
1891 if (win->w_python3_ref)
1892 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001893 self = win->w_python3_ref;
1894 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001895 }
1896 else
1897 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001898 self = PyObject_NEW(WindowObject, &WindowType);
1899 if (self == NULL)
1900 return NULL;
1901 self->win = win;
1902 win->w_python3_ref = self;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001903 }
1904
1905 return (PyObject *)(self);
1906}
1907
1908static void WindowDestructor(PyObject *self)
1909{
1910 WindowObject *this = (WindowObject *)(self);
1911
1912 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001913 this->win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001914}
1915
1916static int CheckWindow(WindowObject *this)
1917{
1918 if (this->win == INVALID_WINDOW_VALUE)
1919 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001920 PyErr_SetVim(_("attempt to refer to deleted window"));
1921 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001922 }
1923
1924 return 0;
1925}
1926
1927static PyObject * WindowGetattro(PyObject *self, PyObject *nameobj)
1928{
1929 WindowObject *this = (WindowObject *)(self);
1930
1931 char *name = "";
1932 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001933 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001934
1935
1936 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001937 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001938
1939 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001940 return (PyObject *)BufferNew(this->win->w_buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001941 else if (strcmp(name, "cursor") == 0)
1942 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001943 pos_T *pos = &this->win->w_cursor;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001944
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001945 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001946 }
1947 else if (strcmp(name, "height") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001948 return Py_BuildValue("l", (long)(this->win->w_height));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001949#ifdef FEAT_VERTSPLIT
1950 else if (strcmp(name, "width") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001951 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001952#endif
1953 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001954 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001955 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001956 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001957}
1958
1959static int WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
1960{
1961 WindowObject *this = (WindowObject *)(self);
1962
1963 char *name = "";
1964 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001965 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001966
1967
1968 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001969 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001970
1971 if (strcmp(name, "buffer") == 0)
1972 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001973 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1974 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001975 }
1976 else if (strcmp(name, "cursor") == 0)
1977 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001978 long lnum;
1979 long col;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001980
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001981 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1982 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001983
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001984 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1985 {
1986 PyErr_SetVim(_("cursor position outside buffer"));
1987 return -1;
1988 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001989
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001990 /* Check for keyboard interrupts */
1991 if (VimErrorCheck())
1992 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001993
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001994 /* NO CHECK ON COLUMN - SEEMS NOT TO MATTER */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001995
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001996 this->win->w_cursor.lnum = lnum;
1997 this->win->w_cursor.col = col;
1998 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001999
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002000 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002001 }
2002 else if (strcmp(name, "height") == 0)
2003 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002004 int height;
2005 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002006
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002007 if (!PyArg_Parse(val, "i", &height))
2008 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002009
2010#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002011 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002012#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002013 savewin = curwin;
2014 curwin = this->win;
2015 win_setheight(height);
2016 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002017
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002018 /* Check for keyboard interrupts */
2019 if (VimErrorCheck())
2020 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002021
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002022 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002023 }
2024#ifdef FEAT_VERTSPLIT
2025 else if (strcmp(name, "width") == 0)
2026 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002027 int width;
2028 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002029
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002030 if (!PyArg_Parse(val, "i", &width))
2031 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002032
2033#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002034 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002035#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002036 savewin = curwin;
2037 curwin = this->win;
2038 win_setwidth(width);
2039 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002040
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002041 /* Check for keyboard interrupts */
2042 if (VimErrorCheck())
2043 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002044
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002045 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002046 }
2047#endif
2048 else
2049 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002050 PyErr_SetString(PyExc_AttributeError, name);
2051 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002052 }
2053}
2054
2055static PyObject * WindowRepr(PyObject *self)
2056{
2057 static char repr[100];
2058 WindowObject *this = (WindowObject *)(self);
2059
2060 if (this->win == INVALID_WINDOW_VALUE)
2061 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002062 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2063 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002064 }
2065 else
2066 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002067 int i = 0;
2068 win_T *w;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002069
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002070 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
2071 ++i;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002072
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002073 if (w == NULL)
2074 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2075 (self));
2076 else
2077 vim_snprintf(repr, 100, _("<window %d>"), i);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002078
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002079 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002080 }
2081}
2082
2083/* Window list object - Definitions
2084 */
2085
2086typedef struct
2087{
2088 PyObject_HEAD
2089}
2090WinListObject;
2091
2092static PySequenceMethods WinListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002093 (lenfunc) WinListLength, /* sq_length, len(x) */
2094 (binaryfunc) 0, /* sq_concat, x+y */
2095 (ssizeargfunc) 0, /* sq_repeat, x*n */
2096 (ssizeargfunc) WinListItem, /* sq_item, x[i] */
2097 0, /* sq_slice, x[i:j] */
2098 (ssizeobjargproc)0, /* sq_as_item, x[i]=v */
2099 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002100 0, /* sq_contains */
2101 0, /* sq_inplace_concat */
2102 0, /* sq_inplace_repeat */
2103};
2104
2105static PyTypeObject WinListType;
2106
2107/* Window list object - Implementation
2108 */
2109/*ARGSUSED*/
2110static Py_ssize_t WinListLength(PyObject *self UNUSED)
2111{
2112 win_T *w = firstwin;
2113 Py_ssize_t n = 0;
2114
2115 while (w != NULL)
2116 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002117 ++n;
2118 w = W_NEXT(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002119 }
2120
2121 return n;
2122}
2123
2124/*ARGSUSED*/
2125static PyObject * WinListItem(PyObject *self UNUSED, Py_ssize_t n)
2126{
2127 win_T *w;
2128
2129 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002130 if (n == 0)
2131 return WindowNew(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002132
2133 PyErr_SetString(PyExc_IndexError, _("no such window"));
2134 return NULL;
2135}
2136
2137/* Current items object - Definitions
2138 */
2139
2140typedef struct
2141{
2142 PyObject_HEAD
2143}
2144CurrentObject;
2145
2146static PyTypeObject CurrentType;
2147
2148/* Current items object - Implementation
2149 */
2150/*ARGSUSED*/
2151static PyObject * CurrentGetattro(PyObject *self UNUSED, PyObject *nameobj)
2152{
2153 char *name = "";
2154 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002155 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002156
2157 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002158 return (PyObject *)BufferNew(curbuf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002159 else if (strcmp(name, "window") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002160 return (PyObject *)WindowNew(curwin);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002161 else if (strcmp(name, "line") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002162 return GetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002163 else if (strcmp(name, "range") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002164 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002165 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002166 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002167 else
2168 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002169 PyErr_SetString(PyExc_AttributeError, name);
2170 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002171 }
2172}
2173
2174/*ARGSUSED*/
2175static int CurrentSetattro(PyObject *self UNUSED, PyObject *nameobj, PyObject *value)
2176{
2177 char *name = "";
2178 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002179 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002180
2181 if (strcmp(name, "line") == 0)
2182 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002183 if (SetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum, value, NULL) == FAIL)
2184 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002185
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002186 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002187 }
2188 else
2189 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002190 PyErr_SetString(PyExc_AttributeError, name);
2191 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002192 }
2193}
2194
2195/* External interface
2196 */
2197
2198 void
2199python3_buffer_free(buf_T *buf)
2200{
2201 if (buf->b_python3_ref != NULL)
2202 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002203 BufferObject *bp = buf->b_python3_ref;
2204 bp->buf = INVALID_BUFFER_VALUE;
2205 buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002206 }
2207}
2208
2209#if defined(FEAT_WINDOWS) || defined(PROTO)
2210 void
2211python3_window_free(win_T *win)
2212{
2213 if (win->w_python3_ref != NULL)
2214 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002215 WindowObject *wp = win->w_python3_ref;
2216 wp->win = INVALID_WINDOW_VALUE;
2217 win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002218 }
2219}
2220#endif
2221
2222static BufListObject TheBufferList =
2223{
2224 PyObject_HEAD_INIT(&BufListType)
2225};
2226
2227static WinListObject TheWindowList =
2228{
2229 PyObject_HEAD_INIT(&WinListType)
2230};
2231
2232static CurrentObject TheCurrent =
2233{
2234 PyObject_HEAD_INIT(&CurrentType)
2235};
2236
2237PyDoc_STRVAR(vim_module_doc,"vim python interface\n");
2238
2239static struct PyModuleDef vimmodule;
2240
Bram Moolenaar69154f22010-07-18 21:42:34 +02002241#ifndef PROTO
2242PyMODINIT_FUNC Py3Init_vim(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002243{
2244 PyObject *mod;
2245 /* The special value is removed from sys.path in Python3_Init(). */
2246 static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
2247
2248 PyType_Ready(&BufferType);
2249 PyType_Ready(&RangeType);
2250 PyType_Ready(&WindowType);
2251 PyType_Ready(&BufListType);
2252 PyType_Ready(&WinListType);
2253 PyType_Ready(&CurrentType);
2254
2255 /* Set sys.argv[] to avoid a crash in warn(). */
2256 PySys_SetArgv(1, argv);
2257
2258 mod = PyModule_Create(&vimmodule);
2259
2260 VimError = Py_BuildValue("s", "vim.error");
2261
2262 PyModule_AddObject(mod, "error", VimError);
2263 Py_INCREF((PyObject *)(void *)&TheBufferList);
2264 PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
2265 Py_INCREF((PyObject *)(void *)&TheCurrent);
2266 PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
2267 Py_INCREF((PyObject *)(void *)&TheWindowList);
2268 PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
2269
2270 if (PyErr_Occurred())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002271 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002272
2273 return mod;
2274}
Bram Moolenaar69154f22010-07-18 21:42:34 +02002275#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002276
2277/*************************************************************************
2278 * 4. Utility functions for handling the interface between Vim and Python.
2279 */
2280
2281
2282/* Get a list of lines from the specified buffer. The line numbers
2283 * are in Vim format (1-based). The range is from lo up to, but not
2284 * including, hi. The list is returned as a Python list of string objects.
2285 */
2286static PyObject * GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi)
2287{
2288 Py_ssize_t i;
2289 Py_ssize_t n = hi - lo;
2290 PyObject *list = PyList_New(n);
2291
2292 if (list == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002293 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002294
2295 for (i = 0; i < n; ++i)
2296 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002297 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002298
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002299 /* Error check - was the Python string creation OK? */
2300 if (str == NULL)
2301 {
2302 Py_DECREF(list);
2303 return NULL;
2304 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002305
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002306 /* Set the list item */
2307 if (PyList_SetItem(list, i, str))
2308 {
2309 Py_DECREF(str);
2310 Py_DECREF(list);
2311 return NULL;
2312 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002313 }
2314
2315 /* The ownership of the Python list is passed to the caller (ie,
2316 * the caller should Py_DECREF() the object when it is finished
2317 * with it).
2318 */
2319
2320 return list;
2321}
2322
2323/* Get a line from the specified buffer. The line number is
2324 * in Vim format (1-based). The line is returned as a Python
2325 * string object.
2326 */
2327static PyObject * GetBufferLine(buf_T *buf, Py_ssize_t n)
2328{
2329 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2330}
2331
2332/*
2333 * Check if deleting lines made the cursor position invalid.
2334 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2335 * deleted).
2336 */
2337static void py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2338{
2339 if (curwin->w_cursor.lnum >= lo)
2340 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002341 /* Adjust the cursor position if it's in/after the changed
2342 * lines. */
2343 if (curwin->w_cursor.lnum >= hi)
2344 {
2345 curwin->w_cursor.lnum += extra;
2346 check_cursor_col();
2347 }
2348 else if (extra < 0)
2349 {
2350 curwin->w_cursor.lnum = lo;
2351 check_cursor();
2352 }
2353 else
2354 check_cursor_col();
2355 changed_cline_bef_curs();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002356 }
2357 invalidate_botline();
2358}
2359
2360/* Replace a line in the specified buffer. The line number is
2361 * in Vim format (1-based). The replacement line is given as
2362 * a Python string object. The object is checked for validity
2363 * and correct format. Errors are returned as a value of FAIL.
2364 * The return value is OK on success.
2365 * If OK is returned and len_change is not NULL, *len_change
2366 * is set to the change in the buffer length.
2367 */
2368static int SetBufferLine(buf_T *buf, Py_ssize_t n, PyObject *line, Py_ssize_t *len_change)
2369{
2370 /* First of all, we check the thpe of the supplied Python object.
2371 * There are three cases:
2372 * 1. NULL, or None - this is a deletion.
2373 * 2. A string - this is a replacement.
2374 * 3. Anything else - this is an error.
2375 */
2376 if (line == Py_None || line == NULL)
2377 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002378 buf_T *savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002379
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002380 PyErr_Clear();
2381 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002382
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002383 if (u_savedel((linenr_T)n, 1L) == FAIL)
2384 PyErr_SetVim(_("cannot save undo information"));
2385 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2386 PyErr_SetVim(_("cannot delete line"));
2387 else
2388 {
2389 deleted_lines_mark((linenr_T)n, 1L);
2390 if (buf == curwin->w_buffer)
2391 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2392 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002393
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002394 curbuf = savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002395
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002396 if (PyErr_Occurred() || VimErrorCheck())
2397 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002398
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002399 if (len_change)
2400 *len_change = -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002401
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002402 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002403 }
2404 else if (PyUnicode_Check(line))
2405 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002406 char *save = StringToLine(line);
2407 buf_T *savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002408
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002409 if (save == NULL)
2410 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002411
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002412 /* We do not need to free "save" if ml_replace() consumes it. */
2413 PyErr_Clear();
2414 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002415
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002416 if (u_savesub((linenr_T)n) == FAIL)
2417 {
2418 PyErr_SetVim(_("cannot save undo information"));
2419 vim_free(save);
2420 }
2421 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2422 {
2423 PyErr_SetVim(_("cannot replace line"));
2424 vim_free(save);
2425 }
2426 else
2427 changed_bytes((linenr_T)n, 0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002428
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002429 curbuf = savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002430
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002431 /* Check that the cursor is not beyond the end of the line now. */
2432 if (buf == curwin->w_buffer)
2433 check_cursor_col();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002434
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002435 if (PyErr_Occurred() || VimErrorCheck())
2436 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002437
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002438 if (len_change)
2439 *len_change = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002440
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002441 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002442 }
2443 else
2444 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002445 PyErr_BadArgument();
2446 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002447 }
2448}
2449
2450/* Insert a number of lines into the specified buffer after the specifed line.
2451 * The line number is in Vim format (1-based). The lines to be inserted are
2452 * given as a Python list of string objects or as a single string. The lines
2453 * to be added are checked for validity and correct format. Errors are
2454 * returned as a value of FAIL. The return value is OK on success.
2455 * If OK is returned and len_change is not NULL, *len_change
2456 * is set to the change in the buffer length.
2457 */
2458static int InsertBufferLines(buf_T *buf, Py_ssize_t n, PyObject *lines, Py_ssize_t *len_change)
2459{
2460 /* First of all, we check the type of the supplied Python object.
2461 * It must be a string or a list, or the call is in error.
2462 */
2463 if (PyUnicode_Check(lines))
2464 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002465 char *str = StringToLine(lines);
2466 buf_T *savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002467
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002468 if (str == NULL)
2469 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002470
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002471 savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002472
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002473 PyErr_Clear();
2474 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002475
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002476 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2477 PyErr_SetVim(_("cannot save undo information"));
2478 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2479 PyErr_SetVim(_("cannot insert line"));
2480 else
2481 appended_lines_mark((linenr_T)n, 1L);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002482
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002483 vim_free(str);
2484 curbuf = savebuf;
2485 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002486
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002487 if (PyErr_Occurred() || VimErrorCheck())
2488 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002489
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002490 if (len_change)
2491 *len_change = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002492
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002493 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002494 }
2495 else if (PyList_Check(lines))
2496 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002497 Py_ssize_t i;
2498 Py_ssize_t size = PyList_Size(lines);
2499 char **array;
2500 buf_T *savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002501
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002502 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2503 if (array == NULL)
2504 {
2505 PyErr_NoMemory();
2506 return FAIL;
2507 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002508
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002509 for (i = 0; i < size; ++i)
2510 {
2511 PyObject *line = PyList_GetItem(lines, i);
2512 array[i] = StringToLine(line);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002513
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002514 if (array[i] == NULL)
2515 {
2516 while (i)
2517 vim_free(array[--i]);
2518 vim_free(array);
2519 return FAIL;
2520 }
2521 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002522
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002523 savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002524
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002525 PyErr_Clear();
2526 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002527
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002528 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2529 PyErr_SetVim(_("cannot save undo information"));
2530 else
2531 {
2532 for (i = 0; i < size; ++i)
2533 {
2534 if (ml_append((linenr_T)(n + i),
2535 (char_u *)array[i], 0, FALSE) == FAIL)
2536 {
2537 PyErr_SetVim(_("cannot insert line"));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002538
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002539 /* Free the rest of the lines */
2540 while (i < size)
2541 vim_free(array[i++]);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002542
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002543 break;
2544 }
2545 vim_free(array[i]);
2546 }
2547 if (i > 0)
2548 appended_lines_mark((linenr_T)n, (long)i);
2549 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002550
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002551 /* Free the array of lines. All of its contents have now
2552 * been freed.
2553 */
2554 vim_free(array);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002555
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002556 curbuf = savebuf;
2557 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002558
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002559 if (PyErr_Occurred() || VimErrorCheck())
2560 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002561
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002562 if (len_change)
2563 *len_change = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002564
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002565 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002566 }
2567 else
2568 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002569 PyErr_BadArgument();
2570 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002571 }
2572}
2573
2574/* Convert a Vim line into a Python string.
2575 * All internal newlines are replaced by null characters.
2576 *
2577 * On errors, the Python exception data is set, and NULL is returned.
2578 */
2579static PyObject * LineToString(const char *str)
2580{
2581 PyObject *result;
2582 Py_ssize_t len = strlen(str);
2583 char *tmp,*p;
2584
2585 tmp = (char *)alloc((unsigned)(len+1));
2586 p = tmp;
2587 if (p == NULL)
2588 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002589 PyErr_NoMemory();
2590 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002591 }
2592
2593 while (*str)
2594 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002595 if (*str == '\n')
2596 *p = '\0';
2597 else
2598 *p = *str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002599
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002600 ++p;
2601 ++str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002602 }
2603 *p = '\0';
2604
2605 result = PyUnicode_FromStringAndSize(tmp, len);
2606
2607 vim_free(tmp);
2608 return result;
2609}
2610
2611/* Convert a Python string into a Vim line.
2612 *
2613 * The result is in allocated memory. All internal nulls are replaced by
2614 * newline characters. It is an error for the string to contain newline
2615 * characters.
2616 *
2617 * On errors, the Python exception data is set, and NULL is returned.
2618 */
2619static char * StringToLine(PyObject *obj)
2620{
2621 const char *str;
2622 char *save;
2623 Py_ssize_t len;
2624 Py_ssize_t i;
2625 char *p;
2626
2627 if (obj == NULL || !PyUnicode_Check(obj))
2628 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002629 PyErr_BadArgument();
2630 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002631 }
2632
2633 str = _PyUnicode_AsString(obj);
2634 len = PyUnicode_GET_SIZE(obj);
2635
2636 /*
2637 * Error checking: String must not contain newlines, as we
2638 * are replacing a single line, and we must replace it with
2639 * a single line.
2640 * A trailing newline is removed, so that append(f.readlines()) works.
2641 */
2642 p = memchr(str, '\n', len);
2643 if (p != NULL)
2644 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002645 if (p == str + len - 1)
2646 --len;
2647 else
2648 {
2649 PyErr_SetVim(_("string cannot contain newlines"));
2650 return NULL;
2651 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002652 }
2653
2654 /* Create a copy of the string, with internal nulls replaced by
2655 * newline characters, as is the vim convention.
2656 */
2657 save = (char *)alloc((unsigned)(len+1));
2658 if (save == NULL)
2659 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002660 PyErr_NoMemory();
2661 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002662 }
2663
2664 for (i = 0; i < len; ++i)
2665 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002666 if (str[i] == '\0')
2667 save[i] = '\n';
2668 else
2669 save[i] = str[i];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002670 }
2671
2672 save[i] = '\0';
2673
2674 return save;
2675}
2676
2677/* Check to see whether a Vim error has been reported, or a keyboard
2678 * interrupt has been detected.
2679 */
2680static int VimErrorCheck(void)
2681{
2682 if (got_int)
2683 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002684 PyErr_SetNone(PyExc_KeyboardInterrupt);
2685 return 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002686 }
2687 else if (did_emsg && !PyErr_Occurred())
2688 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002689 PyErr_SetNone(VimError);
2690 return 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002691 }
2692
2693 return 0;
2694}
2695
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002696static void init_structs(void)
2697{
2698 vim_memset(&OutputType, 0, sizeof(OutputType));
2699 OutputType.tp_name = "vim.message";
2700 OutputType.tp_basicsize = sizeof(OutputObject);
2701 OutputType.tp_getattro = OutputGetattro;
2702 OutputType.tp_setattro = OutputSetattro;
2703 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
2704 OutputType.tp_doc = "vim message object";
2705 OutputType.tp_methods = OutputMethods;
2706 OutputType.tp_alloc = call_PyType_GenericAlloc;
2707 OutputType.tp_new = call_PyType_GenericNew;
2708 OutputType.tp_free = call_PyObject_Free;
2709
2710 vim_memset(&BufferType, 0, sizeof(BufferType));
2711 BufferType.tp_name = "vim.buffer";
2712 BufferType.tp_basicsize = sizeof(BufferType);
2713 BufferType.tp_dealloc = BufferDestructor;
2714 BufferType.tp_repr = BufferRepr;
2715 BufferType.tp_as_sequence = &BufferAsSeq;
2716 BufferType.tp_as_mapping = &BufferAsMapping;
2717 BufferType.tp_getattro = BufferGetattro;
2718 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
2719 BufferType.tp_doc = "vim buffer object";
2720 BufferType.tp_methods = BufferMethods;
2721 BufferType.tp_alloc = call_PyType_GenericAlloc;
2722 BufferType.tp_new = call_PyType_GenericNew;
2723 BufferType.tp_free = call_PyObject_Free;
2724
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002725 vim_memset(&WindowType, 0, sizeof(WindowType));
2726 WindowType.tp_name = "vim.window";
2727 WindowType.tp_basicsize = sizeof(WindowObject);
2728 WindowType.tp_dealloc = WindowDestructor;
2729 WindowType.tp_repr = WindowRepr;
2730 WindowType.tp_getattro = WindowGetattro;
2731 WindowType.tp_setattro = WindowSetattro;
2732 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
2733 WindowType.tp_doc = "vim Window object";
2734 WindowType.tp_methods = WindowMethods;
2735 WindowType.tp_alloc = call_PyType_GenericAlloc;
2736 WindowType.tp_new = call_PyType_GenericNew;
2737 WindowType.tp_free = call_PyObject_Free;
2738
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002739 vim_memset(&BufListType, 0, sizeof(BufListType));
2740 BufListType.tp_name = "vim.bufferlist";
2741 BufListType.tp_basicsize = sizeof(BufListObject);
2742 BufListType.tp_as_sequence = &BufListAsSeq;
2743 BufListType.tp_flags = Py_TPFLAGS_DEFAULT;
2744 BufferType.tp_doc = "vim buffer list";
2745
2746 vim_memset(&WinListType, 0, sizeof(WinListType));
2747 WinListType.tp_name = "vim.windowlist";
2748 WinListType.tp_basicsize = sizeof(WinListType);
2749 WinListType.tp_as_sequence = &WinListAsSeq;
2750 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
2751 WinListType.tp_doc = "vim window list";
2752
2753 vim_memset(&RangeType, 0, sizeof(RangeType));
2754 RangeType.tp_name = "vim.range";
2755 RangeType.tp_basicsize = sizeof(RangeObject);
2756 RangeType.tp_dealloc = RangeDestructor;
2757 RangeType.tp_repr = RangeRepr;
2758 RangeType.tp_as_sequence = &RangeAsSeq;
2759 RangeType.tp_as_mapping = &RangeAsMapping;
2760 RangeType.tp_getattro = RangeGetattro;
2761 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
2762 RangeType.tp_doc = "vim Range object";
2763 RangeType.tp_methods = RangeMethods;
2764 RangeType.tp_alloc = call_PyType_GenericAlloc;
2765 RangeType.tp_new = call_PyType_GenericNew;
2766 RangeType.tp_free = call_PyObject_Free;
2767
2768 vim_memset(&CurrentType, 0, sizeof(CurrentType));
2769 CurrentType.tp_name = "vim.currentdata";
2770 CurrentType.tp_basicsize = sizeof(CurrentObject);
2771 CurrentType.tp_getattro = CurrentGetattro;
2772 CurrentType.tp_setattro = CurrentSetattro;
2773 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
2774 CurrentType.tp_doc = "vim current object";
2775
2776 vim_memset(&vimmodule, 0, sizeof(vimmodule));
2777 vimmodule.m_name = "vim";
2778 vimmodule.m_doc = vim_module_doc;
2779 vimmodule.m_size = -1;
2780 vimmodule.m_methods = VimMethods;
2781}