blob: adcb52d2bdb97577210d887823a8277805cb2423 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* 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#include "vim.h"
21
Bram Moolenaar071d4272004-06-13 20:20:40 +000022#include <limits.h>
23
24/* Python.h defines _POSIX_THREADS itself (if needed) */
25#ifdef _POSIX_THREADS
26# undef _POSIX_THREADS
27#endif
28
29#if defined(_WIN32) && defined (HAVE_FCNTL_H)
30# undef HAVE_FCNTL_H
31#endif
32
33#ifdef _DEBUG
34# undef _DEBUG
35#endif
36
37#ifdef HAVE_STDARG_H
38# undef HAVE_STDARG_H /* Python's config.h defines it as well. */
39#endif
40
41#include <Python.h>
42#if defined(MACOS) && !defined(MACOS_X_UNIX)
43# include "macglue.h"
44# include <CodeFragments.h>
45#endif
46#undef main /* Defined in python.h - aargh */
47#undef HAVE_FCNTL_H /* Clash with os_win32.h */
48
49#if !defined(FEAT_PYTHON) && defined(PROTO)
50/* Use this to be able to generate prototypes without python being used. */
51# define PyObject int
52# define PyThreadState int
53# define PyTypeObject int
54struct PyMethodDef { int a; };
55# define PySequenceMethods int
56#endif
57
58/* Parser flags */
59#define single_input 256
60#define file_input 257
61#define eval_input 258
62
63#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x020300F0
64 /* Python 2.3: can invoke ":python" recursively. */
65# define PY_CAN_RECURSE
66#endif
67
68#if defined(DYNAMIC_PYTHON) || defined(PROTO)
69# ifndef DYNAMIC_PYTHON
70# define HINSTANCE int /* for generating prototypes */
71# endif
72
73/*
74 * Wrapper defines
75 */
76# define PyArg_Parse dll_PyArg_Parse
77# define PyArg_ParseTuple dll_PyArg_ParseTuple
78# define PyDict_SetItemString dll_PyDict_SetItemString
79# define PyErr_BadArgument dll_PyErr_BadArgument
80# define PyErr_Clear dll_PyErr_Clear
81# define PyErr_NoMemory dll_PyErr_NoMemory
82# define PyErr_Occurred dll_PyErr_Occurred
83# define PyErr_SetNone dll_PyErr_SetNone
84# define PyErr_SetString dll_PyErr_SetString
85# define PyEval_InitThreads dll_PyEval_InitThreads
86# define PyEval_RestoreThread dll_PyEval_RestoreThread
87# define PyEval_SaveThread dll_PyEval_SaveThread
88# ifdef PY_CAN_RECURSE
89# define PyGILState_Ensure dll_PyGILState_Ensure
90# define PyGILState_Release dll_PyGILState_Release
91# endif
92# define PyInt_AsLong dll_PyInt_AsLong
93# define PyInt_FromLong dll_PyInt_FromLong
94# define PyInt_Type (*dll_PyInt_Type)
95# define PyList_GetItem dll_PyList_GetItem
Bram Moolenaar0ac93792006-01-21 22:16:51 +000096# define PyList_Append dll_PyList_Append
Bram Moolenaar071d4272004-06-13 20:20:40 +000097# define PyList_New dll_PyList_New
98# define PyList_SetItem dll_PyList_SetItem
99# define PyList_Size dll_PyList_Size
100# define PyList_Type (*dll_PyList_Type)
101# define PyImport_ImportModule dll_PyImport_ImportModule
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000102# define PyDict_New dll_PyDict_New
Bram Moolenaar071d4272004-06-13 20:20:40 +0000103# define PyDict_GetItemString dll_PyDict_GetItemString
104# define PyModule_GetDict dll_PyModule_GetDict
105# define PyRun_SimpleString dll_PyRun_SimpleString
106# define PyString_AsString dll_PyString_AsString
107# define PyString_FromString dll_PyString_FromString
108# define PyString_FromStringAndSize dll_PyString_FromStringAndSize
109# define PyString_Size dll_PyString_Size
110# define PyString_Type (*dll_PyString_Type)
111# define PySys_SetObject dll_PySys_SetObject
112# define PySys_SetArgv dll_PySys_SetArgv
113# define PyType_Type (*dll_PyType_Type)
114# define Py_BuildValue dll_Py_BuildValue
115# define Py_FindMethod dll_Py_FindMethod
116# define Py_InitModule4 dll_Py_InitModule4
117# define Py_Initialize dll_Py_Initialize
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000118# define Py_Finalize dll_Py_Finalize
119# define Py_IsInitialized dll_Py_IsInitialized
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120# define _PyObject_New dll__PyObject_New
121# define _Py_NoneStruct (*dll__Py_NoneStruct)
122# define PyObject_Init dll__PyObject_Init
123# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
124# define PyType_IsSubtype dll_PyType_IsSubtype
125# endif
126# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
127# define PyObject_Malloc dll_PyObject_Malloc
128# define PyObject_Free dll_PyObject_Free
129# endif
130
131/*
132 * Pointers for dynamic link
133 */
134static int(*dll_PyArg_Parse)(PyObject *, char *, ...);
135static int(*dll_PyArg_ParseTuple)(PyObject *, char *, ...);
136static int(*dll_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
137static int(*dll_PyErr_BadArgument)(void);
138static void(*dll_PyErr_Clear)(void);
139static PyObject*(*dll_PyErr_NoMemory)(void);
140static PyObject*(*dll_PyErr_Occurred)(void);
141static void(*dll_PyErr_SetNone)(PyObject *);
142static void(*dll_PyErr_SetString)(PyObject *, const char *);
143static void(*dll_PyEval_InitThreads)(void);
144static void(*dll_PyEval_RestoreThread)(PyThreadState *);
145static PyThreadState*(*dll_PyEval_SaveThread)(void);
146# ifdef PY_CAN_RECURSE
147static PyGILState_STATE (*dll_PyGILState_Ensure)(void);
148static void (*dll_PyGILState_Release)(PyGILState_STATE);
149#endif
150static long(*dll_PyInt_AsLong)(PyObject *);
151static PyObject*(*dll_PyInt_FromLong)(long);
152static PyTypeObject* dll_PyInt_Type;
153static PyObject*(*dll_PyList_GetItem)(PyObject *, int);
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000154static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000155static PyObject*(*dll_PyList_New)(int size);
156static int(*dll_PyList_SetItem)(PyObject *, int, PyObject *);
157static int(*dll_PyList_Size)(PyObject *);
158static PyTypeObject* dll_PyList_Type;
159static PyObject*(*dll_PyImport_ImportModule)(const char *);
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000160static PyObject*(*dll_PyDict_New)(void);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000161static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
162static PyObject*(*dll_PyModule_GetDict)(PyObject *);
163static int(*dll_PyRun_SimpleString)(char *);
164static char*(*dll_PyString_AsString)(PyObject *);
165static PyObject*(*dll_PyString_FromString)(const char *);
166static PyObject*(*dll_PyString_FromStringAndSize)(const char *, int);
167static int(*dll_PyString_Size)(PyObject *);
168static PyTypeObject* dll_PyString_Type;
169static int(*dll_PySys_SetObject)(char *, PyObject *);
170static int(*dll_PySys_SetArgv)(int, char **);
171static PyTypeObject* dll_PyType_Type;
172static PyObject*(*dll_Py_BuildValue)(char *, ...);
173static PyObject*(*dll_Py_FindMethod)(struct PyMethodDef[], PyObject *, char *);
174static PyObject*(*dll_Py_InitModule4)(char *, struct PyMethodDef *, char *, PyObject *, int);
175static void(*dll_Py_Initialize)(void);
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000176static void(*dll_Py_Finalize)(void);
177static int(*dll_Py_IsInitialized)(void);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000178static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
179static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
180static PyObject* dll__Py_NoneStruct;
181# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
182static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
183# endif
184# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
185static void* (*dll_PyObject_Malloc)(size_t);
186static void (*dll_PyObject_Free)(void*);
187# endif
188
189static HINSTANCE hinstPython = 0; /* Instance of python.dll */
190
191/* Imported exception objects */
192static PyObject *imp_PyExc_AttributeError;
193static PyObject *imp_PyExc_IndexError;
194static PyObject *imp_PyExc_KeyboardInterrupt;
195static PyObject *imp_PyExc_TypeError;
196static PyObject *imp_PyExc_ValueError;
197
198# define PyExc_AttributeError imp_PyExc_AttributeError
199# define PyExc_IndexError imp_PyExc_IndexError
200# define PyExc_KeyboardInterrupt imp_PyExc_KeyboardInterrupt
201# define PyExc_TypeError imp_PyExc_TypeError
202# define PyExc_ValueError imp_PyExc_ValueError
203
204/*
205 * Table of name to function pointer of python.
206 */
207# define PYTHON_PROC FARPROC
208static struct
209{
210 char *name;
211 PYTHON_PROC *ptr;
212} python_funcname_table[] =
213{
214 {"PyArg_Parse", (PYTHON_PROC*)&dll_PyArg_Parse},
215 {"PyArg_ParseTuple", (PYTHON_PROC*)&dll_PyArg_ParseTuple},
216 {"PyDict_SetItemString", (PYTHON_PROC*)&dll_PyDict_SetItemString},
217 {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument},
218 {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear},
219 {"PyErr_NoMemory", (PYTHON_PROC*)&dll_PyErr_NoMemory},
220 {"PyErr_Occurred", (PYTHON_PROC*)&dll_PyErr_Occurred},
221 {"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone},
222 {"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString},
223 {"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads},
224 {"PyEval_RestoreThread", (PYTHON_PROC*)&dll_PyEval_RestoreThread},
225 {"PyEval_SaveThread", (PYTHON_PROC*)&dll_PyEval_SaveThread},
226# ifdef PY_CAN_RECURSE
227 {"PyGILState_Ensure", (PYTHON_PROC*)&dll_PyGILState_Ensure},
228 {"PyGILState_Release", (PYTHON_PROC*)&dll_PyGILState_Release},
229# endif
230 {"PyInt_AsLong", (PYTHON_PROC*)&dll_PyInt_AsLong},
231 {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong},
232 {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type},
233 {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000234 {"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000235 {"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
236 {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
237 {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
238 {"PyList_Type", (PYTHON_PROC*)&dll_PyList_Type},
239 {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule},
240 {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString},
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000241 {"PyDict_New", (PYTHON_PROC*)&dll_PyDict_New},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000242 {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
243 {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
244 {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
245 {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
246 {"PyString_FromStringAndSize", (PYTHON_PROC*)&dll_PyString_FromStringAndSize},
247 {"PyString_Size", (PYTHON_PROC*)&dll_PyString_Size},
248 {"PyString_Type", (PYTHON_PROC*)&dll_PyString_Type},
249 {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
250 {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
251 {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
252 {"Py_BuildValue", (PYTHON_PROC*)&dll_Py_BuildValue},
253 {"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod},
254 {"Py_InitModule4", (PYTHON_PROC*)&dll_Py_InitModule4},
255 {"Py_Initialize", (PYTHON_PROC*)&dll_Py_Initialize},
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000256 {"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
257 {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000258 {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
259 {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
260 {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct},
261# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
262 {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype},
263# endif
264# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
265 {"PyObject_Malloc", (PYTHON_PROC*)&dll_PyObject_Malloc},
266 {"PyObject_Free", (PYTHON_PROC*)&dll_PyObject_Free},
267# endif
268 {"", NULL},
269};
270
271/*
272 * Free python.dll
273 */
274 static void
275end_dynamic_python(void)
276{
277 if (hinstPython)
278 {
279 FreeLibrary(hinstPython);
280 hinstPython = 0;
281 }
282}
283
284/*
285 * Load library and get all pointers.
286 * Parameter 'libname' provides name of DLL.
287 * Return OK or FAIL.
288 */
289 static int
290python_runtime_link_init(char *libname, int verbose)
291{
292 int i;
293
294 if (hinstPython)
295 return OK;
296 hinstPython = LoadLibrary(libname);
297 if (!hinstPython)
298 {
299 if (verbose)
300 EMSG2(_(e_loadlib), libname);
301 return FAIL;
302 }
303
304 for (i = 0; python_funcname_table[i].ptr; ++i)
305 {
306 if ((*python_funcname_table[i].ptr = GetProcAddress(hinstPython,
307 python_funcname_table[i].name)) == NULL)
308 {
309 FreeLibrary(hinstPython);
310 hinstPython = 0;
311 if (verbose)
312 EMSG2(_(e_loadfunc), python_funcname_table[i].name);
313 return FAIL;
314 }
315 }
316 return OK;
317}
318
319/*
320 * If python is enabled (there is installed python on Windows system) return
321 * TRUE, else FALSE.
322 */
323 int
324python_enabled(verbose)
325 int verbose;
326{
327 return python_runtime_link_init(DYNAMIC_PYTHON_DLL, verbose) == OK;
328}
329
330/* Load the standard Python exceptions - don't import the symbols from the
331 * DLL, as this can cause errors (importing data symbols is not reliable).
332 */
333static void get_exceptions __ARGS((void));
334
335 static void
336get_exceptions()
337{
338 PyObject *exmod = PyImport_ImportModule("exceptions");
339 PyObject *exdict = PyModule_GetDict(exmod);
340 imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
341 imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
342 imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
343 imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
344 imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
345 Py_XINCREF(imp_PyExc_AttributeError);
346 Py_XINCREF(imp_PyExc_IndexError);
347 Py_XINCREF(imp_PyExc_KeyboardInterrupt);
348 Py_XINCREF(imp_PyExc_TypeError);
349 Py_XINCREF(imp_PyExc_ValueError);
350 Py_XDECREF(exmod);
351}
352#endif /* DYNAMIC_PYTHON */
353
354/******************************************************
355 * Internal function prototypes.
356 */
357
358static void DoPythonCommand(exarg_T *, const char *);
359static int RangeStart;
360static int RangeEnd;
361
362static void PythonIO_Flush(void);
363static int PythonIO_Init(void);
364static int PythonMod_Init(void);
365
366/* Utility functions for the vim/python interface
367 * ----------------------------------------------
368 */
369static PyObject *GetBufferLine(buf_T *, int);
370static PyObject *GetBufferLineList(buf_T *, int, int);
371
372static int SetBufferLine(buf_T *, int, PyObject *, int *);
373static int SetBufferLineList(buf_T *, int, int, PyObject *, int *);
374static int InsertBufferLines(buf_T *, int, PyObject *, int *);
375
376static PyObject *LineToString(const char *);
377static char *StringToLine(PyObject *);
378
379static int VimErrorCheck(void);
380
381#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
382
383/******************************************************
384 * 1. Python interpreter main program.
385 */
386
387static int initialised = 0;
388
389#if PYTHON_API_VERSION < 1007 /* Python 1.4 */
390typedef PyObject PyThreadState;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000391#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000392
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000393#ifdef PY_CAN_RECURSE
394static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
395#else
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000396static PyThreadState *saved_python_thread = NULL;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000397#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000398
399/*
400 * Suspend a thread of the Python interpreter, other threads are allowed to
401 * run.
402 */
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000403 static void
404Python_SaveThread(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000405{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000406#ifdef PY_CAN_RECURSE
407 PyGILState_Release(pygilstate);
408#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000409 saved_python_thread = PyEval_SaveThread();
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000410#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000411}
412
413/*
414 * Restore a thread of the Python interpreter, waits for other threads to
415 * block.
416 */
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000417 static void
418Python_RestoreThread(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000419{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000420#ifdef PY_CAN_RECURSE
421 pygilstate = PyGILState_Ensure();
422#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000423 PyEval_RestoreThread(saved_python_thread);
424 saved_python_thread = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000425#endif
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000426}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000427
428/*
429 * obtain a lock on the Vim data structures
430 */
431static void Python_Lock_Vim(void)
432{
433}
434
435/*
436 * release a lock on the Vim data structures
437 */
438static void Python_Release_Vim(void)
439{
440}
441
442 void
443python_end()
444{
Bram Moolenaara5792f52005-11-23 21:25:05 +0000445 static int recurse = 0;
446
447 /* If a crash occurs while doing this, don't try again. */
448 if (recurse != 0)
449 return;
450
451 ++recurse;
452
Bram Moolenaar071d4272004-06-13 20:20:40 +0000453#ifdef DYNAMIC_PYTHON
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000454 if (hinstPython && Py_IsInitialized())
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000455 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000456 Python_RestoreThread(); /* enter python */
457 Py_Finalize();
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000458 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000459 end_dynamic_python();
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000460#else
461 if (Py_IsInitialized())
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000462 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000463 Python_RestoreThread(); /* enter python */
464 Py_Finalize();
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000465 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000466#endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000467
468 --recurse;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000469}
470
471 static int
472Python_Init(void)
473{
474 if (!initialised)
475 {
476#ifdef DYNAMIC_PYTHON
477 if (!python_enabled(TRUE))
478 {
479 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
480 goto fail;
481 }
482#endif
483
484#if !defined(MACOS) || defined(MACOS_X_UNIX)
485 Py_Initialize();
486#else
487 PyMac_Initialize();
488#endif
489 /* initialise threads */
490 PyEval_InitThreads();
491
492#ifdef DYNAMIC_PYTHON
493 get_exceptions();
494#endif
495
496 if (PythonIO_Init())
497 goto fail;
498
499 if (PythonMod_Init())
500 goto fail;
501
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000502 /* the first python thread is vim's, release the lock */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000503 Python_SaveThread();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000504
505 initialised = 1;
506 }
507
508 return 0;
509
510fail:
511 /* We call PythonIO_Flush() here to print any Python errors.
512 * This is OK, as it is possible to call this function even
513 * if PythonIO_Init() has not completed successfully (it will
514 * not do anything in this case).
515 */
516 PythonIO_Flush();
517 return -1;
518}
519
520/*
521 * External interface
522 */
523 static void
524DoPythonCommand(exarg_T *eap, const char *cmd)
525{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000526#ifndef PY_CAN_RECURSE
Bram Moolenaar071d4272004-06-13 20:20:40 +0000527 static int recursive = 0;
528#endif
529#if defined(MACOS) && !defined(MACOS_X_UNIX)
530 GrafPtr oldPort;
531#endif
532#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
533 char *saved_locale;
534#endif
535
536#ifndef PY_CAN_RECURSE
537 if (recursive)
538 {
539 EMSG(_("E659: Cannot invoke Python recursively"));
540 return;
541 }
542 ++recursive;
543#endif
544
545#if defined(MACOS) && !defined(MACOS_X_UNIX)
546 GetPort(&oldPort);
547 /* Check if the Python library is available */
548 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
549 goto theend;
550#endif
551 if (Python_Init())
552 goto theend;
553
554 RangeStart = eap->line1;
555 RangeEnd = eap->line2;
556 Python_Release_Vim(); /* leave vim */
557
558#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
559 /* Python only works properly when the LC_NUMERIC locale is "C". */
560 saved_locale = setlocale(LC_NUMERIC, NULL);
561 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
562 saved_locale = NULL;
563 else
564 {
565 /* Need to make a copy, value may change when setting new locale. */
566 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
567 (void)setlocale(LC_NUMERIC, "C");
568 }
569#endif
570
Bram Moolenaar071d4272004-06-13 20:20:40 +0000571 Python_RestoreThread(); /* enter python */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000572
573 PyRun_SimpleString((char *)(cmd));
574
Bram Moolenaar071d4272004-06-13 20:20:40 +0000575 Python_SaveThread(); /* leave python */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000576
577#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
578 if (saved_locale != NULL)
579 {
580 (void)setlocale(LC_NUMERIC, saved_locale);
581 vim_free(saved_locale);
582 }
583#endif
584
585 Python_Lock_Vim(); /* enter vim */
586 PythonIO_Flush();
587#if defined(MACOS) && !defined(MACOS_X_UNIX)
588 SetPort(oldPort);
589#endif
590
591theend:
592#ifndef PY_CAN_RECURSE
593 --recursive;
594#endif
595 return; /* keeps lint happy */
596}
597
598/*
599 * ":python"
600 */
601 void
602ex_python(exarg_T *eap)
603{
604 char_u *script;
605
606 script = script_get(eap, eap->arg);
607 if (!eap->skip)
608 {
609 if (script == NULL)
610 DoPythonCommand(eap, (char *)eap->arg);
611 else
612 DoPythonCommand(eap, (char *)script);
613 }
614 vim_free(script);
615}
616
617#define BUFFER_SIZE 1024
618
619/*
620 * ":pyfile"
621 */
622 void
623ex_pyfile(exarg_T *eap)
624{
625 static char buffer[BUFFER_SIZE];
626 const char *file = (char *)eap->arg;
627 char *p;
628
629 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
630 * stdio file pointer, but Vim and the Python DLL are compiled with
631 * different options under Windows, meaning that stdio pointers aren't
632 * compatible between the two. Yuk.
633 *
634 * Put the string "execfile('file')" into buffer. But, we need to
635 * escape any backslashes or single quotes in the file name, so that
636 * Python won't mangle the file name.
637 */
638 strcpy(buffer, "execfile('");
639 p = buffer + 10; /* size of "execfile('" */
640
641 while (*file && p < buffer + (BUFFER_SIZE - 3))
642 {
643 if (*file == '\\' || *file == '\'')
644 *p++ = '\\';
645 *p++ = *file++;
646 }
647
648 /* If we didn't finish the file name, we hit a buffer overflow */
649 if (*file != '\0')
650 return;
651
652 /* Put in the terminating "')" and a null */
653 *p++ = '\'';
654 *p++ = ')';
655 *p++ = '\0';
656
657 /* Execute the file */
658 DoPythonCommand(eap, buffer);
659}
660
661/******************************************************
662 * 2. Python output stream: writes output via [e]msg().
663 */
664
665/* Implementation functions
666 */
667
668static PyObject *OutputGetattr(PyObject *, char *);
669static int OutputSetattr(PyObject *, char *, PyObject *);
670
671static PyObject *OutputWrite(PyObject *, PyObject *);
672static PyObject *OutputWritelines(PyObject *, PyObject *);
673
674typedef void (*writefn)(char_u *);
675static void writer(writefn fn, char_u *str, int n);
676
677/* Output object definition
678 */
679
680typedef struct
681{
682 PyObject_HEAD
683 long softspace;
684 long error;
685} OutputObject;
686
687static struct PyMethodDef OutputMethods[] = {
688 /* name, function, calling, documentation */
689 {"write", OutputWrite, 1, "" },
690 {"writelines", OutputWritelines, 1, "" },
691 { NULL, NULL, 0, NULL }
692};
693
694static PyTypeObject OutputType = {
695 PyObject_HEAD_INIT(0)
696 0,
697 "message",
698 sizeof(OutputObject),
699 0,
700
701 (destructor) 0,
702 (printfunc) 0,
703 (getattrfunc) OutputGetattr,
704 (setattrfunc) OutputSetattr,
705 (cmpfunc) 0,
706 (reprfunc) 0,
707
708 0, /* as number */
709 0, /* as sequence */
710 0, /* as mapping */
711
712 (hashfunc) 0,
713 (ternaryfunc) 0,
714 (reprfunc) 0
715};
716
717/*************/
718
719 static PyObject *
720OutputGetattr(PyObject *self, char *name)
721{
722 if (strcmp(name, "softspace") == 0)
723 return PyInt_FromLong(((OutputObject *)(self))->softspace);
724
725 return Py_FindMethod(OutputMethods, self, name);
726}
727
728 static int
729OutputSetattr(PyObject *self, char *name, PyObject *val)
730{
731 if (val == NULL) {
732 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
733 return -1;
734 }
735
736 if (strcmp(name, "softspace") == 0)
737 {
738 if (!PyInt_Check(val)) {
739 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
740 return -1;
741 }
742
743 ((OutputObject *)(self))->softspace = PyInt_AsLong(val);
744 return 0;
745 }
746
747 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
748 return -1;
749}
750
751/*************/
752
753 static PyObject *
754OutputWrite(PyObject *self, PyObject *args)
755{
756 int len;
757 char *str;
758 int error = ((OutputObject *)(self))->error;
759
760 if (!PyArg_ParseTuple(args, "s#", &str, &len))
761 return NULL;
762
763 Py_BEGIN_ALLOW_THREADS
764 Python_Lock_Vim();
765 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
766 Python_Release_Vim();
767 Py_END_ALLOW_THREADS
768
769 Py_INCREF(Py_None);
770 return Py_None;
771}
772
773 static PyObject *
774OutputWritelines(PyObject *self, PyObject *args)
775{
776 int n;
777 int i;
778 PyObject *list;
779 int error = ((OutputObject *)(self))->error;
780
781 if (!PyArg_ParseTuple(args, "O", &list))
782 return NULL;
783 Py_INCREF(list);
784
785 if (!PyList_Check(list)) {
786 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
787 Py_DECREF(list);
788 return NULL;
789 }
790
791 n = PyList_Size(list);
792
793 for (i = 0; i < n; ++i)
794 {
795 PyObject *line = PyList_GetItem(list, i);
796 char *str;
797 int len;
798
799 if (!PyArg_Parse(line, "s#", &str, &len)) {
800 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
801 Py_DECREF(list);
802 return NULL;
803 }
804
805 Py_BEGIN_ALLOW_THREADS
806 Python_Lock_Vim();
807 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
808 Python_Release_Vim();
809 Py_END_ALLOW_THREADS
810 }
811
812 Py_DECREF(list);
813 Py_INCREF(Py_None);
814 return Py_None;
815}
816
817/* Output buffer management
818 */
819
820static char_u *buffer = NULL;
821static int buffer_len = 0;
822static int buffer_size = 0;
823
824static writefn old_fn = NULL;
825
826 static void
827buffer_ensure(int n)
828{
829 int new_size;
830 char_u *new_buffer;
831
832 if (n < buffer_size)
833 return;
834
835 new_size = buffer_size;
836 while (new_size < n)
837 new_size += 80;
838
839 if (new_size != buffer_size)
840 {
841 new_buffer = alloc((unsigned)new_size);
842 if (new_buffer == NULL)
843 return;
844
845 if (buffer)
846 {
847 memcpy(new_buffer, buffer, buffer_len);
848 vim_free(buffer);
849 }
850
851 buffer = new_buffer;
852 buffer_size = new_size;
853 }
854}
855
856 static void
857PythonIO_Flush(void)
858{
859 if (old_fn && buffer_len)
860 {
861 buffer[buffer_len] = 0;
862 old_fn(buffer);
863 }
864
865 buffer_len = 0;
866}
867
868 static void
869writer(writefn fn, char_u *str, int n)
870{
871 char_u *ptr;
872
873 if (fn != old_fn && old_fn != NULL)
874 PythonIO_Flush();
875
876 old_fn = fn;
877
878 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
879 {
880 int len = ptr - str;
881
882 buffer_ensure(buffer_len + len + 1);
883
884 memcpy(buffer + buffer_len, str, len);
885 buffer_len += len;
886 buffer[buffer_len] = 0;
887 fn(buffer);
888 str = ptr + 1;
889 n -= len + 1;
890 buffer_len = 0;
891 }
892
893 /* Put the remaining text into the buffer for later printing */
894 buffer_ensure(buffer_len + n + 1);
895 memcpy(buffer + buffer_len, str, n);
896 buffer_len += n;
897}
898
899/***************/
900
901static OutputObject Output =
902{
903 PyObject_HEAD_INIT(&OutputType)
904 0,
905 0
906};
907
908static OutputObject Error =
909{
910 PyObject_HEAD_INIT(&OutputType)
911 0,
912 1
913};
914
915 static int
916PythonIO_Init(void)
917{
918 /* Fixups... */
919 OutputType.ob_type = &PyType_Type;
920
Bram Moolenaar7df2d662005-01-25 22:18:08 +0000921 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
922 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000923
924 if (PyErr_Occurred())
925 {
926 EMSG(_("E264: Python: Error initialising I/O objects"));
927 return -1;
928 }
929
930 return 0;
931}
932
933/******************************************************
934 * 3. Implementation of the Vim module for Python
935 */
936
937/* Vim module - Implementation functions
938 * -------------------------------------
939 */
940
941static PyObject *VimError;
942
943static PyObject *VimCommand(PyObject *, PyObject *);
944static PyObject *VimEval(PyObject *, PyObject *);
945
946/* Window type - Implementation functions
947 * --------------------------------------
948 */
949
950typedef struct
951{
952 PyObject_HEAD
953 win_T *win;
954}
955WindowObject;
956
957#define INVALID_WINDOW_VALUE ((win_T *)(-1))
958
959#define WindowType_Check(obj) ((obj)->ob_type == &WindowType)
960
961static PyObject *WindowNew(win_T *);
962
963static void WindowDestructor(PyObject *);
964static PyObject *WindowGetattr(PyObject *, char *);
965static int WindowSetattr(PyObject *, char *, PyObject *);
966static PyObject *WindowRepr(PyObject *);
967
968/* Buffer type - Implementation functions
969 * --------------------------------------
970 */
971
972typedef struct
973{
974 PyObject_HEAD
975 buf_T *buf;
976}
977BufferObject;
978
979#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
980
981#define BufferType_Check(obj) ((obj)->ob_type == &BufferType)
982
983static PyObject *BufferNew (buf_T *);
984
985static void BufferDestructor(PyObject *);
986static PyObject *BufferGetattr(PyObject *, char *);
987static PyObject *BufferRepr(PyObject *);
988
989static int BufferLength(PyObject *);
990static PyObject *BufferItem(PyObject *, int);
991static PyObject *BufferSlice(PyObject *, int, int);
992static int BufferAssItem(PyObject *, int, PyObject *);
993static int BufferAssSlice(PyObject *, int, int, PyObject *);
994
995static PyObject *BufferAppend(PyObject *, PyObject *);
996static PyObject *BufferMark(PyObject *, PyObject *);
997static PyObject *BufferRange(PyObject *, PyObject *);
998
999/* Line range type - Implementation functions
1000 * --------------------------------------
1001 */
1002
1003typedef struct
1004{
1005 PyObject_HEAD
1006 BufferObject *buf;
1007 int start;
1008 int end;
1009}
1010RangeObject;
1011
1012#define RangeType_Check(obj) ((obj)->ob_type == &RangeType)
1013
1014static PyObject *RangeNew(buf_T *, int, int);
1015
1016static void RangeDestructor(PyObject *);
1017static PyObject *RangeGetattr(PyObject *, char *);
1018static PyObject *RangeRepr(PyObject *);
1019
1020static int RangeLength(PyObject *);
1021static PyObject *RangeItem(PyObject *, int);
1022static PyObject *RangeSlice(PyObject *, int, int);
1023static int RangeAssItem(PyObject *, int, PyObject *);
1024static int RangeAssSlice(PyObject *, int, int, PyObject *);
1025
1026static PyObject *RangeAppend(PyObject *, PyObject *);
1027
1028/* Window list type - Implementation functions
1029 * -------------------------------------------
1030 */
1031
1032static int WinListLength(PyObject *);
1033static PyObject *WinListItem(PyObject *, int);
1034
1035/* Buffer list type - Implementation functions
1036 * -------------------------------------------
1037 */
1038
1039static int BufListLength(PyObject *);
1040static PyObject *BufListItem(PyObject *, int);
1041
1042/* Current objects type - Implementation functions
1043 * -----------------------------------------------
1044 */
1045
1046static PyObject *CurrentGetattr(PyObject *, char *);
1047static int CurrentSetattr(PyObject *, char *, PyObject *);
1048
1049/* Vim module - Definitions
1050 */
1051
1052static struct PyMethodDef VimMethods[] = {
1053 /* name, function, calling, documentation */
1054 {"command", VimCommand, 1, "" },
1055 {"eval", VimEval, 1, "" },
1056 { NULL, NULL, 0, NULL }
1057};
1058
1059/* Vim module - Implementation
1060 */
1061/*ARGSUSED*/
1062 static PyObject *
1063VimCommand(PyObject *self, PyObject *args)
1064{
1065 char *cmd;
1066 PyObject *result;
1067
1068 if (!PyArg_ParseTuple(args, "s", &cmd))
1069 return NULL;
1070
1071 PyErr_Clear();
1072
1073 Py_BEGIN_ALLOW_THREADS
1074 Python_Lock_Vim();
1075
1076 do_cmdline_cmd((char_u *)cmd);
1077 update_screen(VALID);
1078
1079 Python_Release_Vim();
1080 Py_END_ALLOW_THREADS
1081
1082 if (VimErrorCheck())
1083 result = NULL;
1084 else
1085 result = Py_None;
1086
1087 Py_XINCREF(result);
1088 return result;
1089}
1090
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001091/*
1092 * Function to translate a typval_T into a PyObject; this will recursively
1093 * translate lists/dictionaries into their Python equivalents.
1094 *
1095 * The depth parameter is too avoid infinite recursion, set it to 1 when
1096 * you call VimToPython.
1097 */
1098 static PyObject *
1099VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
1100{
1101 PyObject *result;
1102 PyObject *newObj;
1103 char ptrBuf[NUMBUFLEN];
1104
1105 /* Avoid infinite recursion */
1106 if (depth > 100)
1107 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001108 Py_INCREF(Py_None);
1109 result = Py_None;
1110 return result;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001111 }
1112
1113 /* Check if we run into a recursive loop. The item must be in lookupDict
1114 * then and we can use it again. */
1115 sprintf(ptrBuf, "%ld", (long)our_tv);
1116 result = PyDict_GetItemString(lookupDict, ptrBuf);
1117 if (result != NULL)
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001118 Py_INCREF(result);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001119 else if (our_tv->v_type == VAR_STRING)
1120 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001121 result = Py_BuildValue("s", our_tv->vval.v_string);
1122 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001123 }
1124 else if (our_tv->v_type == VAR_NUMBER)
1125 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001126 char buf[NUMBUFLEN];
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001127
1128 /* For backwards compatibility numbers are stored as strings. */
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001129 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
1130 result = Py_BuildValue("s", buf);
1131 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001132 }
1133 else if (our_tv->v_type == VAR_LIST)
1134 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001135 list_T *list = our_tv->vval.v_list;
1136 listitem_T *curr;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001137
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001138 result = PyList_New(0);
1139 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001140
1141 if (list != NULL)
1142 {
1143 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
1144 {
1145 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
1146 PyList_Append(result, newObj);
1147 Py_DECREF(newObj);
1148 }
1149 }
1150 }
1151 else if (our_tv->v_type == VAR_DICT)
1152 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001153 result = PyDict_New();
1154 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001155
1156 if (our_tv->vval.v_dict != NULL)
1157 {
1158 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
1159 int todo = ht->ht_used;
1160 hashitem_T *hi;
1161 dictitem_T *di;
1162
1163 for (hi = ht->ht_array; todo > 0; ++hi)
1164 {
1165 if (!HASHITEM_EMPTY(hi))
1166 {
1167 --todo;
1168
1169 di = dict_lookup(hi);
1170 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
1171 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
1172 Py_DECREF(newObj);
1173 }
1174 }
1175 }
1176 }
1177 else
1178 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001179 Py_INCREF(Py_None);
1180 result = Py_None;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001181 }
1182
1183 return result;
1184}
1185
Bram Moolenaar071d4272004-06-13 20:20:40 +00001186/*ARGSUSED*/
1187 static PyObject *
1188VimEval(PyObject *self, PyObject *args)
1189{
1190#ifdef FEAT_EVAL
1191 char *expr;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001192 typval_T *our_tv;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001193 PyObject *result;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001194 PyObject *lookup_dict;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001195
1196 if (!PyArg_ParseTuple(args, "s", &expr))
1197 return NULL;
1198
1199 Py_BEGIN_ALLOW_THREADS
1200 Python_Lock_Vim();
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001201 our_tv = eval_expr((char_u *)expr, NULL);
1202
Bram Moolenaar071d4272004-06-13 20:20:40 +00001203 Python_Release_Vim();
1204 Py_END_ALLOW_THREADS
1205
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001206 if (our_tv == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001207 {
1208 PyErr_SetVim(_("invalid expression"));
1209 return NULL;
1210 }
1211
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001212 /* Convert the Vim type into a Python type. Create a dictionary that's
1213 * used to check for recursive loops. */
1214 lookup_dict = PyDict_New();
1215 result = VimToPython(our_tv, 1, lookup_dict);
1216 Py_DECREF(lookup_dict);
1217
Bram Moolenaar071d4272004-06-13 20:20:40 +00001218
1219 Py_BEGIN_ALLOW_THREADS
1220 Python_Lock_Vim();
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001221 free_tv(our_tv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001222 Python_Release_Vim();
1223 Py_END_ALLOW_THREADS
1224
1225 return result;
1226#else
1227 PyErr_SetVim(_("expressions disabled at compile time"));
1228 return NULL;
1229#endif
1230}
1231
1232/* Common routines for buffers and line ranges
1233 * -------------------------------------------
1234 */
1235 static int
1236CheckBuffer(BufferObject *this)
1237{
1238 if (this->buf == INVALID_BUFFER_VALUE)
1239 {
1240 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1241 return -1;
1242 }
1243
1244 return 0;
1245}
1246
1247 static PyObject *
1248RBItem(BufferObject *self, int n, int start, int end)
1249{
1250 if (CheckBuffer(self))
1251 return NULL;
1252
1253 if (n < 0 || n > end - start)
1254 {
1255 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1256 return NULL;
1257 }
1258
1259 return GetBufferLine(self->buf, n+start);
1260}
1261
1262 static PyObject *
1263RBSlice(BufferObject *self, int lo, int hi, int start, int end)
1264{
1265 int size;
1266
1267 if (CheckBuffer(self))
1268 return NULL;
1269
1270 size = end - start + 1;
1271
1272 if (lo < 0)
1273 lo = 0;
1274 else if (lo > size)
1275 lo = size;
1276 if (hi < 0)
1277 hi = 0;
1278 if (hi < lo)
1279 hi = lo;
1280 else if (hi > size)
1281 hi = size;
1282
1283 return GetBufferLineList(self->buf, lo+start, hi+start);
1284}
1285
1286 static int
1287RBAssItem(BufferObject *self, int n, PyObject *val, int start, int end, int *new_end)
1288{
1289 int len_change;
1290
1291 if (CheckBuffer(self))
1292 return -1;
1293
1294 if (n < 0 || n > end - start)
1295 {
1296 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1297 return -1;
1298 }
1299
1300 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1301 return -1;
1302
1303 if (new_end)
1304 *new_end = end + len_change;
1305
1306 return 0;
1307}
1308
1309 static int
1310RBAssSlice(BufferObject *self, int lo, int hi, PyObject *val, int start, int end, int *new_end)
1311{
1312 int size;
1313 int len_change;
1314
1315 /* Self must be a valid buffer */
1316 if (CheckBuffer(self))
1317 return -1;
1318
1319 /* Sort out the slice range */
1320 size = end - start + 1;
1321
1322 if (lo < 0)
1323 lo = 0;
1324 else if (lo > size)
1325 lo = size;
1326 if (hi < 0)
1327 hi = 0;
1328 if (hi < lo)
1329 hi = lo;
1330 else if (hi > size)
1331 hi = size;
1332
1333 if (SetBufferLineList(self->buf, lo+start, hi+start, val, &len_change) == FAIL)
1334 return -1;
1335
1336 if (new_end)
1337 *new_end = end + len_change;
1338
1339 return 0;
1340}
1341
1342 static PyObject *
1343RBAppend(BufferObject *self, PyObject *args, int start, int end, int *new_end)
1344{
1345 PyObject *lines;
1346 int len_change;
1347 int max;
1348 int n;
1349
1350 if (CheckBuffer(self))
1351 return NULL;
1352
1353 max = n = end - start + 1;
1354
1355 if (!PyArg_ParseTuple(args, "O|i", &lines, &n))
1356 return NULL;
1357
1358 if (n < 0 || n > max)
1359 {
1360 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1361 return NULL;
1362 }
1363
1364 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
1365 return NULL;
1366
1367 if (new_end)
1368 *new_end = end + len_change;
1369
1370 Py_INCREF(Py_None);
1371 return Py_None;
1372}
1373
1374
1375/* Buffer object - Definitions
1376 */
1377
1378static struct PyMethodDef BufferMethods[] = {
1379 /* name, function, calling, documentation */
1380 {"append", BufferAppend, 1, "" },
1381 {"mark", BufferMark, 1, "" },
1382 {"range", BufferRange, 1, "" },
1383 { NULL, NULL, 0, NULL }
1384};
1385
1386static PySequenceMethods BufferAsSeq = {
1387 (inquiry) BufferLength, /* sq_length, len(x) */
1388 (binaryfunc) 0, /* BufferConcat, */ /* sq_concat, x+y */
1389 (intargfunc) 0, /* BufferRepeat, */ /* sq_repeat, x*n */
1390 (intargfunc) BufferItem, /* sq_item, x[i] */
1391 (intintargfunc) BufferSlice, /* sq_slice, x[i:j] */
1392 (intobjargproc) BufferAssItem, /* sq_ass_item, x[i]=v */
1393 (intintobjargproc) BufferAssSlice, /* sq_ass_slice, x[i:j]=v */
1394};
1395
1396static PyTypeObject BufferType = {
1397 PyObject_HEAD_INIT(0)
1398 0,
1399 "buffer",
1400 sizeof(BufferObject),
1401 0,
1402
1403 (destructor) BufferDestructor, /* tp_dealloc, refcount==0 */
1404 (printfunc) 0, /* tp_print, print x */
1405 (getattrfunc) BufferGetattr, /* tp_getattr, x.attr */
1406 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1407 (cmpfunc) 0, /* tp_compare, x>y */
1408 (reprfunc) BufferRepr, /* tp_repr, `x`, print x */
1409
1410 0, /* as number */
1411 &BufferAsSeq, /* as sequence */
1412 0, /* as mapping */
1413
1414 (hashfunc) 0, /* tp_hash, dict(x) */
1415 (ternaryfunc) 0, /* tp_call, x() */
1416 (reprfunc) 0, /* tp_str, str(x) */
1417};
1418
1419/* Buffer object - Implementation
1420 */
1421
1422 static PyObject *
1423BufferNew(buf_T *buf)
1424{
1425 /* We need to handle deletion of buffers underneath us.
Bram Moolenaare344bea2005-09-01 20:46:49 +00001426 * If we add a "b_python_ref" field to the buf_T structure,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001427 * then we can get at it in buf_freeall() in vim. We then
1428 * need to create only ONE Python object per buffer - if
1429 * we try to create a second, just INCREF the existing one
1430 * and return it. The (single) Python object referring to
Bram Moolenaare344bea2005-09-01 20:46:49 +00001431 * the buffer is stored in "b_python_ref".
Bram Moolenaar071d4272004-06-13 20:20:40 +00001432 * Question: what to do on a buf_freeall(). We'll probably
1433 * have to either delete the Python object (DECREF it to
1434 * zero - a bad idea, as it leaves dangling refs!) or
1435 * set the buf_T * value to an invalid value (-1?), which
1436 * means we need checks in all access functions... Bah.
1437 */
1438
1439 BufferObject *self;
1440
Bram Moolenaare344bea2005-09-01 20:46:49 +00001441 if (buf->b_python_ref != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001442 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00001443 self = buf->b_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001444 Py_INCREF(self);
1445 }
1446 else
1447 {
1448 self = PyObject_NEW(BufferObject, &BufferType);
1449 if (self == NULL)
1450 return NULL;
1451 self->buf = buf;
Bram Moolenaare344bea2005-09-01 20:46:49 +00001452 buf->b_python_ref = self;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001453 }
1454
1455 return (PyObject *)(self);
1456}
1457
1458 static void
1459BufferDestructor(PyObject *self)
1460{
1461 BufferObject *this = (BufferObject *)(self);
1462
1463 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaare344bea2005-09-01 20:46:49 +00001464 this->buf->b_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001465
Bram Moolenaar658ada62006-10-03 13:02:36 +00001466 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001467}
1468
1469 static PyObject *
1470BufferGetattr(PyObject *self, char *name)
1471{
1472 BufferObject *this = (BufferObject *)(self);
1473
1474 if (CheckBuffer(this))
1475 return NULL;
1476
1477 if (strcmp(name, "name") == 0)
1478 return Py_BuildValue("s",this->buf->b_ffname);
1479 else if (strcmp(name, "number") == 0)
1480 return Py_BuildValue("i",this->buf->b_fnum);
1481 else if (strcmp(name,"__members__") == 0)
1482 return Py_BuildValue("[ss]", "name", "number");
1483 else
1484 return Py_FindMethod(BufferMethods, self, name);
1485}
1486
1487 static PyObject *
1488BufferRepr(PyObject *self)
1489{
Bram Moolenaar555b2802005-05-19 21:08:39 +00001490 static char repr[100];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001491 BufferObject *this = (BufferObject *)(self);
1492
1493 if (this->buf == INVALID_BUFFER_VALUE)
1494 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00001495 vim_snprintf(repr, 100, _("<buffer object (deleted) at %8lX>"),
1496 (long)(self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001497 return PyString_FromString(repr);
1498 }
1499 else
1500 {
1501 char *name = (char *)this->buf->b_fname;
1502 int len;
1503
1504 if (name == NULL)
1505 name = "";
1506 len = strlen(name);
1507
1508 if (len > 35)
1509 name = name + (35 - len);
1510
Bram Moolenaar555b2802005-05-19 21:08:39 +00001511 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001512
1513 return PyString_FromString(repr);
1514 }
1515}
1516
1517/******************/
1518
1519 static int
1520BufferLength(PyObject *self)
1521{
1522 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1523 if (CheckBuffer((BufferObject *)(self)))
1524 return -1; /* ??? */
1525
1526 return (((BufferObject *)(self))->buf->b_ml.ml_line_count);
1527}
1528
1529 static PyObject *
1530BufferItem(PyObject *self, int n)
1531{
1532 return RBItem((BufferObject *)(self), n, 1,
1533 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1534}
1535
1536 static PyObject *
1537BufferSlice(PyObject *self, int lo, int hi)
1538{
1539 return RBSlice((BufferObject *)(self), lo, hi, 1,
1540 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1541}
1542
1543 static int
1544BufferAssItem(PyObject *self, int n, PyObject *val)
1545{
1546 return RBAssItem((BufferObject *)(self), n, val, 1,
1547 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1548 NULL);
1549}
1550
1551 static int
1552BufferAssSlice(PyObject *self, int lo, int hi, PyObject *val)
1553{
1554 return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
1555 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1556 NULL);
1557}
1558
1559 static PyObject *
1560BufferAppend(PyObject *self, PyObject *args)
1561{
1562 return RBAppend((BufferObject *)(self), args, 1,
1563 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1564 NULL);
1565}
1566
1567 static PyObject *
1568BufferMark(PyObject *self, PyObject *args)
1569{
1570 pos_T *posp;
1571 char mark;
1572 buf_T *curbuf_save;
1573
1574 if (CheckBuffer((BufferObject *)(self)))
1575 return NULL;
1576
1577 if (!PyArg_ParseTuple(args, "c", &mark))
1578 return NULL;
1579
1580 curbuf_save = curbuf;
1581 curbuf = ((BufferObject *)(self))->buf;
1582 posp = getmark(mark, FALSE);
1583 curbuf = curbuf_save;
1584
1585 if (posp == NULL)
1586 {
1587 PyErr_SetVim(_("invalid mark name"));
1588 return NULL;
1589 }
1590
1591 /* Ckeck for keyboard interrupt */
1592 if (VimErrorCheck())
1593 return NULL;
1594
1595 if (posp->lnum <= 0)
1596 {
1597 /* Or raise an error? */
1598 Py_INCREF(Py_None);
1599 return Py_None;
1600 }
1601
1602 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1603}
1604
1605 static PyObject *
1606BufferRange(PyObject *self, PyObject *args)
1607{
1608 int start;
1609 int end;
1610
1611 if (CheckBuffer((BufferObject *)(self)))
1612 return NULL;
1613
1614 if (!PyArg_ParseTuple(args, "ii", &start, &end))
1615 return NULL;
1616
1617 return RangeNew(((BufferObject *)(self))->buf, start, end);
1618}
1619
1620/* Line range object - Definitions
1621 */
1622
1623static struct PyMethodDef RangeMethods[] = {
1624 /* name, function, calling, documentation */
1625 {"append", RangeAppend, 1, "" },
1626 { NULL, NULL, 0, NULL }
1627};
1628
1629static PySequenceMethods RangeAsSeq = {
1630 (inquiry) RangeLength, /* sq_length, len(x) */
1631 (binaryfunc) 0, /* RangeConcat, */ /* sq_concat, x+y */
1632 (intargfunc) 0, /* RangeRepeat, */ /* sq_repeat, x*n */
1633 (intargfunc) RangeItem, /* sq_item, x[i] */
1634 (intintargfunc) RangeSlice, /* sq_slice, x[i:j] */
1635 (intobjargproc) RangeAssItem, /* sq_ass_item, x[i]=v */
1636 (intintobjargproc) RangeAssSlice, /* sq_ass_slice, x[i:j]=v */
1637};
1638
1639static PyTypeObject RangeType = {
1640 PyObject_HEAD_INIT(0)
1641 0,
1642 "range",
1643 sizeof(RangeObject),
1644 0,
1645
1646 (destructor) RangeDestructor, /* tp_dealloc, refcount==0 */
1647 (printfunc) 0, /* tp_print, print x */
1648 (getattrfunc) RangeGetattr, /* tp_getattr, x.attr */
1649 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1650 (cmpfunc) 0, /* tp_compare, x>y */
1651 (reprfunc) RangeRepr, /* tp_repr, `x`, print x */
1652
1653 0, /* as number */
1654 &RangeAsSeq, /* as sequence */
1655 0, /* as mapping */
1656
1657 (hashfunc) 0, /* tp_hash, dict(x) */
1658 (ternaryfunc) 0, /* tp_call, x() */
1659 (reprfunc) 0, /* tp_str, str(x) */
1660};
1661
1662/* Line range object - Implementation
1663 */
1664
1665 static PyObject *
1666RangeNew(buf_T *buf, int start, int end)
1667{
1668 BufferObject *bufr;
1669 RangeObject *self;
1670 self = PyObject_NEW(RangeObject, &RangeType);
1671 if (self == NULL)
1672 return NULL;
1673
1674 bufr = (BufferObject *)BufferNew(buf);
1675 if (bufr == NULL)
1676 {
Bram Moolenaar658ada62006-10-03 13:02:36 +00001677 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001678 return NULL;
1679 }
1680 Py_INCREF(bufr);
1681
1682 self->buf = bufr;
1683 self->start = start;
1684 self->end = end;
1685
1686 return (PyObject *)(self);
1687}
1688
1689 static void
1690RangeDestructor(PyObject *self)
1691{
1692 Py_DECREF(((RangeObject *)(self))->buf);
Bram Moolenaar658ada62006-10-03 13:02:36 +00001693 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001694}
1695
1696 static PyObject *
1697RangeGetattr(PyObject *self, char *name)
1698{
1699 if (strcmp(name, "start") == 0)
1700 return Py_BuildValue("i",((RangeObject *)(self))->start - 1);
1701 else if (strcmp(name, "end") == 0)
1702 return Py_BuildValue("i",((RangeObject *)(self))->end - 1);
1703 else
1704 return Py_FindMethod(RangeMethods, self, name);
1705}
1706
1707 static PyObject *
1708RangeRepr(PyObject *self)
1709{
Bram Moolenaar555b2802005-05-19 21:08:39 +00001710 static char repr[100];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001711 RangeObject *this = (RangeObject *)(self);
1712
1713 if (this->buf->buf == INVALID_BUFFER_VALUE)
1714 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00001715 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %8lX>",
Bram Moolenaar071d4272004-06-13 20:20:40 +00001716 (long)(self));
1717 return PyString_FromString(repr);
1718 }
1719 else
1720 {
1721 char *name = (char *)this->buf->buf->b_fname;
1722 int len;
1723
1724 if (name == NULL)
1725 name = "";
1726 len = strlen(name);
1727
1728 if (len > 45)
1729 name = name + (45 - len);
1730
Bram Moolenaar555b2802005-05-19 21:08:39 +00001731 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
Bram Moolenaar071d4272004-06-13 20:20:40 +00001732 len > 45 ? "..." : "", name,
1733 this->start, this->end);
1734
1735 return PyString_FromString(repr);
1736 }
1737}
1738
1739/****************/
1740
1741 static int
1742RangeLength(PyObject *self)
1743{
1744 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1745 if (CheckBuffer(((RangeObject *)(self))->buf))
1746 return -1; /* ??? */
1747
1748 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1749}
1750
1751 static PyObject *
1752RangeItem(PyObject *self, int n)
1753{
1754 return RBItem(((RangeObject *)(self))->buf, n,
1755 ((RangeObject *)(self))->start,
1756 ((RangeObject *)(self))->end);
1757}
1758
1759 static PyObject *
1760RangeSlice(PyObject *self, int lo, int hi)
1761{
1762 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
1763 ((RangeObject *)(self))->start,
1764 ((RangeObject *)(self))->end);
1765}
1766
1767 static int
1768RangeAssItem(PyObject *self, int n, PyObject *val)
1769{
1770 return RBAssItem(((RangeObject *)(self))->buf, n, val,
1771 ((RangeObject *)(self))->start,
1772 ((RangeObject *)(self))->end,
1773 &((RangeObject *)(self))->end);
1774}
1775
1776 static int
1777RangeAssSlice(PyObject *self, int lo, int hi, PyObject *val)
1778{
1779 return RBAssSlice(((RangeObject *)(self))->buf, lo, hi, val,
1780 ((RangeObject *)(self))->start,
1781 ((RangeObject *)(self))->end,
1782 &((RangeObject *)(self))->end);
1783}
1784
1785 static PyObject *
1786RangeAppend(PyObject *self, PyObject *args)
1787{
1788 return RBAppend(((RangeObject *)(self))->buf, args,
1789 ((RangeObject *)(self))->start,
1790 ((RangeObject *)(self))->end,
1791 &((RangeObject *)(self))->end);
1792}
1793
1794/* Buffer list object - Definitions
1795 */
1796
1797typedef struct
1798{
1799 PyObject_HEAD
1800}
1801BufListObject;
1802
1803static PySequenceMethods BufListAsSeq = {
1804 (inquiry) BufListLength, /* sq_length, len(x) */
1805 (binaryfunc) 0, /* sq_concat, x+y */
1806 (intargfunc) 0, /* sq_repeat, x*n */
1807 (intargfunc) BufListItem, /* sq_item, x[i] */
1808 (intintargfunc) 0, /* sq_slice, x[i:j] */
1809 (intobjargproc) 0, /* sq_ass_item, x[i]=v */
1810 (intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
1811};
1812
1813static PyTypeObject BufListType = {
1814 PyObject_HEAD_INIT(0)
1815 0,
1816 "buffer list",
1817 sizeof(BufListObject),
1818 0,
1819
1820 (destructor) 0, /* tp_dealloc, refcount==0 */
1821 (printfunc) 0, /* tp_print, print x */
1822 (getattrfunc) 0, /* tp_getattr, x.attr */
1823 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1824 (cmpfunc) 0, /* tp_compare, x>y */
1825 (reprfunc) 0, /* tp_repr, `x`, print x */
1826
1827 0, /* as number */
1828 &BufListAsSeq, /* as sequence */
1829 0, /* as mapping */
1830
1831 (hashfunc) 0, /* tp_hash, dict(x) */
1832 (ternaryfunc) 0, /* tp_call, x() */
1833 (reprfunc) 0, /* tp_str, str(x) */
1834};
1835
1836/* Buffer list object - Implementation
1837 */
1838
1839/*ARGSUSED*/
1840 static int
1841BufListLength(PyObject *self)
1842{
1843 buf_T *b = firstbuf;
1844 int n = 0;
1845
1846 while (b)
1847 {
1848 ++n;
1849 b = b->b_next;
1850 }
1851
1852 return n;
1853}
1854
1855/*ARGSUSED*/
1856 static PyObject *
1857BufListItem(PyObject *self, int n)
1858{
1859 buf_T *b;
1860
1861 for (b = firstbuf; b; b = b->b_next, --n)
1862 {
1863 if (n == 0)
1864 return BufferNew(b);
1865 }
1866
1867 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1868 return NULL;
1869}
1870
1871/* Window object - Definitions
1872 */
1873
1874static struct PyMethodDef WindowMethods[] = {
1875 /* name, function, calling, documentation */
1876 { NULL, NULL, 0, NULL }
1877};
1878
1879static PyTypeObject WindowType = {
1880 PyObject_HEAD_INIT(0)
1881 0,
1882 "window",
1883 sizeof(WindowObject),
1884 0,
1885
1886 (destructor) WindowDestructor, /* tp_dealloc, refcount==0 */
1887 (printfunc) 0, /* tp_print, print x */
1888 (getattrfunc) WindowGetattr, /* tp_getattr, x.attr */
1889 (setattrfunc) WindowSetattr, /* tp_setattr, x.attr=v */
1890 (cmpfunc) 0, /* tp_compare, x>y */
1891 (reprfunc) WindowRepr, /* tp_repr, `x`, print x */
1892
1893 0, /* as number */
1894 0, /* as sequence */
1895 0, /* as mapping */
1896
1897 (hashfunc) 0, /* tp_hash, dict(x) */
1898 (ternaryfunc) 0, /* tp_call, x() */
1899 (reprfunc) 0, /* tp_str, str(x) */
1900};
1901
1902/* Window object - Implementation
1903 */
1904
1905 static PyObject *
1906WindowNew(win_T *win)
1907{
1908 /* We need to handle deletion of windows underneath us.
Bram Moolenaare344bea2005-09-01 20:46:49 +00001909 * If we add a "w_python_ref" field to the win_T structure,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001910 * then we can get at it in win_free() in vim. We then
1911 * need to create only ONE Python object per window - if
1912 * we try to create a second, just INCREF the existing one
1913 * and return it. The (single) Python object referring to
Bram Moolenaare344bea2005-09-01 20:46:49 +00001914 * the window is stored in "w_python_ref".
Bram Moolenaar071d4272004-06-13 20:20:40 +00001915 * On a win_free() we set the Python object's win_T* field
1916 * to an invalid value. We trap all uses of a window
1917 * object, and reject them if the win_T* field is invalid.
1918 */
1919
1920 WindowObject *self;
1921
Bram Moolenaare344bea2005-09-01 20:46:49 +00001922 if (win->w_python_ref)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001923 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00001924 self = win->w_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001925 Py_INCREF(self);
1926 }
1927 else
1928 {
1929 self = PyObject_NEW(WindowObject, &WindowType);
1930 if (self == NULL)
1931 return NULL;
1932 self->win = win;
Bram Moolenaare344bea2005-09-01 20:46:49 +00001933 win->w_python_ref = self;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001934 }
1935
1936 return (PyObject *)(self);
1937}
1938
1939 static void
1940WindowDestructor(PyObject *self)
1941{
1942 WindowObject *this = (WindowObject *)(self);
1943
1944 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaare344bea2005-09-01 20:46:49 +00001945 this->win->w_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001946
Bram Moolenaar658ada62006-10-03 13:02:36 +00001947 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001948}
1949
1950 static int
1951CheckWindow(WindowObject *this)
1952{
1953 if (this->win == INVALID_WINDOW_VALUE)
1954 {
1955 PyErr_SetVim(_("attempt to refer to deleted window"));
1956 return -1;
1957 }
1958
1959 return 0;
1960}
1961
1962 static PyObject *
1963WindowGetattr(PyObject *self, char *name)
1964{
1965 WindowObject *this = (WindowObject *)(self);
1966
1967 if (CheckWindow(this))
1968 return NULL;
1969
1970 if (strcmp(name, "buffer") == 0)
1971 return (PyObject *)BufferNew(this->win->w_buffer);
1972 else if (strcmp(name, "cursor") == 0)
1973 {
1974 pos_T *pos = &this->win->w_cursor;
1975
1976 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
1977 }
1978 else if (strcmp(name, "height") == 0)
1979 return Py_BuildValue("l", (long)(this->win->w_height));
1980#ifdef FEAT_VERTSPLIT
1981 else if (strcmp(name, "width") == 0)
1982 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
1983#endif
1984 else if (strcmp(name,"__members__") == 0)
1985 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
1986 else
1987 return Py_FindMethod(WindowMethods, self, name);
1988}
1989
1990 static int
1991WindowSetattr(PyObject *self, char *name, PyObject *val)
1992{
1993 WindowObject *this = (WindowObject *)(self);
1994
1995 if (CheckWindow(this))
1996 return -1;
1997
1998 if (strcmp(name, "buffer") == 0)
1999 {
2000 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2001 return -1;
2002 }
2003 else if (strcmp(name, "cursor") == 0)
2004 {
2005 long lnum;
2006 long col;
2007
2008 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2009 return -1;
2010
2011 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
2012 {
2013 PyErr_SetVim(_("cursor position outside buffer"));
2014 return -1;
2015 }
2016
2017 /* Check for keyboard interrupts */
2018 if (VimErrorCheck())
2019 return -1;
2020
2021 /* NO CHECK ON COLUMN - SEEMS NOT TO MATTER */
2022
2023 this->win->w_cursor.lnum = lnum;
2024 this->win->w_cursor.col = col;
2025 update_screen(VALID);
2026
2027 return 0;
2028 }
2029 else if (strcmp(name, "height") == 0)
2030 {
2031 int height;
2032 win_T *savewin;
2033
2034 if (!PyArg_Parse(val, "i", &height))
2035 return -1;
2036
2037#ifdef FEAT_GUI
2038 need_mouse_correct = TRUE;
2039#endif
2040 savewin = curwin;
2041 curwin = this->win;
2042 win_setheight(height);
2043 curwin = savewin;
2044
2045 /* Check for keyboard interrupts */
2046 if (VimErrorCheck())
2047 return -1;
2048
2049 return 0;
2050 }
2051#ifdef FEAT_VERTSPLIT
2052 else if (strcmp(name, "width") == 0)
2053 {
2054 int width;
2055 win_T *savewin;
2056
2057 if (!PyArg_Parse(val, "i", &width))
2058 return -1;
2059
2060#ifdef FEAT_GUI
2061 need_mouse_correct = TRUE;
2062#endif
2063 savewin = curwin;
2064 curwin = this->win;
2065 win_setwidth(width);
2066 curwin = savewin;
2067
2068 /* Check for keyboard interrupts */
2069 if (VimErrorCheck())
2070 return -1;
2071
2072 return 0;
2073 }
2074#endif
2075 else
2076 {
2077 PyErr_SetString(PyExc_AttributeError, name);
2078 return -1;
2079 }
2080}
2081
2082 static PyObject *
2083WindowRepr(PyObject *self)
2084{
Bram Moolenaar555b2802005-05-19 21:08:39 +00002085 static char repr[100];
Bram Moolenaar071d4272004-06-13 20:20:40 +00002086 WindowObject *this = (WindowObject *)(self);
2087
2088 if (this->win == INVALID_WINDOW_VALUE)
2089 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00002090 vim_snprintf(repr, 100, _("<window object (deleted) at %.8lX>"),
2091 (long)(self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002092 return PyString_FromString(repr);
2093 }
2094 else
2095 {
2096 int i = 0;
2097 win_T *w;
2098
2099 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
2100 ++i;
2101
2102 if (w == NULL)
Bram Moolenaar555b2802005-05-19 21:08:39 +00002103 vim_snprintf(repr, 100, _("<window object (unknown) at %.8lX>"),
2104 (long)(self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002105 else
Bram Moolenaar555b2802005-05-19 21:08:39 +00002106 vim_snprintf(repr, 100, _("<window %d>"), i);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002107
2108 return PyString_FromString(repr);
2109 }
2110}
2111
2112/* Window list object - Definitions
2113 */
2114
2115typedef struct
2116{
2117 PyObject_HEAD
2118}
2119WinListObject;
2120
2121static PySequenceMethods WinListAsSeq = {
2122 (inquiry) WinListLength, /* sq_length, len(x) */
2123 (binaryfunc) 0, /* sq_concat, x+y */
2124 (intargfunc) 0, /* sq_repeat, x*n */
2125 (intargfunc) WinListItem, /* sq_item, x[i] */
2126 (intintargfunc) 0, /* sq_slice, x[i:j] */
2127 (intobjargproc) 0, /* sq_ass_item, x[i]=v */
2128 (intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
2129};
2130
2131static PyTypeObject WinListType = {
2132 PyObject_HEAD_INIT(0)
2133 0,
2134 "window list",
2135 sizeof(WinListObject),
2136 0,
2137
2138 (destructor) 0, /* tp_dealloc, refcount==0 */
2139 (printfunc) 0, /* tp_print, print x */
2140 (getattrfunc) 0, /* tp_getattr, x.attr */
2141 (setattrfunc) 0, /* tp_setattr, x.attr=v */
2142 (cmpfunc) 0, /* tp_compare, x>y */
2143 (reprfunc) 0, /* tp_repr, `x`, print x */
2144
2145 0, /* as number */
2146 &WinListAsSeq, /* as sequence */
2147 0, /* as mapping */
2148
2149 (hashfunc) 0, /* tp_hash, dict(x) */
2150 (ternaryfunc) 0, /* tp_call, x() */
2151 (reprfunc) 0, /* tp_str, str(x) */
2152};
2153
2154/* Window list object - Implementation
2155 */
2156/*ARGSUSED*/
2157 static int
2158WinListLength(PyObject *self)
2159{
2160 win_T *w = firstwin;
2161 int n = 0;
2162
Bram Moolenaarf740b292006-02-16 22:11:02 +00002163 while (w != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002164 {
2165 ++n;
2166 w = W_NEXT(w);
2167 }
2168
2169 return n;
2170}
2171
2172/*ARGSUSED*/
2173 static PyObject *
2174WinListItem(PyObject *self, int n)
2175{
2176 win_T *w;
2177
Bram Moolenaarf740b292006-02-16 22:11:02 +00002178 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002179 if (n == 0)
2180 return WindowNew(w);
2181
2182 PyErr_SetString(PyExc_IndexError, _("no such window"));
2183 return NULL;
2184}
2185
2186/* Current items object - Definitions
2187 */
2188
2189typedef struct
2190{
2191 PyObject_HEAD
2192}
2193CurrentObject;
2194
2195static PyTypeObject CurrentType = {
2196 PyObject_HEAD_INIT(0)
2197 0,
2198 "current data",
2199 sizeof(CurrentObject),
2200 0,
2201
2202 (destructor) 0, /* tp_dealloc, refcount==0 */
2203 (printfunc) 0, /* tp_print, print x */
2204 (getattrfunc) CurrentGetattr, /* tp_getattr, x.attr */
2205 (setattrfunc) CurrentSetattr, /* tp_setattr, x.attr=v */
2206 (cmpfunc) 0, /* tp_compare, x>y */
2207 (reprfunc) 0, /* tp_repr, `x`, print x */
2208
2209 0, /* as number */
2210 0, /* as sequence */
2211 0, /* as mapping */
2212
2213 (hashfunc) 0, /* tp_hash, dict(x) */
2214 (ternaryfunc) 0, /* tp_call, x() */
2215 (reprfunc) 0, /* tp_str, str(x) */
2216};
2217
2218/* Current items object - Implementation
2219 */
2220/*ARGSUSED*/
2221 static PyObject *
2222CurrentGetattr(PyObject *self, char *name)
2223{
2224 if (strcmp(name, "buffer") == 0)
2225 return (PyObject *)BufferNew(curbuf);
2226 else if (strcmp(name, "window") == 0)
2227 return (PyObject *)WindowNew(curwin);
2228 else if (strcmp(name, "line") == 0)
2229 return GetBufferLine(curbuf, (int)curwin->w_cursor.lnum);
2230 else if (strcmp(name, "range") == 0)
2231 return RangeNew(curbuf, RangeStart, RangeEnd);
2232 else if (strcmp(name,"__members__") == 0)
2233 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
2234 else
2235 {
2236 PyErr_SetString(PyExc_AttributeError, name);
2237 return NULL;
2238 }
2239}
2240
2241/*ARGSUSED*/
2242 static int
2243CurrentSetattr(PyObject *self, char *name, PyObject *value)
2244{
2245 if (strcmp(name, "line") == 0)
2246 {
2247 if (SetBufferLine(curbuf, (int)curwin->w_cursor.lnum, value, NULL) == FAIL)
2248 return -1;
2249
2250 return 0;
2251 }
2252 else
2253 {
2254 PyErr_SetString(PyExc_AttributeError, name);
2255 return -1;
2256 }
2257}
2258
2259/* External interface
2260 */
2261
2262 void
2263python_buffer_free(buf_T *buf)
2264{
Bram Moolenaare344bea2005-09-01 20:46:49 +00002265 if (buf->b_python_ref != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002266 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00002267 BufferObject *bp = buf->b_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002268 bp->buf = INVALID_BUFFER_VALUE;
Bram Moolenaare344bea2005-09-01 20:46:49 +00002269 buf->b_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002270 }
2271}
2272
2273#if defined(FEAT_WINDOWS) || defined(PROTO)
2274 void
2275python_window_free(win_T *win)
2276{
Bram Moolenaare344bea2005-09-01 20:46:49 +00002277 if (win->w_python_ref != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002278 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00002279 WindowObject *wp = win->w_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002280 wp->win = INVALID_WINDOW_VALUE;
Bram Moolenaare344bea2005-09-01 20:46:49 +00002281 win->w_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002282 }
2283}
2284#endif
2285
2286static BufListObject TheBufferList =
2287{
2288 PyObject_HEAD_INIT(&BufListType)
2289};
2290
2291static WinListObject TheWindowList =
2292{
2293 PyObject_HEAD_INIT(&WinListType)
2294};
2295
2296static CurrentObject TheCurrent =
2297{
2298 PyObject_HEAD_INIT(&CurrentType)
2299};
2300
2301 static int
2302PythonMod_Init(void)
2303{
2304 PyObject *mod;
2305 PyObject *dict;
2306 static char *(argv[2]) = {"", NULL};
2307
2308 /* Fixups... */
2309 BufferType.ob_type = &PyType_Type;
2310 RangeType.ob_type = &PyType_Type;
2311 WindowType.ob_type = &PyType_Type;
2312 BufListType.ob_type = &PyType_Type;
2313 WinListType.ob_type = &PyType_Type;
2314 CurrentType.ob_type = &PyType_Type;
2315
2316 /* Set sys.argv[] to avoid a crash in warn(). */
2317 PySys_SetArgv(1, argv);
2318
2319 mod = Py_InitModule("vim", VimMethods);
2320 dict = PyModule_GetDict(mod);
2321
2322 VimError = Py_BuildValue("s", "vim.error");
2323
2324 PyDict_SetItemString(dict, "error", VimError);
Bram Moolenaar7df2d662005-01-25 22:18:08 +00002325 PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferList);
2326 PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent);
2327 PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002328
2329 if (PyErr_Occurred())
2330 return -1;
2331
2332 return 0;
2333}
2334
2335/*************************************************************************
2336 * 4. Utility functions for handling the interface between Vim and Python.
2337 */
2338
2339/* Get a line from the specified buffer. The line number is
2340 * in Vim format (1-based). The line is returned as a Python
2341 * string object.
2342 */
2343 static PyObject *
2344GetBufferLine(buf_T *buf, int n)
2345{
2346 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2347}
2348
2349/* Get a list of lines from the specified buffer. The line numbers
2350 * are in Vim format (1-based). The range is from lo up to, but not
2351 * including, hi. The list is returned as a Python list of string objects.
2352 */
2353 static PyObject *
2354GetBufferLineList(buf_T *buf, int lo, int hi)
2355{
2356 int i;
2357 int n = hi - lo;
2358 PyObject *list = PyList_New(n);
2359
2360 if (list == NULL)
2361 return NULL;
2362
2363 for (i = 0; i < n; ++i)
2364 {
2365 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2366
2367 /* Error check - was the Python string creation OK? */
2368 if (str == NULL)
2369 {
2370 Py_DECREF(list);
2371 return NULL;
2372 }
2373
2374 /* Set the list item */
2375 if (PyList_SetItem(list, i, str))
2376 {
2377 Py_DECREF(str);
2378 Py_DECREF(list);
2379 return NULL;
2380 }
2381 }
2382
2383 /* The ownership of the Python list is passed to the caller (ie,
2384 * the caller should Py_DECREF() the object when it is finished
2385 * with it).
2386 */
2387
2388 return list;
2389}
2390
2391/*
2392 * Check if deleting lines made the cursor position invalid.
2393 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2394 * deleted).
2395 */
2396 static void
2397py_fix_cursor(int lo, int hi, int extra)
2398{
2399 if (curwin->w_cursor.lnum >= lo)
2400 {
2401 /* Adjust the cursor position if it's in/after the changed
2402 * lines. */
2403 if (curwin->w_cursor.lnum >= hi)
2404 {
2405 curwin->w_cursor.lnum += extra;
2406 check_cursor_col();
2407 }
2408 else if (extra < 0)
2409 {
2410 curwin->w_cursor.lnum = lo;
2411 check_cursor();
2412 }
2413 changed_cline_bef_curs();
2414 }
2415 invalidate_botline();
2416}
2417
2418/* Replace a line in the specified buffer. The line number is
2419 * in Vim format (1-based). The replacement line is given as
2420 * a Python string object. The object is checked for validity
2421 * and correct format. Errors are returned as a value of FAIL.
2422 * The return value is OK on success.
2423 * If OK is returned and len_change is not NULL, *len_change
2424 * is set to the change in the buffer length.
2425 */
2426 static int
2427SetBufferLine(buf_T *buf, int n, PyObject *line, int *len_change)
2428{
2429 /* First of all, we check the thpe of the supplied Python object.
2430 * There are three cases:
2431 * 1. NULL, or None - this is a deletion.
2432 * 2. A string - this is a replacement.
2433 * 3. Anything else - this is an error.
2434 */
2435 if (line == Py_None || line == NULL)
2436 {
2437 buf_T *savebuf = curbuf;
2438
2439 PyErr_Clear();
2440 curbuf = buf;
2441
2442 if (u_savedel((linenr_T)n, 1L) == FAIL)
2443 PyErr_SetVim(_("cannot save undo information"));
2444 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2445 PyErr_SetVim(_("cannot delete line"));
2446 else
2447 {
2448 deleted_lines_mark((linenr_T)n, 1L);
2449 if (buf == curwin->w_buffer)
2450 py_fix_cursor(n, n + 1, -1);
2451 }
2452
2453 curbuf = savebuf;
2454
2455 if (PyErr_Occurred() || VimErrorCheck())
2456 return FAIL;
2457
2458 if (len_change)
2459 *len_change = -1;
2460
2461 return OK;
2462 }
2463 else if (PyString_Check(line))
2464 {
2465 char *save = StringToLine(line);
2466 buf_T *savebuf = curbuf;
2467
2468 if (save == NULL)
2469 return FAIL;
2470
2471 /* We do not need to free "save" if ml_replace() consumes it. */
2472 PyErr_Clear();
2473 curbuf = buf;
2474
2475 if (u_savesub((linenr_T)n) == FAIL)
2476 {
2477 PyErr_SetVim(_("cannot save undo information"));
2478 vim_free(save);
2479 }
2480 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2481 {
2482 PyErr_SetVim(_("cannot replace line"));
2483 vim_free(save);
2484 }
2485 else
2486 changed_bytes((linenr_T)n, 0);
2487
2488 curbuf = savebuf;
2489
2490 if (PyErr_Occurred() || VimErrorCheck())
2491 return FAIL;
2492
2493 if (len_change)
2494 *len_change = 0;
2495
2496 return OK;
2497 }
2498 else
2499 {
2500 PyErr_BadArgument();
2501 return FAIL;
2502 }
2503}
2504
2505/* Replace a range of lines in the specified buffer. The line numbers are in
2506 * Vim format (1-based). The range is from lo up to, but not including, hi.
2507 * The replacement lines are given as a Python list of string objects. The
2508 * list is checked for validity and correct format. Errors are returned as a
2509 * value of FAIL. The return value is OK on success.
2510 * If OK is returned and len_change is not NULL, *len_change
2511 * is set to the change in the buffer length.
2512 */
2513 static int
2514SetBufferLineList(buf_T *buf, int lo, int hi, PyObject *list, int *len_change)
2515{
2516 /* First of all, we check the thpe of the supplied Python object.
2517 * There are three cases:
2518 * 1. NULL, or None - this is a deletion.
2519 * 2. A list - this is a replacement.
2520 * 3. Anything else - this is an error.
2521 */
2522 if (list == Py_None || list == NULL)
2523 {
2524 int i;
2525 int n = hi - lo;
2526 buf_T *savebuf = curbuf;
2527
2528 PyErr_Clear();
2529 curbuf = buf;
2530
2531 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2532 PyErr_SetVim(_("cannot save undo information"));
2533 else
2534 {
2535 for (i = 0; i < n; ++i)
2536 {
2537 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2538 {
2539 PyErr_SetVim(_("cannot delete line"));
2540 break;
2541 }
2542 }
2543 deleted_lines_mark((linenr_T)lo, (long)i);
2544
2545 if (buf == curwin->w_buffer)
2546 py_fix_cursor(lo, hi, -n);
2547 }
2548
2549 curbuf = savebuf;
2550
2551 if (PyErr_Occurred() || VimErrorCheck())
2552 return FAIL;
2553
2554 if (len_change)
2555 *len_change = -n;
2556
2557 return OK;
2558 }
2559 else if (PyList_Check(list))
2560 {
2561 int i;
2562 int new_len = PyList_Size(list);
2563 int old_len = hi - lo;
2564 int extra = 0; /* lines added to text, can be negative */
2565 char **array;
2566 buf_T *savebuf;
2567
2568 if (new_len == 0) /* avoid allocating zero bytes */
2569 array = NULL;
2570 else
2571 {
2572 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
2573 if (array == NULL)
2574 {
2575 PyErr_NoMemory();
2576 return FAIL;
2577 }
2578 }
2579
2580 for (i = 0; i < new_len; ++i)
2581 {
2582 PyObject *line = PyList_GetItem(list, i);
2583
2584 array[i] = StringToLine(line);
2585 if (array[i] == NULL)
2586 {
2587 while (i)
2588 vim_free(array[--i]);
2589 vim_free(array);
2590 return FAIL;
2591 }
2592 }
2593
2594 savebuf = curbuf;
2595
2596 PyErr_Clear();
2597 curbuf = buf;
2598
2599 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2600 PyErr_SetVim(_("cannot save undo information"));
2601
2602 /* If the size of the range is reducing (ie, new_len < old_len) we
2603 * need to delete some old_len. We do this at the start, by
2604 * repeatedly deleting line "lo".
2605 */
2606 if (!PyErr_Occurred())
2607 {
2608 for (i = 0; i < old_len - new_len; ++i)
2609 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2610 {
2611 PyErr_SetVim(_("cannot delete line"));
2612 break;
2613 }
2614 extra -= i;
2615 }
2616
2617 /* For as long as possible, replace the existing old_len with the
2618 * new old_len. This is a more efficient operation, as it requires
2619 * less memory allocation and freeing.
2620 */
2621 if (!PyErr_Occurred())
2622 {
2623 for (i = 0; i < old_len && i < new_len; ++i)
2624 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2625 == FAIL)
2626 {
2627 PyErr_SetVim(_("cannot replace line"));
2628 break;
2629 }
2630 }
2631 else
2632 i = 0;
2633
2634 /* Now we may need to insert the remaining new old_len. If we do, we
2635 * must free the strings as we finish with them (we can't pass the
2636 * responsibility to vim in this case).
2637 */
2638 if (!PyErr_Occurred())
2639 {
2640 while (i < new_len)
2641 {
2642 if (ml_append((linenr_T)(lo + i - 1),
2643 (char_u *)array[i], 0, FALSE) == FAIL)
2644 {
2645 PyErr_SetVim(_("cannot insert line"));
2646 break;
2647 }
2648 vim_free(array[i]);
2649 ++i;
2650 ++extra;
2651 }
2652 }
2653
2654 /* Free any left-over old_len, as a result of an error */
2655 while (i < new_len)
2656 {
2657 vim_free(array[i]);
2658 ++i;
2659 }
2660
2661 /* Free the array of old_len. All of its contents have now
2662 * been dealt with (either freed, or the responsibility passed
2663 * to vim.
2664 */
2665 vim_free(array);
2666
2667 /* Adjust marks. Invalidate any which lie in the
2668 * changed range, and move any in the remainder of the buffer.
2669 */
2670 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2671 (long)MAXLNUM, (long)extra);
2672 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2673
2674 if (buf == curwin->w_buffer)
2675 py_fix_cursor(lo, hi, extra);
2676
2677 curbuf = savebuf;
2678
2679 if (PyErr_Occurred() || VimErrorCheck())
2680 return FAIL;
2681
2682 if (len_change)
2683 *len_change = new_len - old_len;
2684
2685 return OK;
2686 }
2687 else
2688 {
2689 PyErr_BadArgument();
2690 return FAIL;
2691 }
2692}
2693
2694/* Insert a number of lines into the specified buffer after the specifed line.
2695 * The line number is in Vim format (1-based). The lines to be inserted are
2696 * given as a Python list of string objects or as a single string. The lines
2697 * to be added are checked for validity and correct format. Errors are
2698 * returned as a value of FAIL. The return value is OK on success.
2699 * If OK is returned and len_change is not NULL, *len_change
2700 * is set to the change in the buffer length.
2701 */
2702 static int
2703InsertBufferLines(buf_T *buf, int n, PyObject *lines, int *len_change)
2704{
2705 /* First of all, we check the type of the supplied Python object.
2706 * It must be a string or a list, or the call is in error.
2707 */
2708 if (PyString_Check(lines))
2709 {
2710 char *str = StringToLine(lines);
2711 buf_T *savebuf;
2712
2713 if (str == NULL)
2714 return FAIL;
2715
2716 savebuf = curbuf;
2717
2718 PyErr_Clear();
2719 curbuf = buf;
2720
2721 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2722 PyErr_SetVim(_("cannot save undo information"));
2723 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2724 PyErr_SetVim(_("cannot insert line"));
2725 else
2726 appended_lines_mark((linenr_T)n, 1L);
2727
2728 vim_free(str);
2729 curbuf = savebuf;
2730 update_screen(VALID);
2731
2732 if (PyErr_Occurred() || VimErrorCheck())
2733 return FAIL;
2734
2735 if (len_change)
2736 *len_change = 1;
2737
2738 return OK;
2739 }
2740 else if (PyList_Check(lines))
2741 {
2742 int i;
2743 int size = PyList_Size(lines);
2744 char **array;
2745 buf_T *savebuf;
2746
2747 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2748 if (array == NULL)
2749 {
2750 PyErr_NoMemory();
2751 return FAIL;
2752 }
2753
2754 for (i = 0; i < size; ++i)
2755 {
2756 PyObject *line = PyList_GetItem(lines, i);
2757 array[i] = StringToLine(line);
2758
2759 if (array[i] == NULL)
2760 {
2761 while (i)
2762 vim_free(array[--i]);
2763 vim_free(array);
2764 return FAIL;
2765 }
2766 }
2767
2768 savebuf = curbuf;
2769
2770 PyErr_Clear();
2771 curbuf = buf;
2772
2773 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2774 PyErr_SetVim(_("cannot save undo information"));
2775 else
2776 {
2777 for (i = 0; i < size; ++i)
2778 {
2779 if (ml_append((linenr_T)(n + i),
2780 (char_u *)array[i], 0, FALSE) == FAIL)
2781 {
2782 PyErr_SetVim(_("cannot insert line"));
2783
2784 /* Free the rest of the lines */
2785 while (i < size)
2786 vim_free(array[i++]);
2787
2788 break;
2789 }
2790 vim_free(array[i]);
2791 }
2792 if (i > 0)
2793 appended_lines_mark((linenr_T)n, (long)i);
2794 }
2795
2796 /* Free the array of lines. All of its contents have now
2797 * been freed.
2798 */
2799 vim_free(array);
2800
2801 curbuf = savebuf;
2802 update_screen(VALID);
2803
2804 if (PyErr_Occurred() || VimErrorCheck())
2805 return FAIL;
2806
2807 if (len_change)
2808 *len_change = size;
2809
2810 return OK;
2811 }
2812 else
2813 {
2814 PyErr_BadArgument();
2815 return FAIL;
2816 }
2817}
2818
2819/* Convert a Vim line into a Python string.
2820 * All internal newlines are replaced by null characters.
2821 *
2822 * On errors, the Python exception data is set, and NULL is returned.
2823 */
2824 static PyObject *
2825LineToString(const char *str)
2826{
2827 PyObject *result;
2828 int len = strlen(str);
2829 char *p;
2830
2831 /* Allocate an Python string object, with uninitialised contents. We
2832 * must do it this way, so that we can modify the string in place
2833 * later. See the Python source, Objects/stringobject.c for details.
2834 */
2835 result = PyString_FromStringAndSize(NULL, len);
2836 if (result == NULL)
2837 return NULL;
2838
2839 p = PyString_AsString(result);
2840
2841 while (*str)
2842 {
2843 if (*str == '\n')
2844 *p = '\0';
2845 else
2846 *p = *str;
2847
2848 ++p;
2849 ++str;
2850 }
2851
2852 return result;
2853}
2854
2855/* Convert a Python string into a Vim line.
2856 *
2857 * The result is in allocated memory. All internal nulls are replaced by
2858 * newline characters. It is an error for the string to contain newline
2859 * characters.
2860 *
2861 * On errors, the Python exception data is set, and NULL is returned.
2862 */
2863 static char *
2864StringToLine(PyObject *obj)
2865{
2866 const char *str;
2867 char *save;
2868 int len;
2869 int i;
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002870 char *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002871
2872 if (obj == NULL || !PyString_Check(obj))
2873 {
2874 PyErr_BadArgument();
2875 return NULL;
2876 }
2877
2878 str = PyString_AsString(obj);
2879 len = PyString_Size(obj);
2880
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002881 /*
2882 * Error checking: String must not contain newlines, as we
Bram Moolenaar071d4272004-06-13 20:20:40 +00002883 * are replacing a single line, and we must replace it with
2884 * a single line.
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002885 * A trailing newline is removed, so that append(f.readlines()) works.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002886 */
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002887 p = memchr(str, '\n', len);
2888 if (p != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002889 {
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002890 if (p == str + len - 1)
2891 --len;
2892 else
2893 {
2894 PyErr_SetVim(_("string cannot contain newlines"));
2895 return NULL;
2896 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002897 }
2898
2899 /* Create a copy of the string, with internal nulls replaced by
2900 * newline characters, as is the vim convention.
2901 */
2902 save = (char *)alloc((unsigned)(len+1));
2903 if (save == NULL)
2904 {
2905 PyErr_NoMemory();
2906 return NULL;
2907 }
2908
2909 for (i = 0; i < len; ++i)
2910 {
2911 if (str[i] == '\0')
2912 save[i] = '\n';
2913 else
2914 save[i] = str[i];
2915 }
2916
2917 save[i] = '\0';
2918
2919 return save;
2920}
2921
2922/* Check to see whether a Vim error has been reported, or a keyboard
2923 * interrupt has been detected.
2924 */
2925 static int
2926VimErrorCheck(void)
2927{
2928 if (got_int)
2929 {
2930 PyErr_SetNone(PyExc_KeyboardInterrupt);
2931 return 1;
2932 }
2933 else if (did_emsg && !PyErr_Occurred())
2934 {
2935 PyErr_SetNone(VimError);
2936 return 1;
2937 }
2938
2939 return 0;
2940}
2941
2942
2943/* Don't generate a prototype for the next function, it generates an error on
2944 * newer Python versions. */
2945#if PYTHON_API_VERSION < 1007 /* Python 1.4 */ && !defined(PROTO)
2946
2947 char *
2948Py_GetProgramName(void)
2949{
2950 return "vim";
2951}
2952#endif /* Python 1.4 */