xref: /vim-8.2.3635/src/if_python.c (revision db913953)
1*db913953SBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2071d4279SBram Moolenaar  *
3071d4279SBram Moolenaar  * VIM - Vi IMproved	by Bram Moolenaar
4071d4279SBram Moolenaar  *
5071d4279SBram Moolenaar  * Do ":help uganda"  in Vim to read copying and usage conditions.
6071d4279SBram Moolenaar  * Do ":help credits" in Vim to see a list of people who contributed.
7071d4279SBram Moolenaar  * See README.txt for an overview of the Vim source code.
8071d4279SBram Moolenaar  */
9071d4279SBram Moolenaar /*
10071d4279SBram Moolenaar  * Python extensions by Paul Moore.
11071d4279SBram Moolenaar  * Changes for Unix by David Leonard.
12071d4279SBram Moolenaar  *
13071d4279SBram Moolenaar  * This consists of four parts:
14071d4279SBram Moolenaar  * 1. Python interpreter main program
15071d4279SBram Moolenaar  * 2. Python output stream: writes output via [e]msg().
16071d4279SBram Moolenaar  * 3. Implementation of the Vim module for Python
17071d4279SBram Moolenaar  * 4. Utility functions for handling the interface between Vim and Python.
18071d4279SBram Moolenaar  */
19071d4279SBram Moolenaar 
20071d4279SBram Moolenaar #include "vim.h"
21071d4279SBram Moolenaar 
22071d4279SBram Moolenaar #include <limits.h>
23071d4279SBram Moolenaar 
24071d4279SBram Moolenaar /* Python.h defines _POSIX_THREADS itself (if needed) */
25071d4279SBram Moolenaar #ifdef _POSIX_THREADS
26071d4279SBram Moolenaar # undef _POSIX_THREADS
27071d4279SBram Moolenaar #endif
28071d4279SBram Moolenaar 
29071d4279SBram Moolenaar #if defined(_WIN32) && defined(HAVE_FCNTL_H)
30071d4279SBram Moolenaar # undef HAVE_FCNTL_H
31071d4279SBram Moolenaar #endif
32071d4279SBram Moolenaar 
33071d4279SBram Moolenaar #ifdef _DEBUG
34071d4279SBram Moolenaar # undef _DEBUG
35071d4279SBram Moolenaar #endif
36071d4279SBram Moolenaar 
37071d4279SBram Moolenaar #ifdef HAVE_STDARG_H
38071d4279SBram Moolenaar # undef HAVE_STDARG_H	/* Python's config.h defines it as well. */
39071d4279SBram Moolenaar #endif
40be2c9ae9SBram Moolenaar #ifdef _POSIX_C_SOURCE
41be2c9ae9SBram Moolenaar # undef _POSIX_C_SOURCE	/* pyconfig.h defines it as well. */
42be2c9ae9SBram Moolenaar #endif
43be2c9ae9SBram Moolenaar #ifdef _XOPEN_SOURCE
44be2c9ae9SBram Moolenaar # undef _XOPEN_SOURCE	/* pyconfig.h defines it as well. */
45be2c9ae9SBram Moolenaar #endif
46071d4279SBram Moolenaar 
472c45e945SBram Moolenaar #define PY_SSIZE_T_CLEAN
482c45e945SBram Moolenaar 
49071d4279SBram Moolenaar #include <Python.h>
50071d4279SBram Moolenaar #if defined(MACOS) && !defined(MACOS_X_UNIX)
51071d4279SBram Moolenaar # include "macglue.h"
52071d4279SBram Moolenaar # include <CodeFragments.h>
53071d4279SBram Moolenaar #endif
54071d4279SBram Moolenaar #undef main /* Defined in python.h - aargh */
55071d4279SBram Moolenaar #undef HAVE_FCNTL_H /* Clash with os_win32.h */
56071d4279SBram Moolenaar 
57170bf1aeSBram Moolenaar static void init_structs(void);
58170bf1aeSBram Moolenaar 
59*db913953SBram Moolenaar #define PyBytes_FromString PyString_FromString
60*db913953SBram Moolenaar 
6119e60943SBram Moolenaar /* No-op conversion functions, use with care! */
6219e60943SBram Moolenaar #define PyString_AsBytes(obj) (obj)
6319e60943SBram Moolenaar #define PyString_FreeBytes(obj)
6419e60943SBram Moolenaar 
65071d4279SBram Moolenaar #if !defined(FEAT_PYTHON) && defined(PROTO)
66071d4279SBram Moolenaar /* Use this to be able to generate prototypes without python being used. */
67e7cb9cf6SBram Moolenaar # define PyObject Py_ssize_t
68e7cb9cf6SBram Moolenaar # define PyThreadState Py_ssize_t
69e7cb9cf6SBram Moolenaar # define PyTypeObject Py_ssize_t
70e7cb9cf6SBram Moolenaar struct PyMethodDef { Py_ssize_t a; };
71e7cb9cf6SBram Moolenaar # define PySequenceMethods Py_ssize_t
72071d4279SBram Moolenaar #endif
73071d4279SBram Moolenaar 
742c45e945SBram Moolenaar #if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02050000
752c45e945SBram Moolenaar # define PyInt Py_ssize_t
762c45e945SBram Moolenaar # define PyInquiry lenfunc
772c45e945SBram Moolenaar # define PyIntArgFunc ssizeargfunc
782c45e945SBram Moolenaar # define PyIntIntArgFunc ssizessizeargfunc
792c45e945SBram Moolenaar # define PyIntObjArgProc ssizeobjargproc
802c45e945SBram Moolenaar # define PyIntIntObjArgProc ssizessizeobjargproc
81e7cb9cf6SBram Moolenaar # define Py_ssize_t_fmt "n"
822c45e945SBram Moolenaar #else
832c45e945SBram Moolenaar # define PyInt int
842c45e945SBram Moolenaar # define PyInquiry inquiry
852c45e945SBram Moolenaar # define PyIntArgFunc intargfunc
862c45e945SBram Moolenaar # define PyIntIntArgFunc intintargfunc
872c45e945SBram Moolenaar # define PyIntObjArgProc intobjargproc
882c45e945SBram Moolenaar # define PyIntIntObjArgProc intintobjargproc
89e7cb9cf6SBram Moolenaar # define Py_ssize_t_fmt "i"
902c45e945SBram Moolenaar #endif
912c45e945SBram Moolenaar 
92071d4279SBram Moolenaar /* Parser flags */
93071d4279SBram Moolenaar #define single_input	256
94071d4279SBram Moolenaar #define file_input	257
95071d4279SBram Moolenaar #define eval_input	258
96071d4279SBram Moolenaar 
97071d4279SBram Moolenaar #if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x020300F0
98071d4279SBram Moolenaar   /* Python 2.3: can invoke ":python" recursively. */
99071d4279SBram Moolenaar # define PY_CAN_RECURSE
100071d4279SBram Moolenaar #endif
101071d4279SBram Moolenaar 
102071d4279SBram Moolenaar # if defined(DYNAMIC_PYTHON) || defined(PROTO)
103071d4279SBram Moolenaar #  ifndef DYNAMIC_PYTHON
104e7cb9cf6SBram Moolenaar #   define HINSTANCE long_u		/* for generating prototypes */
105071d4279SBram Moolenaar #  endif
106071d4279SBram Moolenaar 
107fa5d1e63SBram Moolenaar # ifndef WIN3264
108bd5e15fdSBram Moolenaar #  include <dlfcn.h>
109bd5e15fdSBram Moolenaar #  define FARPROC void*
110bd5e15fdSBram Moolenaar #  define HINSTANCE void*
111644d37b8SBram Moolenaar #  if defined(PY_NO_RTLD_GLOBAL) && defined(PY3_NO_RTLD_GLOBAL)
112b61f95c3SBram Moolenaar #   define load_dll(n) dlopen((n), RTLD_LAZY)
113b61f95c3SBram Moolenaar #  else
114fa5d1e63SBram Moolenaar #   define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
115b61f95c3SBram Moolenaar #  endif
116bd5e15fdSBram Moolenaar #  define close_dll dlclose
117bd5e15fdSBram Moolenaar #  define symbol_from_dll dlsym
118bd5e15fdSBram Moolenaar # else
119ebbcb824SBram Moolenaar #  define load_dll vimLoadLib
120bd5e15fdSBram Moolenaar #  define close_dll FreeLibrary
121bd5e15fdSBram Moolenaar #  define symbol_from_dll GetProcAddress
122bd5e15fdSBram Moolenaar # endif
123bd5e15fdSBram Moolenaar 
124e7cb9cf6SBram Moolenaar /* This makes if_python.c compile without warnings against Python 2.5
125e7cb9cf6SBram Moolenaar  * on Win32 and Win64. */
126e7cb9cf6SBram Moolenaar # undef PyRun_SimpleString
127*db913953SBram Moolenaar # undef PyRun_String
128e7cb9cf6SBram Moolenaar # undef PyArg_Parse
129e7cb9cf6SBram Moolenaar # undef PyArg_ParseTuple
130e7cb9cf6SBram Moolenaar # undef Py_BuildValue
131e7cb9cf6SBram Moolenaar # undef Py_InitModule4
132e7cb9cf6SBram Moolenaar # undef Py_InitModule4_64
133*db913953SBram Moolenaar # undef PyObject_CallMethod
134e7cb9cf6SBram Moolenaar 
135071d4279SBram Moolenaar /*
136071d4279SBram Moolenaar  * Wrapper defines
137071d4279SBram Moolenaar  */
138071d4279SBram Moolenaar # define PyArg_Parse dll_PyArg_Parse
139071d4279SBram Moolenaar # define PyArg_ParseTuple dll_PyArg_ParseTuple
14019e60943SBram Moolenaar # define PyMem_Free dll_PyMem_Free
141*db913953SBram Moolenaar # define PyMem_Malloc dll_PyMem_Malloc
142071d4279SBram Moolenaar # define PyDict_SetItemString dll_PyDict_SetItemString
143071d4279SBram Moolenaar # define PyErr_BadArgument dll_PyErr_BadArgument
144071d4279SBram Moolenaar # define PyErr_Clear dll_PyErr_Clear
145071d4279SBram Moolenaar # define PyErr_NoMemory dll_PyErr_NoMemory
146071d4279SBram Moolenaar # define PyErr_Occurred dll_PyErr_Occurred
147071d4279SBram Moolenaar # define PyErr_SetNone dll_PyErr_SetNone
148071d4279SBram Moolenaar # define PyErr_SetString dll_PyErr_SetString
149071d4279SBram Moolenaar # define PyEval_InitThreads dll_PyEval_InitThreads
150071d4279SBram Moolenaar # define PyEval_RestoreThread dll_PyEval_RestoreThread
151071d4279SBram Moolenaar # define PyEval_SaveThread dll_PyEval_SaveThread
152071d4279SBram Moolenaar # ifdef PY_CAN_RECURSE
153071d4279SBram Moolenaar #  define PyGILState_Ensure dll_PyGILState_Ensure
154071d4279SBram Moolenaar #  define PyGILState_Release dll_PyGILState_Release
155071d4279SBram Moolenaar # endif
156071d4279SBram Moolenaar # define PyInt_AsLong dll_PyInt_AsLong
157071d4279SBram Moolenaar # define PyInt_FromLong dll_PyInt_FromLong
158*db913953SBram Moolenaar # define PyLong_AsLong dll_PyLong_AsLong
159*db913953SBram Moolenaar # define PyLong_FromLong dll_PyLong_FromLong
160071d4279SBram Moolenaar # define PyInt_Type (*dll_PyInt_Type)
161*db913953SBram Moolenaar # define PyLong_Type (*dll_PyLong_Type)
162071d4279SBram Moolenaar # define PyList_GetItem dll_PyList_GetItem
1630ac9379aSBram Moolenaar # define PyList_Append dll_PyList_Append
164071d4279SBram Moolenaar # define PyList_New dll_PyList_New
165071d4279SBram Moolenaar # define PyList_SetItem dll_PyList_SetItem
166071d4279SBram Moolenaar # define PyList_Size dll_PyList_Size
167071d4279SBram Moolenaar # define PyList_Type (*dll_PyList_Type)
168*db913953SBram Moolenaar # define PySequence_Check dll_PySequence_Check
169*db913953SBram Moolenaar # define PySequence_Size dll_PySequence_Size
170*db913953SBram Moolenaar # define PySequence_GetItem dll_PySequence_GetItem
171*db913953SBram Moolenaar # define PyTuple_Size dll_PyTuple_Size
172*db913953SBram Moolenaar # define PyTuple_GetItem dll_PyTuple_GetItem
173*db913953SBram Moolenaar # define PyTuple_Type (*dll_PyTuple_Type)
174071d4279SBram Moolenaar # define PyImport_ImportModule dll_PyImport_ImportModule
1750ac9379aSBram Moolenaar # define PyDict_New dll_PyDict_New
176071d4279SBram Moolenaar # define PyDict_GetItemString dll_PyDict_GetItemString
177*db913953SBram Moolenaar # define PyDict_Next dll_PyDict_Next
178*db913953SBram Moolenaar # ifdef PyMapping_Items
179*db913953SBram Moolenaar #  define PY_NO_MAPPING_ITEMS
180*db913953SBram Moolenaar # else
181*db913953SBram Moolenaar #  define PyMapping_Items dll_PyMapping_Items
182*db913953SBram Moolenaar # endif
183*db913953SBram Moolenaar # define PyObject_CallMethod dll_PyObject_CallMethod
184*db913953SBram Moolenaar # define PyMapping_Check dll_PyMapping_Check
185*db913953SBram Moolenaar # define PyIter_Next dll_PyIter_Next
186071d4279SBram Moolenaar # define PyModule_GetDict dll_PyModule_GetDict
187071d4279SBram Moolenaar # define PyRun_SimpleString dll_PyRun_SimpleString
188*db913953SBram Moolenaar # define PyRun_String dll_PyRun_String
189071d4279SBram Moolenaar # define PyString_AsString dll_PyString_AsString
190071d4279SBram Moolenaar # define PyString_FromString dll_PyString_FromString
191071d4279SBram Moolenaar # define PyString_FromStringAndSize dll_PyString_FromStringAndSize
192071d4279SBram Moolenaar # define PyString_Size dll_PyString_Size
193071d4279SBram Moolenaar # define PyString_Type (*dll_PyString_Type)
194*db913953SBram Moolenaar # define PyUnicode_Type (*dll_PyUnicode_Type)
195*db913953SBram Moolenaar # define PyUnicodeUCS4_AsEncodedString (*dll_PyUnicodeUCS4_AsEncodedString)
196*db913953SBram Moolenaar # define PyFloat_AsDouble dll_PyFloat_AsDouble
197*db913953SBram Moolenaar # define PyFloat_FromDouble dll_PyFloat_FromDouble
198*db913953SBram Moolenaar # define PyFloat_Type (*dll_PyFloat_Type)
199*db913953SBram Moolenaar # define PyImport_AddModule (*dll_PyImport_AddModule)
200071d4279SBram Moolenaar # define PySys_SetObject dll_PySys_SetObject
201071d4279SBram Moolenaar # define PySys_SetArgv dll_PySys_SetArgv
202071d4279SBram Moolenaar # define PyType_Type (*dll_PyType_Type)
20330fec7bcSBram Moolenaar # define PyType_Ready (*dll_PyType_Ready)
204071d4279SBram Moolenaar # define Py_BuildValue dll_Py_BuildValue
205071d4279SBram Moolenaar # define Py_FindMethod dll_Py_FindMethod
206071d4279SBram Moolenaar # define Py_InitModule4 dll_Py_InitModule4
207644d37b8SBram Moolenaar # define Py_SetPythonHome dll_Py_SetPythonHome
208071d4279SBram Moolenaar # define Py_Initialize dll_Py_Initialize
2090e21a3f6SBram Moolenaar # define Py_Finalize dll_Py_Finalize
2100e21a3f6SBram Moolenaar # define Py_IsInitialized dll_Py_IsInitialized
211071d4279SBram Moolenaar # define _PyObject_New dll__PyObject_New
212*db913953SBram Moolenaar # define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented)
213071d4279SBram Moolenaar # define _Py_NoneStruct (*dll__Py_NoneStruct)
214071d4279SBram Moolenaar # define PyObject_Init dll__PyObject_Init
215*db913953SBram Moolenaar # define PyObject_GetIter dll_PyObject_GetIter
216071d4279SBram Moolenaar # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
217071d4279SBram Moolenaar #  define PyType_IsSubtype dll_PyType_IsSubtype
218071d4279SBram Moolenaar # endif
219071d4279SBram Moolenaar # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
220071d4279SBram Moolenaar #  define PyObject_Malloc dll_PyObject_Malloc
221071d4279SBram Moolenaar #  define PyObject_Free dll_PyObject_Free
222071d4279SBram Moolenaar # endif
223*db913953SBram Moolenaar # define PyCapsule_New dll_PyCapsule_New
224*db913953SBram Moolenaar # define PyCapsule_GetPointer dll_PyCapsule_GetPointer
225071d4279SBram Moolenaar 
226071d4279SBram Moolenaar /*
227071d4279SBram Moolenaar  * Pointers for dynamic link
228071d4279SBram Moolenaar  */
229071d4279SBram Moolenaar static int(*dll_PyArg_Parse)(PyObject *, char *, ...);
230071d4279SBram Moolenaar static int(*dll_PyArg_ParseTuple)(PyObject *, char *, ...);
23119e60943SBram Moolenaar static int(*dll_PyMem_Free)(void *);
232*db913953SBram Moolenaar static void* (*dll_PyMem_Malloc)(size_t);
233071d4279SBram Moolenaar static int(*dll_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
234071d4279SBram Moolenaar static int(*dll_PyErr_BadArgument)(void);
235071d4279SBram Moolenaar static void(*dll_PyErr_Clear)(void);
236071d4279SBram Moolenaar static PyObject*(*dll_PyErr_NoMemory)(void);
237071d4279SBram Moolenaar static PyObject*(*dll_PyErr_Occurred)(void);
238071d4279SBram Moolenaar static void(*dll_PyErr_SetNone)(PyObject *);
239071d4279SBram Moolenaar static void(*dll_PyErr_SetString)(PyObject *, const char *);
240071d4279SBram Moolenaar static void(*dll_PyEval_InitThreads)(void);
241071d4279SBram Moolenaar static void(*dll_PyEval_RestoreThread)(PyThreadState *);
242071d4279SBram Moolenaar static PyThreadState*(*dll_PyEval_SaveThread)(void);
243071d4279SBram Moolenaar # ifdef PY_CAN_RECURSE
244071d4279SBram Moolenaar static PyGILState_STATE	(*dll_PyGILState_Ensure)(void);
245071d4279SBram Moolenaar static void (*dll_PyGILState_Release)(PyGILState_STATE);
246071d4279SBram Moolenaar # endif
247071d4279SBram Moolenaar static long(*dll_PyInt_AsLong)(PyObject *);
248071d4279SBram Moolenaar static PyObject*(*dll_PyInt_FromLong)(long);
249*db913953SBram Moolenaar static long(*dll_PyLong_AsLong)(PyObject *);
250*db913953SBram Moolenaar static PyObject*(*dll_PyLong_FromLong)(long);
251071d4279SBram Moolenaar static PyTypeObject* dll_PyInt_Type;
252*db913953SBram Moolenaar static PyTypeObject* dll_PyLong_Type;
2532c45e945SBram Moolenaar static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
2540ac9379aSBram Moolenaar static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
2552c45e945SBram Moolenaar static PyObject*(*dll_PyList_New)(PyInt size);
2562c45e945SBram Moolenaar static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
2572c45e945SBram Moolenaar static PyInt(*dll_PyList_Size)(PyObject *);
258071d4279SBram Moolenaar static PyTypeObject* dll_PyList_Type;
259*db913953SBram Moolenaar static int (*dll_PySequence_Check)(PyObject *);
260*db913953SBram Moolenaar static PyInt(*dll_PySequence_Size)(PyObject *);
261*db913953SBram Moolenaar static PyObject*(*dll_PySequence_GetItem)(PyObject *, PyInt);
262*db913953SBram Moolenaar static PyInt(*dll_PyTuple_Size)(PyObject *);
263*db913953SBram Moolenaar static PyObject*(*dll_PyTuple_GetItem)(PyObject *, PyInt);
264*db913953SBram Moolenaar static PyTypeObject* dll_PyTuple_Type;
265071d4279SBram Moolenaar static PyObject*(*dll_PyImport_ImportModule)(const char *);
2660ac9379aSBram Moolenaar static PyObject*(*dll_PyDict_New)(void);
267071d4279SBram Moolenaar static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
268*db913953SBram Moolenaar static int (*dll_PyDict_Next)(PyObject *, Py_ssize_t *, PyObject **, PyObject **);
269*db913953SBram Moolenaar # ifndef PY_NO_MAPPING_ITEMS
270*db913953SBram Moolenaar static PyObject* (*dll_PyMapping_Items)(PyObject *);
271*db913953SBram Moolenaar # endif
272*db913953SBram Moolenaar static PyObject* (*dll_PyObject_CallMethod)(PyObject *, char *, PyObject *);
273*db913953SBram Moolenaar static int (*dll_PyMapping_Check)(PyObject *);
274*db913953SBram Moolenaar static PyObject* (*dll_PyIter_Next)(PyObject *);
275071d4279SBram Moolenaar static PyObject*(*dll_PyModule_GetDict)(PyObject *);
276071d4279SBram Moolenaar static int(*dll_PyRun_SimpleString)(char *);
277*db913953SBram Moolenaar static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *);
278071d4279SBram Moolenaar static char*(*dll_PyString_AsString)(PyObject *);
279071d4279SBram Moolenaar static PyObject*(*dll_PyString_FromString)(const char *);
2802c45e945SBram Moolenaar static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt);
2812c45e945SBram Moolenaar static PyInt(*dll_PyString_Size)(PyObject *);
282071d4279SBram Moolenaar static PyTypeObject* dll_PyString_Type;
283*db913953SBram Moolenaar static PyTypeObject* dll_PyUnicode_Type;
284*db913953SBram Moolenaar static PyObject *(*PyUnicodeUCS4_AsEncodedString)(PyObject *, char *, char *);
285*db913953SBram Moolenaar static double(*dll_PyFloat_AsDouble)(PyObject *);
286*db913953SBram Moolenaar static PyObject*(*dll_PyFloat_FromDouble)(double);
287*db913953SBram Moolenaar static PyTypeObject* dll_PyFloat_Type;
288071d4279SBram Moolenaar static int(*dll_PySys_SetObject)(char *, PyObject *);
289071d4279SBram Moolenaar static int(*dll_PySys_SetArgv)(int, char **);
290071d4279SBram Moolenaar static PyTypeObject* dll_PyType_Type;
29130fec7bcSBram Moolenaar static int (*dll_PyType_Ready)(PyTypeObject *type);
292071d4279SBram Moolenaar static PyObject*(*dll_Py_BuildValue)(char *, ...);
293071d4279SBram Moolenaar static PyObject*(*dll_Py_FindMethod)(struct PyMethodDef[], PyObject *, char *);
294071d4279SBram Moolenaar static PyObject*(*dll_Py_InitModule4)(char *, struct PyMethodDef *, char *, PyObject *, int);
295*db913953SBram Moolenaar static PyObject*(*dll_PyImport_AddModule)(char *);
296644d37b8SBram Moolenaar static void(*dll_Py_SetPythonHome)(char *home);
297071d4279SBram Moolenaar static void(*dll_Py_Initialize)(void);
2980e21a3f6SBram Moolenaar static void(*dll_Py_Finalize)(void);
2990e21a3f6SBram Moolenaar static int(*dll_Py_IsInitialized)(void);
300071d4279SBram Moolenaar static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
301071d4279SBram Moolenaar static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
302*db913953SBram Moolenaar static PyObject* (*dll_PyObject_GetIter)(PyObject *);
303*db913953SBram Moolenaar static iternextfunc dll__PyObject_NextNotImplemented;
304071d4279SBram Moolenaar static PyObject* dll__Py_NoneStruct;
305071d4279SBram Moolenaar # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
306071d4279SBram Moolenaar static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
307071d4279SBram Moolenaar # endif
308071d4279SBram Moolenaar # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
309071d4279SBram Moolenaar static void* (*dll_PyObject_Malloc)(size_t);
310071d4279SBram Moolenaar static void (*dll_PyObject_Free)(void*);
311071d4279SBram Moolenaar # endif
312*db913953SBram Moolenaar static PyObject* (*dll_PyCapsule_New)(void *, char *, PyCapsule_Destructor);
313*db913953SBram Moolenaar static void* (*dll_PyCapsule_GetPointer)(PyObject *, char *);
314071d4279SBram Moolenaar 
315071d4279SBram Moolenaar static HINSTANCE hinstPython = 0; /* Instance of python.dll */
316071d4279SBram Moolenaar 
317071d4279SBram Moolenaar /* Imported exception objects */
318071d4279SBram Moolenaar static PyObject *imp_PyExc_AttributeError;
319071d4279SBram Moolenaar static PyObject *imp_PyExc_IndexError;
320071d4279SBram Moolenaar static PyObject *imp_PyExc_KeyboardInterrupt;
321071d4279SBram Moolenaar static PyObject *imp_PyExc_TypeError;
322071d4279SBram Moolenaar static PyObject *imp_PyExc_ValueError;
323071d4279SBram Moolenaar 
324071d4279SBram Moolenaar # define PyExc_AttributeError imp_PyExc_AttributeError
325071d4279SBram Moolenaar # define PyExc_IndexError imp_PyExc_IndexError
326071d4279SBram Moolenaar # define PyExc_KeyboardInterrupt imp_PyExc_KeyboardInterrupt
327071d4279SBram Moolenaar # define PyExc_TypeError imp_PyExc_TypeError
328071d4279SBram Moolenaar # define PyExc_ValueError imp_PyExc_ValueError
329071d4279SBram Moolenaar 
330071d4279SBram Moolenaar /*
331071d4279SBram Moolenaar  * Table of name to function pointer of python.
332071d4279SBram Moolenaar  */
333071d4279SBram Moolenaar # define PYTHON_PROC FARPROC
334071d4279SBram Moolenaar static struct
335071d4279SBram Moolenaar {
336071d4279SBram Moolenaar     char *name;
337071d4279SBram Moolenaar     PYTHON_PROC *ptr;
338071d4279SBram Moolenaar } python_funcname_table[] =
339071d4279SBram Moolenaar {
340071d4279SBram Moolenaar     {"PyArg_Parse", (PYTHON_PROC*)&dll_PyArg_Parse},
341071d4279SBram Moolenaar     {"PyArg_ParseTuple", (PYTHON_PROC*)&dll_PyArg_ParseTuple},
34219e60943SBram Moolenaar     {"PyMem_Free", (PYTHON_PROC*)&dll_PyMem_Free},
343*db913953SBram Moolenaar     {"PyMem_Malloc", (PYTHON_PROC*)&dll_PyMem_Malloc},
344071d4279SBram Moolenaar     {"PyDict_SetItemString", (PYTHON_PROC*)&dll_PyDict_SetItemString},
345071d4279SBram Moolenaar     {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument},
346071d4279SBram Moolenaar     {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear},
347071d4279SBram Moolenaar     {"PyErr_NoMemory", (PYTHON_PROC*)&dll_PyErr_NoMemory},
348071d4279SBram Moolenaar     {"PyErr_Occurred", (PYTHON_PROC*)&dll_PyErr_Occurred},
349071d4279SBram Moolenaar     {"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone},
350071d4279SBram Moolenaar     {"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString},
351071d4279SBram Moolenaar     {"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads},
352071d4279SBram Moolenaar     {"PyEval_RestoreThread", (PYTHON_PROC*)&dll_PyEval_RestoreThread},
353071d4279SBram Moolenaar     {"PyEval_SaveThread", (PYTHON_PROC*)&dll_PyEval_SaveThread},
354071d4279SBram Moolenaar # ifdef PY_CAN_RECURSE
355071d4279SBram Moolenaar     {"PyGILState_Ensure", (PYTHON_PROC*)&dll_PyGILState_Ensure},
356071d4279SBram Moolenaar     {"PyGILState_Release", (PYTHON_PROC*)&dll_PyGILState_Release},
357071d4279SBram Moolenaar # endif
358071d4279SBram Moolenaar     {"PyInt_AsLong", (PYTHON_PROC*)&dll_PyInt_AsLong},
359071d4279SBram Moolenaar     {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong},
360*db913953SBram Moolenaar     {"PyLong_AsLong", (PYTHON_PROC*)&dll_PyLong_AsLong},
361*db913953SBram Moolenaar     {"PyLong_FromLong", (PYTHON_PROC*)&dll_PyLong_FromLong},
362071d4279SBram Moolenaar     {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type},
363*db913953SBram Moolenaar     {"PyLong_Type", (PYTHON_PROC*)&dll_PyLong_Type},
364071d4279SBram Moolenaar     {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
3650ac9379aSBram Moolenaar     {"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append},
366071d4279SBram Moolenaar     {"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
367071d4279SBram Moolenaar     {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
368071d4279SBram Moolenaar     {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
369071d4279SBram Moolenaar     {"PyList_Type", (PYTHON_PROC*)&dll_PyList_Type},
370*db913953SBram Moolenaar     {"PySequence_GetItem", (PYTHON_PROC*)&dll_PySequence_GetItem},
371*db913953SBram Moolenaar     {"PySequence_Size", (PYTHON_PROC*)&dll_PySequence_Size},
372*db913953SBram Moolenaar     {"PySequence_Check", (PYTHON_PROC*)&dll_PySequence_Check},
373*db913953SBram Moolenaar     {"PyTuple_GetItem", (PYTHON_PROC*)&dll_PyTuple_GetItem},
374*db913953SBram Moolenaar     {"PyTuple_Size", (PYTHON_PROC*)&dll_PyTuple_Size},
375*db913953SBram Moolenaar     {"PyTuple_Type", (PYTHON_PROC*)&dll_PyTuple_Type},
376071d4279SBram Moolenaar     {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule},
377071d4279SBram Moolenaar     {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString},
378*db913953SBram Moolenaar     {"PyDict_Next", (PYTHON_PROC*)&dll_PyDict_Next},
3790ac9379aSBram Moolenaar     {"PyDict_New", (PYTHON_PROC*)&dll_PyDict_New},
380*db913953SBram Moolenaar # ifndef PY_NO_MAPPING_ITEMS
381*db913953SBram Moolenaar     {"PyMapping_Items", (PYTHON_PROC*)&dll_PyMapping_Items},
382*db913953SBram Moolenaar # endif
383*db913953SBram Moolenaar     {"PyObject_CallMethod", (PYTHON_PROC*)&dll_PyObject_CallMethod},
384*db913953SBram Moolenaar     {"PyMapping_Check", (PYTHON_PROC*)&dll_PyMapping_Check},
385*db913953SBram Moolenaar     {"PyIter_Next", (PYTHON_PROC*)&dll_PyIter_Next},
386071d4279SBram Moolenaar     {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
387071d4279SBram Moolenaar     {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
388*db913953SBram Moolenaar     {"PyRun_String", (PYTHON_PROC*)&dll_PyRun_String},
389071d4279SBram Moolenaar     {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
390071d4279SBram Moolenaar     {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
391071d4279SBram Moolenaar     {"PyString_FromStringAndSize", (PYTHON_PROC*)&dll_PyString_FromStringAndSize},
392071d4279SBram Moolenaar     {"PyString_Size", (PYTHON_PROC*)&dll_PyString_Size},
393071d4279SBram Moolenaar     {"PyString_Type", (PYTHON_PROC*)&dll_PyString_Type},
394*db913953SBram Moolenaar     {"PyUnicode_Type", (PYTHON_PROC*)&dll_PyUnicode_Type},
395*db913953SBram Moolenaar     {"PyUnicodeUCS4_AsEncodedString", (PYTHON_PROC*)&dll_PyUnicodeUCS4_AsEncodedString},
396*db913953SBram Moolenaar     {"PyFloat_Type", (PYTHON_PROC*)&dll_PyFloat_Type},
397*db913953SBram Moolenaar     {"PyFloat_AsDouble", (PYTHON_PROC*)&dll_PyFloat_AsDouble},
398*db913953SBram Moolenaar     {"PyFloat_FromDouble", (PYTHON_PROC*)&dll_PyFloat_FromDouble},
399*db913953SBram Moolenaar     {"PyImport_AddModule", (PYTHON_PROC*)&dll_PyImport_AddModule},
400071d4279SBram Moolenaar     {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
401071d4279SBram Moolenaar     {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
402071d4279SBram Moolenaar     {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
40330fec7bcSBram Moolenaar     {"PyType_Ready", (PYTHON_PROC*)&dll_PyType_Ready},
404071d4279SBram Moolenaar     {"Py_BuildValue", (PYTHON_PROC*)&dll_Py_BuildValue},
405071d4279SBram Moolenaar     {"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod},
406e7cb9cf6SBram Moolenaar # if (PY_VERSION_HEX >= 0x02050000) && SIZEOF_SIZE_T != SIZEOF_INT
407e7cb9cf6SBram Moolenaar     {"Py_InitModule4_64", (PYTHON_PROC*)&dll_Py_InitModule4},
408e7cb9cf6SBram Moolenaar # else
409071d4279SBram Moolenaar     {"Py_InitModule4", (PYTHON_PROC*)&dll_Py_InitModule4},
410e7cb9cf6SBram Moolenaar # endif
411644d37b8SBram Moolenaar     {"Py_SetPythonHome", (PYTHON_PROC*)&dll_Py_SetPythonHome},
412071d4279SBram Moolenaar     {"Py_Initialize", (PYTHON_PROC*)&dll_Py_Initialize},
4130e21a3f6SBram Moolenaar     {"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
4140e21a3f6SBram Moolenaar     {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
415071d4279SBram Moolenaar     {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
416071d4279SBram Moolenaar     {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
417*db913953SBram Moolenaar     {"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter},
418*db913953SBram Moolenaar     {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&dll__PyObject_NextNotImplemented},
419071d4279SBram Moolenaar     {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct},
420071d4279SBram Moolenaar # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
421071d4279SBram Moolenaar     {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype},
422071d4279SBram Moolenaar # endif
423071d4279SBram Moolenaar # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
424071d4279SBram Moolenaar     {"PyObject_Malloc", (PYTHON_PROC*)&dll_PyObject_Malloc},
425071d4279SBram Moolenaar     {"PyObject_Free", (PYTHON_PROC*)&dll_PyObject_Free},
426071d4279SBram Moolenaar # endif
427*db913953SBram Moolenaar     {"PyCapsule_New", (PYTHON_PROC*)&dll_PyCapsule_New},
428*db913953SBram Moolenaar     {"PyCapsule_GetPointer", (PYTHON_PROC*)&dll_PyCapsule_GetPointer},
429071d4279SBram Moolenaar     {"", NULL},
430071d4279SBram Moolenaar };
431071d4279SBram Moolenaar 
432071d4279SBram Moolenaar /*
433071d4279SBram Moolenaar  * Free python.dll
434071d4279SBram Moolenaar  */
435071d4279SBram Moolenaar     static void
436071d4279SBram Moolenaar end_dynamic_python(void)
437071d4279SBram Moolenaar {
438071d4279SBram Moolenaar     if (hinstPython)
439071d4279SBram Moolenaar     {
440bd5e15fdSBram Moolenaar 	close_dll(hinstPython);
441071d4279SBram Moolenaar 	hinstPython = 0;
442071d4279SBram Moolenaar     }
443071d4279SBram Moolenaar }
444071d4279SBram Moolenaar 
445071d4279SBram Moolenaar /*
446071d4279SBram Moolenaar  * Load library and get all pointers.
447071d4279SBram Moolenaar  * Parameter 'libname' provides name of DLL.
448071d4279SBram Moolenaar  * Return OK or FAIL.
449071d4279SBram Moolenaar  */
450071d4279SBram Moolenaar     static int
451071d4279SBram Moolenaar python_runtime_link_init(char *libname, int verbose)
452071d4279SBram Moolenaar {
453071d4279SBram Moolenaar     int i;
454071d4279SBram Moolenaar 
455644d37b8SBram Moolenaar #if !(defined(PY_NO_RTLD_GLOBAL) && defined(PY3_NO_RTLD_GLOBAL)) && defined(UNIX) && defined(FEAT_PYTHON3)
456b744b2faSBram Moolenaar     /* Can't have Python and Python3 loaded at the same time.
457b744b2faSBram Moolenaar      * It cause a crash, because RTLD_GLOBAL is needed for
458b744b2faSBram Moolenaar      * standard C extension libraries of one or both python versions. */
4594c3a326cSBram Moolenaar     if (python3_loaded())
4604c3a326cSBram Moolenaar     {
4619dc93ae4SBram Moolenaar 	if (verbose)
462b744b2faSBram Moolenaar 	    EMSG(_("E836: This Vim cannot execute :python after using :py3"));
4634c3a326cSBram Moolenaar 	return FAIL;
4644c3a326cSBram Moolenaar     }
4654c3a326cSBram Moolenaar #endif
4664c3a326cSBram Moolenaar 
467071d4279SBram Moolenaar     if (hinstPython)
468071d4279SBram Moolenaar 	return OK;
469bd5e15fdSBram Moolenaar     hinstPython = load_dll(libname);
470071d4279SBram Moolenaar     if (!hinstPython)
471071d4279SBram Moolenaar     {
472071d4279SBram Moolenaar 	if (verbose)
473071d4279SBram Moolenaar 	    EMSG2(_(e_loadlib), libname);
474071d4279SBram Moolenaar 	return FAIL;
475071d4279SBram Moolenaar     }
476071d4279SBram Moolenaar 
477071d4279SBram Moolenaar     for (i = 0; python_funcname_table[i].ptr; ++i)
478071d4279SBram Moolenaar     {
479bd5e15fdSBram Moolenaar 	if ((*python_funcname_table[i].ptr = symbol_from_dll(hinstPython,
480071d4279SBram Moolenaar 			python_funcname_table[i].name)) == NULL)
481071d4279SBram Moolenaar 	{
482bd5e15fdSBram Moolenaar 	    close_dll(hinstPython);
483071d4279SBram Moolenaar 	    hinstPython = 0;
484071d4279SBram Moolenaar 	    if (verbose)
485071d4279SBram Moolenaar 		EMSG2(_(e_loadfunc), python_funcname_table[i].name);
486071d4279SBram Moolenaar 	    return FAIL;
487071d4279SBram Moolenaar 	}
488071d4279SBram Moolenaar     }
489071d4279SBram Moolenaar     return OK;
490071d4279SBram Moolenaar }
491071d4279SBram Moolenaar 
492071d4279SBram Moolenaar /*
493071d4279SBram Moolenaar  * If python is enabled (there is installed python on Windows system) return
494071d4279SBram Moolenaar  * TRUE, else FALSE.
495071d4279SBram Moolenaar  */
496071d4279SBram Moolenaar     int
497e7cb9cf6SBram Moolenaar python_enabled(int verbose)
498071d4279SBram Moolenaar {
499071d4279SBram Moolenaar     return python_runtime_link_init(DYNAMIC_PYTHON_DLL, verbose) == OK;
500071d4279SBram Moolenaar }
501071d4279SBram Moolenaar 
502ca8a4dfeSBram Moolenaar /*
503ca8a4dfeSBram Moolenaar  * Load the standard Python exceptions - don't import the symbols from the
504071d4279SBram Moolenaar  * DLL, as this can cause errors (importing data symbols is not reliable).
505071d4279SBram Moolenaar  */
506071d4279SBram Moolenaar     static void
507ca8a4dfeSBram Moolenaar get_exceptions(void)
508071d4279SBram Moolenaar {
509071d4279SBram Moolenaar     PyObject *exmod = PyImport_ImportModule("exceptions");
510071d4279SBram Moolenaar     PyObject *exdict = PyModule_GetDict(exmod);
511071d4279SBram Moolenaar     imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
512071d4279SBram Moolenaar     imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
513071d4279SBram Moolenaar     imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
514071d4279SBram Moolenaar     imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
515071d4279SBram Moolenaar     imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
516071d4279SBram Moolenaar     Py_XINCREF(imp_PyExc_AttributeError);
517071d4279SBram Moolenaar     Py_XINCREF(imp_PyExc_IndexError);
518071d4279SBram Moolenaar     Py_XINCREF(imp_PyExc_KeyboardInterrupt);
519071d4279SBram Moolenaar     Py_XINCREF(imp_PyExc_TypeError);
520071d4279SBram Moolenaar     Py_XINCREF(imp_PyExc_ValueError);
521071d4279SBram Moolenaar     Py_XDECREF(exmod);
522071d4279SBram Moolenaar }
523071d4279SBram Moolenaar #endif /* DYNAMIC_PYTHON */
524071d4279SBram Moolenaar 
525ca8a4dfeSBram Moolenaar static PyObject *BufferNew (buf_T *);
526ca8a4dfeSBram Moolenaar static PyObject *WindowNew(win_T *);
527*db913953SBram Moolenaar static PyObject *DictionaryNew(dict_T *);
528ca8a4dfeSBram Moolenaar static PyObject *LineToString(const char *);
529ca8a4dfeSBram Moolenaar 
530ca8a4dfeSBram Moolenaar static PyTypeObject RangeType;
531ca8a4dfeSBram Moolenaar 
532*db913953SBram Moolenaar static int initialised = 0;
533*db913953SBram Moolenaar #define PYINITIALISED initialised
534*db913953SBram Moolenaar 
535*db913953SBram Moolenaar /* Add conversion from PyInt? */
536*db913953SBram Moolenaar #define DICTKEY_GET(err) \
537*db913953SBram Moolenaar     if (!PyString_Check(keyObject)) \
538*db913953SBram Moolenaar     { \
539*db913953SBram Moolenaar 	PyErr_SetString(PyExc_TypeError, _("only string keys are allowed")); \
540*db913953SBram Moolenaar 	return err; \
541*db913953SBram Moolenaar     } \
542*db913953SBram Moolenaar     key = (char_u *) PyString_AsString(keyObject);
543*db913953SBram Moolenaar #define DICTKEY_UNREF
544*db913953SBram Moolenaar #define DICTKEY_DECL
545*db913953SBram Moolenaar 
546170bf1aeSBram Moolenaar /*
547170bf1aeSBram Moolenaar  * Include the code shared with if_python3.c
548170bf1aeSBram Moolenaar  */
549170bf1aeSBram Moolenaar #include "if_py_both.h"
550170bf1aeSBram Moolenaar 
551170bf1aeSBram Moolenaar 
552071d4279SBram Moolenaar /******************************************************
553071d4279SBram Moolenaar  * Internal function prototypes.
554071d4279SBram Moolenaar  */
555071d4279SBram Moolenaar 
556e7cb9cf6SBram Moolenaar static PyInt RangeStart;
557e7cb9cf6SBram Moolenaar static PyInt RangeEnd;
558071d4279SBram Moolenaar 
559*db913953SBram Moolenaar static PyObject *globals;
560*db913953SBram Moolenaar 
561071d4279SBram Moolenaar static void PythonIO_Flush(void);
562071d4279SBram Moolenaar static int PythonIO_Init(void);
563071d4279SBram Moolenaar static int PythonMod_Init(void);
564071d4279SBram Moolenaar 
565071d4279SBram Moolenaar /* Utility functions for the vim/python interface
566071d4279SBram Moolenaar  * ----------------------------------------------
567071d4279SBram Moolenaar  */
568071d4279SBram Moolenaar 
569e7cb9cf6SBram Moolenaar static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, PyInt *);
570071d4279SBram Moolenaar 
571071d4279SBram Moolenaar 
572071d4279SBram Moolenaar /******************************************************
573071d4279SBram Moolenaar  * 1. Python interpreter main program.
574071d4279SBram Moolenaar  */
575071d4279SBram Moolenaar 
576071d4279SBram Moolenaar #if PYTHON_API_VERSION < 1007 /* Python 1.4 */
577071d4279SBram Moolenaar typedef PyObject PyThreadState;
5789ba0eb85SBram Moolenaar #endif
579071d4279SBram Moolenaar 
5809ba0eb85SBram Moolenaar #ifdef PY_CAN_RECURSE
5819ba0eb85SBram Moolenaar static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
5829ba0eb85SBram Moolenaar #else
583071d4279SBram Moolenaar static PyThreadState *saved_python_thread = NULL;
5849ba0eb85SBram Moolenaar #endif
585071d4279SBram Moolenaar 
586071d4279SBram Moolenaar /*
587071d4279SBram Moolenaar  * Suspend a thread of the Python interpreter, other threads are allowed to
588071d4279SBram Moolenaar  * run.
589071d4279SBram Moolenaar  */
590293ee4d4SBram Moolenaar     static void
591293ee4d4SBram Moolenaar Python_SaveThread(void)
592071d4279SBram Moolenaar {
5939ba0eb85SBram Moolenaar #ifdef PY_CAN_RECURSE
5949ba0eb85SBram Moolenaar     PyGILState_Release(pygilstate);
5959ba0eb85SBram Moolenaar #else
596071d4279SBram Moolenaar     saved_python_thread = PyEval_SaveThread();
5979ba0eb85SBram Moolenaar #endif
598071d4279SBram Moolenaar }
599071d4279SBram Moolenaar 
600071d4279SBram Moolenaar /*
601071d4279SBram Moolenaar  * Restore a thread of the Python interpreter, waits for other threads to
602071d4279SBram Moolenaar  * block.
603071d4279SBram Moolenaar  */
604293ee4d4SBram Moolenaar     static void
605293ee4d4SBram Moolenaar Python_RestoreThread(void)
606071d4279SBram Moolenaar {
6079ba0eb85SBram Moolenaar #ifdef PY_CAN_RECURSE
6089ba0eb85SBram Moolenaar     pygilstate = PyGILState_Ensure();
6099ba0eb85SBram Moolenaar #else
610071d4279SBram Moolenaar     PyEval_RestoreThread(saved_python_thread);
611071d4279SBram Moolenaar     saved_python_thread = NULL;
612071d4279SBram Moolenaar #endif
6139ba0eb85SBram Moolenaar }
614071d4279SBram Moolenaar 
615071d4279SBram Moolenaar     void
616071d4279SBram Moolenaar python_end()
617071d4279SBram Moolenaar {
618a5792f58SBram Moolenaar     static int recurse = 0;
619a5792f58SBram Moolenaar 
620a5792f58SBram Moolenaar     /* If a crash occurs while doing this, don't try again. */
621a5792f58SBram Moolenaar     if (recurse != 0)
622a5792f58SBram Moolenaar 	return;
623a5792f58SBram Moolenaar 
624a5792f58SBram Moolenaar     ++recurse;
625a5792f58SBram Moolenaar 
626071d4279SBram Moolenaar #ifdef DYNAMIC_PYTHON
6270e21a3f6SBram Moolenaar     if (hinstPython && Py_IsInitialized())
6289ba0eb85SBram Moolenaar     {
6299ba0eb85SBram Moolenaar 	Python_RestoreThread();	    /* enter python */
6300e21a3f6SBram Moolenaar 	Py_Finalize();
6319ba0eb85SBram Moolenaar     }
632071d4279SBram Moolenaar     end_dynamic_python();
6330e21a3f6SBram Moolenaar #else
6340e21a3f6SBram Moolenaar     if (Py_IsInitialized())
6359ba0eb85SBram Moolenaar     {
6369ba0eb85SBram Moolenaar 	Python_RestoreThread();	    /* enter python */
6370e21a3f6SBram Moolenaar 	Py_Finalize();
6389ba0eb85SBram Moolenaar     }
639071d4279SBram Moolenaar #endif
640a5792f58SBram Moolenaar 
641a5792f58SBram Moolenaar     --recurse;
642071d4279SBram Moolenaar }
643071d4279SBram Moolenaar 
6444c3a326cSBram Moolenaar #if (defined(DYNAMIC_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO)
6454c3a326cSBram Moolenaar     int
6464c3a326cSBram Moolenaar python_loaded()
6474c3a326cSBram Moolenaar {
6484c3a326cSBram Moolenaar     return (hinstPython != 0);
6494c3a326cSBram Moolenaar }
6504c3a326cSBram Moolenaar #endif
6514c3a326cSBram Moolenaar 
652071d4279SBram Moolenaar     static int
653071d4279SBram Moolenaar Python_Init(void)
654071d4279SBram Moolenaar {
655071d4279SBram Moolenaar     if (!initialised)
656071d4279SBram Moolenaar     {
657071d4279SBram Moolenaar #ifdef DYNAMIC_PYTHON
658071d4279SBram Moolenaar 	if (!python_enabled(TRUE))
659071d4279SBram Moolenaar 	{
660071d4279SBram Moolenaar 	    EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
661071d4279SBram Moolenaar 	    goto fail;
662071d4279SBram Moolenaar 	}
663071d4279SBram Moolenaar #endif
664071d4279SBram Moolenaar 
665644d37b8SBram Moolenaar #ifdef PYTHON_HOME
666644d37b8SBram Moolenaar 	Py_SetPythonHome(PYTHON_HOME);
667644d37b8SBram Moolenaar #endif
668644d37b8SBram Moolenaar 
669170bf1aeSBram Moolenaar 	init_structs();
670170bf1aeSBram Moolenaar 
671071d4279SBram Moolenaar #if !defined(MACOS) || defined(MACOS_X_UNIX)
672071d4279SBram Moolenaar 	Py_Initialize();
673071d4279SBram Moolenaar #else
674071d4279SBram Moolenaar 	PyMac_Initialize();
675071d4279SBram Moolenaar #endif
676071d4279SBram Moolenaar 	/* initialise threads */
677071d4279SBram Moolenaar 	PyEval_InitThreads();
678071d4279SBram Moolenaar 
679071d4279SBram Moolenaar #ifdef DYNAMIC_PYTHON
680071d4279SBram Moolenaar 	get_exceptions();
681071d4279SBram Moolenaar #endif
682071d4279SBram Moolenaar 
683071d4279SBram Moolenaar 	if (PythonIO_Init())
684071d4279SBram Moolenaar 	    goto fail;
685071d4279SBram Moolenaar 
686071d4279SBram Moolenaar 	if (PythonMod_Init())
687071d4279SBram Moolenaar 	    goto fail;
688071d4279SBram Moolenaar 
689*db913953SBram Moolenaar 	globals = PyModule_GetDict(PyImport_AddModule("__main__"));
690*db913953SBram Moolenaar 
6919774ecc8SBram Moolenaar 	/* Remove the element from sys.path that was added because of our
6929774ecc8SBram Moolenaar 	 * argv[0] value in PythonMod_Init().  Previously we used an empty
6939774ecc8SBram Moolenaar 	 * string, but dependinding on the OS we then get an empty entry or
6949774ecc8SBram Moolenaar 	 * the current directory in sys.path. */
6959774ecc8SBram Moolenaar 	PyRun_SimpleString("import sys; sys.path = filter(lambda x: x != '/must>not&exist', sys.path)");
6969774ecc8SBram Moolenaar 
697293ee4d4SBram Moolenaar 	/* the first python thread is vim's, release the lock */
698071d4279SBram Moolenaar 	Python_SaveThread();
699071d4279SBram Moolenaar 
700071d4279SBram Moolenaar 	initialised = 1;
701071d4279SBram Moolenaar     }
702071d4279SBram Moolenaar 
703071d4279SBram Moolenaar     return 0;
704071d4279SBram Moolenaar 
705071d4279SBram Moolenaar fail:
706071d4279SBram Moolenaar     /* We call PythonIO_Flush() here to print any Python errors.
707071d4279SBram Moolenaar      * This is OK, as it is possible to call this function even
708071d4279SBram Moolenaar      * if PythonIO_Init() has not completed successfully (it will
709071d4279SBram Moolenaar      * not do anything in this case).
710071d4279SBram Moolenaar      */
711071d4279SBram Moolenaar     PythonIO_Flush();
712071d4279SBram Moolenaar     return -1;
713071d4279SBram Moolenaar }
714071d4279SBram Moolenaar 
715071d4279SBram Moolenaar /*
716071d4279SBram Moolenaar  * External interface
717071d4279SBram Moolenaar  */
718071d4279SBram Moolenaar     static void
719*db913953SBram Moolenaar DoPythonCommand(exarg_T *eap, const char *cmd, typval_T *rettv)
720071d4279SBram Moolenaar {
7219ba0eb85SBram Moolenaar #ifndef PY_CAN_RECURSE
722071d4279SBram Moolenaar     static int		recursive = 0;
723071d4279SBram Moolenaar #endif
724071d4279SBram Moolenaar #if defined(MACOS) && !defined(MACOS_X_UNIX)
725071d4279SBram Moolenaar     GrafPtr		oldPort;
726071d4279SBram Moolenaar #endif
727071d4279SBram Moolenaar #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
728071d4279SBram Moolenaar     char		*saved_locale;
729071d4279SBram Moolenaar #endif
730071d4279SBram Moolenaar 
731071d4279SBram Moolenaar #ifndef PY_CAN_RECURSE
732071d4279SBram Moolenaar     if (recursive)
733071d4279SBram Moolenaar     {
734071d4279SBram Moolenaar 	EMSG(_("E659: Cannot invoke Python recursively"));
735071d4279SBram Moolenaar 	return;
736071d4279SBram Moolenaar     }
737071d4279SBram Moolenaar     ++recursive;
738071d4279SBram Moolenaar #endif
739071d4279SBram Moolenaar 
740071d4279SBram Moolenaar #if defined(MACOS) && !defined(MACOS_X_UNIX)
741071d4279SBram Moolenaar     GetPort(&oldPort);
742071d4279SBram Moolenaar     /* Check if the Python library is available */
743071d4279SBram Moolenaar     if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
744071d4279SBram Moolenaar 	goto theend;
745071d4279SBram Moolenaar #endif
746071d4279SBram Moolenaar     if (Python_Init())
747071d4279SBram Moolenaar 	goto theend;
748071d4279SBram Moolenaar 
749*db913953SBram Moolenaar     if (rettv == NULL)
750*db913953SBram Moolenaar     {
751071d4279SBram Moolenaar 	RangeStart = eap->line1;
752071d4279SBram Moolenaar 	RangeEnd = eap->line2;
753*db913953SBram Moolenaar     }
754*db913953SBram Moolenaar     else
755*db913953SBram Moolenaar     {
756*db913953SBram Moolenaar 	RangeStart = (PyInt) curwin->w_cursor.lnum;
757*db913953SBram Moolenaar 	RangeEnd = RangeStart;
758*db913953SBram Moolenaar     }
759071d4279SBram Moolenaar     Python_Release_Vim();	    /* leave vim */
760071d4279SBram Moolenaar 
761071d4279SBram Moolenaar #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
762071d4279SBram Moolenaar     /* Python only works properly when the LC_NUMERIC locale is "C". */
763071d4279SBram Moolenaar     saved_locale = setlocale(LC_NUMERIC, NULL);
764071d4279SBram Moolenaar     if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
765071d4279SBram Moolenaar 	saved_locale = NULL;
766071d4279SBram Moolenaar     else
767071d4279SBram Moolenaar     {
768071d4279SBram Moolenaar 	/* Need to make a copy, value may change when setting new locale. */
769071d4279SBram Moolenaar 	saved_locale = (char *)vim_strsave((char_u *)saved_locale);
770071d4279SBram Moolenaar 	(void)setlocale(LC_NUMERIC, "C");
771071d4279SBram Moolenaar     }
772071d4279SBram Moolenaar #endif
773071d4279SBram Moolenaar 
774071d4279SBram Moolenaar     Python_RestoreThread();	    /* enter python */
775071d4279SBram Moolenaar 
776*db913953SBram Moolenaar     if (rettv == NULL)
777071d4279SBram Moolenaar 	PyRun_SimpleString((char *)(cmd));
778*db913953SBram Moolenaar     else
779*db913953SBram Moolenaar     {
780*db913953SBram Moolenaar 	PyObject	*r;
781*db913953SBram Moolenaar 
782*db913953SBram Moolenaar 	r = PyRun_String((char *)(cmd), Py_eval_input, globals, globals);
783*db913953SBram Moolenaar 	if (r == NULL)
784*db913953SBram Moolenaar 	    EMSG(_("E858: Eval did not return a valid python object"));
785*db913953SBram Moolenaar 	else
786*db913953SBram Moolenaar 	{
787*db913953SBram Moolenaar 	    if (ConvertFromPyObject(r, rettv) == -1)
788*db913953SBram Moolenaar 		EMSG(_("E859: Failed to convert returned python object to vim value"));
789*db913953SBram Moolenaar 	    Py_DECREF(r);
790*db913953SBram Moolenaar 	}
791*db913953SBram Moolenaar 	PyErr_Clear();
792*db913953SBram Moolenaar     }
793071d4279SBram Moolenaar 
794071d4279SBram Moolenaar     Python_SaveThread();	    /* leave python */
795071d4279SBram Moolenaar 
796071d4279SBram Moolenaar #if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
797071d4279SBram Moolenaar     if (saved_locale != NULL)
798071d4279SBram Moolenaar     {
799071d4279SBram Moolenaar 	(void)setlocale(LC_NUMERIC, saved_locale);
800071d4279SBram Moolenaar 	vim_free(saved_locale);
801071d4279SBram Moolenaar     }
802071d4279SBram Moolenaar #endif
803071d4279SBram Moolenaar 
804071d4279SBram Moolenaar     Python_Lock_Vim();		    /* enter vim */
805071d4279SBram Moolenaar     PythonIO_Flush();
806071d4279SBram Moolenaar #if defined(MACOS) && !defined(MACOS_X_UNIX)
807071d4279SBram Moolenaar     SetPort(oldPort);
808071d4279SBram Moolenaar #endif
809071d4279SBram Moolenaar 
810071d4279SBram Moolenaar theend:
811071d4279SBram Moolenaar #ifndef PY_CAN_RECURSE
812071d4279SBram Moolenaar     --recursive;
813071d4279SBram Moolenaar #endif
814*db913953SBram Moolenaar     return;
815071d4279SBram Moolenaar }
816071d4279SBram Moolenaar 
817071d4279SBram Moolenaar /*
818071d4279SBram Moolenaar  * ":python"
819071d4279SBram Moolenaar  */
820071d4279SBram Moolenaar     void
821071d4279SBram Moolenaar ex_python(exarg_T *eap)
822071d4279SBram Moolenaar {
823071d4279SBram Moolenaar     char_u *script;
824071d4279SBram Moolenaar 
825071d4279SBram Moolenaar     script = script_get(eap, eap->arg);
826071d4279SBram Moolenaar     if (!eap->skip)
827071d4279SBram Moolenaar     {
828071d4279SBram Moolenaar 	if (script == NULL)
829*db913953SBram Moolenaar 	    DoPythonCommand(eap, (char *)eap->arg, NULL);
830071d4279SBram Moolenaar 	else
831*db913953SBram Moolenaar 	    DoPythonCommand(eap, (char *)script, NULL);
832071d4279SBram Moolenaar     }
833071d4279SBram Moolenaar     vim_free(script);
834071d4279SBram Moolenaar }
835071d4279SBram Moolenaar 
836071d4279SBram Moolenaar #define BUFFER_SIZE 1024
837071d4279SBram Moolenaar 
838071d4279SBram Moolenaar /*
839071d4279SBram Moolenaar  * ":pyfile"
840071d4279SBram Moolenaar  */
841071d4279SBram Moolenaar     void
842071d4279SBram Moolenaar ex_pyfile(exarg_T *eap)
843071d4279SBram Moolenaar {
844071d4279SBram Moolenaar     static char buffer[BUFFER_SIZE];
845071d4279SBram Moolenaar     const char *file = (char *)eap->arg;
846071d4279SBram Moolenaar     char *p;
847071d4279SBram Moolenaar 
848071d4279SBram Moolenaar     /* Have to do it like this. PyRun_SimpleFile requires you to pass a
849071d4279SBram Moolenaar      * stdio file pointer, but Vim and the Python DLL are compiled with
850071d4279SBram Moolenaar      * different options under Windows, meaning that stdio pointers aren't
851071d4279SBram Moolenaar      * compatible between the two. Yuk.
852071d4279SBram Moolenaar      *
853071d4279SBram Moolenaar      * Put the string "execfile('file')" into buffer. But, we need to
854071d4279SBram Moolenaar      * escape any backslashes or single quotes in the file name, so that
855071d4279SBram Moolenaar      * Python won't mangle the file name.
856071d4279SBram Moolenaar      */
857071d4279SBram Moolenaar     strcpy(buffer, "execfile('");
858071d4279SBram Moolenaar     p = buffer + 10; /* size of "execfile('" */
859071d4279SBram Moolenaar 
860071d4279SBram Moolenaar     while (*file && p < buffer + (BUFFER_SIZE - 3))
861071d4279SBram Moolenaar     {
862071d4279SBram Moolenaar 	if (*file == '\\' || *file == '\'')
863071d4279SBram Moolenaar 	    *p++ = '\\';
864071d4279SBram Moolenaar 	*p++ = *file++;
865071d4279SBram Moolenaar     }
866071d4279SBram Moolenaar 
867071d4279SBram Moolenaar     /* If we didn't finish the file name, we hit a buffer overflow */
868071d4279SBram Moolenaar     if (*file != '\0')
869071d4279SBram Moolenaar 	return;
870071d4279SBram Moolenaar 
871071d4279SBram Moolenaar     /* Put in the terminating "')" and a null */
872071d4279SBram Moolenaar     *p++ = '\'';
873071d4279SBram Moolenaar     *p++ = ')';
874071d4279SBram Moolenaar     *p++ = '\0';
875071d4279SBram Moolenaar 
876071d4279SBram Moolenaar     /* Execute the file */
877*db913953SBram Moolenaar     DoPythonCommand(eap, buffer, NULL);
878071d4279SBram Moolenaar }
879071d4279SBram Moolenaar 
880071d4279SBram Moolenaar /******************************************************
881071d4279SBram Moolenaar  * 2. Python output stream: writes output via [e]msg().
882071d4279SBram Moolenaar  */
883071d4279SBram Moolenaar 
884071d4279SBram Moolenaar /* Implementation functions
885071d4279SBram Moolenaar  */
886071d4279SBram Moolenaar 
887071d4279SBram Moolenaar     static PyObject *
888071d4279SBram Moolenaar OutputGetattr(PyObject *self, char *name)
889071d4279SBram Moolenaar {
890071d4279SBram Moolenaar     if (strcmp(name, "softspace") == 0)
891071d4279SBram Moolenaar 	return PyInt_FromLong(((OutputObject *)(self))->softspace);
892071d4279SBram Moolenaar 
893071d4279SBram Moolenaar     return Py_FindMethod(OutputMethods, self, name);
894071d4279SBram Moolenaar }
895071d4279SBram Moolenaar 
896071d4279SBram Moolenaar     static int
897071d4279SBram Moolenaar OutputSetattr(PyObject *self, char *name, PyObject *val)
898071d4279SBram Moolenaar {
899*db913953SBram Moolenaar     if (val == NULL)
900*db913953SBram Moolenaar     {
901071d4279SBram Moolenaar 	PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
902071d4279SBram Moolenaar 	return -1;
903071d4279SBram Moolenaar     }
904071d4279SBram Moolenaar 
905071d4279SBram Moolenaar     if (strcmp(name, "softspace") == 0)
906071d4279SBram Moolenaar     {
907*db913953SBram Moolenaar 	if (!PyInt_Check(val))
908*db913953SBram Moolenaar 	{
909071d4279SBram Moolenaar 	    PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
910071d4279SBram Moolenaar 	    return -1;
911071d4279SBram Moolenaar 	}
912071d4279SBram Moolenaar 
913071d4279SBram Moolenaar 	((OutputObject *)(self))->softspace = PyInt_AsLong(val);
914071d4279SBram Moolenaar 	return 0;
915071d4279SBram Moolenaar     }
916071d4279SBram Moolenaar 
917071d4279SBram Moolenaar     PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
918071d4279SBram Moolenaar     return -1;
919071d4279SBram Moolenaar }
920071d4279SBram Moolenaar 
921071d4279SBram Moolenaar /***************/
922071d4279SBram Moolenaar 
923071d4279SBram Moolenaar     static int
924071d4279SBram Moolenaar PythonIO_Init(void)
925071d4279SBram Moolenaar {
926071d4279SBram Moolenaar     /* Fixups... */
92721377c8dSBram Moolenaar     PyType_Ready(&OutputType);
928071d4279SBram Moolenaar 
929170bf1aeSBram Moolenaar     return PythonIO_Init_io();
930071d4279SBram Moolenaar }
931071d4279SBram Moolenaar 
932071d4279SBram Moolenaar /******************************************************
933071d4279SBram Moolenaar  * 3. Implementation of the Vim module for Python
934071d4279SBram Moolenaar  */
935071d4279SBram Moolenaar 
936*db913953SBram Moolenaar static PyObject *ConvertToPyObject(typval_T *);
937*db913953SBram Moolenaar static int ConvertFromPyObject(PyObject *, typval_T *);
938*db913953SBram Moolenaar 
939071d4279SBram Moolenaar /* Window type - Implementation functions
940071d4279SBram Moolenaar  * --------------------------------------
941071d4279SBram Moolenaar  */
942071d4279SBram Moolenaar 
943071d4279SBram Moolenaar #define WindowType_Check(obj) ((obj)->ob_type == &WindowType)
944071d4279SBram Moolenaar 
945071d4279SBram Moolenaar static void WindowDestructor(PyObject *);
946071d4279SBram Moolenaar static PyObject *WindowGetattr(PyObject *, char *);
947071d4279SBram Moolenaar 
948071d4279SBram Moolenaar /* Buffer type - Implementation functions
949071d4279SBram Moolenaar  * --------------------------------------
950071d4279SBram Moolenaar  */
951071d4279SBram Moolenaar 
952071d4279SBram Moolenaar #define BufferType_Check(obj) ((obj)->ob_type == &BufferType)
953071d4279SBram Moolenaar 
954071d4279SBram Moolenaar static void BufferDestructor(PyObject *);
955071d4279SBram Moolenaar static PyObject *BufferGetattr(PyObject *, char *);
956071d4279SBram Moolenaar static PyObject *BufferRepr(PyObject *);
957071d4279SBram Moolenaar 
9582c45e945SBram Moolenaar static PyInt BufferLength(PyObject *);
9592c45e945SBram Moolenaar static PyObject *BufferItem(PyObject *, PyInt);
9602c45e945SBram Moolenaar static PyObject *BufferSlice(PyObject *, PyInt, PyInt);
9612c45e945SBram Moolenaar static PyInt BufferAssItem(PyObject *, PyInt, PyObject *);
9622c45e945SBram Moolenaar static PyInt BufferAssSlice(PyObject *, PyInt, PyInt, PyObject *);
963071d4279SBram Moolenaar 
964071d4279SBram Moolenaar /* Line range type - Implementation functions
965071d4279SBram Moolenaar  * --------------------------------------
966071d4279SBram Moolenaar  */
967071d4279SBram Moolenaar 
968071d4279SBram Moolenaar #define RangeType_Check(obj) ((obj)->ob_type == &RangeType)
969071d4279SBram Moolenaar 
9702c45e945SBram Moolenaar static PyInt RangeAssItem(PyObject *, PyInt, PyObject *);
9712c45e945SBram Moolenaar static PyInt RangeAssSlice(PyObject *, PyInt, PyInt, PyObject *);
972071d4279SBram Moolenaar 
973071d4279SBram Moolenaar /* Current objects type - Implementation functions
974071d4279SBram Moolenaar  * -----------------------------------------------
975071d4279SBram Moolenaar  */
976071d4279SBram Moolenaar 
977071d4279SBram Moolenaar static PyObject *CurrentGetattr(PyObject *, char *);
978071d4279SBram Moolenaar static int CurrentSetattr(PyObject *, char *, PyObject *);
979071d4279SBram Moolenaar 
980071d4279SBram Moolenaar static PySequenceMethods BufferAsSeq = {
9812c45e945SBram Moolenaar     (PyInquiry)		BufferLength,	    /* sq_length,    len(x)   */
982071d4279SBram Moolenaar     (binaryfunc)	0, /* BufferConcat, */	     /* sq_concat,    x+y      */
9832c45e945SBram Moolenaar     (PyIntArgFunc)	0, /* BufferRepeat, */	     /* sq_repeat,    x*n      */
9842c45e945SBram Moolenaar     (PyIntArgFunc)	BufferItem,	    /* sq_item,      x[i]     */
9852c45e945SBram Moolenaar     (PyIntIntArgFunc)	BufferSlice,	    /* sq_slice,     x[i:j]   */
9862c45e945SBram Moolenaar     (PyIntObjArgProc)	BufferAssItem,	    /* sq_ass_item,  x[i]=v   */
9872c45e945SBram Moolenaar     (PyIntIntObjArgProc)	BufferAssSlice,     /* sq_ass_slice, x[i:j]=v */
988071d4279SBram Moolenaar };
989071d4279SBram Moolenaar 
990071d4279SBram Moolenaar static PyTypeObject BufferType = {
991071d4279SBram Moolenaar     PyObject_HEAD_INIT(0)
992071d4279SBram Moolenaar     0,
993071d4279SBram Moolenaar     "buffer",
994071d4279SBram Moolenaar     sizeof(BufferObject),
995071d4279SBram Moolenaar     0,
996071d4279SBram Moolenaar 
997071d4279SBram Moolenaar     (destructor)    BufferDestructor,	/* tp_dealloc,	refcount==0  */
998071d4279SBram Moolenaar     (printfunc)     0,			/* tp_print,	print x      */
999071d4279SBram Moolenaar     (getattrfunc)   BufferGetattr,	/* tp_getattr,	x.attr	     */
1000071d4279SBram Moolenaar     (setattrfunc)   0,			/* tp_setattr,	x.attr=v     */
1001071d4279SBram Moolenaar     (cmpfunc)	    0,			/* tp_compare,	x>y	     */
1002071d4279SBram Moolenaar     (reprfunc)	    BufferRepr,		/* tp_repr,	`x`, print x */
1003071d4279SBram Moolenaar 
1004071d4279SBram Moolenaar     0,		    /* as number */
1005071d4279SBram Moolenaar     &BufferAsSeq,   /* as sequence */
1006071d4279SBram Moolenaar     0,		    /* as mapping */
1007071d4279SBram Moolenaar 
1008071d4279SBram Moolenaar     (hashfunc) 0,			/* tp_hash, dict(x) */
1009071d4279SBram Moolenaar     (ternaryfunc) 0,			/* tp_call, x()     */
1010071d4279SBram Moolenaar     (reprfunc) 0,			/* tp_str,  str(x)  */
1011071d4279SBram Moolenaar };
1012071d4279SBram Moolenaar 
1013071d4279SBram Moolenaar /* Buffer object - Implementation
1014071d4279SBram Moolenaar  */
1015071d4279SBram Moolenaar 
1016071d4279SBram Moolenaar     static PyObject *
1017071d4279SBram Moolenaar BufferNew(buf_T *buf)
1018071d4279SBram Moolenaar {
1019071d4279SBram Moolenaar     /* We need to handle deletion of buffers underneath us.
1020e344beadSBram Moolenaar      * If we add a "b_python_ref" field to the buf_T structure,
1021071d4279SBram Moolenaar      * then we can get at it in buf_freeall() in vim. We then
1022071d4279SBram Moolenaar      * need to create only ONE Python object per buffer - if
1023071d4279SBram Moolenaar      * we try to create a second, just INCREF the existing one
1024071d4279SBram Moolenaar      * and return it. The (single) Python object referring to
1025e344beadSBram Moolenaar      * the buffer is stored in "b_python_ref".
1026071d4279SBram Moolenaar      * Question: what to do on a buf_freeall(). We'll probably
1027071d4279SBram Moolenaar      * have to either delete the Python object (DECREF it to
1028071d4279SBram Moolenaar      * zero - a bad idea, as it leaves dangling refs!) or
1029071d4279SBram Moolenaar      * set the buf_T * value to an invalid value (-1?), which
1030071d4279SBram Moolenaar      * means we need checks in all access functions... Bah.
1031071d4279SBram Moolenaar      */
1032071d4279SBram Moolenaar 
1033071d4279SBram Moolenaar     BufferObject *self;
1034071d4279SBram Moolenaar 
1035e344beadSBram Moolenaar     if (buf->b_python_ref != NULL)
1036071d4279SBram Moolenaar     {
1037e344beadSBram Moolenaar 	self = buf->b_python_ref;
1038071d4279SBram Moolenaar 	Py_INCREF(self);
1039071d4279SBram Moolenaar     }
1040071d4279SBram Moolenaar     else
1041071d4279SBram Moolenaar     {
1042071d4279SBram Moolenaar 	self = PyObject_NEW(BufferObject, &BufferType);
1043071d4279SBram Moolenaar 	if (self == NULL)
1044071d4279SBram Moolenaar 	    return NULL;
1045071d4279SBram Moolenaar 	self->buf = buf;
1046e344beadSBram Moolenaar 	buf->b_python_ref = self;
1047071d4279SBram Moolenaar     }
1048071d4279SBram Moolenaar 
1049071d4279SBram Moolenaar     return (PyObject *)(self);
1050071d4279SBram Moolenaar }
1051071d4279SBram Moolenaar 
1052071d4279SBram Moolenaar     static void
1053071d4279SBram Moolenaar BufferDestructor(PyObject *self)
1054071d4279SBram Moolenaar {
1055071d4279SBram Moolenaar     BufferObject *this = (BufferObject *)(self);
1056071d4279SBram Moolenaar 
1057071d4279SBram Moolenaar     if (this->buf && this->buf != INVALID_BUFFER_VALUE)
1058e344beadSBram Moolenaar 	this->buf->b_python_ref = NULL;
1059071d4279SBram Moolenaar 
1060658ada69SBram Moolenaar     Py_DECREF(self);
1061071d4279SBram Moolenaar }
1062071d4279SBram Moolenaar 
1063071d4279SBram Moolenaar     static PyObject *
1064071d4279SBram Moolenaar BufferGetattr(PyObject *self, char *name)
1065071d4279SBram Moolenaar {
1066071d4279SBram Moolenaar     BufferObject *this = (BufferObject *)(self);
1067071d4279SBram Moolenaar 
1068071d4279SBram Moolenaar     if (CheckBuffer(this))
1069071d4279SBram Moolenaar 	return NULL;
1070071d4279SBram Moolenaar 
1071071d4279SBram Moolenaar     if (strcmp(name, "name") == 0)
1072071d4279SBram Moolenaar 	return Py_BuildValue("s", this->buf->b_ffname);
1073071d4279SBram Moolenaar     else if (strcmp(name, "number") == 0)
1074e7cb9cf6SBram Moolenaar 	return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
1075071d4279SBram Moolenaar     else if (strcmp(name,"__members__") == 0)
1076071d4279SBram Moolenaar 	return Py_BuildValue("[ss]", "name", "number");
1077071d4279SBram Moolenaar     else
1078071d4279SBram Moolenaar 	return Py_FindMethod(BufferMethods, self, name);
1079071d4279SBram Moolenaar }
1080071d4279SBram Moolenaar 
1081071d4279SBram Moolenaar     static PyObject *
1082071d4279SBram Moolenaar BufferRepr(PyObject *self)
1083071d4279SBram Moolenaar {
1084555b280fSBram Moolenaar     static char repr[100];
1085071d4279SBram Moolenaar     BufferObject *this = (BufferObject *)(self);
1086071d4279SBram Moolenaar 
1087071d4279SBram Moolenaar     if (this->buf == INVALID_BUFFER_VALUE)
1088071d4279SBram Moolenaar     {
1089e7cb9cf6SBram Moolenaar 	vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
1090071d4279SBram Moolenaar 	return PyString_FromString(repr);
1091071d4279SBram Moolenaar     }
1092071d4279SBram Moolenaar     else
1093071d4279SBram Moolenaar     {
1094071d4279SBram Moolenaar 	char *name = (char *)this->buf->b_fname;
1095e7cb9cf6SBram Moolenaar 	PyInt len;
1096071d4279SBram Moolenaar 
1097071d4279SBram Moolenaar 	if (name == NULL)
1098071d4279SBram Moolenaar 	    name = "";
1099071d4279SBram Moolenaar 	len = strlen(name);
1100071d4279SBram Moolenaar 
1101071d4279SBram Moolenaar 	if (len > 35)
1102071d4279SBram Moolenaar 	    name = name + (35 - len);
1103071d4279SBram Moolenaar 
1104555b280fSBram Moolenaar 	vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
1105071d4279SBram Moolenaar 
1106071d4279SBram Moolenaar 	return PyString_FromString(repr);
1107071d4279SBram Moolenaar     }
1108071d4279SBram Moolenaar }
1109071d4279SBram Moolenaar 
1110071d4279SBram Moolenaar /******************/
1111071d4279SBram Moolenaar 
11122c45e945SBram Moolenaar     static PyInt
1113071d4279SBram Moolenaar BufferLength(PyObject *self)
1114071d4279SBram Moolenaar {
1115071d4279SBram Moolenaar     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1116071d4279SBram Moolenaar     if (CheckBuffer((BufferObject *)(self)))
1117071d4279SBram Moolenaar 	return -1; /* ??? */
1118071d4279SBram Moolenaar 
1119071d4279SBram Moolenaar     return (((BufferObject *)(self))->buf->b_ml.ml_line_count);
1120071d4279SBram Moolenaar }
1121071d4279SBram Moolenaar 
1122071d4279SBram Moolenaar     static PyObject *
11232c45e945SBram Moolenaar BufferItem(PyObject *self, PyInt n)
1124071d4279SBram Moolenaar {
1125071d4279SBram Moolenaar     return RBItem((BufferObject *)(self), n, 1,
1126071d4279SBram Moolenaar 		  (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1127071d4279SBram Moolenaar }
1128071d4279SBram Moolenaar 
1129071d4279SBram Moolenaar     static PyObject *
11302c45e945SBram Moolenaar BufferSlice(PyObject *self, PyInt lo, PyInt hi)
1131071d4279SBram Moolenaar {
1132071d4279SBram Moolenaar     return RBSlice((BufferObject *)(self), lo, hi, 1,
1133071d4279SBram Moolenaar 		   (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1134071d4279SBram Moolenaar }
1135071d4279SBram Moolenaar 
11362c45e945SBram Moolenaar     static PyInt
11372c45e945SBram Moolenaar BufferAssItem(PyObject *self, PyInt n, PyObject *val)
1138071d4279SBram Moolenaar {
1139ca8a4dfeSBram Moolenaar     return RBAsItem((BufferObject *)(self), n, val, 1,
1140e7cb9cf6SBram Moolenaar 		     (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1141071d4279SBram Moolenaar 		     NULL);
1142071d4279SBram Moolenaar }
1143071d4279SBram Moolenaar 
11442c45e945SBram Moolenaar     static PyInt
11452c45e945SBram Moolenaar BufferAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
1146071d4279SBram Moolenaar {
114719e60943SBram Moolenaar     return RBAsSlice((BufferObject *)(self), lo, hi, val, 1,
1148e7cb9cf6SBram Moolenaar 		      (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1149071d4279SBram Moolenaar 		      NULL);
1150071d4279SBram Moolenaar }
1151071d4279SBram Moolenaar 
1152071d4279SBram Moolenaar static PySequenceMethods RangeAsSeq = {
11532c45e945SBram Moolenaar     (PyInquiry)		RangeLength,	    /* sq_length,    len(x)   */
1154071d4279SBram Moolenaar     (binaryfunc)	0, /* RangeConcat, */	     /* sq_concat,    x+y      */
11552c45e945SBram Moolenaar     (PyIntArgFunc)	0, /* RangeRepeat, */	     /* sq_repeat,    x*n      */
11562c45e945SBram Moolenaar     (PyIntArgFunc)	RangeItem,	    /* sq_item,      x[i]     */
11572c45e945SBram Moolenaar     (PyIntIntArgFunc)	RangeSlice,	    /* sq_slice,     x[i:j]   */
11582c45e945SBram Moolenaar     (PyIntObjArgProc)	RangeAssItem,	    /* sq_ass_item,  x[i]=v   */
11592c45e945SBram Moolenaar     (PyIntIntObjArgProc)	RangeAssSlice,	    /* sq_ass_slice, x[i:j]=v */
1160071d4279SBram Moolenaar };
1161071d4279SBram Moolenaar 
1162071d4279SBram Moolenaar /* Line range object - Implementation
1163071d4279SBram Moolenaar  */
1164071d4279SBram Moolenaar 
1165071d4279SBram Moolenaar     static void
1166071d4279SBram Moolenaar RangeDestructor(PyObject *self)
1167071d4279SBram Moolenaar {
1168071d4279SBram Moolenaar     Py_DECREF(((RangeObject *)(self))->buf);
1169658ada69SBram Moolenaar     Py_DECREF(self);
1170071d4279SBram Moolenaar }
1171071d4279SBram Moolenaar 
1172071d4279SBram Moolenaar     static PyObject *
1173071d4279SBram Moolenaar RangeGetattr(PyObject *self, char *name)
1174071d4279SBram Moolenaar {
1175071d4279SBram Moolenaar     if (strcmp(name, "start") == 0)
1176e7cb9cf6SBram Moolenaar 	return Py_BuildValue(Py_ssize_t_fmt, ((RangeObject *)(self))->start - 1);
1177071d4279SBram Moolenaar     else if (strcmp(name, "end") == 0)
1178e7cb9cf6SBram Moolenaar 	return Py_BuildValue(Py_ssize_t_fmt, ((RangeObject *)(self))->end - 1);
1179071d4279SBram Moolenaar     else
1180071d4279SBram Moolenaar 	return Py_FindMethod(RangeMethods, self, name);
1181071d4279SBram Moolenaar }
1182071d4279SBram Moolenaar 
1183071d4279SBram Moolenaar /****************/
1184071d4279SBram Moolenaar 
11852c45e945SBram Moolenaar     static PyInt
11862c45e945SBram Moolenaar RangeAssItem(PyObject *self, PyInt n, PyObject *val)
1187071d4279SBram Moolenaar {
1188ca8a4dfeSBram Moolenaar     return RBAsItem(((RangeObject *)(self))->buf, n, val,
1189071d4279SBram Moolenaar 		     ((RangeObject *)(self))->start,
1190071d4279SBram Moolenaar 		     ((RangeObject *)(self))->end,
1191071d4279SBram Moolenaar 		     &((RangeObject *)(self))->end);
1192071d4279SBram Moolenaar }
1193071d4279SBram Moolenaar 
11942c45e945SBram Moolenaar     static PyInt
11952c45e945SBram Moolenaar RangeAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
1196071d4279SBram Moolenaar {
119719e60943SBram Moolenaar     return RBAsSlice(((RangeObject *)(self))->buf, lo, hi, val,
1198071d4279SBram Moolenaar 		      ((RangeObject *)(self))->start,
1199071d4279SBram Moolenaar 		      ((RangeObject *)(self))->end,
1200071d4279SBram Moolenaar 		      &((RangeObject *)(self))->end);
1201071d4279SBram Moolenaar }
1202071d4279SBram Moolenaar 
1203071d4279SBram Moolenaar /* Buffer list object - Definitions
1204071d4279SBram Moolenaar  */
1205071d4279SBram Moolenaar 
1206071d4279SBram Moolenaar typedef struct
1207071d4279SBram Moolenaar {
1208071d4279SBram Moolenaar     PyObject_HEAD
1209ca8a4dfeSBram Moolenaar } BufListObject;
1210071d4279SBram Moolenaar 
1211071d4279SBram Moolenaar static PySequenceMethods BufListAsSeq = {
12122c45e945SBram Moolenaar     (PyInquiry)		BufListLength,	    /* sq_length,    len(x)   */
1213071d4279SBram Moolenaar     (binaryfunc)	0,		    /* sq_concat,    x+y      */
12142c45e945SBram Moolenaar     (PyIntArgFunc)	0,		    /* sq_repeat,    x*n      */
12152c45e945SBram Moolenaar     (PyIntArgFunc)	BufListItem,	    /* sq_item,      x[i]     */
12162c45e945SBram Moolenaar     (PyIntIntArgFunc)	0,		    /* sq_slice,     x[i:j]   */
12172c45e945SBram Moolenaar     (PyIntObjArgProc)	0,		    /* sq_ass_item,  x[i]=v   */
12182c45e945SBram Moolenaar     (PyIntIntObjArgProc)	0,		    /* sq_ass_slice, x[i:j]=v */
1219071d4279SBram Moolenaar };
1220071d4279SBram Moolenaar 
1221071d4279SBram Moolenaar static PyTypeObject BufListType = {
1222071d4279SBram Moolenaar     PyObject_HEAD_INIT(0)
1223071d4279SBram Moolenaar     0,
1224071d4279SBram Moolenaar     "buffer list",
1225071d4279SBram Moolenaar     sizeof(BufListObject),
1226071d4279SBram Moolenaar     0,
1227071d4279SBram Moolenaar 
1228071d4279SBram Moolenaar     (destructor)    0,			/* tp_dealloc,	refcount==0  */
1229071d4279SBram Moolenaar     (printfunc)     0,			/* tp_print,	print x      */
1230071d4279SBram Moolenaar     (getattrfunc)   0,			/* tp_getattr,	x.attr	     */
1231071d4279SBram Moolenaar     (setattrfunc)   0,			/* tp_setattr,	x.attr=v     */
1232071d4279SBram Moolenaar     (cmpfunc)	    0,			/* tp_compare,	x>y	     */
1233071d4279SBram Moolenaar     (reprfunc)	    0,			/* tp_repr,	`x`, print x */
1234071d4279SBram Moolenaar 
1235071d4279SBram Moolenaar     0,		    /* as number */
1236071d4279SBram Moolenaar     &BufListAsSeq,  /* as sequence */
1237071d4279SBram Moolenaar     0,		    /* as mapping */
1238071d4279SBram Moolenaar 
1239071d4279SBram Moolenaar     (hashfunc) 0,			/* tp_hash, dict(x) */
1240071d4279SBram Moolenaar     (ternaryfunc) 0,			/* tp_call, x()     */
1241071d4279SBram Moolenaar     (reprfunc) 0,			/* tp_str,  str(x)  */
1242071d4279SBram Moolenaar };
1243071d4279SBram Moolenaar 
1244071d4279SBram Moolenaar /* Window object - Definitions
1245071d4279SBram Moolenaar  */
1246071d4279SBram Moolenaar 
1247071d4279SBram Moolenaar static struct PyMethodDef WindowMethods[] = {
1248071d4279SBram Moolenaar     /* name,	    function,		calling,    documentation */
1249071d4279SBram Moolenaar     { NULL,	    NULL,		0,	    NULL }
1250071d4279SBram Moolenaar };
1251071d4279SBram Moolenaar 
1252071d4279SBram Moolenaar static PyTypeObject WindowType = {
1253071d4279SBram Moolenaar     PyObject_HEAD_INIT(0)
1254071d4279SBram Moolenaar     0,
1255071d4279SBram Moolenaar     "window",
1256071d4279SBram Moolenaar     sizeof(WindowObject),
1257071d4279SBram Moolenaar     0,
1258071d4279SBram Moolenaar 
1259071d4279SBram Moolenaar     (destructor)    WindowDestructor,	/* tp_dealloc,	refcount==0  */
1260071d4279SBram Moolenaar     (printfunc)     0,			/* tp_print,	print x      */
1261071d4279SBram Moolenaar     (getattrfunc)   WindowGetattr,	/* tp_getattr,	x.attr	     */
1262071d4279SBram Moolenaar     (setattrfunc)   WindowSetattr,	/* tp_setattr,	x.attr=v     */
1263071d4279SBram Moolenaar     (cmpfunc)	    0,			/* tp_compare,	x>y	     */
1264071d4279SBram Moolenaar     (reprfunc)	    WindowRepr,		/* tp_repr,	`x`, print x */
1265071d4279SBram Moolenaar 
1266071d4279SBram Moolenaar     0,		    /* as number */
1267071d4279SBram Moolenaar     0,		    /* as sequence */
1268071d4279SBram Moolenaar     0,		    /* as mapping */
1269071d4279SBram Moolenaar 
1270071d4279SBram Moolenaar     (hashfunc) 0,			/* tp_hash, dict(x) */
1271071d4279SBram Moolenaar     (ternaryfunc) 0,			/* tp_call, x()     */
1272071d4279SBram Moolenaar     (reprfunc) 0,			/* tp_str,  str(x)  */
1273071d4279SBram Moolenaar };
1274071d4279SBram Moolenaar 
1275071d4279SBram Moolenaar /* Window object - Implementation
1276071d4279SBram Moolenaar  */
1277071d4279SBram Moolenaar 
1278071d4279SBram Moolenaar     static PyObject *
1279071d4279SBram Moolenaar WindowNew(win_T *win)
1280071d4279SBram Moolenaar {
1281071d4279SBram Moolenaar     /* We need to handle deletion of windows underneath us.
1282e344beadSBram Moolenaar      * If we add a "w_python_ref" field to the win_T structure,
1283071d4279SBram Moolenaar      * then we can get at it in win_free() in vim. We then
1284071d4279SBram Moolenaar      * need to create only ONE Python object per window - if
1285071d4279SBram Moolenaar      * we try to create a second, just INCREF the existing one
1286071d4279SBram Moolenaar      * and return it. The (single) Python object referring to
1287e344beadSBram Moolenaar      * the window is stored in "w_python_ref".
1288071d4279SBram Moolenaar      * On a win_free() we set the Python object's win_T* field
1289071d4279SBram Moolenaar      * to an invalid value. We trap all uses of a window
1290071d4279SBram Moolenaar      * object, and reject them if the win_T* field is invalid.
1291071d4279SBram Moolenaar      */
1292071d4279SBram Moolenaar 
1293071d4279SBram Moolenaar     WindowObject *self;
1294071d4279SBram Moolenaar 
1295e344beadSBram Moolenaar     if (win->w_python_ref)
1296071d4279SBram Moolenaar     {
1297e344beadSBram Moolenaar 	self = win->w_python_ref;
1298071d4279SBram Moolenaar 	Py_INCREF(self);
1299071d4279SBram Moolenaar     }
1300071d4279SBram Moolenaar     else
1301071d4279SBram Moolenaar     {
1302071d4279SBram Moolenaar 	self = PyObject_NEW(WindowObject, &WindowType);
1303071d4279SBram Moolenaar 	if (self == NULL)
1304071d4279SBram Moolenaar 	    return NULL;
1305071d4279SBram Moolenaar 	self->win = win;
1306e344beadSBram Moolenaar 	win->w_python_ref = self;
1307071d4279SBram Moolenaar     }
1308071d4279SBram Moolenaar 
1309071d4279SBram Moolenaar     return (PyObject *)(self);
1310071d4279SBram Moolenaar }
1311071d4279SBram Moolenaar 
1312071d4279SBram Moolenaar     static void
1313071d4279SBram Moolenaar WindowDestructor(PyObject *self)
1314071d4279SBram Moolenaar {
1315071d4279SBram Moolenaar     WindowObject *this = (WindowObject *)(self);
1316071d4279SBram Moolenaar 
1317071d4279SBram Moolenaar     if (this->win && this->win != INVALID_WINDOW_VALUE)
1318e344beadSBram Moolenaar 	this->win->w_python_ref = NULL;
1319071d4279SBram Moolenaar 
1320658ada69SBram Moolenaar     Py_DECREF(self);
1321071d4279SBram Moolenaar }
1322071d4279SBram Moolenaar 
1323071d4279SBram Moolenaar     static PyObject *
1324071d4279SBram Moolenaar WindowGetattr(PyObject *self, char *name)
1325071d4279SBram Moolenaar {
1326071d4279SBram Moolenaar     WindowObject *this = (WindowObject *)(self);
1327071d4279SBram Moolenaar 
1328071d4279SBram Moolenaar     if (CheckWindow(this))
1329071d4279SBram Moolenaar 	return NULL;
1330071d4279SBram Moolenaar 
1331071d4279SBram Moolenaar     if (strcmp(name, "buffer") == 0)
1332071d4279SBram Moolenaar 	return (PyObject *)BufferNew(this->win->w_buffer);
1333071d4279SBram Moolenaar     else if (strcmp(name, "cursor") == 0)
1334071d4279SBram Moolenaar     {
1335071d4279SBram Moolenaar 	pos_T *pos = &this->win->w_cursor;
1336071d4279SBram Moolenaar 
1337071d4279SBram Moolenaar 	return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
1338071d4279SBram Moolenaar     }
1339071d4279SBram Moolenaar     else if (strcmp(name, "height") == 0)
1340071d4279SBram Moolenaar 	return Py_BuildValue("l", (long)(this->win->w_height));
1341071d4279SBram Moolenaar #ifdef FEAT_VERTSPLIT
1342071d4279SBram Moolenaar     else if (strcmp(name, "width") == 0)
1343071d4279SBram Moolenaar 	return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
1344071d4279SBram Moolenaar #endif
1345071d4279SBram Moolenaar     else if (strcmp(name,"__members__") == 0)
1346071d4279SBram Moolenaar 	return Py_BuildValue("[sss]", "buffer", "cursor", "height");
1347071d4279SBram Moolenaar     else
1348071d4279SBram Moolenaar 	return Py_FindMethod(WindowMethods, self, name);
1349071d4279SBram Moolenaar }
1350071d4279SBram Moolenaar 
1351071d4279SBram Moolenaar /* Window list object - Definitions
1352071d4279SBram Moolenaar  */
1353071d4279SBram Moolenaar 
1354071d4279SBram Moolenaar typedef struct
1355071d4279SBram Moolenaar {
1356071d4279SBram Moolenaar     PyObject_HEAD
1357071d4279SBram Moolenaar }
1358071d4279SBram Moolenaar WinListObject;
1359071d4279SBram Moolenaar 
1360071d4279SBram Moolenaar static PySequenceMethods WinListAsSeq = {
13612c45e945SBram Moolenaar     (PyInquiry)		WinListLength,	    /* sq_length,    len(x)   */
1362071d4279SBram Moolenaar     (binaryfunc)	0,		    /* sq_concat,    x+y      */
13632c45e945SBram Moolenaar     (PyIntArgFunc)	0,		    /* sq_repeat,    x*n      */
13642c45e945SBram Moolenaar     (PyIntArgFunc)	WinListItem,	    /* sq_item,      x[i]     */
13652c45e945SBram Moolenaar     (PyIntIntArgFunc)	0,		    /* sq_slice,     x[i:j]   */
13662c45e945SBram Moolenaar     (PyIntObjArgProc)	0,		    /* sq_ass_item,  x[i]=v   */
13672c45e945SBram Moolenaar     (PyIntIntObjArgProc)	0,		    /* sq_ass_slice, x[i:j]=v */
1368071d4279SBram Moolenaar };
1369071d4279SBram Moolenaar 
1370071d4279SBram Moolenaar static PyTypeObject WinListType = {
1371071d4279SBram Moolenaar     PyObject_HEAD_INIT(0)
1372071d4279SBram Moolenaar     0,
1373071d4279SBram Moolenaar     "window list",
1374071d4279SBram Moolenaar     sizeof(WinListObject),
1375071d4279SBram Moolenaar     0,
1376071d4279SBram Moolenaar 
1377071d4279SBram Moolenaar     (destructor)    0,			/* tp_dealloc,	refcount==0  */
1378071d4279SBram Moolenaar     (printfunc)     0,			/* tp_print,	print x      */
1379071d4279SBram Moolenaar     (getattrfunc)   0,			/* tp_getattr,	x.attr	     */
1380071d4279SBram Moolenaar     (setattrfunc)   0,			/* tp_setattr,	x.attr=v     */
1381071d4279SBram Moolenaar     (cmpfunc)	    0,			/* tp_compare,	x>y	     */
1382071d4279SBram Moolenaar     (reprfunc)	    0,			/* tp_repr,	`x`, print x */
1383071d4279SBram Moolenaar 
1384071d4279SBram Moolenaar     0,		    /* as number */
1385071d4279SBram Moolenaar     &WinListAsSeq,  /* as sequence */
1386071d4279SBram Moolenaar     0,		    /* as mapping */
1387071d4279SBram Moolenaar 
1388071d4279SBram Moolenaar     (hashfunc) 0,			/* tp_hash, dict(x) */
1389071d4279SBram Moolenaar     (ternaryfunc) 0,			/* tp_call, x()     */
1390071d4279SBram Moolenaar     (reprfunc) 0,			/* tp_str,  str(x)  */
1391071d4279SBram Moolenaar };
1392071d4279SBram Moolenaar 
1393071d4279SBram Moolenaar /* Current items object - Definitions
1394071d4279SBram Moolenaar  */
1395071d4279SBram Moolenaar 
1396071d4279SBram Moolenaar typedef struct
1397071d4279SBram Moolenaar {
1398071d4279SBram Moolenaar     PyObject_HEAD
1399ca8a4dfeSBram Moolenaar } CurrentObject;
1400071d4279SBram Moolenaar 
1401071d4279SBram Moolenaar static PyTypeObject CurrentType = {
1402071d4279SBram Moolenaar     PyObject_HEAD_INIT(0)
1403071d4279SBram Moolenaar     0,
1404071d4279SBram Moolenaar     "current data",
1405071d4279SBram Moolenaar     sizeof(CurrentObject),
1406071d4279SBram Moolenaar     0,
1407071d4279SBram Moolenaar 
1408071d4279SBram Moolenaar     (destructor)    0,			/* tp_dealloc,	refcount==0  */
1409071d4279SBram Moolenaar     (printfunc)     0,			/* tp_print,	print x      */
1410071d4279SBram Moolenaar     (getattrfunc)   CurrentGetattr,	/* tp_getattr,	x.attr	     */
1411071d4279SBram Moolenaar     (setattrfunc)   CurrentSetattr,	/* tp_setattr,	x.attr=v     */
1412071d4279SBram Moolenaar     (cmpfunc)	    0,			/* tp_compare,	x>y	     */
1413071d4279SBram Moolenaar     (reprfunc)	    0,			/* tp_repr,	`x`, print x */
1414071d4279SBram Moolenaar 
1415071d4279SBram Moolenaar     0,		    /* as number */
1416071d4279SBram Moolenaar     0,		    /* as sequence */
1417071d4279SBram Moolenaar     0,		    /* as mapping */
1418071d4279SBram Moolenaar 
1419071d4279SBram Moolenaar     (hashfunc) 0,			/* tp_hash, dict(x) */
1420071d4279SBram Moolenaar     (ternaryfunc) 0,			/* tp_call, x()     */
1421071d4279SBram Moolenaar     (reprfunc) 0,			/* tp_str,  str(x)  */
1422071d4279SBram Moolenaar };
1423071d4279SBram Moolenaar 
1424071d4279SBram Moolenaar /* Current items object - Implementation
1425071d4279SBram Moolenaar  */
1426071d4279SBram Moolenaar     static PyObject *
14274bdbbf70SBram Moolenaar CurrentGetattr(PyObject *self UNUSED, char *name)
1428071d4279SBram Moolenaar {
1429071d4279SBram Moolenaar     if (strcmp(name, "buffer") == 0)
1430071d4279SBram Moolenaar 	return (PyObject *)BufferNew(curbuf);
1431071d4279SBram Moolenaar     else if (strcmp(name, "window") == 0)
1432071d4279SBram Moolenaar 	return (PyObject *)WindowNew(curwin);
1433071d4279SBram Moolenaar     else if (strcmp(name, "line") == 0)
1434e7cb9cf6SBram Moolenaar 	return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
1435071d4279SBram Moolenaar     else if (strcmp(name, "range") == 0)
1436071d4279SBram Moolenaar 	return RangeNew(curbuf, RangeStart, RangeEnd);
1437071d4279SBram Moolenaar     else if (strcmp(name,"__members__") == 0)
1438071d4279SBram Moolenaar 	return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
1439071d4279SBram Moolenaar     else
1440071d4279SBram Moolenaar     {
1441071d4279SBram Moolenaar 	PyErr_SetString(PyExc_AttributeError, name);
1442071d4279SBram Moolenaar 	return NULL;
1443071d4279SBram Moolenaar     }
1444071d4279SBram Moolenaar }
1445071d4279SBram Moolenaar 
1446071d4279SBram Moolenaar     static int
14474bdbbf70SBram Moolenaar CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
1448071d4279SBram Moolenaar {
1449071d4279SBram Moolenaar     if (strcmp(name, "line") == 0)
1450071d4279SBram Moolenaar     {
1451e7cb9cf6SBram Moolenaar 	if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
1452071d4279SBram Moolenaar 	    return -1;
1453071d4279SBram Moolenaar 
1454071d4279SBram Moolenaar 	return 0;
1455071d4279SBram Moolenaar     }
1456071d4279SBram Moolenaar     else
1457071d4279SBram Moolenaar     {
1458071d4279SBram Moolenaar 	PyErr_SetString(PyExc_AttributeError, name);
1459071d4279SBram Moolenaar 	return -1;
1460071d4279SBram Moolenaar     }
1461071d4279SBram Moolenaar }
1462071d4279SBram Moolenaar 
1463071d4279SBram Moolenaar /* External interface
1464071d4279SBram Moolenaar  */
1465071d4279SBram Moolenaar 
1466071d4279SBram Moolenaar     void
1467071d4279SBram Moolenaar python_buffer_free(buf_T *buf)
1468071d4279SBram Moolenaar {
1469e344beadSBram Moolenaar     if (buf->b_python_ref != NULL)
1470071d4279SBram Moolenaar     {
1471e344beadSBram Moolenaar 	BufferObject *bp = buf->b_python_ref;
1472071d4279SBram Moolenaar 	bp->buf = INVALID_BUFFER_VALUE;
1473e344beadSBram Moolenaar 	buf->b_python_ref = NULL;
1474071d4279SBram Moolenaar     }
1475071d4279SBram Moolenaar }
1476071d4279SBram Moolenaar 
1477071d4279SBram Moolenaar #if defined(FEAT_WINDOWS) || defined(PROTO)
1478071d4279SBram Moolenaar     void
1479071d4279SBram Moolenaar python_window_free(win_T *win)
1480071d4279SBram Moolenaar {
1481e344beadSBram Moolenaar     if (win->w_python_ref != NULL)
1482071d4279SBram Moolenaar     {
1483e344beadSBram Moolenaar 	WindowObject *wp = win->w_python_ref;
1484071d4279SBram Moolenaar 	wp->win = INVALID_WINDOW_VALUE;
1485e344beadSBram Moolenaar 	win->w_python_ref = NULL;
1486071d4279SBram Moolenaar     }
1487071d4279SBram Moolenaar }
1488071d4279SBram Moolenaar #endif
1489071d4279SBram Moolenaar 
1490071d4279SBram Moolenaar static BufListObject TheBufferList =
1491071d4279SBram Moolenaar {
1492071d4279SBram Moolenaar     PyObject_HEAD_INIT(&BufListType)
1493071d4279SBram Moolenaar };
1494071d4279SBram Moolenaar 
1495071d4279SBram Moolenaar static WinListObject TheWindowList =
1496071d4279SBram Moolenaar {
1497071d4279SBram Moolenaar     PyObject_HEAD_INIT(&WinListType)
1498071d4279SBram Moolenaar };
1499071d4279SBram Moolenaar 
1500071d4279SBram Moolenaar static CurrentObject TheCurrent =
1501071d4279SBram Moolenaar {
1502071d4279SBram Moolenaar     PyObject_HEAD_INIT(&CurrentType)
1503071d4279SBram Moolenaar };
1504071d4279SBram Moolenaar 
1505071d4279SBram Moolenaar     static int
1506071d4279SBram Moolenaar PythonMod_Init(void)
1507071d4279SBram Moolenaar {
1508071d4279SBram Moolenaar     PyObject *mod;
1509071d4279SBram Moolenaar     PyObject *dict;
15109774ecc8SBram Moolenaar     /* The special value is removed from sys.path in Python_Init(). */
15119774ecc8SBram Moolenaar     static char *(argv[2]) = {"/must>not&exist/foo", NULL};
1512071d4279SBram Moolenaar 
1513071d4279SBram Moolenaar     /* Fixups... */
151421377c8dSBram Moolenaar     PyType_Ready(&BufferType);
151521377c8dSBram Moolenaar     PyType_Ready(&RangeType);
151621377c8dSBram Moolenaar     PyType_Ready(&WindowType);
151721377c8dSBram Moolenaar     PyType_Ready(&BufListType);
151821377c8dSBram Moolenaar     PyType_Ready(&WinListType);
151921377c8dSBram Moolenaar     PyType_Ready(&CurrentType);
1520071d4279SBram Moolenaar 
1521071d4279SBram Moolenaar     /* Set sys.argv[] to avoid a crash in warn(). */
1522071d4279SBram Moolenaar     PySys_SetArgv(1, argv);
1523071d4279SBram Moolenaar 
1524e7cb9cf6SBram Moolenaar     mod = Py_InitModule4("vim", VimMethods, (char *)NULL, (PyObject *)NULL, PYTHON_API_VERSION);
1525071d4279SBram Moolenaar     dict = PyModule_GetDict(mod);
1526071d4279SBram Moolenaar 
1527071d4279SBram Moolenaar     VimError = Py_BuildValue("s", "vim.error");
1528071d4279SBram Moolenaar 
1529071d4279SBram Moolenaar     PyDict_SetItemString(dict, "error", VimError);
15307df2d662SBram Moolenaar     PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferList);
15317df2d662SBram Moolenaar     PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent);
15327df2d662SBram Moolenaar     PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList);
1533071d4279SBram Moolenaar 
1534071d4279SBram Moolenaar     if (PyErr_Occurred())
1535071d4279SBram Moolenaar 	return -1;
1536071d4279SBram Moolenaar 
1537071d4279SBram Moolenaar     return 0;
1538071d4279SBram Moolenaar }
1539071d4279SBram Moolenaar 
1540071d4279SBram Moolenaar /*************************************************************************
1541071d4279SBram Moolenaar  * 4. Utility functions for handling the interface between Vim and Python.
1542071d4279SBram Moolenaar  */
1543071d4279SBram Moolenaar 
1544071d4279SBram Moolenaar /* Convert a Vim line into a Python string.
1545071d4279SBram Moolenaar  * All internal newlines are replaced by null characters.
1546071d4279SBram Moolenaar  *
1547071d4279SBram Moolenaar  * On errors, the Python exception data is set, and NULL is returned.
1548071d4279SBram Moolenaar  */
1549071d4279SBram Moolenaar     static PyObject *
1550071d4279SBram Moolenaar LineToString(const char *str)
1551071d4279SBram Moolenaar {
1552071d4279SBram Moolenaar     PyObject *result;
15532c45e945SBram Moolenaar     PyInt len = strlen(str);
1554071d4279SBram Moolenaar     char *p;
1555071d4279SBram Moolenaar 
1556071d4279SBram Moolenaar     /* Allocate an Python string object, with uninitialised contents. We
1557071d4279SBram Moolenaar      * must do it this way, so that we can modify the string in place
1558071d4279SBram Moolenaar      * later. See the Python source, Objects/stringobject.c for details.
1559071d4279SBram Moolenaar      */
1560071d4279SBram Moolenaar     result = PyString_FromStringAndSize(NULL, len);
1561071d4279SBram Moolenaar     if (result == NULL)
1562071d4279SBram Moolenaar 	return NULL;
1563071d4279SBram Moolenaar 
1564071d4279SBram Moolenaar     p = PyString_AsString(result);
1565071d4279SBram Moolenaar 
1566071d4279SBram Moolenaar     while (*str)
1567071d4279SBram Moolenaar     {
1568071d4279SBram Moolenaar 	if (*str == '\n')
1569071d4279SBram Moolenaar 	    *p = '\0';
1570071d4279SBram Moolenaar 	else
1571071d4279SBram Moolenaar 	    *p = *str;
1572071d4279SBram Moolenaar 
1573071d4279SBram Moolenaar 	++p;
1574071d4279SBram Moolenaar 	++str;
1575071d4279SBram Moolenaar     }
1576071d4279SBram Moolenaar 
1577071d4279SBram Moolenaar     return result;
1578071d4279SBram Moolenaar }
1579071d4279SBram Moolenaar 
1580*db913953SBram Moolenaar static void DictionaryDestructor(PyObject *);
1581*db913953SBram Moolenaar static PyObject *DictionaryGetattr(PyObject *, char*);
1582*db913953SBram Moolenaar 
1583*db913953SBram Moolenaar static PyMappingMethods DictionaryAsMapping = {
1584*db913953SBram Moolenaar     (PyInquiry)		DictionaryLength,
1585*db913953SBram Moolenaar     (binaryfunc)	DictionaryItem,
1586*db913953SBram Moolenaar     (objobjargproc)	DictionaryAssItem,
1587*db913953SBram Moolenaar };
1588*db913953SBram Moolenaar 
1589*db913953SBram Moolenaar static PyTypeObject DictionaryType = {
1590*db913953SBram Moolenaar     PyObject_HEAD_INIT(0)
1591*db913953SBram Moolenaar     0,
1592*db913953SBram Moolenaar     "vimdictionary",
1593*db913953SBram Moolenaar     sizeof(DictionaryObject),
1594*db913953SBram Moolenaar     0,
1595*db913953SBram Moolenaar 
1596*db913953SBram Moolenaar     (destructor)  DictionaryDestructor,
1597*db913953SBram Moolenaar     (printfunc)   0,
1598*db913953SBram Moolenaar     (getattrfunc) DictionaryGetattr,
1599*db913953SBram Moolenaar     (setattrfunc) 0,
1600*db913953SBram Moolenaar     (cmpfunc)     0,
1601*db913953SBram Moolenaar     (reprfunc)    0,
1602*db913953SBram Moolenaar 
1603*db913953SBram Moolenaar     0,			    /* as number */
1604*db913953SBram Moolenaar     0,			    /* as sequence */
1605*db913953SBram Moolenaar     &DictionaryAsMapping,   /* as mapping */
1606*db913953SBram Moolenaar 
1607*db913953SBram Moolenaar     (hashfunc)    0,
1608*db913953SBram Moolenaar     (ternaryfunc) 0,
1609*db913953SBram Moolenaar     (reprfunc)    0,
1610*db913953SBram Moolenaar };
1611*db913953SBram Moolenaar 
1612*db913953SBram Moolenaar     static void
1613*db913953SBram Moolenaar DictionaryDestructor(PyObject *self)
1614*db913953SBram Moolenaar {
1615*db913953SBram Moolenaar     DictionaryObject	*this = ((DictionaryObject *) (self));
1616*db913953SBram Moolenaar 
1617*db913953SBram Moolenaar     pyll_remove(&this->ref, &lastdict);
1618*db913953SBram Moolenaar     dict_unref(this->dict);
1619*db913953SBram Moolenaar 
1620*db913953SBram Moolenaar     Py_DECREF(self);
1621*db913953SBram Moolenaar }
1622*db913953SBram Moolenaar 
1623*db913953SBram Moolenaar     static PyObject *
1624*db913953SBram Moolenaar DictionaryGetattr(PyObject *self, char *name)
1625*db913953SBram Moolenaar {
1626*db913953SBram Moolenaar     return Py_FindMethod(DictionaryMethods, self, name);
1627*db913953SBram Moolenaar }
1628*db913953SBram Moolenaar 
1629*db913953SBram Moolenaar static void ListDestructor(PyObject *);
1630*db913953SBram Moolenaar static PyObject *ListGetattr(PyObject *, char *);
1631*db913953SBram Moolenaar 
1632*db913953SBram Moolenaar static PySequenceMethods ListAsSeq = {
1633*db913953SBram Moolenaar     (PyInquiry)			ListLength,
1634*db913953SBram Moolenaar     (binaryfunc)		0,
1635*db913953SBram Moolenaar     (PyIntArgFunc)		0,
1636*db913953SBram Moolenaar     (PyIntArgFunc)		ListItem,
1637*db913953SBram Moolenaar     (PyIntIntArgFunc)		ListSlice,
1638*db913953SBram Moolenaar     (PyIntObjArgProc)		ListAssItem,
1639*db913953SBram Moolenaar     (PyIntIntObjArgProc)	ListAssSlice,
1640*db913953SBram Moolenaar     (objobjproc)		0,
1641*db913953SBram Moolenaar #if PY_MAJOR_VERSION >= 2
1642*db913953SBram Moolenaar     (binaryfunc)		ListConcatInPlace,
1643*db913953SBram Moolenaar     0,
1644*db913953SBram Moolenaar #endif
1645*db913953SBram Moolenaar };
1646*db913953SBram Moolenaar 
1647*db913953SBram Moolenaar static PyTypeObject ListType = {
1648*db913953SBram Moolenaar     PyObject_HEAD_INIT(0)
1649*db913953SBram Moolenaar     0,
1650*db913953SBram Moolenaar     "vimlist",
1651*db913953SBram Moolenaar     sizeof(ListObject),
1652*db913953SBram Moolenaar     0,
1653*db913953SBram Moolenaar 
1654*db913953SBram Moolenaar     (destructor)  ListDestructor,
1655*db913953SBram Moolenaar     (printfunc)   0,
1656*db913953SBram Moolenaar     (getattrfunc) ListGetattr,
1657*db913953SBram Moolenaar     (setattrfunc) 0,
1658*db913953SBram Moolenaar     (cmpfunc)     0,
1659*db913953SBram Moolenaar     (reprfunc)    0,
1660*db913953SBram Moolenaar 
1661*db913953SBram Moolenaar     0,			    /* as number */
1662*db913953SBram Moolenaar     &ListAsSeq,		    /* as sequence */
1663*db913953SBram Moolenaar     0,			    /* as mapping */
1664*db913953SBram Moolenaar 
1665*db913953SBram Moolenaar     (hashfunc)    0,
1666*db913953SBram Moolenaar     (ternaryfunc) 0,
1667*db913953SBram Moolenaar     (reprfunc)    0,
1668*db913953SBram Moolenaar };
1669*db913953SBram Moolenaar 
1670*db913953SBram Moolenaar     static void
1671*db913953SBram Moolenaar ListDestructor(PyObject *self)
1672*db913953SBram Moolenaar {
1673*db913953SBram Moolenaar     ListObject	*this = ((ListObject *) (self));
1674*db913953SBram Moolenaar 
1675*db913953SBram Moolenaar     pyll_remove(&this->ref, &lastlist);
1676*db913953SBram Moolenaar     list_unref(this->list);
1677*db913953SBram Moolenaar 
1678*db913953SBram Moolenaar     Py_DECREF(self);
1679*db913953SBram Moolenaar }
1680*db913953SBram Moolenaar 
1681*db913953SBram Moolenaar     static PyObject *
1682*db913953SBram Moolenaar ListGetattr(PyObject *self, char *name)
1683*db913953SBram Moolenaar {
1684*db913953SBram Moolenaar     return Py_FindMethod(ListMethods, self, name);
1685*db913953SBram Moolenaar }
1686*db913953SBram Moolenaar 
1687*db913953SBram Moolenaar static void FunctionDestructor(PyObject *);
1688*db913953SBram Moolenaar static PyObject *FunctionGetattr(PyObject *, char *);
1689*db913953SBram Moolenaar 
1690*db913953SBram Moolenaar static PyTypeObject FunctionType = {
1691*db913953SBram Moolenaar     PyObject_HEAD_INIT(0)
1692*db913953SBram Moolenaar     0,
1693*db913953SBram Moolenaar     "vimfunction",
1694*db913953SBram Moolenaar     sizeof(FunctionObject),
1695*db913953SBram Moolenaar     0,
1696*db913953SBram Moolenaar 
1697*db913953SBram Moolenaar     (destructor)  FunctionDestructor,
1698*db913953SBram Moolenaar     (printfunc)   0,
1699*db913953SBram Moolenaar     (getattrfunc) FunctionGetattr,
1700*db913953SBram Moolenaar     (setattrfunc) 0,
1701*db913953SBram Moolenaar     (cmpfunc)     0,
1702*db913953SBram Moolenaar     (reprfunc)    0,
1703*db913953SBram Moolenaar 
1704*db913953SBram Moolenaar     0,			    /* as number */
1705*db913953SBram Moolenaar     0,			    /* as sequence */
1706*db913953SBram Moolenaar     0,			    /* as mapping */
1707*db913953SBram Moolenaar 
1708*db913953SBram Moolenaar     (hashfunc)    0,
1709*db913953SBram Moolenaar     (ternaryfunc) FunctionCall,
1710*db913953SBram Moolenaar     (reprfunc)    0,
1711*db913953SBram Moolenaar };
1712*db913953SBram Moolenaar 
1713*db913953SBram Moolenaar     static void
1714*db913953SBram Moolenaar FunctionDestructor(PyObject *self)
1715*db913953SBram Moolenaar {
1716*db913953SBram Moolenaar     FunctionObject	*this = (FunctionObject *) (self);
1717*db913953SBram Moolenaar 
1718*db913953SBram Moolenaar     func_unref(this->name);
1719*db913953SBram Moolenaar     PyMem_Del(this->name);
1720*db913953SBram Moolenaar 
1721*db913953SBram Moolenaar     Py_DECREF(self);
1722*db913953SBram Moolenaar }
1723*db913953SBram Moolenaar 
1724*db913953SBram Moolenaar     static PyObject *
1725*db913953SBram Moolenaar FunctionGetattr(PyObject *self, char *name)
1726*db913953SBram Moolenaar {
1727*db913953SBram Moolenaar     FunctionObject	*this = (FunctionObject *)(self);
1728*db913953SBram Moolenaar 
1729*db913953SBram Moolenaar     if (strcmp(name, "name") == 0)
1730*db913953SBram Moolenaar 	return PyString_FromString((char *)(this->name));
1731*db913953SBram Moolenaar     else
1732*db913953SBram Moolenaar 	return Py_FindMethod(FunctionMethods, self, name);
1733*db913953SBram Moolenaar }
1734*db913953SBram Moolenaar 
1735*db913953SBram Moolenaar     void
1736*db913953SBram Moolenaar do_pyeval (char_u *str, typval_T *rettv)
1737*db913953SBram Moolenaar {
1738*db913953SBram Moolenaar     DoPythonCommand(NULL, (char *) str, rettv);
1739*db913953SBram Moolenaar     switch(rettv->v_type)
1740*db913953SBram Moolenaar     {
1741*db913953SBram Moolenaar 	case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
1742*db913953SBram Moolenaar 	case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break;
1743*db913953SBram Moolenaar 	case VAR_FUNC: func_ref(rettv->vval.v_string);    break;
1744*db913953SBram Moolenaar     }
1745*db913953SBram Moolenaar }
1746071d4279SBram Moolenaar 
1747071d4279SBram Moolenaar /* Don't generate a prototype for the next function, it generates an error on
1748071d4279SBram Moolenaar  * newer Python versions. */
1749071d4279SBram Moolenaar #if PYTHON_API_VERSION < 1007 /* Python 1.4 */ && !defined(PROTO)
1750071d4279SBram Moolenaar 
1751071d4279SBram Moolenaar     char *
1752071d4279SBram Moolenaar Py_GetProgramName(void)
1753071d4279SBram Moolenaar {
1754071d4279SBram Moolenaar     return "vim";
1755071d4279SBram Moolenaar }
1756071d4279SBram Moolenaar #endif /* Python 1.4 */
1757170bf1aeSBram Moolenaar 
1758*db913953SBram Moolenaar     void
1759*db913953SBram Moolenaar set_ref_in_python (int copyID)
1760*db913953SBram Moolenaar {
1761*db913953SBram Moolenaar     set_ref_in_py(copyID);
1762*db913953SBram Moolenaar }
1763*db913953SBram Moolenaar 
1764170bf1aeSBram Moolenaar     static void
1765170bf1aeSBram Moolenaar init_structs(void)
1766170bf1aeSBram Moolenaar {
1767170bf1aeSBram Moolenaar     vim_memset(&OutputType, 0, sizeof(OutputType));
1768170bf1aeSBram Moolenaar     OutputType.tp_name = "message";
1769170bf1aeSBram Moolenaar     OutputType.tp_basicsize = sizeof(OutputObject);
1770170bf1aeSBram Moolenaar     OutputType.tp_getattr = OutputGetattr;
1771170bf1aeSBram Moolenaar     OutputType.tp_setattr = OutputSetattr;
1772ca8a4dfeSBram Moolenaar 
1773ca8a4dfeSBram Moolenaar     vim_memset(&RangeType, 0, sizeof(RangeType));
1774ca8a4dfeSBram Moolenaar     RangeType.tp_name = "range";
1775ca8a4dfeSBram Moolenaar     RangeType.tp_basicsize = sizeof(RangeObject);
1776ca8a4dfeSBram Moolenaar     RangeType.tp_dealloc = RangeDestructor;
1777ca8a4dfeSBram Moolenaar     RangeType.tp_getattr = RangeGetattr;
1778ca8a4dfeSBram Moolenaar     RangeType.tp_repr = RangeRepr;
1779ca8a4dfeSBram Moolenaar     RangeType.tp_as_sequence = &RangeAsSeq;
1780170bf1aeSBram Moolenaar }
1781