blob: 5a49d1e9e2dc2108677f8e36e467db377c00aa4a [file] [log] [blame]
Bram Moolenaardb913952012-06-29 12:54:53 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020010 * Python extensions by Paul Moore, David Leonard, Roland Puntaier, Nikolay
11 * Pavlov.
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020012 *
13 * Common code for if_python.c and if_python3.c.
14 */
15
Bram Moolenaar41009372013-07-01 22:03:04 +020016static char_u e_py_systemexit[] = "E880: Can't handle SystemExit of %s exception in vim";
17
Bram Moolenaarc1a995d2012-08-08 16:05:07 +020018#if PY_VERSION_HEX < 0x02050000
19typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
20#endif
21
Bram Moolenaar91805fc2011-06-26 04:01:44 +020022#ifdef FEAT_MBYTE
Bram Moolenaar808c2bc2013-06-23 13:11:18 +020023# define ENC_OPT ((char *)p_enc)
Bram Moolenaar91805fc2011-06-26 04:01:44 +020024#else
25# define ENC_OPT "latin1"
26#endif
Bram Moolenaard620aa92013-05-17 16:40:06 +020027#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020028
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020029static const char *vim_special_path = "_vim_path_";
30
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020031#define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020032#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020033#define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
Bram Moolenaarc476e522013-06-23 13:46:40 +020034#define PyErr_FORMAT(exc, str, tail) PyErr_Format(exc, _(str), tail)
35#define PyErr_VIM_FORMAT(str, tail) PyErr_FORMAT(VimError, str, tail)
36
37#define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
38 ? "(NULL)" \
39 : obj->ob_type->tp_name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020040
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020041#define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020042 N_("empty keys are not allowed"))
43#define RAISE_LOCKED_DICTIONARY PyErr_SET_VIM(N_("dictionary is locked"))
44#define RAISE_LOCKED_LIST PyErr_SET_VIM(N_("list is locked"))
45#define RAISE_UNDO_FAIL PyErr_SET_VIM(N_("cannot save undo information"))
46#define RAISE_DELETE_LINE_FAIL PyErr_SET_VIM(N_("cannot delete line"))
47#define RAISE_INSERT_LINE_FAIL PyErr_SET_VIM(N_("cannot insert line"))
48#define RAISE_REPLACE_LINE_FAIL PyErr_SET_VIM(N_("cannot replace line"))
Bram Moolenaarc476e522013-06-23 13:46:40 +020049#define RAISE_KEY_ADD_FAIL(key) \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020050 PyErr_VIM_FORMAT(N_("failed to add key '%s' to dictionary"), key)
Bram Moolenaarc476e522013-06-23 13:46:40 +020051#define RAISE_INVALID_INDEX_TYPE(idx) \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020052 PyErr_FORMAT(PyExc_TypeError, N_("index must be int or slice, not %s"), \
Bram Moolenaarc476e522013-06-23 13:46:40 +020053 Py_TYPE_NAME(idx));
Bram Moolenaar35eacd72013-05-30 22:06:33 +020054
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020055#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
56#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020057#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020058
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020059typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020060typedef void (*runner)(const char *, void *
61#ifdef PY_CAN_RECURSE
62 , PyGILState_STATE *
63#endif
64 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020065
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020066static int ConvertFromPyObject(PyObject *, typval_T *);
67static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaara9922d62013-05-30 13:01:18 +020068static int ConvertFromPyMapping(PyObject *, typval_T *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020069static PyObject *WindowNew(win_T *, tabpage_T *);
70static PyObject *BufferNew (buf_T *);
71static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020072
73static PyInt RangeStart;
74static PyInt RangeEnd;
75
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020076static PyObject *globals;
77
Bram Moolenaarf4258302013-06-02 18:20:17 +020078static PyObject *py_chdir;
79static PyObject *py_fchdir;
80static PyObject *py_getcwd;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020081static PyObject *vim_module;
82static PyObject *vim_special_path_object;
Bram Moolenaarf4258302013-06-02 18:20:17 +020083
Bram Moolenaar81c40c52013-06-12 14:41:04 +020084static PyObject *py_find_module;
85static PyObject *py_load_module;
86
87static PyObject *VimError;
88
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020089/*
90 * obtain a lock on the Vim data structures
91 */
92 static void
93Python_Lock_Vim(void)
94{
95}
96
97/*
98 * release a lock on the Vim data structures
99 */
100 static void
101Python_Release_Vim(void)
102{
103}
104
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200105/*
106 * The "todecref" argument holds a pointer to PyObject * that must be
107 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
108 * was needed to generate returned value is object.
109 *
110 * Use Py_XDECREF to decrement reference count.
111 */
112 static char_u *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200113StringToChars(PyObject *obj, PyObject **todecref)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200114{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200115 char_u *str;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200116
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200117 if (PyBytes_Check(obj))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200118 {
119
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200120 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1
121 || str == NULL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200122 return NULL;
123
124 *todecref = NULL;
125 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200126 else if (PyUnicode_Check(obj))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200127 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200128 PyObject *bytes;
129
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200130 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200131 return NULL;
132
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200133 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1
134 || str == NULL)
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200135 {
136 Py_DECREF(bytes);
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200137 return NULL;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200138 }
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200139
140 *todecref = bytes;
141 }
142 else
143 {
Bram Moolenaarc476e522013-06-23 13:46:40 +0200144#if PY_MAJOR_VERSION < 3
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200145 PyErr_FORMAT(PyExc_TypeError,
146 N_("expected str() or unicode() instance, but got %s"),
147 Py_TYPE_NAME(obj));
Bram Moolenaarc476e522013-06-23 13:46:40 +0200148#else
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200149 PyErr_FORMAT(PyExc_TypeError,
150 N_("expected bytes() or str() instance, but got %s"),
151 Py_TYPE_NAME(obj));
Bram Moolenaarc476e522013-06-23 13:46:40 +0200152#endif
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200153 return NULL;
154 }
155
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200156 return (char_u *) str;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200157}
158
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200159#define NUMBER_LONG 1
160#define NUMBER_INT 2
161#define NUMBER_NATURAL 4
162#define NUMBER_UNSIGNED 8
163
164 static int
165NumberToLong(PyObject *obj, long *result, int flags)
166{
167#if PY_MAJOR_VERSION < 3
168 if (PyInt_Check(obj))
169 {
170 *result = PyInt_AsLong(obj);
171 if (PyErr_Occurred())
172 return -1;
173 }
174 else
175#endif
176 if (PyLong_Check(obj))
177 {
178 *result = PyLong_AsLong(obj);
179 if (PyErr_Occurred())
180 return -1;
181 }
182 else if (PyNumber_Check(obj))
183 {
184 PyObject *num;
185
186 if (!(num = PyNumber_Long(obj)))
187 return -1;
188
189 *result = PyLong_AsLong(num);
190
191 Py_DECREF(num);
192
193 if (PyErr_Occurred())
194 return -1;
195 }
196 else
197 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200198#if PY_MAJOR_VERSION < 3
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200199 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200200 N_("expected int(), long() or something supporting "
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200201 "coercing to long(), but got %s"),
202 Py_TYPE_NAME(obj));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200203#else
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200204 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200205 N_("expected int() or something supporting coercing to int(), "
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200206 "but got %s"),
207 Py_TYPE_NAME(obj));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200208#endif
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200209 return -1;
210 }
211
212 if (flags & NUMBER_INT)
213 {
214 if (*result > INT_MAX)
215 {
216 PyErr_SET_STRING(PyExc_OverflowError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200217 N_("value is too large to fit into C int type"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200218 return -1;
219 }
220 else if (*result < INT_MIN)
221 {
222 PyErr_SET_STRING(PyExc_OverflowError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200223 N_("value is too small to fit into C int type"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200224 return -1;
225 }
226 }
227
228 if (flags & NUMBER_NATURAL)
229 {
230 if (*result <= 0)
231 {
232 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200233 N_("number must be greater then zero"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200234 return -1;
235 }
236 }
237 else if (flags & NUMBER_UNSIGNED)
238 {
239 if (*result < 0)
240 {
241 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200242 N_("number must be greater or equal to zero"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200243 return -1;
244 }
245 }
246
247 return 0;
248}
249
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200250 static int
251add_string(PyObject *list, char *s)
252{
253 PyObject *string;
254
255 if (!(string = PyString_FromString(s)))
256 return -1;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200257
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200258 if (PyList_Append(list, string))
259 {
260 Py_DECREF(string);
261 return -1;
262 }
263
264 Py_DECREF(string);
265 return 0;
266}
267
268 static PyObject *
269ObjectDir(PyObject *self, char **attributes)
270{
271 PyMethodDef *method;
272 char **attr;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200273 PyObject *ret;
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200274
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200275 if (!(ret = PyList_New(0)))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200276 return NULL;
277
278 if (self)
279 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
Bram Moolenaar41009372013-07-01 22:03:04 +0200280 if (add_string(ret, (char *)method->ml_name))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200281 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200282 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200283 return NULL;
284 }
285
286 for (attr = attributes ; *attr ; ++attr)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200287 if (add_string(ret, *attr))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200288 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200289 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200290 return NULL;
291 }
292
293#if PY_MAJOR_VERSION < 3
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200294 if (add_string(ret, "__members__"))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200295 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200296 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200297 return NULL;
298 }
299#endif
300
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200301 return ret;
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200302}
303
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200304/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200305 */
306
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200307/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200308typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200309
310static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200311
312typedef struct
313{
314 PyObject_HEAD
315 long softspace;
316 long error;
317} OutputObject;
318
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200319static char *OutputAttrs[] = {
320 "softspace",
321 NULL
322};
323
324 static PyObject *
325OutputDir(PyObject *self)
326{
327 return ObjectDir(self, OutputAttrs);
328}
329
Bram Moolenaar77045652012-09-21 13:46:06 +0200330 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200331OutputSetattr(OutputObject *self, char *name, PyObject *valObject)
Bram Moolenaar77045652012-09-21 13:46:06 +0200332{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200333 if (valObject == NULL)
Bram Moolenaar77045652012-09-21 13:46:06 +0200334 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200335 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200336 N_("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200337 return -1;
338 }
339
340 if (strcmp(name, "softspace") == 0)
341 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200342 if (NumberToLong(valObject, &(self->softspace), NUMBER_UNSIGNED))
Bram Moolenaar77045652012-09-21 13:46:06 +0200343 return -1;
Bram Moolenaar77045652012-09-21 13:46:06 +0200344 return 0;
345 }
346
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200347 PyErr_FORMAT(PyExc_AttributeError, N_("invalid attribute: %s"), name);
Bram Moolenaar77045652012-09-21 13:46:06 +0200348 return -1;
349}
350
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200351/* Buffer IO, we write one whole line at a time. */
352static garray_T io_ga = {0, 0, 1, 80, NULL};
353static writefn old_fn = NULL;
354
355 static void
356PythonIO_Flush(void)
357{
358 if (old_fn != NULL && io_ga.ga_len > 0)
359 {
360 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
361 old_fn((char_u *)io_ga.ga_data);
362 }
363 io_ga.ga_len = 0;
364}
365
366 static void
367writer(writefn fn, char_u *str, PyInt n)
368{
369 char_u *ptr;
370
371 /* Flush when switching output function. */
372 if (fn != old_fn)
373 PythonIO_Flush();
374 old_fn = fn;
375
376 /* Write each NL separated line. Text after the last NL is kept for
377 * writing later. */
378 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
379 {
380 PyInt len = ptr - str;
381
382 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
383 break;
384
385 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
386 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
387 fn((char_u *)io_ga.ga_data);
388 str = ptr + 1;
389 n -= len + 1;
390 io_ga.ga_len = 0;
391 }
392
393 /* Put the remaining text into io_ga for later printing. */
394 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
395 {
396 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
397 io_ga.ga_len += (int)n;
398 }
399}
400
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200401 static int
402write_output(OutputObject *self, PyObject *string)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200403{
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200404 Py_ssize_t len = 0;
405 char *str = NULL;
406 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200407
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200408 if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
409 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200410
411 Py_BEGIN_ALLOW_THREADS
412 Python_Lock_Vim();
413 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
414 Python_Release_Vim();
415 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200416 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200417
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200418 return 0;
419}
420
421 static PyObject *
422OutputWrite(OutputObject *self, PyObject *string)
423{
424 if (write_output(self, string))
425 return NULL;
426
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200427 Py_INCREF(Py_None);
428 return Py_None;
429}
430
431 static PyObject *
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200432OutputWritelines(OutputObject *self, PyObject *seq)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200433{
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200434 PyObject *iterator;
435 PyObject *item;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200436
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200437 if (!(iterator = PyObject_GetIter(seq)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200438 return NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200439
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200440 while ((item = PyIter_Next(iterator)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200441 {
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200442 if (write_output(self, item))
Bram Moolenaardb913952012-06-29 12:54:53 +0200443 {
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200444 Py_DECREF(iterator);
445 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200446 return NULL;
447 }
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200448 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200449 }
450
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200451 Py_DECREF(iterator);
452
453 /* Iterator may have finished due to an exception */
454 if (PyErr_Occurred())
455 return NULL;
456
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200457 Py_INCREF(Py_None);
458 return Py_None;
459}
460
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100461 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200462OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100463{
464 /* do nothing */
465 Py_INCREF(Py_None);
466 return Py_None;
467}
468
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200469/***************/
470
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200471static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200472 /* name, function, calling, doc */
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200473 {"write", (PyCFunction)OutputWrite, METH_O, ""},
474 {"writelines", (PyCFunction)OutputWritelines, METH_O, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200475 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200476 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200477 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200478};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200479
480static OutputObject Output =
481{
482 PyObject_HEAD_INIT(&OutputType)
483 0,
484 0
485};
486
487static OutputObject Error =
488{
489 PyObject_HEAD_INIT(&OutputType)
490 0,
491 1
492};
493
494 static int
495PythonIO_Init_io(void)
496{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +0200497 if (PySys_SetObject("stdout", (PyObject *)(void *)&Output))
498 return -1;
499 if (PySys_SetObject("stderr", (PyObject *)(void *)&Error))
500 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200501
502 if (PyErr_Occurred())
503 {
504 EMSG(_("E264: Python: Error initialising I/O objects"));
505 return -1;
506 }
507
508 return 0;
509}
510
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200511typedef struct
512{
513 PyObject_HEAD
514 PyObject *module;
515} LoaderObject;
516static PyTypeObject LoaderType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200517
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200518 static void
519LoaderDestructor(LoaderObject *self)
520{
521 Py_DECREF(self->module);
522 DESTRUCTOR_FINISH(self);
523}
524
525 static PyObject *
526LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
527{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200528 PyObject *ret = self->module;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200529
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200530 Py_INCREF(ret);
531 return ret;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200532}
533
534static struct PyMethodDef LoaderMethods[] = {
535 /* name, function, calling, doc */
536 {"load_module", (PyCFunction)LoaderLoadModule, METH_VARARGS, ""},
537 { NULL, NULL, 0, NULL}
538};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200539
540/* Check to see whether a Vim error has been reported, or a keyboard
541 * interrupt has been detected.
542 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200543
544 static void
545VimTryStart(void)
546{
547 ++trylevel;
548}
549
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200550 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200551VimTryEnd(void)
552{
553 --trylevel;
Bram Moolenaar41009372013-07-01 22:03:04 +0200554 /* Without this it stops processing all subsequent VimL commands and
555 * generates strange error messages if I e.g. try calling Test() in a
556 * cycle */
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200557 did_emsg = FALSE;
558 /* Keyboard interrupt should be preferred over anything else */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200559 if (got_int)
560 {
Bram Moolenaard6b8a522013-11-11 01:05:48 +0100561 if (current_exception != NULL)
562 discard_current_exception();
563 else
564 need_rethrow = did_throw = FALSE;
565 got_int = FALSE;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200566 PyErr_SetNone(PyExc_KeyboardInterrupt);
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200567 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200568 }
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100569 else if (msg_list != NULL && *msg_list != NULL)
570 {
571 int should_free;
572 char_u *msg;
573
574 msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free);
575
576 if (msg == NULL)
577 {
578 PyErr_NoMemory();
579 return -1;
580 }
581
582 PyErr_SetVim((char *) msg);
583
584 free_global_msglist();
585
586 if (should_free)
587 vim_free(msg);
588
589 return -1;
590 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200591 else if (!did_throw)
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200592 return (PyErr_Occurred() ? -1 : 0);
593 /* Python exception is preferred over vim one; unlikely to occur though */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200594 else if (PyErr_Occurred())
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200595 {
Bram Moolenaard6b8a522013-11-11 01:05:48 +0100596 if (current_exception != NULL)
597 discard_current_exception();
598 else
599 need_rethrow = did_throw = FALSE;
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200600 return -1;
601 }
602 /* Finally transform VimL exception to python one */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200603 else
604 {
Bram Moolenaar41009372013-07-01 22:03:04 +0200605 PyErr_SetVim((char *)current_exception->value);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200606 discard_current_exception();
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200607 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200608 }
609}
610
611 static int
612VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200613{
614 if (got_int)
615 {
616 PyErr_SetNone(PyExc_KeyboardInterrupt);
617 return 1;
618 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200619 return 0;
620}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200621
622/* Vim module - Implementation
623 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200624
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200625 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200626VimCommand(PyObject *self UNUSED, PyObject *string)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200627{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200628 char_u *cmd;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200629 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200630 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200631
Bram Moolenaar389a1792013-06-23 13:00:44 +0200632 if (!(cmd = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200633 return NULL;
634
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200635 Py_BEGIN_ALLOW_THREADS
636 Python_Lock_Vim();
637
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200638 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200639 do_cmdline_cmd(cmd);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200640 update_screen(VALID);
641
642 Python_Release_Vim();
643 Py_END_ALLOW_THREADS
644
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200645 if (VimTryEnd())
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200646 ret = NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200647 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200648 ret = Py_None;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200649
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200650 Py_XINCREF(ret);
Bram Moolenaar389a1792013-06-23 13:00:44 +0200651 Py_XDECREF(todecref);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200652 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200653}
654
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200655/*
656 * Function to translate a typval_T into a PyObject; this will recursively
657 * translate lists/dictionaries into their Python equivalents.
658 *
659 * The depth parameter is to avoid infinite recursion, set it to 1 when
660 * you call VimToPython.
661 */
662 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200663VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200664{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200665 PyObject *ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200666 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200667 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200668
669 /* Avoid infinite recursion */
670 if (depth > 100)
671 {
672 Py_INCREF(Py_None);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200673 ret = Py_None;
674 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200675 }
676
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200677 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200678 * then and we can use it again. */
679 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
680 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
681 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200682 sprintf(ptrBuf, "%p",
683 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
684 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200685
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200686 if ((ret = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200687 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200688 Py_INCREF(ret);
689 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200690 }
691 }
692
693 if (our_tv->v_type == VAR_STRING)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200694 ret = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200695 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200696 else if (our_tv->v_type == VAR_NUMBER)
697 {
698 char buf[NUMBUFLEN];
699
700 /* For backwards compatibility numbers are stored as strings. */
701 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar41009372013-07-01 22:03:04 +0200702 ret = PyString_FromString((char *)buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200703 }
704# ifdef FEAT_FLOAT
705 else if (our_tv->v_type == VAR_FLOAT)
706 {
707 char buf[NUMBUFLEN];
708
709 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar41009372013-07-01 22:03:04 +0200710 ret = PyString_FromString((char *)buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200711 }
712# endif
713 else if (our_tv->v_type == VAR_LIST)
714 {
715 list_T *list = our_tv->vval.v_list;
716 listitem_T *curr;
717
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200718 if (list == NULL)
719 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200720
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200721 if (!(ret = PyList_New(0)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200722 return NULL;
723
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200724 if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200725 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200726 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200727 return NULL;
728 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200729
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200730 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
731 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200732 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200733 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200734 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200735 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200736 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200737 if (PyList_Append(ret, newObj))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200738 {
739 Py_DECREF(newObj);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200740 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200741 return NULL;
742 }
743 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200744 }
745 }
746 else if (our_tv->v_type == VAR_DICT)
747 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200748
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200749 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
750 long_u todo = ht->ht_used;
751 hashitem_T *hi;
752 dictitem_T *di;
753 if (our_tv->vval.v_dict == NULL)
754 return NULL;
755
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200756 if (!(ret = PyDict_New()))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200757 return NULL;
758
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200759 if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200760 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200761 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200762 return NULL;
763 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200764
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200765 for (hi = ht->ht_array; todo > 0; ++hi)
766 {
767 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200768 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200769 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200770
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200771 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200772 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200773 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200774 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200775 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200776 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200777 if (PyDict_SetItemString(ret, (char *)hi->hi_key, newObj))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200778 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200779 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200780 Py_DECREF(newObj);
781 return NULL;
782 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200783 }
784 }
785 }
786 else
787 {
788 Py_INCREF(Py_None);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200789 ret = Py_None;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200790 }
791
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200792 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200793}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200794
795 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200796VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200797{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200798 char_u *expr;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200799 typval_T *our_tv;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200800 PyObject *string;
801 PyObject *todecref;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200802 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200803 PyObject *lookup_dict;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200804
Bram Moolenaar389a1792013-06-23 13:00:44 +0200805 if (!PyArg_ParseTuple(args, "O", &string))
806 return NULL;
807
808 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200809 return NULL;
810
811 Py_BEGIN_ALLOW_THREADS
812 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200813 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200814 our_tv = eval_expr(expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200815 Python_Release_Vim();
816 Py_END_ALLOW_THREADS
817
Bram Moolenaar389a1792013-06-23 13:00:44 +0200818 Py_XDECREF(todecref);
819
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200820 if (VimTryEnd())
821 return NULL;
822
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200823 if (our_tv == NULL)
824 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200825 PyErr_SET_VIM(N_("invalid expression"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200826 return NULL;
827 }
828
829 /* Convert the Vim type into a Python type. Create a dictionary that's
830 * used to check for recursive loops. */
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200831 if (!(lookup_dict = PyDict_New()))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200832 ret = NULL;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200833 else
834 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200835 ret = VimToPython(our_tv, 1, lookup_dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200836 Py_DECREF(lookup_dict);
837 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200838
839
840 Py_BEGIN_ALLOW_THREADS
841 Python_Lock_Vim();
842 free_tv(our_tv);
843 Python_Release_Vim();
844 Py_END_ALLOW_THREADS
845
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200846 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200847}
848
Bram Moolenaardb913952012-06-29 12:54:53 +0200849static PyObject *ConvertToPyObject(typval_T *);
850
851 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200852VimEvalPy(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200853{
Bram Moolenaardb913952012-06-29 12:54:53 +0200854 typval_T *our_tv;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200855 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200856 char_u *expr;
857 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +0200858
Bram Moolenaar389a1792013-06-23 13:00:44 +0200859 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200860 return NULL;
861
862 Py_BEGIN_ALLOW_THREADS
863 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200864 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200865 our_tv = eval_expr(expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200866 Python_Release_Vim();
867 Py_END_ALLOW_THREADS
868
Bram Moolenaar389a1792013-06-23 13:00:44 +0200869 Py_XDECREF(todecref);
870
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200871 if (VimTryEnd())
872 return NULL;
873
Bram Moolenaardb913952012-06-29 12:54:53 +0200874 if (our_tv == NULL)
875 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200876 PyErr_SET_VIM(N_("invalid expression"));
Bram Moolenaardb913952012-06-29 12:54:53 +0200877 return NULL;
878 }
879
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200880 ret = ConvertToPyObject(our_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200881 Py_BEGIN_ALLOW_THREADS
882 Python_Lock_Vim();
883 free_tv(our_tv);
884 Python_Release_Vim();
885 Py_END_ALLOW_THREADS
886
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200887 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +0200888}
889
890 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200891VimStrwidth(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200892{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200893 char_u *str;
894 PyObject *todecref;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200895 int len;
Bram Moolenaardb913952012-06-29 12:54:53 +0200896
Bram Moolenaar389a1792013-06-23 13:00:44 +0200897 if (!(str = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200898 return NULL;
899
Bram Moolenaara54bf402012-12-05 16:30:07 +0100900#ifdef FEAT_MBYTE
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200901 len = mb_string2cells(str, (int)STRLEN(str));
Bram Moolenaara54bf402012-12-05 16:30:07 +0100902#else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200903 len = STRLEN(str);
Bram Moolenaara54bf402012-12-05 16:30:07 +0100904#endif
Bram Moolenaar389a1792013-06-23 13:00:44 +0200905
906 Py_XDECREF(todecref);
907
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200908 return PyLong_FromLong(len);
Bram Moolenaardb913952012-06-29 12:54:53 +0200909}
910
Bram Moolenaarf4258302013-06-02 18:20:17 +0200911 static PyObject *
912_VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
913{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200914 PyObject *ret;
Bram Moolenaarf4258302013-06-02 18:20:17 +0200915 PyObject *newwd;
916 PyObject *todecref;
917 char_u *new_dir;
918
Bram Moolenaard4209d22013-06-05 20:34:15 +0200919 if (_chdir == NULL)
920 return NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200921 if (!(ret = PyObject_Call(_chdir, args, kwargs)))
Bram Moolenaarf4258302013-06-02 18:20:17 +0200922 return NULL;
923
924 if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
925 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200926 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200927 return NULL;
928 }
929
930 if (!(new_dir = StringToChars(newwd, &todecref)))
931 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200932 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200933 Py_DECREF(newwd);
934 return NULL;
935 }
936
937 VimTryStart();
938
939 if (vim_chdir(new_dir))
940 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200941 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200942 Py_DECREF(newwd);
943 Py_XDECREF(todecref);
944
945 if (VimTryEnd())
946 return NULL;
947
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200948 PyErr_SET_VIM(N_("failed to change directory"));
Bram Moolenaarf4258302013-06-02 18:20:17 +0200949 return NULL;
950 }
951
952 Py_DECREF(newwd);
953 Py_XDECREF(todecref);
954
955 post_chdir(FALSE);
956
957 if (VimTryEnd())
958 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200959 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200960 return NULL;
961 }
962
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200963 return ret;
Bram Moolenaarf4258302013-06-02 18:20:17 +0200964}
965
966 static PyObject *
967VimChdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
968{
969 return _VimChdir(py_chdir, args, kwargs);
970}
971
972 static PyObject *
973VimFchdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
974{
975 return _VimChdir(py_fchdir, args, kwargs);
976}
977
Bram Moolenaarc09a6d62013-06-10 21:27:29 +0200978typedef struct {
979 PyObject *callable;
980 PyObject *result;
981} map_rtp_data;
982
983 static void
984map_rtp_callback(char_u *path, void *_data)
985{
986 void **data = (void **) _data;
987 PyObject *pathObject;
988 map_rtp_data *mr_data = *((map_rtp_data **) data);
989
Bram Moolenaar41009372013-07-01 22:03:04 +0200990 if (!(pathObject = PyString_FromString((char *)path)))
Bram Moolenaarc09a6d62013-06-10 21:27:29 +0200991 {
992 *data = NULL;
993 return;
994 }
995
996 mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
997 pathObject, NULL);
998
999 Py_DECREF(pathObject);
1000
1001 if (!mr_data->result || mr_data->result != Py_None)
1002 *data = NULL;
1003 else
1004 {
1005 Py_DECREF(mr_data->result);
1006 mr_data->result = NULL;
1007 }
1008}
1009
1010 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02001011VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001012{
1013 map_rtp_data data;
1014
Bram Moolenaar389a1792013-06-23 13:00:44 +02001015 data.callable = callable;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001016 data.result = NULL;
1017
1018 do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
1019
1020 if (data.result == NULL)
1021 {
1022 if (PyErr_Occurred())
1023 return NULL;
1024 else
1025 {
1026 Py_INCREF(Py_None);
1027 return Py_None;
1028 }
1029 }
1030 return data.result;
1031}
1032
1033/*
1034 * _vim_runtimepath_ special path implementation.
1035 */
1036
1037 static void
1038map_finder_callback(char_u *path, void *_data)
1039{
1040 void **data = (void **) _data;
1041 PyObject *list = *((PyObject **) data);
1042 PyObject *pathObject1, *pathObject2;
1043 char *pathbuf;
1044 size_t pathlen;
1045
1046 pathlen = STRLEN(path);
1047
1048#if PY_MAJOR_VERSION < 3
1049# define PY_MAIN_DIR_STRING "python2"
1050#else
1051# define PY_MAIN_DIR_STRING "python3"
1052#endif
1053#define PY_ALTERNATE_DIR_STRING "pythonx"
1054
1055#define PYTHONX_STRING_LENGTH 7 /* STRLEN("pythonx") */
1056 if (!(pathbuf = PyMem_New(char,
1057 pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
1058 {
1059 PyErr_NoMemory();
1060 *data = NULL;
1061 return;
1062 }
1063
1064 mch_memmove(pathbuf, path, pathlen + 1);
1065 add_pathsep((char_u *) pathbuf);
1066
1067 pathlen = STRLEN(pathbuf);
1068 mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
1069 PYTHONX_STRING_LENGTH + 1);
1070
1071 if (!(pathObject1 = PyString_FromString(pathbuf)))
1072 {
1073 *data = NULL;
1074 PyMem_Free(pathbuf);
1075 return;
1076 }
1077
1078 mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
1079 PYTHONX_STRING_LENGTH + 1);
1080
1081 if (!(pathObject2 = PyString_FromString(pathbuf)))
1082 {
1083 Py_DECREF(pathObject1);
1084 PyMem_Free(pathbuf);
1085 *data = NULL;
1086 return;
1087 }
1088
1089 PyMem_Free(pathbuf);
1090
1091 if (PyList_Append(list, pathObject1)
1092 || PyList_Append(list, pathObject2))
1093 *data = NULL;
1094
1095 Py_DECREF(pathObject1);
1096 Py_DECREF(pathObject2);
1097}
1098
1099 static PyObject *
1100Vim_GetPaths(PyObject *self UNUSED)
1101{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001102 PyObject *ret;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001103
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001104 if (!(ret = PyList_New(0)))
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001105 return NULL;
1106
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001107 do_in_runtimepath(NULL, FALSE, &map_finder_callback, ret);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001108
1109 if (PyErr_Occurred())
1110 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001111 Py_DECREF(ret);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001112 return NULL;
1113 }
1114
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001115 return ret;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001116}
1117
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001118 static PyObject *
1119call_load_module(char *name, int len, PyObject *find_module_result)
1120{
1121 PyObject *fd, *pathname, *description;
1122
Bram Moolenaarc476e522013-06-23 13:46:40 +02001123 if (!PyTuple_Check(find_module_result))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001124 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001125 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001126 N_("expected 3-tuple as imp.find_module() result, but got %s"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02001127 Py_TYPE_NAME(find_module_result));
1128 return NULL;
1129 }
1130 if (PyTuple_GET_SIZE(find_module_result) != 3)
1131 {
1132 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001133 N_("expected 3-tuple as imp.find_module() result, but got "
1134 "tuple of size %d"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02001135 (int) PyTuple_GET_SIZE(find_module_result));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001136 return NULL;
1137 }
1138
1139 if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
1140 || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
1141 || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
1142 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001143 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001144 N_("internal error: imp.find_module returned tuple with NULL"));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001145 return NULL;
1146 }
1147
1148 return PyObject_CallFunction(py_load_module,
1149 "s#OOO", name, len, fd, pathname, description);
1150}
1151
1152 static PyObject *
1153find_module(char *fullname, char *tail, PyObject *new_path)
1154{
1155 PyObject *find_module_result;
1156 PyObject *module;
1157 char *dot;
1158
Bram Moolenaar41009372013-07-01 22:03:04 +02001159 if ((dot = (char *)vim_strchr((char_u *) tail, '.')))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001160 {
1161 /*
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001162 * There is a dot in the name: call find_module recursively without the
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001163 * first component
1164 */
1165 PyObject *newest_path;
1166 int partlen = (int) (dot - 1 - tail);
1167
1168 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1169 "s#O", tail, partlen, new_path)))
1170 return NULL;
1171
1172 if (!(module = call_load_module(
1173 fullname,
1174 ((int) (tail - fullname)) + partlen,
1175 find_module_result)))
1176 {
1177 Py_DECREF(find_module_result);
1178 return NULL;
1179 }
1180
1181 Py_DECREF(find_module_result);
1182
1183 if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
1184 {
1185 Py_DECREF(module);
1186 return NULL;
1187 }
1188
1189 Py_DECREF(module);
1190
1191 module = find_module(fullname, dot + 1, newest_path);
1192
1193 Py_DECREF(newest_path);
1194
1195 return module;
1196 }
1197 else
1198 {
1199 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1200 "sO", tail, new_path)))
1201 return NULL;
1202
1203 if (!(module = call_load_module(
1204 fullname,
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001205 (int)STRLEN(fullname),
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001206 find_module_result)))
1207 {
1208 Py_DECREF(find_module_result);
1209 return NULL;
1210 }
1211
1212 Py_DECREF(find_module_result);
1213
1214 return module;
1215 }
1216}
1217
1218 static PyObject *
1219FinderFindModule(PyObject *self, PyObject *args)
1220{
1221 char *fullname;
1222 PyObject *module;
1223 PyObject *new_path;
1224 LoaderObject *loader;
1225
1226 if (!PyArg_ParseTuple(args, "s", &fullname))
1227 return NULL;
1228
1229 if (!(new_path = Vim_GetPaths(self)))
1230 return NULL;
1231
1232 module = find_module(fullname, fullname, new_path);
1233
1234 Py_DECREF(new_path);
1235
1236 if (!module)
1237 {
Bram Moolenaar7e85d3d2013-06-23 16:40:39 +02001238 if (PyErr_Occurred())
1239 {
1240 if (PyErr_ExceptionMatches(PyExc_ImportError))
1241 PyErr_Clear();
1242 else
1243 return NULL;
1244 }
1245
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001246 Py_INCREF(Py_None);
1247 return Py_None;
1248 }
1249
1250 if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
1251 {
1252 Py_DECREF(module);
1253 return NULL;
1254 }
1255
1256 loader->module = module;
1257
1258 return (PyObject *) loader;
1259}
1260
1261 static PyObject *
1262VimPathHook(PyObject *self UNUSED, PyObject *args)
1263{
1264 char *path;
1265
1266 if (PyArg_ParseTuple(args, "s", &path)
1267 && STRCMP(path, vim_special_path) == 0)
1268 {
1269 Py_INCREF(vim_module);
1270 return vim_module;
1271 }
1272
1273 PyErr_Clear();
1274 PyErr_SetNone(PyExc_ImportError);
1275 return NULL;
1276}
1277
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001278/*
1279 * Vim module - Definitions
1280 */
1281
1282static struct PyMethodDef VimMethods[] = {
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001283 /* name, function, calling, documentation */
Bram Moolenaar389a1792013-06-23 13:00:44 +02001284 {"command", VimCommand, METH_O, "Execute a Vim ex-mode command" },
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001285 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02001286 {"bindeval", VimEvalPy, METH_O, "Like eval(), but returns objects attached to vim ones"},
1287 {"strwidth", VimStrwidth, METH_O, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001288 {"chdir", (PyCFunction)VimChdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
1289 {"fchdir", (PyCFunction)VimFchdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
Bram Moolenaar389a1792013-06-23 13:00:44 +02001290 {"foreach_rtp", VimForeachRTP, METH_O, "Call given callable for each path in &rtp"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001291 {"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001292 {"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
1293 {"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
1294 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001295};
1296
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001297/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001298 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001299 */
1300
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001301static PyTypeObject IterType;
1302
1303typedef PyObject *(*nextfun)(void **);
1304typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001305typedef int (*traversefun)(void *, visitproc, void *);
1306typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001307
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001308/* Main purpose of this object is removing the need for do python
1309 * initialization (i.e. PyType_Ready and setting type attributes) for a big
1310 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001311
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001312typedef struct
1313{
1314 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001315 void *cur;
1316 nextfun next;
1317 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001318 traversefun traverse;
1319 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001320} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001321
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001322 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001323IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
1324 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001325{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001326 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001327
Bram Moolenaar774267b2013-05-21 20:51:59 +02001328 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001329 self->cur = start;
1330 self->next = next;
1331 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001332 self->traverse = traverse;
1333 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001334
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001335 return (PyObject *)(self);
1336}
1337
1338 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001339IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001340{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001341 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02001342 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +02001343 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001344}
1345
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001346 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001347IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001348{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001349 if (self->traverse != NULL)
1350 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001351 else
1352 return 0;
1353}
1354
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001355/* Mac OSX defines clear() somewhere. */
1356#ifdef clear
1357# undef clear
1358#endif
1359
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001360 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001361IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001362{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001363 if (self->clear != NULL)
1364 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001365 else
1366 return 0;
1367}
1368
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001369 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001370IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001371{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001372 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001373}
1374
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001375 static PyObject *
1376IterIter(PyObject *self)
1377{
Bram Moolenaar1bcabe12013-05-29 22:52:32 +02001378 Py_INCREF(self);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001379 return self;
1380}
Bram Moolenaardfa38d42013-05-15 13:38:47 +02001381
Bram Moolenaardb913952012-06-29 12:54:53 +02001382typedef struct pylinkedlist_S {
1383 struct pylinkedlist_S *pll_next;
1384 struct pylinkedlist_S *pll_prev;
1385 PyObject *pll_obj;
1386} pylinkedlist_T;
1387
1388static pylinkedlist_T *lastdict = NULL;
1389static pylinkedlist_T *lastlist = NULL;
1390
1391 static void
1392pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
1393{
1394 if (ref->pll_prev == NULL)
1395 {
1396 if (ref->pll_next == NULL)
1397 {
1398 *last = NULL;
1399 return;
1400 }
1401 }
1402 else
1403 ref->pll_prev->pll_next = ref->pll_next;
1404
1405 if (ref->pll_next == NULL)
1406 *last = ref->pll_prev;
1407 else
1408 ref->pll_next->pll_prev = ref->pll_prev;
1409}
1410
1411 static void
1412pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
1413{
1414 if (*last == NULL)
1415 ref->pll_prev = NULL;
1416 else
1417 {
1418 (*last)->pll_next = ref;
1419 ref->pll_prev = *last;
1420 }
1421 ref->pll_next = NULL;
1422 ref->pll_obj = self;
1423 *last = ref;
1424}
1425
1426static PyTypeObject DictionaryType;
1427
1428typedef struct
1429{
1430 PyObject_HEAD
1431 dict_T *dict;
1432 pylinkedlist_T ref;
1433} DictionaryObject;
1434
Bram Moolenaara9922d62013-05-30 13:01:18 +02001435static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
1436
1437#define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
1438
Bram Moolenaardb913952012-06-29 12:54:53 +02001439 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001440DictionaryNew(PyTypeObject *subtype, dict_T *dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02001441{
1442 DictionaryObject *self;
1443
Bram Moolenaara9922d62013-05-30 13:01:18 +02001444 self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02001445 if (self == NULL)
1446 return NULL;
1447 self->dict = dict;
1448 ++dict->dv_refcount;
1449
1450 pyll_add((PyObject *)(self), &self->ref, &lastdict);
1451
1452 return (PyObject *)(self);
1453}
1454
Bram Moolenaara9922d62013-05-30 13:01:18 +02001455 static dict_T *
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001456py_dict_alloc(void)
Bram Moolenaara9922d62013-05-30 13:01:18 +02001457{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001458 dict_T *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001459
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001460 if (!(ret = dict_alloc()))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001461 {
1462 PyErr_NoMemory();
1463 return NULL;
1464 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001465 ++ret->dv_refcount;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001466
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001467 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001468}
1469
1470 static PyObject *
1471DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1472{
1473 DictionaryObject *self;
1474 dict_T *dict;
1475
1476 if (!(dict = py_dict_alloc()))
1477 return NULL;
1478
1479 self = (DictionaryObject *) DictionaryNew(subtype, dict);
1480
1481 --dict->dv_refcount;
1482
1483 if (kwargs || PyTuple_Size(args))
1484 {
1485 PyObject *tmp;
1486 if (!(tmp = DictionaryUpdate(self, args, kwargs)))
1487 {
1488 Py_DECREF(self);
1489 return NULL;
1490 }
1491
1492 Py_DECREF(tmp);
1493 }
1494
1495 return (PyObject *)(self);
1496}
1497
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001498 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001499DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001500{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001501 pyll_remove(&self->ref, &lastdict);
1502 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001503
1504 DESTRUCTOR_FINISH(self);
1505}
1506
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001507static char *DictionaryAttrs[] = {
1508 "locked", "scope",
1509 NULL
1510};
1511
1512 static PyObject *
1513DictionaryDir(PyObject *self)
1514{
1515 return ObjectDir(self, DictionaryAttrs);
1516}
1517
Bram Moolenaardb913952012-06-29 12:54:53 +02001518 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001519DictionarySetattr(DictionaryObject *self, char *name, PyObject *valObject)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001520{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001521 if (valObject == NULL)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001522 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001523 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001524 N_("cannot delete vim.Dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001525 return -1;
1526 }
1527
1528 if (strcmp(name, "locked") == 0)
1529 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001530 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001531 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001532 PyErr_SET_STRING(PyExc_TypeError,
1533 N_("cannot modify fixed dictionary"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001534 return -1;
1535 }
1536 else
1537 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001538 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarb983f752013-05-15 16:11:50 +02001539 if (istrue == -1)
1540 return -1;
1541 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001542 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001543 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001544 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001545 }
1546 return 0;
1547 }
1548 else
1549 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001550 PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02001551 return -1;
1552 }
1553}
1554
1555 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001556DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001557{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001558 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +02001559}
1560
Bram Moolenaara9922d62013-05-30 13:01:18 +02001561#define DICT_FLAG_HAS_DEFAULT 0x01
1562#define DICT_FLAG_POP 0x02
1563#define DICT_FLAG_NONE_DEFAULT 0x04
1564#define DICT_FLAG_RETURN_BOOL 0x08 /* Incompatible with DICT_FLAG_POP */
1565#define DICT_FLAG_RETURN_PAIR 0x10
1566
Bram Moolenaardb913952012-06-29 12:54:53 +02001567 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001568_DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
Bram Moolenaardb913952012-06-29 12:54:53 +02001569{
Bram Moolenaara9922d62013-05-30 13:01:18 +02001570 PyObject *keyObject;
1571 PyObject *defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001572 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001573 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001574 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001575 dict_T *dict = self->dict;
1576 hashitem_T *hi;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001577 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001578
Bram Moolenaara9922d62013-05-30 13:01:18 +02001579 if (flags & DICT_FLAG_HAS_DEFAULT)
1580 {
1581 if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1582 return NULL;
1583 }
1584 else
1585 keyObject = args;
1586
1587 if (flags & DICT_FLAG_RETURN_BOOL)
1588 defObject = Py_False;
1589
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001590 if (!(key = StringToChars(keyObject, &todecref)))
1591 return NULL;
1592
1593 if (*key == NUL)
1594 {
1595 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001596 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001597 return NULL;
1598 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001599
Bram Moolenaara9922d62013-05-30 13:01:18 +02001600 hi = hash_find(&dict->dv_hashtab, key);
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001601
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001602 Py_XDECREF(todecref);
Bram Moolenaar696c2112012-09-21 13:43:14 +02001603
Bram Moolenaara9922d62013-05-30 13:01:18 +02001604 if (HASHITEM_EMPTY(hi))
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001605 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001606 if (defObject)
1607 {
1608 Py_INCREF(defObject);
1609 return defObject;
1610 }
1611 else
1612 {
1613 PyErr_SetObject(PyExc_KeyError, keyObject);
1614 return NULL;
1615 }
1616 }
1617 else if (flags & DICT_FLAG_RETURN_BOOL)
1618 {
1619 Py_INCREF(Py_True);
1620 return Py_True;
1621 }
1622
1623 di = dict_lookup(hi);
1624
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001625 if (!(ret = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001626 return NULL;
1627
1628 if (flags & DICT_FLAG_POP)
1629 {
1630 if (dict->dv_lock)
1631 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001632 RAISE_LOCKED_DICTIONARY;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001633 Py_DECREF(ret);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001634 return NULL;
1635 }
1636
1637 hash_remove(&dict->dv_hashtab, hi);
1638 dictitem_free(di);
1639 }
1640
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001641 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001642}
1643
1644 static PyObject *
1645DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1646{
1647 return _DictionaryItem(self, keyObject, 0);
1648}
1649
1650 static int
1651DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1652{
1653 PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001654 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001655
Bram Moolenaarba2d7ff2013-11-04 00:34:53 +01001656 if (rObj == NULL)
1657 return -1;
1658
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001659 ret = (rObj == Py_True);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001660
Bram Moolenaardee2e312013-06-23 16:35:47 +02001661 Py_DECREF(rObj);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001662
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001663 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001664}
1665
1666typedef struct
1667{
1668 hashitem_T *ht_array;
1669 long_u ht_used;
1670 hashtab_T *ht;
1671 hashitem_T *hi;
Bram Moolenaar99dc19d2013-05-31 20:49:31 +02001672 long_u todo;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001673} dictiterinfo_T;
1674
1675 static PyObject *
1676DictionaryIterNext(dictiterinfo_T **dii)
1677{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001678 PyObject *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001679
1680 if (!(*dii)->todo)
1681 return NULL;
1682
1683 if ((*dii)->ht->ht_array != (*dii)->ht_array ||
1684 (*dii)->ht->ht_used != (*dii)->ht_used)
1685 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001686 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001687 N_("hashtab changed during iteration"));
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001688 return NULL;
1689 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001690
Bram Moolenaara9922d62013-05-30 13:01:18 +02001691 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
1692 ++((*dii)->hi);
1693
1694 --((*dii)->todo);
1695
Bram Moolenaar41009372013-07-01 22:03:04 +02001696 if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001697 return NULL;
1698
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001699 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001700}
1701
1702 static PyObject *
1703DictionaryIter(DictionaryObject *self)
1704{
1705 dictiterinfo_T *dii;
1706 hashtab_T *ht;
1707
1708 if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1709 {
1710 PyErr_NoMemory();
1711 return NULL;
1712 }
1713
1714 ht = &self->dict->dv_hashtab;
1715 dii->ht_array = ht->ht_array;
1716 dii->ht_used = ht->ht_used;
1717 dii->ht = ht;
1718 dii->hi = dii->ht_array;
1719 dii->todo = dii->ht_used;
1720
1721 return IterNew(dii,
1722 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1723 NULL, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02001724}
1725
1726 static PyInt
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001727DictionaryAssItem(
1728 DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +02001729{
1730 char_u *key;
1731 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001732 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001733 dictitem_T *di;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001734 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001735
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001736 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +02001737 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001738 RAISE_LOCKED_DICTIONARY;
Bram Moolenaardb913952012-06-29 12:54:53 +02001739 return -1;
1740 }
1741
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001742 if (!(key = StringToChars(keyObject, &todecref)))
1743 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001744
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001745 if (*key == NUL)
1746 {
1747 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001748 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001749 return -1;
1750 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001751
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001752 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +02001753
1754 if (valObject == NULL)
1755 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +02001756 hashitem_T *hi;
1757
Bram Moolenaardb913952012-06-29 12:54:53 +02001758 if (di == NULL)
1759 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001760 Py_XDECREF(todecref);
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001761 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +02001762 return -1;
1763 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001764 hi = hash_find(&dict->dv_hashtab, di->di_key);
1765 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +02001766 dictitem_free(di);
Bram Moolenaar78b59572013-06-02 18:54:21 +02001767 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001768 return 0;
1769 }
1770
1771 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaar78b59572013-06-02 18:54:21 +02001772 {
1773 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001774 return -1;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001775 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001776
1777 if (di == NULL)
1778 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001779 if (!(di = dictitem_alloc(key)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001780 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001781 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001782 PyErr_NoMemory();
1783 return -1;
1784 }
1785 di->di_tv.v_lock = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001786 di->di_tv.v_type = VAR_UNKNOWN;
Bram Moolenaardb913952012-06-29 12:54:53 +02001787
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001788 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001789 {
1790 vim_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001791 dictitem_free(di);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001792 RAISE_KEY_ADD_FAIL(key);
1793 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001794 return -1;
1795 }
1796 }
1797 else
1798 clear_tv(&di->di_tv);
1799
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001800 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001801
1802 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001803 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001804 return 0;
1805}
1806
Bram Moolenaara9922d62013-05-30 13:01:18 +02001807typedef PyObject *(*hi_to_py)(hashitem_T *);
1808
Bram Moolenaardb913952012-06-29 12:54:53 +02001809 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001810DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
Bram Moolenaardb913952012-06-29 12:54:53 +02001811{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001812 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001813 long_u todo = dict->dv_hashtab.ht_used;
1814 Py_ssize_t i = 0;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001815 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001816 hashitem_T *hi;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001817 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +02001818
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001819 ret = PyList_New(todo);
Bram Moolenaardb913952012-06-29 12:54:53 +02001820 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1821 {
1822 if (!HASHITEM_EMPTY(hi))
1823 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001824 if (!(newObj = hiconvert(hi)))
1825 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001826 Py_DECREF(ret);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001827 return NULL;
1828 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001829 PyList_SET_ITEM(ret, i, newObj);
Bram Moolenaardb913952012-06-29 12:54:53 +02001830 --todo;
1831 ++i;
1832 }
1833 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001834 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001835}
1836
Bram Moolenaara9922d62013-05-30 13:01:18 +02001837 static PyObject *
1838dict_key(hashitem_T *hi)
1839{
1840 return PyBytes_FromString((char *)(hi->hi_key));
1841}
1842
1843 static PyObject *
1844DictionaryListKeys(DictionaryObject *self)
1845{
1846 return DictionaryListObjects(self, dict_key);
1847}
1848
1849 static PyObject *
1850dict_val(hashitem_T *hi)
1851{
1852 dictitem_T *di;
1853
1854 di = dict_lookup(hi);
1855 return ConvertToPyObject(&di->di_tv);
1856}
1857
1858 static PyObject *
1859DictionaryListValues(DictionaryObject *self)
1860{
1861 return DictionaryListObjects(self, dict_val);
1862}
1863
1864 static PyObject *
1865dict_item(hashitem_T *hi)
1866{
1867 PyObject *keyObject;
1868 PyObject *valObject;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001869 PyObject *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001870
1871 if (!(keyObject = dict_key(hi)))
1872 return NULL;
1873
1874 if (!(valObject = dict_val(hi)))
1875 {
1876 Py_DECREF(keyObject);
1877 return NULL;
1878 }
1879
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001880 ret = Py_BuildValue("(OO)", keyObject, valObject);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001881
1882 Py_DECREF(keyObject);
1883 Py_DECREF(valObject);
1884
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001885 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001886}
1887
1888 static PyObject *
1889DictionaryListItems(DictionaryObject *self)
1890{
1891 return DictionaryListObjects(self, dict_item);
1892}
1893
1894 static PyObject *
1895DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
1896{
1897 dict_T *dict = self->dict;
1898
1899 if (dict->dv_lock)
1900 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001901 RAISE_LOCKED_DICTIONARY;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001902 return NULL;
1903 }
1904
1905 if (kwargs)
1906 {
1907 typval_T tv;
1908
1909 if (ConvertFromPyMapping(kwargs, &tv) == -1)
1910 return NULL;
1911
1912 VimTryStart();
1913 dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force");
1914 clear_tv(&tv);
1915 if (VimTryEnd())
1916 return NULL;
1917 }
1918 else
1919 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001920 PyObject *obj;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001921
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001922 if (!PyArg_ParseTuple(args, "O", &obj))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001923 return NULL;
1924
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001925 if (PyObject_HasAttrString(obj, "keys"))
1926 return DictionaryUpdate(self, NULL, obj);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001927 else
1928 {
1929 PyObject *iterator;
1930 PyObject *item;
1931
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001932 if (!(iterator = PyObject_GetIter(obj)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001933 return NULL;
1934
1935 while ((item = PyIter_Next(iterator)))
1936 {
1937 PyObject *fast;
1938 PyObject *keyObject;
1939 PyObject *valObject;
1940 PyObject *todecref;
1941 char_u *key;
1942 dictitem_T *di;
1943
1944 if (!(fast = PySequence_Fast(item, "")))
1945 {
1946 Py_DECREF(iterator);
1947 Py_DECREF(item);
1948 return NULL;
1949 }
1950
1951 Py_DECREF(item);
1952
1953 if (PySequence_Fast_GET_SIZE(fast) != 2)
1954 {
1955 Py_DECREF(iterator);
1956 Py_DECREF(fast);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001957 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001958 N_("expected sequence element of size 2, "
1959 "but got sequence of size %d"),
Bram Moolenaardee2e312013-06-23 16:35:47 +02001960 (int) PySequence_Fast_GET_SIZE(fast));
Bram Moolenaara9922d62013-05-30 13:01:18 +02001961 return NULL;
1962 }
1963
1964 keyObject = PySequence_Fast_GET_ITEM(fast, 0);
1965
1966 if (!(key = StringToChars(keyObject, &todecref)))
1967 {
1968 Py_DECREF(iterator);
1969 Py_DECREF(fast);
1970 return NULL;
1971 }
1972
1973 di = dictitem_alloc(key);
1974
1975 Py_XDECREF(todecref);
1976
1977 if (di == NULL)
1978 {
1979 Py_DECREF(fast);
1980 Py_DECREF(iterator);
1981 PyErr_NoMemory();
1982 return NULL;
1983 }
1984 di->di_tv.v_lock = 0;
1985 di->di_tv.v_type = VAR_UNKNOWN;
1986
1987 valObject = PySequence_Fast_GET_ITEM(fast, 1);
1988
1989 if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
1990 {
1991 Py_DECREF(iterator);
1992 Py_DECREF(fast);
1993 dictitem_free(di);
1994 return NULL;
1995 }
1996
1997 Py_DECREF(fast);
1998
1999 if (dict_add(dict, di) == FAIL)
2000 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002001 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002002 Py_DECREF(iterator);
2003 dictitem_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002004 return NULL;
2005 }
2006 }
2007
2008 Py_DECREF(iterator);
2009
2010 /* Iterator may have finished due to an exception */
2011 if (PyErr_Occurred())
2012 return NULL;
2013 }
2014 }
2015 Py_INCREF(Py_None);
2016 return Py_None;
2017}
2018
2019 static PyObject *
2020DictionaryGet(DictionaryObject *self, PyObject *args)
2021{
2022 return _DictionaryItem(self, args,
2023 DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
2024}
2025
2026 static PyObject *
2027DictionaryPop(DictionaryObject *self, PyObject *args)
2028{
2029 return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
2030}
2031
2032 static PyObject *
Bram Moolenaarde71b562013-06-02 17:41:54 +02002033DictionaryPopItem(DictionaryObject *self)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002034{
Bram Moolenaarde71b562013-06-02 17:41:54 +02002035 hashitem_T *hi;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002036 PyObject *ret;
Bram Moolenaarde71b562013-06-02 17:41:54 +02002037 PyObject *valObject;
2038 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002039
Bram Moolenaarde71b562013-06-02 17:41:54 +02002040 if (self->dict->dv_hashtab.ht_used == 0)
2041 {
2042 PyErr_SetNone(PyExc_KeyError);
2043 return NULL;
2044 }
2045
2046 hi = self->dict->dv_hashtab.ht_array;
2047 while (HASHITEM_EMPTY(hi))
2048 ++hi;
2049
2050 di = dict_lookup(hi);
2051
2052 if (!(valObject = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02002053 return NULL;
2054
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002055 if (!(ret = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
Bram Moolenaarde71b562013-06-02 17:41:54 +02002056 {
2057 Py_DECREF(valObject);
2058 return NULL;
2059 }
2060
2061 hash_remove(&self->dict->dv_hashtab, hi);
2062 dictitem_free(di);
2063
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002064 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002065}
2066
2067 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02002068DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002069{
Bram Moolenaara9922d62013-05-30 13:01:18 +02002070 return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
2071}
2072
2073static PySequenceMethods DictionaryAsSeq = {
2074 0, /* sq_length */
2075 0, /* sq_concat */
2076 0, /* sq_repeat */
2077 0, /* sq_item */
2078 0, /* sq_slice */
2079 0, /* sq_ass_item */
2080 0, /* sq_ass_slice */
2081 (objobjproc) DictionaryContains, /* sq_contains */
2082 0, /* sq_inplace_concat */
2083 0, /* sq_inplace_repeat */
2084};
2085
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002086static PyMappingMethods DictionaryAsMapping = {
2087 (lenfunc) DictionaryLength,
2088 (binaryfunc) DictionaryItem,
2089 (objobjargproc) DictionaryAssItem,
2090};
2091
Bram Moolenaardb913952012-06-29 12:54:53 +02002092static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02002093 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaara9922d62013-05-30 13:01:18 +02002094 {"values", (PyCFunction)DictionaryListValues, METH_NOARGS, ""},
2095 {"items", (PyCFunction)DictionaryListItems, METH_NOARGS, ""},
2096 {"update", (PyCFunction)DictionaryUpdate, METH_VARARGS|METH_KEYWORDS, ""},
2097 {"get", (PyCFunction)DictionaryGet, METH_VARARGS, ""},
2098 {"pop", (PyCFunction)DictionaryPop, METH_VARARGS, ""},
Bram Moolenaarde71b562013-06-02 17:41:54 +02002099 {"popitem", (PyCFunction)DictionaryPopItem, METH_NOARGS, ""},
Bram Moolenaar389a1792013-06-23 13:00:44 +02002100 {"has_key", (PyCFunction)DictionaryHasKey, METH_O, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002101 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
2102 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002103};
2104
2105static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002106static PySequenceMethods ListAsSeq;
2107static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +02002108
2109typedef struct
2110{
2111 PyObject_HEAD
2112 list_T *list;
2113 pylinkedlist_T ref;
2114} ListObject;
2115
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002116#define NEW_LIST(list) ListNew(&ListType, list)
2117
Bram Moolenaardb913952012-06-29 12:54:53 +02002118 static PyObject *
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002119ListNew(PyTypeObject *subtype, list_T *list)
Bram Moolenaardb913952012-06-29 12:54:53 +02002120{
2121 ListObject *self;
2122
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002123 self = (ListObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02002124 if (self == NULL)
2125 return NULL;
2126 self->list = list;
2127 ++list->lv_refcount;
2128
2129 pyll_add((PyObject *)(self), &self->ref, &lastlist);
2130
2131 return (PyObject *)(self);
2132}
2133
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002134 static list_T *
Bram Moolenaarfb97f282013-07-09 17:42:46 +02002135py_list_alloc(void)
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002136{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002137 list_T *ret;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002138
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002139 if (!(ret = list_alloc()))
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002140 {
2141 PyErr_NoMemory();
2142 return NULL;
2143 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002144 ++ret->lv_refcount;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002145
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002146 return ret;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002147}
2148
2149 static int
2150list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
2151{
2152 PyObject *iterator;
2153 PyObject *item;
2154 listitem_T *li;
2155
2156 if (!(iterator = PyObject_GetIter(obj)))
2157 return -1;
2158
2159 while ((item = PyIter_Next(iterator)))
2160 {
2161 if (!(li = listitem_alloc()))
2162 {
2163 PyErr_NoMemory();
2164 Py_DECREF(item);
2165 Py_DECREF(iterator);
2166 return -1;
2167 }
2168 li->li_tv.v_lock = 0;
2169 li->li_tv.v_type = VAR_UNKNOWN;
2170
2171 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
2172 {
2173 Py_DECREF(item);
2174 Py_DECREF(iterator);
2175 listitem_free(li);
2176 return -1;
2177 }
2178
2179 Py_DECREF(item);
2180
2181 list_append(l, li);
2182 }
2183
2184 Py_DECREF(iterator);
2185
2186 /* Iterator may have finished due to an exception */
2187 if (PyErr_Occurred())
2188 return -1;
2189
2190 return 0;
2191}
2192
2193 static PyObject *
2194ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2195{
2196 list_T *list;
2197 PyObject *obj = NULL;
2198
2199 if (kwargs)
2200 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002201 PyErr_SET_STRING(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002202 N_("list constructor does not accept keyword arguments"));
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002203 return NULL;
2204 }
2205
2206 if (!PyArg_ParseTuple(args, "|O", &obj))
2207 return NULL;
2208
2209 if (!(list = py_list_alloc()))
2210 return NULL;
2211
2212 if (obj)
2213 {
2214 PyObject *lookup_dict;
2215
2216 if (!(lookup_dict = PyDict_New()))
2217 {
2218 list_unref(list);
2219 return NULL;
2220 }
2221
2222 if (list_py_concat(list, obj, lookup_dict) == -1)
2223 {
2224 Py_DECREF(lookup_dict);
2225 list_unref(list);
2226 return NULL;
2227 }
2228
2229 Py_DECREF(lookup_dict);
2230 }
2231
2232 return ListNew(subtype, list);
2233}
2234
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002235 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002236ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002237{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002238 pyll_remove(&self->ref, &lastlist);
2239 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002240
2241 DESTRUCTOR_FINISH(self);
2242}
2243
Bram Moolenaardb913952012-06-29 12:54:53 +02002244 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002245ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02002246{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002247 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02002248}
2249
2250 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002251ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02002252{
2253 listitem_T *li;
2254
Bram Moolenaard6e39182013-05-21 18:30:34 +02002255 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02002256 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002257 PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002258 return NULL;
2259 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02002260 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002261 if (li == NULL)
2262 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002263 /* No more suitable format specifications in python-2.3 */
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002264 PyErr_VIM_FORMAT(N_("internal error: failed to get vim list item %d"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02002265 (int) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002266 return NULL;
2267 }
2268 return ConvertToPyObject(&li->li_tv);
2269}
2270
2271#define PROC_RANGE \
2272 if (last < 0) {\
2273 if (last < -size) \
2274 last = 0; \
2275 else \
2276 last += size; \
2277 } \
2278 if (first < 0) \
2279 first = 0; \
2280 if (first > size) \
2281 first = size; \
2282 if (last > size) \
2283 last = size;
2284
2285 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002286ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +02002287{
2288 PyInt i;
2289 PyInt size = ListLength(self);
2290 PyInt n;
2291 PyObject *list;
2292 int reversed = 0;
2293
2294 PROC_RANGE
2295 if (first >= last)
2296 first = last;
2297
2298 n = last-first;
2299 list = PyList_New(n);
2300 if (list == NULL)
2301 return NULL;
2302
2303 for (i = 0; i < n; ++i)
2304 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +02002305 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02002306 if (item == NULL)
2307 {
2308 Py_DECREF(list);
2309 return NULL;
2310 }
2311
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02002312 PyList_SET_ITEM(list, ((reversed)?(n-i-1):(i)), item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002313 }
2314
2315 return list;
2316}
2317
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002318typedef struct
2319{
2320 listwatch_T lw;
2321 list_T *list;
2322} listiterinfo_T;
2323
2324 static void
2325ListIterDestruct(listiterinfo_T *lii)
2326{
2327 list_rem_watch(lii->list, &lii->lw);
2328 PyMem_Free(lii);
2329}
2330
2331 static PyObject *
2332ListIterNext(listiterinfo_T **lii)
2333{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002334 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002335
2336 if (!((*lii)->lw.lw_item))
2337 return NULL;
2338
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002339 if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002340 return NULL;
2341
2342 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
2343
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002344 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002345}
2346
2347 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002348ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002349{
2350 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002351 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002352
2353 if (!(lii = PyMem_New(listiterinfo_T, 1)))
2354 {
2355 PyErr_NoMemory();
2356 return NULL;
2357 }
2358
2359 list_add_watch(l, &lii->lw);
2360 lii->lw.lw_item = l->lv_first;
2361 lii->list = l;
2362
2363 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002364 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
2365 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002366}
2367
Bram Moolenaardb913952012-06-29 12:54:53 +02002368 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002369ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02002370{
2371 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002372 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02002373 listitem_T *li;
2374 Py_ssize_t length = ListLength(self);
2375
2376 if (l->lv_lock)
2377 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002378 RAISE_LOCKED_LIST;
Bram Moolenaardb913952012-06-29 12:54:53 +02002379 return -1;
2380 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002381 if (index > length || (index == length && obj == NULL))
Bram Moolenaardb913952012-06-29 12:54:53 +02002382 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002383 PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002384 return -1;
2385 }
2386
2387 if (obj == NULL)
2388 {
2389 li = list_find(l, (long) index);
2390 list_remove(l, li, li);
2391 clear_tv(&li->li_tv);
2392 vim_free(li);
2393 return 0;
2394 }
2395
2396 if (ConvertFromPyObject(obj, &tv) == -1)
2397 return -1;
2398
2399 if (index == length)
2400 {
2401 if (list_append_tv(l, &tv) == FAIL)
2402 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002403 clear_tv(&tv);
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002404 PyErr_SET_VIM(N_("failed to add item to list"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002405 return -1;
2406 }
2407 }
2408 else
2409 {
2410 li = list_find(l, (long) index);
2411 clear_tv(&li->li_tv);
2412 copy_tv(&tv, &li->li_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002413 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002414 }
2415 return 0;
2416}
2417
2418 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002419ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02002420{
2421 PyInt size = ListLength(self);
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002422 PyObject *iterator;
2423 PyObject *item;
Bram Moolenaardb913952012-06-29 12:54:53 +02002424 listitem_T *li;
2425 listitem_T *next;
2426 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002427 list_T *l = self->list;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002428 PyInt i;
Bram Moolenaardb913952012-06-29 12:54:53 +02002429
2430 if (l->lv_lock)
2431 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002432 RAISE_LOCKED_LIST;
Bram Moolenaardb913952012-06-29 12:54:53 +02002433 return -1;
2434 }
2435
2436 PROC_RANGE
2437
2438 if (first == size)
2439 li = NULL;
2440 else
2441 {
2442 li = list_find(l, (long) first);
2443 if (li == NULL)
2444 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002445 PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
2446 (int)first);
Bram Moolenaardb913952012-06-29 12:54:53 +02002447 return -1;
2448 }
2449 if (last > first)
2450 {
2451 i = last - first;
2452 while (i-- && li != NULL)
2453 {
2454 next = li->li_next;
2455 listitem_remove(l, li);
2456 li = next;
2457 }
2458 }
2459 }
2460
2461 if (obj == NULL)
2462 return 0;
2463
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002464 if (!(iterator = PyObject_GetIter(obj)))
Bram Moolenaardb913952012-06-29 12:54:53 +02002465 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02002466
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002467 while ((item = PyIter_Next(iterator)))
Bram Moolenaardb913952012-06-29 12:54:53 +02002468 {
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002469 if (ConvertFromPyObject(item, &v) == -1)
2470 {
2471 Py_DECREF(iterator);
2472 Py_DECREF(item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002473 return -1;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002474 }
2475 Py_DECREF(item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002476 if (list_insert_tv(l, &v, li) == FAIL)
2477 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002478 clear_tv(&v);
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002479 PyErr_SET_VIM(N_("internal error: failed to add item to list"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002480 return -1;
2481 }
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002482 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02002483 }
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002484 Py_DECREF(iterator);
Bram Moolenaardee2e312013-06-23 16:35:47 +02002485
2486 if (PyErr_Occurred())
2487 return -1;
2488
Bram Moolenaardb913952012-06-29 12:54:53 +02002489 return 0;
2490}
2491
2492 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002493ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02002494{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002495 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02002496 PyObject *lookup_dict;
2497
2498 if (l->lv_lock)
2499 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002500 RAISE_LOCKED_LIST;
Bram Moolenaardb913952012-06-29 12:54:53 +02002501 return NULL;
2502 }
2503
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02002504 if (!(lookup_dict = PyDict_New()))
2505 return NULL;
2506
Bram Moolenaardb913952012-06-29 12:54:53 +02002507 if (list_py_concat(l, obj, lookup_dict) == -1)
2508 {
2509 Py_DECREF(lookup_dict);
2510 return NULL;
2511 }
2512 Py_DECREF(lookup_dict);
2513
2514 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02002515 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02002516}
2517
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002518static char *ListAttrs[] = {
2519 "locked",
2520 NULL
2521};
2522
2523 static PyObject *
2524ListDir(PyObject *self)
2525{
2526 return ObjectDir(self, ListAttrs);
2527}
2528
Bram Moolenaar66b79852012-09-21 14:00:35 +02002529 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002530ListSetattr(ListObject *self, char *name, PyObject *valObject)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002531{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002532 if (valObject == NULL)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002533 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002534 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002535 N_("cannot delete vim.List attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02002536 return -1;
2537 }
2538
2539 if (strcmp(name, "locked") == 0)
2540 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002541 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002542 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002543 PyErr_SET_STRING(PyExc_TypeError, N_("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02002544 return -1;
2545 }
2546 else
2547 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002548 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarb983f752013-05-15 16:11:50 +02002549 if (istrue == -1)
2550 return -1;
2551 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002552 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002553 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02002554 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002555 }
2556 return 0;
2557 }
2558 else
2559 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002560 PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02002561 return -1;
2562 }
2563}
2564
Bram Moolenaardb913952012-06-29 12:54:53 +02002565static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002566 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
2567 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
2568 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002569};
2570
2571typedef struct
2572{
2573 PyObject_HEAD
2574 char_u *name;
2575} FunctionObject;
2576
2577static PyTypeObject FunctionType;
2578
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002579#define NEW_FUNCTION(name) FunctionNew(&FunctionType, name)
2580
Bram Moolenaardb913952012-06-29 12:54:53 +02002581 static PyObject *
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002582FunctionNew(PyTypeObject *subtype, char_u *name)
Bram Moolenaardb913952012-06-29 12:54:53 +02002583{
2584 FunctionObject *self;
2585
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002586 self = (FunctionObject *) subtype->tp_alloc(subtype, 0);
2587
Bram Moolenaardb913952012-06-29 12:54:53 +02002588 if (self == NULL)
2589 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002590
2591 if (isdigit(*name))
Bram Moolenaardb913952012-06-29 12:54:53 +02002592 {
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002593 if (!translated_function_exists(name))
2594 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002595 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002596 N_("unnamed function %s does not exist"), name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002597 return NULL;
2598 }
2599 self->name = vim_strsave(name);
2600 func_ref(self->name);
2601 }
2602 else
Bram Moolenaar018acca2013-05-30 13:37:28 +02002603 if ((self->name = get_expanded_name(name,
2604 vim_strchr(name, AUTOLOAD_CHAR) == NULL))
2605 == NULL)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002606 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002607 PyErr_FORMAT(PyExc_ValueError,
2608 N_("function %s does not exist"), name);
Bram Moolenaar018acca2013-05-30 13:37:28 +02002609 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002610 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002611
2612 return (PyObject *)(self);
2613}
2614
2615 static PyObject *
2616FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2617{
2618 PyObject *self;
2619 char_u *name;
2620
2621 if (kwargs)
2622 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002623 PyErr_SET_STRING(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002624 N_("function constructor does not accept keyword arguments"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002625 return NULL;
2626 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002627
Bram Moolenaar389a1792013-06-23 13:00:44 +02002628 if (!PyArg_ParseTuple(args, "et", "ascii", &name))
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002629 return NULL;
2630
2631 self = FunctionNew(subtype, name);
2632
Bram Moolenaar389a1792013-06-23 13:00:44 +02002633 PyMem_Free(name);
2634
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002635 return self;
Bram Moolenaardb913952012-06-29 12:54:53 +02002636}
2637
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002638 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002639FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002640{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002641 func_unref(self->name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002642 vim_free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002643
2644 DESTRUCTOR_FINISH(self);
2645}
2646
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002647static char *FunctionAttrs[] = {
2648 "softspace",
2649 NULL
2650};
2651
2652 static PyObject *
2653FunctionDir(PyObject *self)
2654{
2655 return ObjectDir(self, FunctionAttrs);
2656}
2657
Bram Moolenaardb913952012-06-29 12:54:53 +02002658 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002659FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02002660{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002661 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02002662 typval_T args;
2663 typval_T selfdicttv;
2664 typval_T rettv;
2665 dict_T *selfdict = NULL;
2666 PyObject *selfdictObject;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002667 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02002668 int error;
2669
2670 if (ConvertFromPyObject(argsObject, &args) == -1)
2671 return NULL;
2672
2673 if (kwargs != NULL)
2674 {
2675 selfdictObject = PyDict_GetItemString(kwargs, "self");
2676 if (selfdictObject != NULL)
2677 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02002678 if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002679 {
2680 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02002681 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002682 }
Bram Moolenaardb913952012-06-29 12:54:53 +02002683 selfdict = selfdicttv.vval.v_dict;
2684 }
2685 }
2686
Bram Moolenaar71700b82013-05-15 17:49:05 +02002687 Py_BEGIN_ALLOW_THREADS
2688 Python_Lock_Vim();
2689
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002690 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02002691 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02002692
2693 Python_Release_Vim();
2694 Py_END_ALLOW_THREADS
2695
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002696 if (VimTryEnd())
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002697 ret = NULL;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002698 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02002699 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002700 ret = NULL;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002701 PyErr_VIM_FORMAT(N_("failed to run function %s"), (char *)name);
Bram Moolenaardb913952012-06-29 12:54:53 +02002702 }
2703 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002704 ret = ConvertToPyObject(&rettv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002705
Bram Moolenaardb913952012-06-29 12:54:53 +02002706 clear_tv(&args);
2707 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002708 if (selfdict != NULL)
2709 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002710
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002711 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02002712}
2713
Bram Moolenaara5b725c2013-05-30 12:43:54 +02002714 static PyObject *
2715FunctionRepr(FunctionObject *self)
2716{
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002717#ifdef Py_TRACE_REFS
Bram Moolenaar41009372013-07-01 22:03:04 +02002718 /* For unknown reason self->name may be NULL after calling
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002719 * Finalize */
2720 return PyString_FromFormat("<vim.Function '%s'>",
Bram Moolenaar41009372013-07-01 22:03:04 +02002721 (self->name == NULL ? "<NULL>" : (char *)self->name));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002722#else
Bram Moolenaar41009372013-07-01 22:03:04 +02002723 return PyString_FromFormat("<vim.Function '%s'>", (char *)self->name);
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002724#endif
Bram Moolenaara5b725c2013-05-30 12:43:54 +02002725}
2726
Bram Moolenaardb913952012-06-29 12:54:53 +02002727static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002728 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
2729 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002730};
2731
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002732/*
2733 * Options object
2734 */
2735
2736static PyTypeObject OptionsType;
2737
2738typedef int (*checkfun)(void *);
2739
2740typedef struct
2741{
2742 PyObject_HEAD
2743 int opt_type;
2744 void *from;
2745 checkfun Check;
2746 PyObject *fromObj;
2747} OptionsObject;
2748
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002749 static int
2750dummy_check(void *arg UNUSED)
2751{
2752 return 0;
2753}
2754
2755 static PyObject *
2756OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
2757{
2758 OptionsObject *self;
2759
Bram Moolenaar774267b2013-05-21 20:51:59 +02002760 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002761 if (self == NULL)
2762 return NULL;
2763
2764 self->opt_type = opt_type;
2765 self->from = from;
2766 self->Check = Check;
2767 self->fromObj = fromObj;
2768 if (fromObj)
2769 Py_INCREF(fromObj);
2770
2771 return (PyObject *)(self);
2772}
2773
2774 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002775OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002776{
Bram Moolenaar774267b2013-05-21 20:51:59 +02002777 PyObject_GC_UnTrack((void *)(self));
2778 Py_XDECREF(self->fromObj);
2779 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002780}
2781
2782 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002783OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002784{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002785 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002786 return 0;
2787}
2788
2789 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002790OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002791{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002792 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002793 return 0;
2794}
2795
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002796 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002797OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002798{
2799 char_u *key;
2800 int flags;
2801 long numval;
2802 char_u *stringval;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002803 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002804
Bram Moolenaard6e39182013-05-21 18:30:34 +02002805 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002806 return NULL;
2807
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002808 if (!(key = StringToChars(keyObject, &todecref)))
2809 return NULL;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002810
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002811 if (*key == NUL)
2812 {
2813 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002814 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002815 return NULL;
2816 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002817
2818 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002819 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002820
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002821 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002822
2823 if (flags == 0)
2824 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02002825 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002826 return NULL;
2827 }
2828
2829 if (flags & SOPT_UNSET)
2830 {
2831 Py_INCREF(Py_None);
2832 return Py_None;
2833 }
2834 else if (flags & SOPT_BOOL)
2835 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002836 PyObject *ret;
2837 ret = numval ? Py_True : Py_False;
2838 Py_INCREF(ret);
2839 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002840 }
2841 else if (flags & SOPT_NUM)
2842 return PyInt_FromLong(numval);
2843 else if (flags & SOPT_STRING)
2844 {
2845 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002846 {
Bram Moolenaar41009372013-07-01 22:03:04 +02002847 PyObject *ret = PyBytes_FromString((char *)stringval);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002848 vim_free(stringval);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002849 return ret;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002850 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002851 else
2852 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002853 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002854 N_("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002855 return NULL;
2856 }
2857 }
2858 else
2859 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002860 PyErr_SET_VIM(N_("internal error: unknown option type"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002861 return NULL;
2862 }
2863}
2864
2865 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02002866set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002867{
2868 char_u *errmsg;
2869
2870 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
2871 {
2872 if (VimTryEnd())
2873 return FAIL;
2874 PyErr_SetVim((char *)errmsg);
2875 return FAIL;
2876 }
2877 return OK;
2878}
2879
2880 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02002881set_option_value_for(
2882 char_u *key,
2883 int numval,
2884 char_u *stringval,
2885 int opt_flags,
2886 int opt_type,
2887 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002888{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002889 win_T *save_curwin = NULL;
2890 tabpage_T *save_curtab = NULL;
2891 buf_T *save_curbuf = NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002892 int set_ret = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002893
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002894 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002895 switch (opt_type)
2896 {
2897 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02002898 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
Bram Moolenaard6949742013-06-16 14:18:28 +02002899 win_find_tabpage((win_T *)from), FALSE) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002900 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002901 if (VimTryEnd())
2902 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002903 PyErr_SET_VIM(N_("problem while switching windows"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002904 return -1;
2905 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002906 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
2907 restore_win(save_curwin, save_curtab, TRUE);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002908 break;
2909 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02002910 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002911 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002912 restore_buffer(save_curbuf);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002913 break;
2914 case SREQ_GLOBAL:
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002915 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002916 break;
2917 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002918 if (set_ret == FAIL)
2919 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002920 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002921}
2922
2923 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002924OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002925{
2926 char_u *key;
2927 int flags;
2928 int opt_flags;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002929 int ret = 0;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002930 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002931
Bram Moolenaard6e39182013-05-21 18:30:34 +02002932 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002933 return -1;
2934
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002935 if (!(key = StringToChars(keyObject, &todecref)))
2936 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002937
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002938 if (*key == NUL)
2939 {
2940 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002941 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002942 return -1;
2943 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002944
2945 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002946 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002947
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002948 if (flags == 0)
2949 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02002950 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002951 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002952 return -1;
2953 }
2954
2955 if (valObject == NULL)
2956 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002957 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002958 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002959 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002960 N_("unable to unset global option %s"), key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002961 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002962 return -1;
2963 }
2964 else if (!(flags & SOPT_GLOBAL))
2965 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002966 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002967 N_("unable to unset option %s "
2968 "which does not have global value"), key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002969 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002970 return -1;
2971 }
2972 else
2973 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002974 unset_global_local_option(key, self->from);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002975 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002976 return 0;
2977 }
2978 }
2979
Bram Moolenaard6e39182013-05-21 18:30:34 +02002980 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002981
2982 if (flags & SOPT_BOOL)
2983 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02002984 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002985
Bram Moolenaarb983f752013-05-15 16:11:50 +02002986 if (istrue == -1)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002987 ret = -1;
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002988 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002989 ret = set_option_value_for(key, istrue, NULL,
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002990 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002991 }
2992 else if (flags & SOPT_NUM)
2993 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02002994 long val;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002995
Bram Moolenaar141be8a2013-06-23 14:16:57 +02002996 if (NumberToLong(valObject, &val, NUMBER_INT))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002997 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002998 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002999 return -1;
3000 }
3001
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003002 ret = set_option_value_for(key, (int) val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003003 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003004 }
3005 else
3006 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003007 char_u *val;
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003008 PyObject *todecref2;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003009
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003010 if ((val = StringToChars(valObject, &todecref2)))
3011 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003012 ret = set_option_value_for(key, 0, val, opt_flags,
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003013 self->opt_type, self->from);
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003014 Py_XDECREF(todecref2);
3015 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003016 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003017 ret = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003018 }
3019
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003020 Py_XDECREF(todecref);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003021
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003022 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003023}
3024
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003025static PyMappingMethods OptionsAsMapping = {
3026 (lenfunc) NULL,
3027 (binaryfunc) OptionsItem,
3028 (objobjargproc) OptionsAssItem,
3029};
3030
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003031/* Tabpage object
3032 */
3033
3034typedef struct
3035{
3036 PyObject_HEAD
3037 tabpage_T *tab;
3038} TabPageObject;
3039
3040static PyObject *WinListNew(TabPageObject *tabObject);
3041
3042static PyTypeObject TabPageType;
3043
3044 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003045CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003046{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003047 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003048 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003049 PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003050 return -1;
3051 }
3052
3053 return 0;
3054}
3055
3056 static PyObject *
3057TabPageNew(tabpage_T *tab)
3058{
3059 TabPageObject *self;
3060
3061 if (TAB_PYTHON_REF(tab))
3062 {
3063 self = TAB_PYTHON_REF(tab);
3064 Py_INCREF(self);
3065 }
3066 else
3067 {
3068 self = PyObject_NEW(TabPageObject, &TabPageType);
3069 if (self == NULL)
3070 return NULL;
3071 self->tab = tab;
3072 TAB_PYTHON_REF(tab) = self;
3073 }
3074
3075 return (PyObject *)(self);
3076}
3077
3078 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003079TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003080{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003081 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
3082 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003083
3084 DESTRUCTOR_FINISH(self);
3085}
3086
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003087static char *TabPageAttrs[] = {
3088 "windows", "number", "vars", "window", "valid",
3089 NULL
3090};
3091
3092 static PyObject *
3093TabPageDir(PyObject *self)
3094{
3095 return ObjectDir(self, TabPageAttrs);
3096}
3097
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003098 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003099TabPageAttrValid(TabPageObject *self, char *name)
3100{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003101 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003102
3103 if (strcmp(name, "valid") != 0)
3104 return NULL;
3105
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003106 ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
3107 Py_INCREF(ret);
3108 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003109}
3110
3111 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003112TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003113{
3114 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003115 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003116 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003117 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003118 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003119 return NEW_DICTIONARY(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003120 else if (strcmp(name, "window") == 0)
3121 {
3122 /* For current tab window.c does not bother to set or update tp_curwin
3123 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003124 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003125 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003126 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02003127 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003128 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003129 else if (strcmp(name, "__members__") == 0)
3130 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003131 return NULL;
3132}
3133
3134 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003135TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003136{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003137 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003138 return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003139 else
3140 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003141 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003142
3143 if (t == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003144 return PyString_FromFormat("<tabpage object (unknown) at %p>",
3145 (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003146 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003147 return PyString_FromFormat("<tabpage %d>", t - 1);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003148 }
3149}
3150
3151static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003152 /* name, function, calling, documentation */
3153 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
3154 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003155};
3156
3157/*
3158 * Window list object
3159 */
3160
3161static PyTypeObject TabListType;
3162static PySequenceMethods TabListAsSeq;
3163
3164typedef struct
3165{
3166 PyObject_HEAD
3167} TabListObject;
3168
3169 static PyInt
3170TabListLength(PyObject *self UNUSED)
3171{
3172 tabpage_T *tp = first_tabpage;
3173 PyInt n = 0;
3174
3175 while (tp != NULL)
3176 {
3177 ++n;
3178 tp = tp->tp_next;
3179 }
3180
3181 return n;
3182}
3183
3184 static PyObject *
3185TabListItem(PyObject *self UNUSED, PyInt n)
3186{
3187 tabpage_T *tp;
3188
3189 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3190 if (n == 0)
3191 return TabPageNew(tp);
3192
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003193 PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003194 return NULL;
3195}
3196
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +02003197/*
3198 * Window object
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003199 */
3200
3201typedef struct
3202{
3203 PyObject_HEAD
3204 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003205 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003206} WindowObject;
3207
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003208static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003209
3210 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003211CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003212{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003213 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003214 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003215 PyErr_SET_VIM(N_("attempt to refer to deleted window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003216 return -1;
3217 }
3218
3219 return 0;
3220}
3221
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003222 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003223WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02003224{
3225 /* We need to handle deletion of windows underneath us.
3226 * If we add a "w_python*_ref" field to the win_T structure,
3227 * then we can get at it in win_free() in vim. We then
3228 * need to create only ONE Python object per window - if
3229 * we try to create a second, just INCREF the existing one
3230 * and return it. The (single) Python object referring to
3231 * the window is stored in "w_python*_ref".
3232 * On a win_free() we set the Python object's win_T* field
3233 * to an invalid value. We trap all uses of a window
3234 * object, and reject them if the win_T* field is invalid.
3235 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003236 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003237 * w_python_ref and w_python3_ref fields respectively.
3238 */
3239
3240 WindowObject *self;
3241
3242 if (WIN_PYTHON_REF(win))
3243 {
3244 self = WIN_PYTHON_REF(win);
3245 Py_INCREF(self);
3246 }
3247 else
3248 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02003249 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02003250 if (self == NULL)
3251 return NULL;
3252 self->win = win;
3253 WIN_PYTHON_REF(win) = self;
3254 }
3255
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003256 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3257
Bram Moolenaar971db462013-05-12 18:44:48 +02003258 return (PyObject *)(self);
3259}
3260
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003261 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003262WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003263{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003264 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02003265 if (self->win && self->win != INVALID_WINDOW_VALUE)
3266 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003267 Py_XDECREF(((PyObject *)(self->tabObject)));
3268 PyObject_GC_Del((void *)(self));
3269}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003270
Bram Moolenaar774267b2013-05-21 20:51:59 +02003271 static int
3272WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3273{
3274 Py_VISIT(((PyObject *)(self->tabObject)));
3275 return 0;
3276}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003277
Bram Moolenaar774267b2013-05-21 20:51:59 +02003278 static int
3279WindowClear(WindowObject *self)
3280{
3281 Py_CLEAR(self->tabObject);
3282 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003283}
3284
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003285 static win_T *
3286get_firstwin(TabPageObject *tabObject)
3287{
3288 if (tabObject)
3289 {
3290 if (CheckTabPage(tabObject))
3291 return NULL;
3292 /* For current tab window.c does not bother to set or update tp_firstwin
3293 */
3294 else if (tabObject->tab == curtab)
3295 return firstwin;
3296 else
3297 return tabObject->tab->tp_firstwin;
3298 }
3299 else
3300 return firstwin;
3301}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003302static char *WindowAttrs[] = {
3303 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
3304 "tabpage", "valid",
3305 NULL
3306};
3307
3308 static PyObject *
3309WindowDir(PyObject *self)
3310{
3311 return ObjectDir(self, WindowAttrs);
3312}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003313
Bram Moolenaar971db462013-05-12 18:44:48 +02003314 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003315WindowAttrValid(WindowObject *self, char *name)
3316{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003317 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003318
3319 if (strcmp(name, "valid") != 0)
3320 return NULL;
3321
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003322 ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3323 Py_INCREF(ret);
3324 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003325}
3326
3327 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003328WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003329{
3330 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003331 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003332 else if (strcmp(name, "cursor") == 0)
3333 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003334 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003335
3336 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
3337 }
3338 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003339 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003340#ifdef FEAT_WINDOWS
3341 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003342 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003343#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003344#ifdef FEAT_VERTSPLIT
3345 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003346 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003347 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003348 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003349#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02003350 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003351 return NEW_DICTIONARY(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003352 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003353 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
3354 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02003355 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003356 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003357 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003358 return NULL;
3359 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003360 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003361 }
3362 else if (strcmp(name, "tabpage") == 0)
3363 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003364 Py_INCREF(self->tabObject);
3365 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003366 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003367 else if (strcmp(name, "__members__") == 0)
3368 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003369 else
3370 return NULL;
3371}
3372
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003373 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003374WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003375{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003376 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003377 return -1;
3378
3379 if (strcmp(name, "buffer") == 0)
3380 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003381 PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003382 return -1;
3383 }
3384 else if (strcmp(name, "cursor") == 0)
3385 {
3386 long lnum;
3387 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003388
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003389 if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003390 return -1;
3391
Bram Moolenaard6e39182013-05-21 18:30:34 +02003392 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003393 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003394 PyErr_SET_VIM(N_("cursor position outside buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003395 return -1;
3396 }
3397
3398 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003399 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003400 return -1;
3401
Bram Moolenaard6e39182013-05-21 18:30:34 +02003402 self->win->w_cursor.lnum = lnum;
3403 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003404#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02003405 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003406#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003407 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003408 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003409
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003410 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003411 return 0;
3412 }
3413 else if (strcmp(name, "height") == 0)
3414 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003415 long height;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003416 win_T *savewin;
3417
Bram Moolenaardee2e312013-06-23 16:35:47 +02003418 if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003419 return -1;
3420
3421#ifdef FEAT_GUI
3422 need_mouse_correct = TRUE;
3423#endif
3424 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003425 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003426
3427 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003428 win_setheight((int) height);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003429 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003430 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003431 return -1;
3432
3433 return 0;
3434 }
3435#ifdef FEAT_VERTSPLIT
3436 else if (strcmp(name, "width") == 0)
3437 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003438 long width;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003439 win_T *savewin;
3440
Bram Moolenaardee2e312013-06-23 16:35:47 +02003441 if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003442 return -1;
3443
3444#ifdef FEAT_GUI
3445 need_mouse_correct = TRUE;
3446#endif
3447 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003448 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003449
3450 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003451 win_setwidth((int) width);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003452 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003453 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003454 return -1;
3455
3456 return 0;
3457 }
3458#endif
3459 else
3460 {
3461 PyErr_SetString(PyExc_AttributeError, name);
3462 return -1;
3463 }
3464}
3465
3466 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003467WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003468{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003469 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003470 return PyString_FromFormat("<window object (deleted) at %p>", (self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003471 else
3472 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003473 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003474
Bram Moolenaar6d216452013-05-12 19:00:41 +02003475 if (w == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003476 return PyString_FromFormat("<window object (unknown) at %p>",
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003477 (self));
3478 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003479 return PyString_FromFormat("<window %d>", w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003480 }
3481}
3482
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003483static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003484 /* name, function, calling, documentation */
3485 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
3486 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003487};
3488
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003489/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003490 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003491 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003492
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003493static PyTypeObject WinListType;
3494static PySequenceMethods WinListAsSeq;
3495
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003496typedef struct
3497{
3498 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003499 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003500} WinListObject;
3501
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003502 static PyObject *
3503WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003504{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003505 WinListObject *self;
3506
3507 self = PyObject_NEW(WinListObject, &WinListType);
3508 self->tabObject = tabObject;
3509 Py_INCREF(tabObject);
3510
3511 return (PyObject *)(self);
3512}
3513
3514 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003515WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003516{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003517 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003518
3519 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02003520 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003521 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02003522 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003523
3524 DESTRUCTOR_FINISH(self);
3525}
3526
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003527 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003528WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003529{
3530 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003531 PyInt n = 0;
3532
Bram Moolenaard6e39182013-05-21 18:30:34 +02003533 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003534 return -1;
3535
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003536 while (w != NULL)
3537 {
3538 ++n;
3539 w = W_NEXT(w);
3540 }
3541
3542 return n;
3543}
3544
3545 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003546WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003547{
3548 win_T *w;
3549
Bram Moolenaard6e39182013-05-21 18:30:34 +02003550 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003551 return NULL;
3552
3553 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003554 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003555 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003556
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003557 PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003558 return NULL;
3559}
3560
3561/* Convert a Python string into a Vim line.
3562 *
3563 * The result is in allocated memory. All internal nulls are replaced by
3564 * newline characters. It is an error for the string to contain newline
3565 * characters.
3566 *
3567 * On errors, the Python exception data is set, and NULL is returned.
3568 */
3569 static char *
3570StringToLine(PyObject *obj)
3571{
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003572 char *str;
3573 char *save;
3574 PyObject *bytes = NULL;
Bram Moolenaardee2e312013-06-23 16:35:47 +02003575 Py_ssize_t len = 0;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003576 PyInt i;
3577 char *p;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003578
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003579 if (PyBytes_Check(obj))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003580 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003581 if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
3582 || str == NULL)
3583 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003584 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003585 else if (PyUnicode_Check(obj))
3586 {
3587 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
3588 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003589
Bram Moolenaardaa27022013-06-24 22:33:30 +02003590 if (PyBytes_AsStringAndSize(bytes, &str, &len) == -1
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003591 || str == NULL)
3592 {
3593 Py_DECREF(bytes);
3594 return NULL;
3595 }
3596 }
Bram Moolenaardaa27022013-06-24 22:33:30 +02003597 else
3598 {
3599#if PY_MAJOR_VERSION < 3
3600 PyErr_FORMAT(PyExc_TypeError,
3601 N_("expected str() or unicode() instance, but got %s"),
3602 Py_TYPE_NAME(obj));
3603#else
3604 PyErr_FORMAT(PyExc_TypeError,
3605 N_("expected bytes() or str() instance, but got %s"),
3606 Py_TYPE_NAME(obj));
3607#endif
3608 return NULL;
3609 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003610
3611 /*
3612 * Error checking: String must not contain newlines, as we
3613 * are replacing a single line, and we must replace it with
3614 * a single line.
3615 * A trailing newline is removed, so that append(f.readlines()) works.
3616 */
3617 p = memchr(str, '\n', len);
3618 if (p != NULL)
3619 {
3620 if (p == str + len - 1)
3621 --len;
3622 else
3623 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003624 PyErr_SET_VIM(N_("string cannot contain newlines"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02003625 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003626 return NULL;
3627 }
3628 }
3629
3630 /* Create a copy of the string, with internal nulls replaced by
3631 * newline characters, as is the vim convention.
3632 */
3633 save = (char *)alloc((unsigned)(len+1));
3634 if (save == NULL)
3635 {
3636 PyErr_NoMemory();
Bram Moolenaar841fbd22013-06-23 14:37:07 +02003637 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003638 return NULL;
3639 }
3640
3641 for (i = 0; i < len; ++i)
3642 {
3643 if (str[i] == '\0')
3644 save[i] = '\n';
3645 else
3646 save[i] = str[i];
3647 }
3648
3649 save[i] = '\0';
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003650 Py_XDECREF(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003651
3652 return save;
3653}
3654
3655/* Get a line from the specified buffer. The line number is
3656 * in Vim format (1-based). The line is returned as a Python
3657 * string object.
3658 */
3659 static PyObject *
3660GetBufferLine(buf_T *buf, PyInt n)
3661{
3662 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
3663}
3664
3665
3666/* Get a list of lines from the specified buffer. The line numbers
3667 * are in Vim format (1-based). The range is from lo up to, but not
3668 * including, hi. The list is returned as a Python list of string objects.
3669 */
3670 static PyObject *
3671GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
3672{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003673 PyInt i;
3674 PyInt n = hi - lo;
3675 PyObject *list = PyList_New(n);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003676
3677 if (list == NULL)
3678 return NULL;
3679
3680 for (i = 0; i < n; ++i)
3681 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003682 PyObject *string = LineToString(
3683 (char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003684
3685 /* Error check - was the Python string creation OK? */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003686 if (string == NULL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003687 {
3688 Py_DECREF(list);
3689 return NULL;
3690 }
3691
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003692 PyList_SET_ITEM(list, i, string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003693 }
3694
3695 /* The ownership of the Python list is passed to the caller (ie,
3696 * the caller should Py_DECREF() the object when it is finished
3697 * with it).
3698 */
3699
3700 return list;
3701}
3702
3703/*
3704 * Check if deleting lines made the cursor position invalid.
3705 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
3706 * deleted).
3707 */
3708 static void
3709py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
3710{
3711 if (curwin->w_cursor.lnum >= lo)
3712 {
3713 /* Adjust the cursor position if it's in/after the changed
3714 * lines. */
3715 if (curwin->w_cursor.lnum >= hi)
3716 {
3717 curwin->w_cursor.lnum += extra;
3718 check_cursor_col();
3719 }
3720 else if (extra < 0)
3721 {
3722 curwin->w_cursor.lnum = lo;
3723 check_cursor();
3724 }
3725 else
3726 check_cursor_col();
3727 changed_cline_bef_curs();
3728 }
3729 invalidate_botline();
3730}
3731
Bram Moolenaar19e60942011-06-19 00:27:51 +02003732/*
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003733 * Find a window that contains "buf" and switch to it.
3734 * If there is no such window, use the current window and change "curbuf".
3735 * Caller must initialize save_curbuf to NULL.
3736 * restore_win_for_buf() MUST be called later!
3737 */
3738 static void
3739switch_to_win_for_buf(
3740 buf_T *buf,
3741 win_T **save_curwinp,
3742 tabpage_T **save_curtabp,
3743 buf_T **save_curbufp)
3744{
3745 win_T *wp;
3746 tabpage_T *tp;
3747
3748 if (find_win_for_buf(buf, &wp, &tp) == FAIL
3749 || switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL)
3750 switch_buffer(save_curbufp, buf);
3751}
3752
3753 static void
3754restore_win_for_buf(
3755 win_T *save_curwin,
3756 tabpage_T *save_curtab,
3757 buf_T *save_curbuf)
3758{
3759 if (save_curbuf == NULL)
3760 restore_win(save_curwin, save_curtab, TRUE);
3761 else
3762 restore_buffer(save_curbuf);
3763}
3764
3765/*
Bram Moolenaar19e60942011-06-19 00:27:51 +02003766 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003767 * in Vim format (1-based). The replacement line is given as
3768 * a Python string object. The object is checked for validity
3769 * and correct format. Errors are returned as a value of FAIL.
3770 * The return value is OK on success.
3771 * If OK is returned and len_change is not NULL, *len_change
3772 * is set to the change in the buffer length.
3773 */
3774 static int
3775SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
3776{
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003777 buf_T *save_curbuf = NULL;
3778 win_T *save_curwin = NULL;
3779 tabpage_T *save_curtab = NULL;
3780
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003781 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003782 * There are three cases:
3783 * 1. NULL, or None - this is a deletion.
3784 * 2. A string - this is a replacement.
3785 * 3. Anything else - this is an error.
3786 */
3787 if (line == Py_None || line == NULL)
3788 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003789 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003790 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003791
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003792 VimTryStart();
3793
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003794 if (u_savedel((linenr_T)n, 1L) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003795 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003796 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003797 RAISE_DELETE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003798 else
3799 {
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003800 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003801 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003802 if (save_curbuf == NULL)
3803 /* Only adjust marks if we managed to switch to a window that
3804 * holds the buffer, otherwise line numbers will be invalid. */
3805 deleted_lines_mark((linenr_T)n, 1L);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003806 }
3807
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003808 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003809
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003810 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003811 return FAIL;
3812
3813 if (len_change)
3814 *len_change = -1;
3815
3816 return OK;
3817 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003818 else if (PyBytes_Check(line) || PyUnicode_Check(line))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003819 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003820 char *save = StringToLine(line);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003821
3822 if (save == NULL)
3823 return FAIL;
3824
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003825 VimTryStart();
3826
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003827 /* We do not need to free "save" if ml_replace() consumes it. */
3828 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003829 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003830
3831 if (u_savesub((linenr_T)n) == FAIL)
3832 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003833 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003834 vim_free(save);
3835 }
3836 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
3837 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003838 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003839 vim_free(save);
3840 }
3841 else
3842 changed_bytes((linenr_T)n, 0);
3843
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003844 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003845
3846 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003847 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003848 check_cursor_col();
3849
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003850 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003851 return FAIL;
3852
3853 if (len_change)
3854 *len_change = 0;
3855
3856 return OK;
3857 }
3858 else
3859 {
3860 PyErr_BadArgument();
3861 return FAIL;
3862 }
3863}
3864
Bram Moolenaar19e60942011-06-19 00:27:51 +02003865/* Replace a range of lines in the specified buffer. The line numbers are in
3866 * Vim format (1-based). The range is from lo up to, but not including, hi.
3867 * The replacement lines are given as a Python list of string objects. The
3868 * list is checked for validity and correct format. Errors are returned as a
3869 * value of FAIL. The return value is OK on success.
3870 * If OK is returned and len_change is not NULL, *len_change
3871 * is set to the change in the buffer length.
3872 */
3873 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003874SetBufferLineList(
3875 buf_T *buf,
3876 PyInt lo,
3877 PyInt hi,
3878 PyObject *list,
3879 PyInt *len_change)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003880{
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003881 buf_T *save_curbuf = NULL;
3882 win_T *save_curwin = NULL;
3883 tabpage_T *save_curtab = NULL;
3884
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003885 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02003886 * There are three cases:
3887 * 1. NULL, or None - this is a deletion.
3888 * 2. A list - this is a replacement.
3889 * 3. Anything else - this is an error.
3890 */
3891 if (list == Py_None || list == NULL)
3892 {
3893 PyInt i;
3894 PyInt n = (int)(hi - lo);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003895
3896 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003897 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003898 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003899
3900 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003901 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003902 else
3903 {
3904 for (i = 0; i < n; ++i)
3905 {
3906 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3907 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003908 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003909 break;
3910 }
3911 }
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003912 if (buf == curbuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003913 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003914 if (save_curbuf == NULL)
3915 /* Only adjust marks if we managed to switch to a window that
3916 * holds the buffer, otherwise line numbers will be invalid. */
3917 deleted_lines_mark((linenr_T)lo, (long)i);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003918 }
3919
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003920 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003921
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003922 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02003923 return FAIL;
3924
3925 if (len_change)
3926 *len_change = -n;
3927
3928 return OK;
3929 }
3930 else if (PyList_Check(list))
3931 {
3932 PyInt i;
3933 PyInt new_len = PyList_Size(list);
3934 PyInt old_len = hi - lo;
3935 PyInt extra = 0; /* lines added to text, can be negative */
3936 char **array;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003937
3938 if (new_len == 0) /* avoid allocating zero bytes */
3939 array = NULL;
3940 else
3941 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003942 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003943 if (array == NULL)
3944 {
3945 PyErr_NoMemory();
3946 return FAIL;
3947 }
3948 }
3949
3950 for (i = 0; i < new_len; ++i)
3951 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003952 PyObject *line;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003953
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003954 if (!(line = PyList_GetItem(list, i)) ||
3955 !(array[i] = StringToLine(line)))
Bram Moolenaar19e60942011-06-19 00:27:51 +02003956 {
3957 while (i)
3958 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003959 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003960 return FAIL;
3961 }
3962 }
3963
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003964 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02003965 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003966
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003967 /* START of region without "return". Must call restore_buffer()! */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003968 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003969
3970 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003971 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003972
3973 /* If the size of the range is reducing (ie, new_len < old_len) we
3974 * need to delete some old_len. We do this at the start, by
3975 * repeatedly deleting line "lo".
3976 */
3977 if (!PyErr_Occurred())
3978 {
3979 for (i = 0; i < old_len - new_len; ++i)
3980 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3981 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003982 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003983 break;
3984 }
3985 extra -= i;
3986 }
3987
3988 /* For as long as possible, replace the existing old_len with the
3989 * new old_len. This is a more efficient operation, as it requires
3990 * less memory allocation and freeing.
3991 */
3992 if (!PyErr_Occurred())
3993 {
3994 for (i = 0; i < old_len && i < new_len; ++i)
3995 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
3996 == FAIL)
3997 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003998 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003999 break;
4000 }
4001 }
4002 else
4003 i = 0;
4004
4005 /* Now we may need to insert the remaining new old_len. If we do, we
4006 * must free the strings as we finish with them (we can't pass the
4007 * responsibility to vim in this case).
4008 */
4009 if (!PyErr_Occurred())
4010 {
4011 while (i < new_len)
4012 {
4013 if (ml_append((linenr_T)(lo + i - 1),
4014 (char_u *)array[i], 0, FALSE) == FAIL)
4015 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004016 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004017 break;
4018 }
4019 vim_free(array[i]);
4020 ++i;
4021 ++extra;
4022 }
4023 }
4024
4025 /* Free any left-over old_len, as a result of an error */
4026 while (i < new_len)
4027 {
4028 vim_free(array[i]);
4029 ++i;
4030 }
4031
4032 /* Free the array of old_len. All of its contents have now
4033 * been dealt with (either freed, or the responsibility passed
4034 * to vim.
4035 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004036 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004037
4038 /* Adjust marks. Invalidate any which lie in the
4039 * changed range, and move any in the remainder of the buffer.
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004040 * Only adjust marks if we managed to switch to a window that holds
4041 * the buffer, otherwise line numbers will be invalid. */
4042 if (save_curbuf == NULL)
4043 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
Bram Moolenaar19e60942011-06-19 00:27:51 +02004044 (long)MAXLNUM, (long)extra);
4045 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
4046
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004047 if (buf == curbuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004048 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
4049
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004050 /* END of region without "return". */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004051 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004052
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004053 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02004054 return FAIL;
4055
4056 if (len_change)
4057 *len_change = new_len - old_len;
4058
4059 return OK;
4060 }
4061 else
4062 {
4063 PyErr_BadArgument();
4064 return FAIL;
4065 }
4066}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004067
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004068/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004069 * The line number is in Vim format (1-based). The lines to be inserted are
4070 * given as a Python list of string objects or as a single string. The lines
4071 * to be added are checked for validity and correct format. Errors are
4072 * returned as a value of FAIL. The return value is OK on success.
4073 * If OK is returned and len_change is not NULL, *len_change
4074 * is set to the change in the buffer length.
4075 */
4076 static int
4077InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
4078{
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004079 buf_T *save_curbuf = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004080 win_T *save_curwin = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004081 tabpage_T *save_curtab = NULL;
4082
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004083 /* First of all, we check the type of the supplied Python object.
4084 * It must be a string or a list, or the call is in error.
4085 */
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004086 if (PyBytes_Check(lines) || PyUnicode_Check(lines))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004087 {
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004088 char *str = StringToLine(lines);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004089
4090 if (str == NULL)
4091 return FAIL;
4092
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004093 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004094 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004095 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004096
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004097 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004098 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004099 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004100 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004101 else if (save_curbuf == NULL)
4102 /* Only adjust marks if we managed to switch to a window that
4103 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004104 appended_lines_mark((linenr_T)n, 1L);
4105
4106 vim_free(str);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004107 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004108 update_screen(VALID);
4109
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004110 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004111 return FAIL;
4112
4113 if (len_change)
4114 *len_change = 1;
4115
4116 return OK;
4117 }
4118 else if (PyList_Check(lines))
4119 {
4120 PyInt i;
4121 PyInt size = PyList_Size(lines);
4122 char **array;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004123
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004124 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004125 if (array == NULL)
4126 {
4127 PyErr_NoMemory();
4128 return FAIL;
4129 }
4130
4131 for (i = 0; i < size; ++i)
4132 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004133 PyObject *line;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004134
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004135 if (!(line = PyList_GetItem(lines, i)) ||
4136 !(array[i] = StringToLine(line)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004137 {
4138 while (i)
4139 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004140 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004141 return FAIL;
4142 }
4143 }
4144
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004145 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004146 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004147 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004148
4149 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004150 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004151 else
4152 {
4153 for (i = 0; i < size; ++i)
4154 {
4155 if (ml_append((linenr_T)(n + i),
4156 (char_u *)array[i], 0, FALSE) == FAIL)
4157 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004158 RAISE_INSERT_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004159
4160 /* Free the rest of the lines */
4161 while (i < size)
4162 vim_free(array[i++]);
4163
4164 break;
4165 }
4166 vim_free(array[i]);
4167 }
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004168 if (i > 0 && save_curbuf == NULL)
4169 /* Only adjust marks if we managed to switch to a window that
4170 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004171 appended_lines_mark((linenr_T)n, (long)i);
4172 }
4173
4174 /* Free the array of lines. All of its contents have now
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004175 * been freed. */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004176 PyMem_Free(array);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004177 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004178
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004179 update_screen(VALID);
4180
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004181 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004182 return FAIL;
4183
4184 if (len_change)
4185 *len_change = size;
4186
4187 return OK;
4188 }
4189 else
4190 {
4191 PyErr_BadArgument();
4192 return FAIL;
4193 }
4194}
4195
4196/*
4197 * Common routines for buffers and line ranges
4198 * -------------------------------------------
4199 */
4200
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004201typedef struct
4202{
4203 PyObject_HEAD
4204 buf_T *buf;
4205} BufferObject;
4206
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004207 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02004208CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004209{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004210 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004211 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004212 PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004213 return -1;
4214 }
4215
4216 return 0;
4217}
4218
4219 static PyObject *
4220RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4221{
4222 if (CheckBuffer(self))
4223 return NULL;
4224
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004225 if (end == -1)
4226 end = self->buf->b_ml.ml_line_count;
4227
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004228 if (n < 0)
4229 n += end - start + 1;
4230
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004231 if (n < 0 || n > end - start)
4232 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004233 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004234 return NULL;
4235 }
4236
4237 return GetBufferLine(self->buf, n+start);
4238}
4239
4240 static PyObject *
4241RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4242{
4243 PyInt size;
4244
4245 if (CheckBuffer(self))
4246 return NULL;
4247
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004248 if (end == -1)
4249 end = self->buf->b_ml.ml_line_count;
4250
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004251 size = end - start + 1;
4252
4253 if (lo < 0)
4254 lo = 0;
4255 else if (lo > size)
4256 lo = size;
4257 if (hi < 0)
4258 hi = 0;
4259 if (hi < lo)
4260 hi = lo;
4261 else if (hi > size)
4262 hi = size;
4263
4264 return GetBufferLineList(self->buf, lo+start, hi+start);
4265}
4266
4267 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004268RBAsItem(
4269 BufferObject *self,
4270 PyInt n,
4271 PyObject *valObject,
4272 PyInt start,
4273 PyInt end,
4274 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004275{
4276 PyInt len_change;
4277
4278 if (CheckBuffer(self))
4279 return -1;
4280
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004281 if (end == -1)
4282 end = self->buf->b_ml.ml_line_count;
4283
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004284 if (n < 0)
4285 n += end - start + 1;
4286
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004287 if (n < 0 || n > end - start)
4288 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004289 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004290 return -1;
4291 }
4292
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004293 if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004294 return -1;
4295
4296 if (new_end)
4297 *new_end = end + len_change;
4298
4299 return 0;
4300}
4301
Bram Moolenaar19e60942011-06-19 00:27:51 +02004302 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004303RBAsSlice(
4304 BufferObject *self,
4305 PyInt lo,
4306 PyInt hi,
4307 PyObject *valObject,
4308 PyInt start,
4309 PyInt end,
4310 PyInt *new_end)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004311{
4312 PyInt size;
4313 PyInt len_change;
4314
4315 /* Self must be a valid buffer */
4316 if (CheckBuffer(self))
4317 return -1;
4318
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004319 if (end == -1)
4320 end = self->buf->b_ml.ml_line_count;
4321
Bram Moolenaar19e60942011-06-19 00:27:51 +02004322 /* Sort out the slice range */
4323 size = end - start + 1;
4324
4325 if (lo < 0)
4326 lo = 0;
4327 else if (lo > size)
4328 lo = size;
4329 if (hi < 0)
4330 hi = 0;
4331 if (hi < lo)
4332 hi = lo;
4333 else if (hi > size)
4334 hi = size;
4335
4336 if (SetBufferLineList(self->buf, lo + start, hi + start,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004337 valObject, &len_change) == FAIL)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004338 return -1;
4339
4340 if (new_end)
4341 *new_end = end + len_change;
4342
4343 return 0;
4344}
4345
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004346
4347 static PyObject *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004348RBAppend(
4349 BufferObject *self,
4350 PyObject *args,
4351 PyInt start,
4352 PyInt end,
4353 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004354{
4355 PyObject *lines;
4356 PyInt len_change;
4357 PyInt max;
4358 PyInt n;
4359
4360 if (CheckBuffer(self))
4361 return NULL;
4362
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004363 if (end == -1)
4364 end = self->buf->b_ml.ml_line_count;
4365
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004366 max = n = end - start + 1;
4367
4368 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
4369 return NULL;
4370
4371 if (n < 0 || n > max)
4372 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004373 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004374 return NULL;
4375 }
4376
4377 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
4378 return NULL;
4379
4380 if (new_end)
4381 *new_end = end + len_change;
4382
4383 Py_INCREF(Py_None);
4384 return Py_None;
4385}
4386
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004387/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004388 */
4389
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004390static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004391static PySequenceMethods RangeAsSeq;
4392static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004393
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004394typedef struct
4395{
4396 PyObject_HEAD
4397 BufferObject *buf;
4398 PyInt start;
4399 PyInt end;
4400} RangeObject;
4401
4402 static PyObject *
4403RangeNew(buf_T *buf, PyInt start, PyInt end)
4404{
4405 BufferObject *bufr;
4406 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004407 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004408 if (self == NULL)
4409 return NULL;
4410
4411 bufr = (BufferObject *)BufferNew(buf);
4412 if (bufr == NULL)
4413 {
4414 Py_DECREF(self);
4415 return NULL;
4416 }
4417 Py_INCREF(bufr);
4418
4419 self->buf = bufr;
4420 self->start = start;
4421 self->end = end;
4422
4423 return (PyObject *)(self);
4424}
4425
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004426 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004427RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004428{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004429 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004430 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02004431 PyObject_GC_Del((void *)(self));
4432}
4433
4434 static int
4435RangeTraverse(RangeObject *self, visitproc visit, void *arg)
4436{
4437 Py_VISIT(((PyObject *)(self->buf)));
4438 return 0;
4439}
4440
4441 static int
4442RangeClear(RangeObject *self)
4443{
4444 Py_CLEAR(self->buf);
4445 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004446}
4447
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004448 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004449RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004450{
4451 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004452 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004453 return -1; /* ??? */
4454
Bram Moolenaard6e39182013-05-21 18:30:34 +02004455 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004456}
4457
4458 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004459RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004460{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004461 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004462}
4463
4464 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004465RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004466{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004467 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004468}
4469
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004470static char *RangeAttrs[] = {
4471 "start", "end",
4472 NULL
4473};
4474
4475 static PyObject *
4476RangeDir(PyObject *self)
4477{
4478 return ObjectDir(self, RangeAttrs);
4479}
4480
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004481 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004482RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004483{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004484 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004485}
4486
4487 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004488RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004489{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004490 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004491 return PyString_FromFormat("<range object (for deleted buffer) at %p>",
4492 (self));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004493 else
4494 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02004495 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004496
4497 if (name == NULL)
4498 name = "";
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004499
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004500 return PyString_FromFormat("<range %s (%d:%d)>",
Bram Moolenaarf62d9422013-05-30 19:01:24 +02004501 name, (int)self->start, (int)self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004502 }
4503}
4504
4505static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004506 /* name, function, calling, documentation */
4507 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004508 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
4509 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004510};
4511
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004512static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004513static PySequenceMethods BufferAsSeq;
4514static PyMappingMethods BufferAsMapping;
4515
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004516 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02004517BufferNew(buf_T *buf)
4518{
4519 /* We need to handle deletion of buffers underneath us.
4520 * If we add a "b_python*_ref" field to the buf_T structure,
4521 * then we can get at it in buf_freeall() in vim. We then
4522 * need to create only ONE Python object per buffer - if
4523 * we try to create a second, just INCREF the existing one
4524 * and return it. The (single) Python object referring to
4525 * the buffer is stored in "b_python*_ref".
4526 * Question: what to do on a buf_freeall(). We'll probably
4527 * have to either delete the Python object (DECREF it to
4528 * zero - a bad idea, as it leaves dangling refs!) or
4529 * set the buf_T * value to an invalid value (-1?), which
4530 * means we need checks in all access functions... Bah.
4531 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004532 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02004533 * b_python_ref and b_python3_ref fields respectively.
4534 */
4535
4536 BufferObject *self;
4537
4538 if (BUF_PYTHON_REF(buf) != NULL)
4539 {
4540 self = BUF_PYTHON_REF(buf);
4541 Py_INCREF(self);
4542 }
4543 else
4544 {
4545 self = PyObject_NEW(BufferObject, &BufferType);
4546 if (self == NULL)
4547 return NULL;
4548 self->buf = buf;
4549 BUF_PYTHON_REF(buf) = self;
4550 }
4551
4552 return (PyObject *)(self);
4553}
4554
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004555 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004556BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004557{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004558 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
4559 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004560
4561 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004562}
4563
Bram Moolenaar971db462013-05-12 18:44:48 +02004564 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004565BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02004566{
4567 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004568 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02004569 return -1; /* ??? */
4570
Bram Moolenaard6e39182013-05-21 18:30:34 +02004571 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02004572}
4573
4574 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004575BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02004576{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004577 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004578}
4579
4580 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004581BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02004582{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004583 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004584}
4585
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004586static char *BufferAttrs[] = {
4587 "name", "number", "vars", "options", "valid",
4588 NULL
4589};
4590
4591 static PyObject *
4592BufferDir(PyObject *self)
4593{
4594 return ObjectDir(self, BufferAttrs);
4595}
4596
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004597 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004598BufferAttrValid(BufferObject *self, char *name)
4599{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004600 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004601
4602 if (strcmp(name, "valid") != 0)
4603 return NULL;
4604
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004605 ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
4606 Py_INCREF(ret);
4607 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004608}
4609
4610 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004611BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004612{
4613 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02004614 return PyString_FromString((self->buf->b_ffname == NULL
Bram Moolenaar41009372013-07-01 22:03:04 +02004615 ? "" : (char *)self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004616 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004617 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004618 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02004619 return NEW_DICTIONARY(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004620 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004621 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
4622 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004623 else if (strcmp(name, "__members__") == 0)
4624 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004625 else
4626 return NULL;
4627}
4628
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004629 static int
4630BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
4631{
4632 if (CheckBuffer(self))
4633 return -1;
4634
4635 if (strcmp(name, "name") == 0)
4636 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004637 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004638 aco_save_T aco;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004639 int ren_ret;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004640 PyObject *todecref;
4641
4642 if (!(val = StringToChars(valObject, &todecref)))
4643 return -1;
4644
4645 VimTryStart();
4646 /* Using aucmd_*: autocommands will be executed by rename_buffer */
4647 aucmd_prepbuf(&aco, self->buf);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004648 ren_ret = rename_buffer(val);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004649 aucmd_restbuf(&aco);
4650 Py_XDECREF(todecref);
4651 if (VimTryEnd())
4652 return -1;
4653
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004654 if (ren_ret == FAIL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004655 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004656 PyErr_SET_VIM(N_("failed to rename buffer"));
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004657 return -1;
4658 }
4659 return 0;
4660 }
4661 else
4662 {
4663 PyErr_SetString(PyExc_AttributeError, name);
4664 return -1;
4665 }
4666}
4667
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004668 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004669BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004670{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004671 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004672}
4673
4674 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02004675BufferMark(BufferObject *self, PyObject *pmarkObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004676{
4677 pos_T *posp;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004678 char_u *pmark;
4679 char_u mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02004680 buf_T *savebuf;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004681 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004682
Bram Moolenaard6e39182013-05-21 18:30:34 +02004683 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004684 return NULL;
4685
Bram Moolenaar389a1792013-06-23 13:00:44 +02004686 if (!(pmark = StringToChars(pmarkObject, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004687 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004688
Bram Moolenaar389a1792013-06-23 13:00:44 +02004689 if (pmark[0] == '\0' || pmark[1] != '\0')
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004690 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004691 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004692 N_("mark name must be a single character"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02004693 Py_XDECREF(todecref);
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004694 return NULL;
4695 }
4696
4697 mark = *pmark;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004698
4699 Py_XDECREF(todecref);
4700
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004701 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02004702 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004703 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02004704 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004705 if (VimTryEnd())
4706 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004707
4708 if (posp == NULL)
4709 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004710 PyErr_SET_VIM(N_("invalid mark name"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004711 return NULL;
4712 }
4713
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004714 if (posp->lnum <= 0)
4715 {
4716 /* Or raise an error? */
4717 Py_INCREF(Py_None);
4718 return Py_None;
4719 }
4720
4721 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
4722}
4723
4724 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004725BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004726{
4727 PyInt start;
4728 PyInt end;
4729
Bram Moolenaard6e39182013-05-21 18:30:34 +02004730 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004731 return NULL;
4732
4733 if (!PyArg_ParseTuple(args, "nn", &start, &end))
4734 return NULL;
4735
Bram Moolenaard6e39182013-05-21 18:30:34 +02004736 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004737}
4738
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004739 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004740BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004741{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004742 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004743 return PyString_FromFormat("<buffer object (deleted) at %p>", self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004744 else
4745 {
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004746 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004747
4748 if (name == NULL)
4749 name = "";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004750
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004751 return PyString_FromFormat("<buffer %s>", name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004752 }
4753}
4754
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004755static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004756 /* name, function, calling, documentation */
4757 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02004758 {"mark", (PyCFunction)BufferMark, METH_O, "Return (row,col) representing position of named mark" },
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004759 {"range", (PyCFunction)BufferRange, METH_VARARGS, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004760 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
4761 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004762};
4763
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004764/*
4765 * Buffer list object - Implementation
4766 */
4767
4768static PyTypeObject BufMapType;
4769
4770typedef struct
4771{
4772 PyObject_HEAD
4773} BufMapObject;
4774
4775 static PyInt
4776BufMapLength(PyObject *self UNUSED)
4777{
4778 buf_T *b = firstbuf;
4779 PyInt n = 0;
4780
4781 while (b)
4782 {
4783 ++n;
4784 b = b->b_next;
4785 }
4786
4787 return n;
4788}
4789
4790 static PyObject *
4791BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
4792{
4793 buf_T *b;
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004794 long bnr;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004795
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004796 if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004797 return NULL;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004798
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004799 b = buflist_findnr((int) bnr);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004800
4801 if (b)
4802 return BufferNew(b);
4803 else
4804 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02004805 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004806 return NULL;
4807 }
4808}
4809
4810 static void
4811BufMapIterDestruct(PyObject *buffer)
4812{
4813 /* Iteration was stopped before all buffers were processed */
4814 if (buffer)
4815 {
4816 Py_DECREF(buffer);
4817 }
4818}
4819
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004820 static int
4821BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
4822{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004823 if (buffer)
4824 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004825 return 0;
4826}
4827
4828 static int
4829BufMapIterClear(PyObject **buffer)
4830{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004831 if (*buffer)
4832 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004833 return 0;
4834}
4835
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004836 static PyObject *
4837BufMapIterNext(PyObject **buffer)
4838{
4839 PyObject *next;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004840 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004841
4842 if (!*buffer)
4843 return NULL;
4844
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004845 ret = *buffer;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004846
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004847 if (CheckBuffer((BufferObject *)(ret)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004848 {
4849 *buffer = NULL;
4850 return NULL;
4851 }
4852
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004853 if (!((BufferObject *)(ret))->buf->b_next)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004854 next = NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004855 else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004856 return NULL;
4857 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02004858 /* Do not increment reference: we no longer hold it (decref), but whoever
4859 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004860 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004861}
4862
4863 static PyObject *
4864BufMapIter(PyObject *self UNUSED)
4865{
4866 PyObject *buffer;
4867
4868 buffer = BufferNew(firstbuf);
4869 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004870 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
4871 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004872}
4873
4874static PyMappingMethods BufMapAsMapping = {
4875 (lenfunc) BufMapLength,
4876 (binaryfunc) BufMapItem,
4877 (objobjargproc) 0,
4878};
4879
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004880/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004881 */
4882
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004883static char *CurrentAttrs[] = {
4884 "buffer", "window", "line", "range", "tabpage",
4885 NULL
4886};
4887
4888 static PyObject *
4889CurrentDir(PyObject *self)
4890{
4891 return ObjectDir(self, CurrentAttrs);
4892}
4893
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004894 static PyObject *
4895CurrentGetattr(PyObject *self UNUSED, char *name)
4896{
4897 if (strcmp(name, "buffer") == 0)
4898 return (PyObject *)BufferNew(curbuf);
4899 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02004900 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004901 else if (strcmp(name, "tabpage") == 0)
4902 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004903 else if (strcmp(name, "line") == 0)
4904 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
4905 else if (strcmp(name, "range") == 0)
4906 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004907 else if (strcmp(name, "__members__") == 0)
4908 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004909 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004910#if PY_MAJOR_VERSION < 3
4911 return Py_FindMethod(WindowMethods, self, name);
4912#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004913 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004914#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004915}
4916
4917 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004918CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004919{
4920 if (strcmp(name, "line") == 0)
4921 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004922 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
4923 NULL) == FAIL)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004924 return -1;
4925
4926 return 0;
4927 }
Bram Moolenaare7614592013-05-15 15:51:08 +02004928 else if (strcmp(name, "buffer") == 0)
4929 {
4930 int count;
4931
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004932 if (valObject->ob_type != &BufferType)
Bram Moolenaare7614592013-05-15 15:51:08 +02004933 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004934 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004935 N_("expected vim.Buffer object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004936 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02004937 return -1;
4938 }
4939
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004940 if (CheckBuffer((BufferObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02004941 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004942 count = ((BufferObject *)(valObject))->buf->b_fnum;
Bram Moolenaare7614592013-05-15 15:51:08 +02004943
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004944 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004945 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
4946 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004947 if (VimTryEnd())
4948 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004949 PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
Bram Moolenaare7614592013-05-15 15:51:08 +02004950 return -1;
4951 }
4952
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004953 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004954 }
4955 else if (strcmp(name, "window") == 0)
4956 {
4957 int count;
4958
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004959 if (valObject->ob_type != &WindowType)
Bram Moolenaare7614592013-05-15 15:51:08 +02004960 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004961 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004962 N_("expected vim.Window object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004963 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02004964 return -1;
4965 }
4966
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004967 if (CheckWindow((WindowObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02004968 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004969 count = get_win_number(((WindowObject *)(valObject))->win, firstwin);
Bram Moolenaare7614592013-05-15 15:51:08 +02004970
4971 if (!count)
4972 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004973 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004974 N_("failed to find window in the current tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004975 return -1;
4976 }
4977
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004978 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004979 win_goto(((WindowObject *)(valObject))->win);
4980 if (((WindowObject *)(valObject))->win != curwin)
Bram Moolenaare7614592013-05-15 15:51:08 +02004981 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004982 if (VimTryEnd())
4983 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004984 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004985 N_("did not switch to the specified window"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004986 return -1;
4987 }
4988
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004989 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004990 }
4991 else if (strcmp(name, "tabpage") == 0)
4992 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004993 if (valObject->ob_type != &TabPageType)
Bram Moolenaare7614592013-05-15 15:51:08 +02004994 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004995 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004996 N_("expected vim.TabPage object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004997 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02004998 return -1;
4999 }
5000
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005001 if (CheckTabPage((TabPageObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005002 return -1;
5003
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005004 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005005 goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
5006 if (((TabPageObject *)(valObject))->tab != curtab)
Bram Moolenaare7614592013-05-15 15:51:08 +02005007 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005008 if (VimTryEnd())
5009 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005010 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005011 N_("did not switch to the specified tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005012 return -1;
5013 }
5014
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005015 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005016 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005017 else
5018 {
5019 PyErr_SetString(PyExc_AttributeError, name);
5020 return -1;
5021 }
5022}
5023
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005024static struct PyMethodDef CurrentMethods[] = {
5025 /* name, function, calling, documentation */
5026 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
5027 { NULL, NULL, 0, NULL}
5028};
5029
Bram Moolenaardb913952012-06-29 12:54:53 +02005030 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005031init_range_cmd(exarg_T *eap)
5032{
5033 RangeStart = eap->line1;
5034 RangeEnd = eap->line2;
5035}
5036
5037 static void
5038init_range_eval(typval_T *rettv UNUSED)
5039{
5040 RangeStart = (PyInt) curwin->w_cursor.lnum;
5041 RangeEnd = RangeStart;
5042}
5043
5044 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005045run_cmd(const char *cmd, void *arg UNUSED
5046#ifdef PY_CAN_RECURSE
5047 , PyGILState_STATE *pygilstate UNUSED
5048#endif
5049 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005050{
Bram Moolenaar41009372013-07-01 22:03:04 +02005051 PyObject *run_ret;
5052 run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
5053 if (run_ret != NULL)
5054 {
5055 Py_DECREF(run_ret);
5056 }
5057 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5058 {
5059 EMSG2(_(e_py_systemexit), "python");
5060 PyErr_Clear();
5061 }
5062 else
5063 PyErr_PrintEx(1);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005064}
5065
5066static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
5067static int code_hdr_len = 30;
5068
5069 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005070run_do(const char *cmd, void *arg UNUSED
5071#ifdef PY_CAN_RECURSE
5072 , PyGILState_STATE *pygilstate
5073#endif
5074 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005075{
5076 PyInt lnum;
5077 size_t len;
5078 char *code;
5079 int status;
5080 PyObject *pyfunc, *pymain;
Bram Moolenaar41009372013-07-01 22:03:04 +02005081 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005082
Bram Moolenaar4ac66762013-05-28 22:31:46 +02005083 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005084 {
5085 EMSG(_("cannot save undo information"));
5086 return;
5087 }
5088
5089 len = code_hdr_len + STRLEN(cmd);
5090 code = PyMem_New(char, len + 1);
5091 memcpy(code, code_hdr, code_hdr_len);
5092 STRCPY(code + code_hdr_len, cmd);
Bram Moolenaar41009372013-07-01 22:03:04 +02005093 run_ret = PyRun_String(code, Py_file_input, globals, globals);
5094 status = -1;
5095 if (run_ret != NULL)
5096 {
5097 status = 0;
5098 Py_DECREF(run_ret);
5099 }
5100 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5101 {
5102 PyMem_Free(code);
5103 EMSG2(_(e_py_systemexit), "python");
5104 PyErr_Clear();
5105 return;
5106 }
5107 else
5108 PyErr_PrintEx(1);
5109
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005110 PyMem_Free(code);
5111
5112 if (status)
5113 {
5114 EMSG(_("failed to run the code"));
5115 return;
5116 }
5117
5118 status = 0;
5119 pymain = PyImport_AddModule("__main__");
5120 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005121#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005122 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005123#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005124
5125 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
5126 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005127 PyObject *line;
5128 PyObject *linenr;
5129 PyObject *ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005130
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005131#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005132 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005133#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005134 if (!(line = GetBufferLine(curbuf, lnum)))
5135 goto err;
5136 if (!(linenr = PyInt_FromLong((long) lnum)))
5137 {
5138 Py_DECREF(line);
5139 goto err;
5140 }
5141 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
5142 Py_DECREF(line);
5143 Py_DECREF(linenr);
5144 if (!ret)
5145 goto err;
5146
5147 if (ret != Py_None)
5148 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
5149 goto err;
5150
5151 Py_XDECREF(ret);
5152 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005153#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005154 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005155#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005156 }
5157 goto out;
5158err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005159#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005160 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005161#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005162 PyErr_PrintEx(0);
5163 PythonIO_Flush();
5164 status = 1;
5165out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005166#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005167 if (!status)
5168 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005169#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005170 Py_DECREF(pyfunc);
5171 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
5172 if (status)
5173 return;
5174 check_cursor();
5175 update_curbuf(NOT_VALID);
5176}
5177
5178 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005179run_eval(const char *cmd, typval_T *rettv
5180#ifdef PY_CAN_RECURSE
5181 , PyGILState_STATE *pygilstate UNUSED
5182#endif
5183 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005184{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005185 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005186
Bram Moolenaar41009372013-07-01 22:03:04 +02005187 run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005188 if (run_ret == NULL)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005189 {
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005190 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
Bram Moolenaar41009372013-07-01 22:03:04 +02005191 {
5192 EMSG2(_(e_py_systemexit), "python");
5193 PyErr_Clear();
5194 }
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005195 else
5196 {
5197 if (PyErr_Occurred() && !msg_silent)
5198 PyErr_PrintEx(0);
5199 EMSG(_("E858: Eval did not return a valid python object"));
5200 }
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005201 }
5202 else
5203 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005204 if (ConvertFromPyObject(run_ret, rettv) == -1)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005205 EMSG(_("E859: Failed to convert returned python object to vim value"));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005206 Py_DECREF(run_ret);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005207 }
5208 PyErr_Clear();
5209}
5210
5211 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02005212set_ref_in_py(const int copyID)
5213{
5214 pylinkedlist_T *cur;
5215 dict_T *dd;
5216 list_T *ll;
5217
5218 if (lastdict != NULL)
5219 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
5220 {
5221 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
5222 if (dd->dv_copyID != copyID)
5223 {
5224 dd->dv_copyID = copyID;
5225 set_ref_in_ht(&dd->dv_hashtab, copyID);
5226 }
5227 }
5228
5229 if (lastlist != NULL)
5230 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
5231 {
5232 ll = ((ListObject *) (cur->pll_obj))->list;
5233 if (ll->lv_copyID != copyID)
5234 {
5235 ll->lv_copyID = copyID;
5236 set_ref_in_list(ll, copyID);
5237 }
5238 }
5239}
5240
5241 static int
5242set_string_copy(char_u *str, typval_T *tv)
5243{
5244 tv->vval.v_string = vim_strsave(str);
5245 if (tv->vval.v_string == NULL)
5246 {
5247 PyErr_NoMemory();
5248 return -1;
5249 }
5250 return 0;
5251}
5252
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005253 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005254pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005255{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005256 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005257 char_u *key;
5258 dictitem_T *di;
5259 PyObject *keyObject;
5260 PyObject *valObject;
5261 Py_ssize_t iter = 0;
5262
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005263 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005264 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005265
5266 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005267 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005268
5269 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5270 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005271 PyObject *todecref = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005272
Bram Moolenaara03e6312013-05-29 22:49:26 +02005273 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005274 {
5275 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005276 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005277 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005278
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005279 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005280 {
5281 dict_unref(dict);
5282 return -1;
5283 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005284
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005285 if (*key == NUL)
5286 {
5287 dict_unref(dict);
5288 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005289 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005290 return -1;
5291 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005292
5293 di = dictitem_alloc(key);
5294
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005295 Py_XDECREF(todecref);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005296
5297 if (di == NULL)
5298 {
5299 PyErr_NoMemory();
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005300 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005301 return -1;
5302 }
5303 di->di_tv.v_lock = 0;
5304
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005305 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005306 {
5307 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005308 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005309 return -1;
5310 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005311
5312 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005313 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005314 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara03e6312013-05-29 22:49:26 +02005315 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005316 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005317 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005318 return -1;
5319 }
5320 }
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005321
5322 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005323 return 0;
5324}
5325
5326 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005327pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005328{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005329 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005330 char_u *key;
5331 dictitem_T *di;
5332 PyObject *list;
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005333 PyObject *iterator;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005334 PyObject *keyObject;
5335 PyObject *valObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005336
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005337 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005338 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005339
5340 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005341 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005342
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005343 if (!(list = PyMapping_Keys(obj)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005344 {
5345 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005346 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005347 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005348
5349 if (!(iterator = PyObject_GetIter(list)))
5350 {
5351 dict_unref(dict);
5352 Py_DECREF(list);
5353 return -1;
5354 }
5355 Py_DECREF(list);
5356
5357 while ((keyObject = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005358 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005359 PyObject *todecref;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005360
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005361 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005362 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005363 Py_DECREF(keyObject);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005364 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005365 dict_unref(dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005366 return -1;
5367 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005368
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005369 if (*key == NUL)
5370 {
5371 Py_DECREF(keyObject);
5372 Py_DECREF(iterator);
5373 Py_XDECREF(todecref);
5374 dict_unref(dict);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005375 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005376 return -1;
5377 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005378
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005379 if (!(valObject = PyObject_GetItem(obj, keyObject)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005380 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005381 Py_DECREF(keyObject);
5382 Py_DECREF(iterator);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005383 Py_XDECREF(todecref);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005384 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005385 return -1;
5386 }
5387
5388 di = dictitem_alloc(key);
5389
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005390 Py_DECREF(keyObject);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005391 Py_XDECREF(todecref);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005392
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005393 if (di == NULL)
5394 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005395 Py_DECREF(iterator);
5396 Py_DECREF(valObject);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005397 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005398 PyErr_NoMemory();
5399 return -1;
5400 }
5401 di->di_tv.v_lock = 0;
5402
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005403 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005404 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005405 Py_DECREF(iterator);
5406 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005407 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005408 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005409 return -1;
5410 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02005411
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005412 Py_DECREF(valObject);
5413
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005414 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005415 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005416 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005417 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005418 dictitem_free(di);
5419 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005420 return -1;
5421 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005422 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005423 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005424 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005425 return 0;
5426}
5427
5428 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005429pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005430{
5431 list_T *l;
5432
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005433 if (!(l = py_list_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005434 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005435
5436 tv->v_type = VAR_LIST;
5437 tv->vval.v_list = l;
5438
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005439 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005440 {
5441 list_unref(l);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005442 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005443 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005444
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005445 --l->lv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005446 return 0;
5447}
5448
Bram Moolenaardb913952012-06-29 12:54:53 +02005449typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
5450
5451 static int
5452convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005453 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005454{
5455 PyObject *capsule;
5456 char hexBuf[sizeof(void *) * 2 + 3];
5457
5458 sprintf(hexBuf, "%p", obj);
5459
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005460# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005461 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005462# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005463 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005464# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02005465 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005466 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005467# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02005468 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02005469# else
5470 capsule = PyCObject_FromVoidPtr(tv, NULL);
5471# endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02005472 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
5473 {
5474 Py_DECREF(capsule);
5475 tv->v_type = VAR_UNKNOWN;
5476 return -1;
5477 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005478
5479 Py_DECREF(capsule);
5480
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005481 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005482 {
5483 tv->v_type = VAR_UNKNOWN;
5484 return -1;
5485 }
5486 /* As we are not using copy_tv which increments reference count we must
5487 * do it ourself. */
5488 switch(tv->v_type)
5489 {
5490 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
5491 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
5492 }
5493 }
5494 else
5495 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005496 typval_T *v;
5497
5498# ifdef PY_USE_CAPSULE
5499 v = PyCapsule_GetPointer(capsule, NULL);
5500# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02005501 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005502# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02005503 copy_tv(v, tv);
5504 }
5505 return 0;
5506}
5507
5508 static int
Bram Moolenaara9922d62013-05-30 13:01:18 +02005509ConvertFromPyMapping(PyObject *obj, typval_T *tv)
5510{
5511 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005512 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005513
5514 if (!(lookup_dict = PyDict_New()))
5515 return -1;
5516
5517 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
5518 {
5519 tv->v_type = VAR_DICT;
5520 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5521 ++tv->vval.v_dict->dv_refcount;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005522 ret = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005523 }
5524 else if (PyDict_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005525 ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02005526 else if (PyMapping_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005527 ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02005528 else
5529 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005530 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005531 N_("unable to convert %s to vim dictionary"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02005532 Py_TYPE_NAME(obj));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005533 ret = -1;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005534 }
5535 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005536 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005537}
5538
5539 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02005540ConvertFromPyObject(PyObject *obj, typval_T *tv)
5541{
5542 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005543 int ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02005544
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005545 if (!(lookup_dict = PyDict_New()))
5546 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005547 ret = _ConvertFromPyObject(obj, tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005548 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005549 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02005550}
5551
5552 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005553_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005554{
Bram Moolenaara9922d62013-05-30 13:01:18 +02005555 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005556 {
5557 tv->v_type = VAR_DICT;
5558 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5559 ++tv->vval.v_dict->dv_refcount;
5560 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005561 else if (PyType_IsSubtype(obj->ob_type, &ListType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005562 {
5563 tv->v_type = VAR_LIST;
5564 tv->vval.v_list = (((ListObject *)(obj))->list);
5565 ++tv->vval.v_list->lv_refcount;
5566 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005567 else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005568 {
5569 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
5570 return -1;
5571
5572 tv->v_type = VAR_FUNC;
5573 func_ref(tv->vval.v_string);
5574 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005575 else if (PyBytes_Check(obj))
5576 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005577 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02005578
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005579 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005580 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005581 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005582 return -1;
5583
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005584 if (set_string_copy(str, tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005585 return -1;
5586
5587 tv->v_type = VAR_STRING;
5588 }
5589 else if (PyUnicode_Check(obj))
5590 {
5591 PyObject *bytes;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005592 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02005593
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02005594 bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005595 if (bytes == NULL)
5596 return -1;
5597
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005598 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005599 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005600 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005601 return -1;
5602
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005603 if (set_string_copy(str, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02005604 {
5605 Py_XDECREF(bytes);
5606 return -1;
5607 }
5608 Py_XDECREF(bytes);
5609
5610 tv->v_type = VAR_STRING;
5611 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02005612#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02005613 else if (PyInt_Check(obj))
5614 {
5615 tv->v_type = VAR_NUMBER;
5616 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005617 if (PyErr_Occurred())
5618 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005619 }
5620#endif
5621 else if (PyLong_Check(obj))
5622 {
5623 tv->v_type = VAR_NUMBER;
5624 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005625 if (PyErr_Occurred())
5626 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005627 }
5628 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005629 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005630#ifdef FEAT_FLOAT
5631 else if (PyFloat_Check(obj))
5632 {
5633 tv->v_type = VAR_FLOAT;
5634 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
5635 }
5636#endif
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005637 else if (PyObject_HasAttrString(obj, "keys"))
5638 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardee2e312013-06-23 16:35:47 +02005639 /* PyObject_GetIter can create built-in iterator for any sequence object */
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005640 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005641 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005642 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005643 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005644 else if (PyNumber_Check(obj))
5645 {
5646 PyObject *num;
5647
5648 if (!(num = PyNumber_Long(obj)))
5649 return -1;
5650
5651 tv->v_type = VAR_NUMBER;
5652 tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
5653
5654 Py_DECREF(num);
5655 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005656 else
5657 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005658 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005659 N_("unable to convert %s to vim structure"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02005660 Py_TYPE_NAME(obj));
Bram Moolenaardb913952012-06-29 12:54:53 +02005661 return -1;
5662 }
5663 return 0;
5664}
5665
5666 static PyObject *
5667ConvertToPyObject(typval_T *tv)
5668{
5669 if (tv == NULL)
5670 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005671 PyErr_SET_VIM(N_("internal error: NULL reference passed"));
Bram Moolenaardb913952012-06-29 12:54:53 +02005672 return NULL;
5673 }
5674 switch (tv->v_type)
5675 {
5676 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02005677 return PyBytes_FromString(tv->vval.v_string == NULL
5678 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02005679 case VAR_NUMBER:
5680 return PyLong_FromLong((long) tv->vval.v_number);
5681#ifdef FEAT_FLOAT
5682 case VAR_FLOAT:
5683 return PyFloat_FromDouble((double) tv->vval.v_float);
5684#endif
5685 case VAR_LIST:
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005686 return NEW_LIST(tv->vval.v_list);
Bram Moolenaardb913952012-06-29 12:54:53 +02005687 case VAR_DICT:
Bram Moolenaara9922d62013-05-30 13:01:18 +02005688 return NEW_DICTIONARY(tv->vval.v_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005689 case VAR_FUNC:
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005690 return NEW_FUNCTION(tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02005691 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02005692 case VAR_UNKNOWN:
5693 Py_INCREF(Py_None);
5694 return Py_None;
5695 default:
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005696 PyErr_SET_VIM(N_("internal error: invalid value type"));
Bram Moolenaardb913952012-06-29 12:54:53 +02005697 return NULL;
5698 }
5699}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005700
5701typedef struct
5702{
5703 PyObject_HEAD
5704} CurrentObject;
5705static PyTypeObject CurrentType;
5706
5707 static void
5708init_structs(void)
5709{
5710 vim_memset(&OutputType, 0, sizeof(OutputType));
5711 OutputType.tp_name = "vim.message";
5712 OutputType.tp_basicsize = sizeof(OutputObject);
5713 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
5714 OutputType.tp_doc = "vim message object";
5715 OutputType.tp_methods = OutputMethods;
5716#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005717 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
5718 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005719 OutputType.tp_alloc = call_PyType_GenericAlloc;
5720 OutputType.tp_new = call_PyType_GenericNew;
5721 OutputType.tp_free = call_PyObject_Free;
5722#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005723 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
5724 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005725#endif
5726
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005727 vim_memset(&IterType, 0, sizeof(IterType));
5728 IterType.tp_name = "vim.iter";
5729 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005730 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005731 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005732 IterType.tp_iter = (getiterfunc)IterIter;
5733 IterType.tp_iternext = (iternextfunc)IterNext;
5734 IterType.tp_dealloc = (destructor)IterDestructor;
5735 IterType.tp_traverse = (traverseproc)IterTraverse;
5736 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005737
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005738 vim_memset(&BufferType, 0, sizeof(BufferType));
5739 BufferType.tp_name = "vim.buffer";
5740 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005741 BufferType.tp_dealloc = (destructor)BufferDestructor;
5742 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005743 BufferType.tp_as_sequence = &BufferAsSeq;
5744 BufferType.tp_as_mapping = &BufferAsMapping;
5745 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
5746 BufferType.tp_doc = "vim buffer object";
5747 BufferType.tp_methods = BufferMethods;
5748#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005749 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005750 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005751 BufferType.tp_alloc = call_PyType_GenericAlloc;
5752 BufferType.tp_new = call_PyType_GenericNew;
5753 BufferType.tp_free = call_PyObject_Free;
5754#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005755 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005756 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005757#endif
5758
5759 vim_memset(&WindowType, 0, sizeof(WindowType));
5760 WindowType.tp_name = "vim.window";
5761 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005762 WindowType.tp_dealloc = (destructor)WindowDestructor;
5763 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005764 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005765 WindowType.tp_doc = "vim Window object";
5766 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005767 WindowType.tp_traverse = (traverseproc)WindowTraverse;
5768 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005769#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005770 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
5771 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005772 WindowType.tp_alloc = call_PyType_GenericAlloc;
5773 WindowType.tp_new = call_PyType_GenericNew;
5774 WindowType.tp_free = call_PyObject_Free;
5775#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005776 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
5777 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005778#endif
5779
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005780 vim_memset(&TabPageType, 0, sizeof(TabPageType));
5781 TabPageType.tp_name = "vim.tabpage";
5782 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005783 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
5784 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005785 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
5786 TabPageType.tp_doc = "vim tab page object";
5787 TabPageType.tp_methods = TabPageMethods;
5788#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005789 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005790 TabPageType.tp_alloc = call_PyType_GenericAlloc;
5791 TabPageType.tp_new = call_PyType_GenericNew;
5792 TabPageType.tp_free = call_PyObject_Free;
5793#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005794 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005795#endif
5796
Bram Moolenaardfa38d42013-05-15 13:38:47 +02005797 vim_memset(&BufMapType, 0, sizeof(BufMapType));
5798 BufMapType.tp_name = "vim.bufferlist";
5799 BufMapType.tp_basicsize = sizeof(BufMapObject);
5800 BufMapType.tp_as_mapping = &BufMapAsMapping;
5801 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005802 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005803 BufferType.tp_doc = "vim buffer list";
5804
5805 vim_memset(&WinListType, 0, sizeof(WinListType));
5806 WinListType.tp_name = "vim.windowlist";
5807 WinListType.tp_basicsize = sizeof(WinListType);
5808 WinListType.tp_as_sequence = &WinListAsSeq;
5809 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
5810 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005811 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005812
5813 vim_memset(&TabListType, 0, sizeof(TabListType));
5814 TabListType.tp_name = "vim.tabpagelist";
5815 TabListType.tp_basicsize = sizeof(TabListType);
5816 TabListType.tp_as_sequence = &TabListAsSeq;
5817 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
5818 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005819
5820 vim_memset(&RangeType, 0, sizeof(RangeType));
5821 RangeType.tp_name = "vim.range";
5822 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005823 RangeType.tp_dealloc = (destructor)RangeDestructor;
5824 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005825 RangeType.tp_as_sequence = &RangeAsSeq;
5826 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005827 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005828 RangeType.tp_doc = "vim Range object";
5829 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02005830 RangeType.tp_traverse = (traverseproc)RangeTraverse;
5831 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005832#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005833 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005834 RangeType.tp_alloc = call_PyType_GenericAlloc;
5835 RangeType.tp_new = call_PyType_GenericNew;
5836 RangeType.tp_free = call_PyObject_Free;
5837#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005838 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005839#endif
5840
5841 vim_memset(&CurrentType, 0, sizeof(CurrentType));
5842 CurrentType.tp_name = "vim.currentdata";
5843 CurrentType.tp_basicsize = sizeof(CurrentObject);
5844 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
5845 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005846 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005847#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005848 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
5849 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005850#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005851 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
5852 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005853#endif
5854
5855 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
5856 DictionaryType.tp_name = "vim.dictionary";
5857 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005858 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005859 DictionaryType.tp_as_sequence = &DictionaryAsSeq;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005860 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005861 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005862 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
5863 DictionaryType.tp_methods = DictionaryMethods;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005864 DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
5865 DictionaryType.tp_new = (newfunc)DictionaryConstructor;
5866 DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005867#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005868 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
5869 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005870#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005871 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
5872 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005873#endif
5874
5875 vim_memset(&ListType, 0, sizeof(ListType));
5876 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005877 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005878 ListType.tp_basicsize = sizeof(ListObject);
5879 ListType.tp_as_sequence = &ListAsSeq;
5880 ListType.tp_as_mapping = &ListAsMapping;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005881 ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005882 ListType.tp_doc = "list pushing modifications to vim structure";
5883 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005884 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005885 ListType.tp_new = (newfunc)ListConstructor;
5886 ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005887#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005888 ListType.tp_getattro = (getattrofunc)ListGetattro;
5889 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005890#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005891 ListType.tp_getattr = (getattrfunc)ListGetattr;
5892 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005893#endif
5894
5895 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005896 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005897 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005898 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
5899 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005900 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005901 FunctionType.tp_doc = "object that calls vim function";
5902 FunctionType.tp_methods = FunctionMethods;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02005903 FunctionType.tp_repr = (reprfunc)FunctionRepr;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005904 FunctionType.tp_new = (newfunc)FunctionConstructor;
5905 FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005906#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005907 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005908#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005909 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005910#endif
5911
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005912 vim_memset(&OptionsType, 0, sizeof(OptionsType));
5913 OptionsType.tp_name = "vim.options";
5914 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005915 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005916 OptionsType.tp_doc = "object for manipulating options";
5917 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005918 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
5919 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
5920 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005921
Bram Moolenaar81c40c52013-06-12 14:41:04 +02005922 vim_memset(&LoaderType, 0, sizeof(LoaderType));
5923 LoaderType.tp_name = "vim.Loader";
5924 LoaderType.tp_basicsize = sizeof(LoaderObject);
5925 LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
5926 LoaderType.tp_doc = "vim message object";
5927 LoaderType.tp_methods = LoaderMethods;
5928 LoaderType.tp_dealloc = (destructor)LoaderDestructor;
5929
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005930#if PY_MAJOR_VERSION >= 3
5931 vim_memset(&vimmodule, 0, sizeof(vimmodule));
5932 vimmodule.m_name = "vim";
5933 vimmodule.m_doc = "Vim Python interface\n";
5934 vimmodule.m_size = -1;
5935 vimmodule.m_methods = VimMethods;
5936#endif
5937}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005938
5939#define PYTYPE_READY(type) \
5940 if (PyType_Ready(&type)) \
5941 return -1;
5942
5943 static int
Bram Moolenaarfb97f282013-07-09 17:42:46 +02005944init_types(void)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005945{
5946 PYTYPE_READY(IterType);
5947 PYTYPE_READY(BufferType);
5948 PYTYPE_READY(RangeType);
5949 PYTYPE_READY(WindowType);
5950 PYTYPE_READY(TabPageType);
5951 PYTYPE_READY(BufMapType);
5952 PYTYPE_READY(WinListType);
5953 PYTYPE_READY(TabListType);
5954 PYTYPE_READY(CurrentType);
5955 PYTYPE_READY(DictionaryType);
5956 PYTYPE_READY(ListType);
5957 PYTYPE_READY(FunctionType);
5958 PYTYPE_READY(OptionsType);
5959 PYTYPE_READY(OutputType);
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02005960 PYTYPE_READY(LoaderType);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005961 return 0;
5962}
5963
5964 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02005965init_sys_path(void)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005966{
5967 PyObject *path;
5968 PyObject *path_hook;
5969 PyObject *path_hooks;
5970
5971 if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
5972 return -1;
5973
5974 if (!(path_hooks = PySys_GetObject("path_hooks")))
5975 {
5976 PyErr_Clear();
5977 path_hooks = PyList_New(1);
5978 PyList_SET_ITEM(path_hooks, 0, path_hook);
5979 if (PySys_SetObject("path_hooks", path_hooks))
5980 {
5981 Py_DECREF(path_hooks);
5982 return -1;
5983 }
5984 Py_DECREF(path_hooks);
5985 }
5986 else if (PyList_Check(path_hooks))
5987 {
5988 if (PyList_Append(path_hooks, path_hook))
5989 {
5990 Py_DECREF(path_hook);
5991 return -1;
5992 }
5993 Py_DECREF(path_hook);
5994 }
5995 else
5996 {
5997 VimTryStart();
5998 EMSG(_("Failed to set path hook: sys.path_hooks is not a list\n"
5999 "You should now do the following:\n"
6000 "- append vim.path_hook to sys.path_hooks\n"
6001 "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
6002 VimTryEnd(); /* Discard the error */
6003 Py_DECREF(path_hook);
6004 return 0;
6005 }
6006
6007 if (!(path = PySys_GetObject("path")))
6008 {
6009 PyErr_Clear();
6010 path = PyList_New(1);
6011 Py_INCREF(vim_special_path_object);
6012 PyList_SET_ITEM(path, 0, vim_special_path_object);
6013 if (PySys_SetObject("path", path))
6014 {
6015 Py_DECREF(path);
6016 return -1;
6017 }
6018 Py_DECREF(path);
6019 }
6020 else if (PyList_Check(path))
6021 {
6022 if (PyList_Append(path, vim_special_path_object))
6023 return -1;
6024 }
6025 else
6026 {
6027 VimTryStart();
6028 EMSG(_("Failed to set path: sys.path is not a list\n"
6029 "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
6030 VimTryEnd(); /* Discard the error */
6031 }
6032
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006033 return 0;
6034}
6035
6036static BufMapObject TheBufferMap =
6037{
6038 PyObject_HEAD_INIT(&BufMapType)
6039};
6040
6041static WinListObject TheWindowList =
6042{
6043 PyObject_HEAD_INIT(&WinListType)
6044 NULL
6045};
6046
6047static CurrentObject TheCurrent =
6048{
6049 PyObject_HEAD_INIT(&CurrentType)
6050};
6051
6052static TabListObject TheTabPageList =
6053{
6054 PyObject_HEAD_INIT(&TabListType)
6055};
6056
6057static struct numeric_constant {
6058 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006059 int val;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006060} numeric_constants[] = {
6061 {"VAR_LOCKED", VAR_LOCKED},
6062 {"VAR_FIXED", VAR_FIXED},
6063 {"VAR_SCOPE", VAR_SCOPE},
6064 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
6065};
6066
6067static struct object_constant {
6068 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006069 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006070} object_constants[] = {
6071 {"buffers", (PyObject *)(void *)&TheBufferMap},
6072 {"windows", (PyObject *)(void *)&TheWindowList},
6073 {"tabpages", (PyObject *)(void *)&TheTabPageList},
6074 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02006075
6076 {"Buffer", (PyObject *)&BufferType},
6077 {"Range", (PyObject *)&RangeType},
6078 {"Window", (PyObject *)&WindowType},
6079 {"TabPage", (PyObject *)&TabPageType},
6080 {"Dictionary", (PyObject *)&DictionaryType},
6081 {"List", (PyObject *)&ListType},
6082 {"Function", (PyObject *)&FunctionType},
6083 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006084 {"_Loader", (PyObject *)&LoaderType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006085};
6086
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006087#define ADD_OBJECT(m, name, obj) \
Bram Moolenaardee2e312013-06-23 16:35:47 +02006088 if (PyModule_AddObject(m, name, obj)) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006089 return -1;
6090
6091#define ADD_CHECKED_OBJECT(m, name, obj) \
6092 { \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006093 PyObject *valObject = obj; \
6094 if (!valObject) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006095 return -1; \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006096 ADD_OBJECT(m, name, valObject); \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006097 }
6098
6099 static int
Bram Moolenaardee2e312013-06-23 16:35:47 +02006100populate_module(PyObject *m)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006101{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006102 int i;
6103 PyObject *other_module;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006104 PyObject *attr;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006105 PyObject *imp;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006106
6107 for (i = 0; i < (int)(sizeof(numeric_constants)
6108 / sizeof(struct numeric_constant));
6109 ++i)
6110 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006111 PyInt_FromLong(numeric_constants[i].val));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006112
6113 for (i = 0; i < (int)(sizeof(object_constants)
6114 / sizeof(struct object_constant));
6115 ++i)
6116 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006117 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006118
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006119 valObject = object_constants[i].valObject;
6120 Py_INCREF(valObject);
6121 ADD_OBJECT(m, object_constants[i].name, valObject);
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006122 }
6123
6124 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
6125 return -1;
6126 ADD_OBJECT(m, "error", VimError);
6127
Bram Moolenaara9922d62013-05-30 13:01:18 +02006128 ADD_CHECKED_OBJECT(m, "vars", NEW_DICTIONARY(&globvardict));
6129 ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006130 ADD_CHECKED_OBJECT(m, "options",
6131 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
Bram Moolenaarf4258302013-06-02 18:20:17 +02006132
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006133 if (!(other_module = PyImport_ImportModule("os")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006134 return -1;
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006135 ADD_OBJECT(m, "os", other_module);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006136
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006137 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006138 return -1;
6139 ADD_OBJECT(m, "_getcwd", py_getcwd)
6140
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006141 if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006142 return -1;
6143 ADD_OBJECT(m, "_chdir", py_chdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006144 if (!(attr = PyObject_GetAttrString(m, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006145 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006146 if (PyObject_SetAttrString(other_module, "chdir", attr))
6147 {
6148 Py_DECREF(attr);
6149 return -1;
6150 }
6151 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006152
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006153 if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006154 {
6155 ADD_OBJECT(m, "_fchdir", py_fchdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006156 if (!(attr = PyObject_GetAttrString(m, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006157 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006158 if (PyObject_SetAttrString(other_module, "fchdir", attr))
6159 {
6160 Py_DECREF(attr);
6161 return -1;
6162 }
6163 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006164 }
Bram Moolenaare9056b12013-06-03 20:04:48 +02006165 else
6166 PyErr_Clear();
Bram Moolenaarf4258302013-06-02 18:20:17 +02006167
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006168 if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
6169 return -1;
6170
6171 ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
6172
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006173 if (!(imp = PyImport_ImportModule("imp")))
6174 return -1;
6175
6176 if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
6177 {
6178 Py_DECREF(imp);
6179 return -1;
6180 }
6181
6182 if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
6183 {
6184 Py_DECREF(py_find_module);
6185 Py_DECREF(imp);
6186 return -1;
6187 }
6188
6189 Py_DECREF(imp);
6190
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02006191 ADD_OBJECT(m, "_find_module", py_find_module);
6192 ADD_OBJECT(m, "_load_module", py_load_module);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006193
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006194 return 0;
6195}