blob: a8188c16f4db11c4bee876e01f3b1d969e517f58 [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 Moolenaare9ba5162013-05-29 22:02:22 +02003008 PyObject *todecref;
3009
3010 if ((val = StringToChars(valObject, &todecref)))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003011 ret = set_option_value_for(key, 0, val, opt_flags,
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003012 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003013 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003014 ret = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003015 }
3016
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003017 Py_XDECREF(todecref);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003018
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003019 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003020}
3021
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003022static PyMappingMethods OptionsAsMapping = {
3023 (lenfunc) NULL,
3024 (binaryfunc) OptionsItem,
3025 (objobjargproc) OptionsAssItem,
3026};
3027
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003028/* Tabpage object
3029 */
3030
3031typedef struct
3032{
3033 PyObject_HEAD
3034 tabpage_T *tab;
3035} TabPageObject;
3036
3037static PyObject *WinListNew(TabPageObject *tabObject);
3038
3039static PyTypeObject TabPageType;
3040
3041 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003042CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003043{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003044 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003045 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003046 PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003047 return -1;
3048 }
3049
3050 return 0;
3051}
3052
3053 static PyObject *
3054TabPageNew(tabpage_T *tab)
3055{
3056 TabPageObject *self;
3057
3058 if (TAB_PYTHON_REF(tab))
3059 {
3060 self = TAB_PYTHON_REF(tab);
3061 Py_INCREF(self);
3062 }
3063 else
3064 {
3065 self = PyObject_NEW(TabPageObject, &TabPageType);
3066 if (self == NULL)
3067 return NULL;
3068 self->tab = tab;
3069 TAB_PYTHON_REF(tab) = self;
3070 }
3071
3072 return (PyObject *)(self);
3073}
3074
3075 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003076TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003077{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003078 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
3079 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003080
3081 DESTRUCTOR_FINISH(self);
3082}
3083
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003084static char *TabPageAttrs[] = {
3085 "windows", "number", "vars", "window", "valid",
3086 NULL
3087};
3088
3089 static PyObject *
3090TabPageDir(PyObject *self)
3091{
3092 return ObjectDir(self, TabPageAttrs);
3093}
3094
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003095 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003096TabPageAttrValid(TabPageObject *self, char *name)
3097{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003098 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003099
3100 if (strcmp(name, "valid") != 0)
3101 return NULL;
3102
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003103 ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
3104 Py_INCREF(ret);
3105 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003106}
3107
3108 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003109TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003110{
3111 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003112 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003113 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003114 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003115 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003116 return NEW_DICTIONARY(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003117 else if (strcmp(name, "window") == 0)
3118 {
3119 /* For current tab window.c does not bother to set or update tp_curwin
3120 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003121 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003122 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003123 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02003124 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003125 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003126 else if (strcmp(name, "__members__") == 0)
3127 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003128 return NULL;
3129}
3130
3131 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003132TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003133{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003134 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003135 return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003136 else
3137 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003138 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003139
3140 if (t == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003141 return PyString_FromFormat("<tabpage object (unknown) at %p>",
3142 (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003143 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003144 return PyString_FromFormat("<tabpage %d>", t - 1);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003145 }
3146}
3147
3148static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003149 /* name, function, calling, documentation */
3150 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
3151 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003152};
3153
3154/*
3155 * Window list object
3156 */
3157
3158static PyTypeObject TabListType;
3159static PySequenceMethods TabListAsSeq;
3160
3161typedef struct
3162{
3163 PyObject_HEAD
3164} TabListObject;
3165
3166 static PyInt
3167TabListLength(PyObject *self UNUSED)
3168{
3169 tabpage_T *tp = first_tabpage;
3170 PyInt n = 0;
3171
3172 while (tp != NULL)
3173 {
3174 ++n;
3175 tp = tp->tp_next;
3176 }
3177
3178 return n;
3179}
3180
3181 static PyObject *
3182TabListItem(PyObject *self UNUSED, PyInt n)
3183{
3184 tabpage_T *tp;
3185
3186 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3187 if (n == 0)
3188 return TabPageNew(tp);
3189
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003190 PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003191 return NULL;
3192}
3193
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +02003194/*
3195 * Window object
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003196 */
3197
3198typedef struct
3199{
3200 PyObject_HEAD
3201 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003202 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003203} WindowObject;
3204
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003205static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003206
3207 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003208CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003209{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003210 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003211 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003212 PyErr_SET_VIM(N_("attempt to refer to deleted window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003213 return -1;
3214 }
3215
3216 return 0;
3217}
3218
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003219 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003220WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02003221{
3222 /* We need to handle deletion of windows underneath us.
3223 * If we add a "w_python*_ref" field to the win_T structure,
3224 * then we can get at it in win_free() in vim. We then
3225 * need to create only ONE Python object per window - if
3226 * we try to create a second, just INCREF the existing one
3227 * and return it. The (single) Python object referring to
3228 * the window is stored in "w_python*_ref".
3229 * On a win_free() we set the Python object's win_T* field
3230 * to an invalid value. We trap all uses of a window
3231 * object, and reject them if the win_T* field is invalid.
3232 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003233 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003234 * w_python_ref and w_python3_ref fields respectively.
3235 */
3236
3237 WindowObject *self;
3238
3239 if (WIN_PYTHON_REF(win))
3240 {
3241 self = WIN_PYTHON_REF(win);
3242 Py_INCREF(self);
3243 }
3244 else
3245 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02003246 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02003247 if (self == NULL)
3248 return NULL;
3249 self->win = win;
3250 WIN_PYTHON_REF(win) = self;
3251 }
3252
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003253 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3254
Bram Moolenaar971db462013-05-12 18:44:48 +02003255 return (PyObject *)(self);
3256}
3257
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003258 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003259WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003260{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003261 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02003262 if (self->win && self->win != INVALID_WINDOW_VALUE)
3263 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003264 Py_XDECREF(((PyObject *)(self->tabObject)));
3265 PyObject_GC_Del((void *)(self));
3266}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003267
Bram Moolenaar774267b2013-05-21 20:51:59 +02003268 static int
3269WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3270{
3271 Py_VISIT(((PyObject *)(self->tabObject)));
3272 return 0;
3273}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003274
Bram Moolenaar774267b2013-05-21 20:51:59 +02003275 static int
3276WindowClear(WindowObject *self)
3277{
3278 Py_CLEAR(self->tabObject);
3279 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003280}
3281
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003282 static win_T *
3283get_firstwin(TabPageObject *tabObject)
3284{
3285 if (tabObject)
3286 {
3287 if (CheckTabPage(tabObject))
3288 return NULL;
3289 /* For current tab window.c does not bother to set or update tp_firstwin
3290 */
3291 else if (tabObject->tab == curtab)
3292 return firstwin;
3293 else
3294 return tabObject->tab->tp_firstwin;
3295 }
3296 else
3297 return firstwin;
3298}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003299static char *WindowAttrs[] = {
3300 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
3301 "tabpage", "valid",
3302 NULL
3303};
3304
3305 static PyObject *
3306WindowDir(PyObject *self)
3307{
3308 return ObjectDir(self, WindowAttrs);
3309}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003310
Bram Moolenaar971db462013-05-12 18:44:48 +02003311 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003312WindowAttrValid(WindowObject *self, char *name)
3313{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003314 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003315
3316 if (strcmp(name, "valid") != 0)
3317 return NULL;
3318
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003319 ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3320 Py_INCREF(ret);
3321 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003322}
3323
3324 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003325WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003326{
3327 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003328 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003329 else if (strcmp(name, "cursor") == 0)
3330 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003331 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003332
3333 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
3334 }
3335 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003336 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003337#ifdef FEAT_WINDOWS
3338 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003339 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003340#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003341#ifdef FEAT_VERTSPLIT
3342 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003343 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003344 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003345 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003346#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02003347 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003348 return NEW_DICTIONARY(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003349 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003350 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
3351 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02003352 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003353 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003354 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003355 return NULL;
3356 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003357 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003358 }
3359 else if (strcmp(name, "tabpage") == 0)
3360 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003361 Py_INCREF(self->tabObject);
3362 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003363 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003364 else if (strcmp(name, "__members__") == 0)
3365 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003366 else
3367 return NULL;
3368}
3369
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003370 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003371WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003372{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003373 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003374 return -1;
3375
3376 if (strcmp(name, "buffer") == 0)
3377 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003378 PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003379 return -1;
3380 }
3381 else if (strcmp(name, "cursor") == 0)
3382 {
3383 long lnum;
3384 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003385
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003386 if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003387 return -1;
3388
Bram Moolenaard6e39182013-05-21 18:30:34 +02003389 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003390 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003391 PyErr_SET_VIM(N_("cursor position outside buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003392 return -1;
3393 }
3394
3395 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003396 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003397 return -1;
3398
Bram Moolenaard6e39182013-05-21 18:30:34 +02003399 self->win->w_cursor.lnum = lnum;
3400 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003401#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02003402 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003403#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003404 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003405 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003406
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003407 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003408 return 0;
3409 }
3410 else if (strcmp(name, "height") == 0)
3411 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003412 long height;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003413 win_T *savewin;
3414
Bram Moolenaardee2e312013-06-23 16:35:47 +02003415 if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003416 return -1;
3417
3418#ifdef FEAT_GUI
3419 need_mouse_correct = TRUE;
3420#endif
3421 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003422 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003423
3424 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003425 win_setheight((int) height);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003426 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003427 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003428 return -1;
3429
3430 return 0;
3431 }
3432#ifdef FEAT_VERTSPLIT
3433 else if (strcmp(name, "width") == 0)
3434 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003435 long width;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003436 win_T *savewin;
3437
Bram Moolenaardee2e312013-06-23 16:35:47 +02003438 if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003439 return -1;
3440
3441#ifdef FEAT_GUI
3442 need_mouse_correct = TRUE;
3443#endif
3444 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003445 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003446
3447 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003448 win_setwidth((int) width);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003449 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003450 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003451 return -1;
3452
3453 return 0;
3454 }
3455#endif
3456 else
3457 {
3458 PyErr_SetString(PyExc_AttributeError, name);
3459 return -1;
3460 }
3461}
3462
3463 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003464WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003465{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003466 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003467 return PyString_FromFormat("<window object (deleted) at %p>", (self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003468 else
3469 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003470 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003471
Bram Moolenaar6d216452013-05-12 19:00:41 +02003472 if (w == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003473 return PyString_FromFormat("<window object (unknown) at %p>",
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003474 (self));
3475 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003476 return PyString_FromFormat("<window %d>", w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003477 }
3478}
3479
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003480static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003481 /* name, function, calling, documentation */
3482 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
3483 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003484};
3485
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003486/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003487 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003488 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003489
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003490static PyTypeObject WinListType;
3491static PySequenceMethods WinListAsSeq;
3492
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003493typedef struct
3494{
3495 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003496 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003497} WinListObject;
3498
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003499 static PyObject *
3500WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003501{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003502 WinListObject *self;
3503
3504 self = PyObject_NEW(WinListObject, &WinListType);
3505 self->tabObject = tabObject;
3506 Py_INCREF(tabObject);
3507
3508 return (PyObject *)(self);
3509}
3510
3511 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003512WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003513{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003514 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003515
3516 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02003517 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003518 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02003519 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003520
3521 DESTRUCTOR_FINISH(self);
3522}
3523
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003524 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003525WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003526{
3527 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003528 PyInt n = 0;
3529
Bram Moolenaard6e39182013-05-21 18:30:34 +02003530 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003531 return -1;
3532
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003533 while (w != NULL)
3534 {
3535 ++n;
3536 w = W_NEXT(w);
3537 }
3538
3539 return n;
3540}
3541
3542 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003543WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003544{
3545 win_T *w;
3546
Bram Moolenaard6e39182013-05-21 18:30:34 +02003547 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003548 return NULL;
3549
3550 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003551 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003552 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003553
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003554 PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003555 return NULL;
3556}
3557
3558/* Convert a Python string into a Vim line.
3559 *
3560 * The result is in allocated memory. All internal nulls are replaced by
3561 * newline characters. It is an error for the string to contain newline
3562 * characters.
3563 *
3564 * On errors, the Python exception data is set, and NULL is returned.
3565 */
3566 static char *
3567StringToLine(PyObject *obj)
3568{
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003569 char *str;
3570 char *save;
3571 PyObject *bytes = NULL;
Bram Moolenaardee2e312013-06-23 16:35:47 +02003572 Py_ssize_t len = 0;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003573 PyInt i;
3574 char *p;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003575
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003576 if (PyBytes_Check(obj))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003577 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003578 if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
3579 || str == NULL)
3580 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003581 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003582 else if (PyUnicode_Check(obj))
3583 {
3584 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
3585 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003586
Bram Moolenaardaa27022013-06-24 22:33:30 +02003587 if (PyBytes_AsStringAndSize(bytes, &str, &len) == -1
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003588 || str == NULL)
3589 {
3590 Py_DECREF(bytes);
3591 return NULL;
3592 }
3593 }
Bram Moolenaardaa27022013-06-24 22:33:30 +02003594 else
3595 {
3596#if PY_MAJOR_VERSION < 3
3597 PyErr_FORMAT(PyExc_TypeError,
3598 N_("expected str() or unicode() instance, but got %s"),
3599 Py_TYPE_NAME(obj));
3600#else
3601 PyErr_FORMAT(PyExc_TypeError,
3602 N_("expected bytes() or str() instance, but got %s"),
3603 Py_TYPE_NAME(obj));
3604#endif
3605 return NULL;
3606 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003607
3608 /*
3609 * Error checking: String must not contain newlines, as we
3610 * are replacing a single line, and we must replace it with
3611 * a single line.
3612 * A trailing newline is removed, so that append(f.readlines()) works.
3613 */
3614 p = memchr(str, '\n', len);
3615 if (p != NULL)
3616 {
3617 if (p == str + len - 1)
3618 --len;
3619 else
3620 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003621 PyErr_SET_VIM(N_("string cannot contain newlines"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02003622 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003623 return NULL;
3624 }
3625 }
3626
3627 /* Create a copy of the string, with internal nulls replaced by
3628 * newline characters, as is the vim convention.
3629 */
3630 save = (char *)alloc((unsigned)(len+1));
3631 if (save == NULL)
3632 {
3633 PyErr_NoMemory();
Bram Moolenaar841fbd22013-06-23 14:37:07 +02003634 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003635 return NULL;
3636 }
3637
3638 for (i = 0; i < len; ++i)
3639 {
3640 if (str[i] == '\0')
3641 save[i] = '\n';
3642 else
3643 save[i] = str[i];
3644 }
3645
3646 save[i] = '\0';
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003647 Py_XDECREF(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003648
3649 return save;
3650}
3651
3652/* Get a line from the specified buffer. The line number is
3653 * in Vim format (1-based). The line is returned as a Python
3654 * string object.
3655 */
3656 static PyObject *
3657GetBufferLine(buf_T *buf, PyInt n)
3658{
3659 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
3660}
3661
3662
3663/* Get a list of lines from the specified buffer. The line numbers
3664 * are in Vim format (1-based). The range is from lo up to, but not
3665 * including, hi. The list is returned as a Python list of string objects.
3666 */
3667 static PyObject *
3668GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
3669{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003670 PyInt i;
3671 PyInt n = hi - lo;
3672 PyObject *list = PyList_New(n);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003673
3674 if (list == NULL)
3675 return NULL;
3676
3677 for (i = 0; i < n; ++i)
3678 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003679 PyObject *string = LineToString(
3680 (char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003681
3682 /* Error check - was the Python string creation OK? */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003683 if (string == NULL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003684 {
3685 Py_DECREF(list);
3686 return NULL;
3687 }
3688
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003689 PyList_SET_ITEM(list, i, string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003690 }
3691
3692 /* The ownership of the Python list is passed to the caller (ie,
3693 * the caller should Py_DECREF() the object when it is finished
3694 * with it).
3695 */
3696
3697 return list;
3698}
3699
3700/*
3701 * Check if deleting lines made the cursor position invalid.
3702 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
3703 * deleted).
3704 */
3705 static void
3706py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
3707{
3708 if (curwin->w_cursor.lnum >= lo)
3709 {
3710 /* Adjust the cursor position if it's in/after the changed
3711 * lines. */
3712 if (curwin->w_cursor.lnum >= hi)
3713 {
3714 curwin->w_cursor.lnum += extra;
3715 check_cursor_col();
3716 }
3717 else if (extra < 0)
3718 {
3719 curwin->w_cursor.lnum = lo;
3720 check_cursor();
3721 }
3722 else
3723 check_cursor_col();
3724 changed_cline_bef_curs();
3725 }
3726 invalidate_botline();
3727}
3728
Bram Moolenaar19e60942011-06-19 00:27:51 +02003729/*
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003730 * Find a window that contains "buf" and switch to it.
3731 * If there is no such window, use the current window and change "curbuf".
3732 * Caller must initialize save_curbuf to NULL.
3733 * restore_win_for_buf() MUST be called later!
3734 */
3735 static void
3736switch_to_win_for_buf(
3737 buf_T *buf,
3738 win_T **save_curwinp,
3739 tabpage_T **save_curtabp,
3740 buf_T **save_curbufp)
3741{
3742 win_T *wp;
3743 tabpage_T *tp;
3744
3745 if (find_win_for_buf(buf, &wp, &tp) == FAIL
3746 || switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL)
3747 switch_buffer(save_curbufp, buf);
3748}
3749
3750 static void
3751restore_win_for_buf(
3752 win_T *save_curwin,
3753 tabpage_T *save_curtab,
3754 buf_T *save_curbuf)
3755{
3756 if (save_curbuf == NULL)
3757 restore_win(save_curwin, save_curtab, TRUE);
3758 else
3759 restore_buffer(save_curbuf);
3760}
3761
3762/*
Bram Moolenaar19e60942011-06-19 00:27:51 +02003763 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003764 * in Vim format (1-based). The replacement line is given as
3765 * a Python string object. The object is checked for validity
3766 * and correct format. Errors are returned as a value of FAIL.
3767 * The return value is OK on success.
3768 * If OK is returned and len_change is not NULL, *len_change
3769 * is set to the change in the buffer length.
3770 */
3771 static int
3772SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
3773{
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003774 buf_T *save_curbuf = NULL;
3775 win_T *save_curwin = NULL;
3776 tabpage_T *save_curtab = NULL;
3777
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003778 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003779 * There are three cases:
3780 * 1. NULL, or None - this is a deletion.
3781 * 2. A string - this is a replacement.
3782 * 3. Anything else - this is an error.
3783 */
3784 if (line == Py_None || line == NULL)
3785 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003786 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003787 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003788
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003789 VimTryStart();
3790
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003791 if (u_savedel((linenr_T)n, 1L) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003792 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003793 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003794 RAISE_DELETE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003795 else
3796 {
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003797 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003798 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003799 if (save_curbuf == NULL)
3800 /* Only adjust marks if we managed to switch to a window that
3801 * holds the buffer, otherwise line numbers will be invalid. */
3802 deleted_lines_mark((linenr_T)n, 1L);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003803 }
3804
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003805 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003806
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003807 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003808 return FAIL;
3809
3810 if (len_change)
3811 *len_change = -1;
3812
3813 return OK;
3814 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003815 else if (PyBytes_Check(line) || PyUnicode_Check(line))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003816 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003817 char *save = StringToLine(line);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003818
3819 if (save == NULL)
3820 return FAIL;
3821
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003822 VimTryStart();
3823
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003824 /* We do not need to free "save" if ml_replace() consumes it. */
3825 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003826 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003827
3828 if (u_savesub((linenr_T)n) == FAIL)
3829 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003830 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003831 vim_free(save);
3832 }
3833 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
3834 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003835 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003836 vim_free(save);
3837 }
3838 else
3839 changed_bytes((linenr_T)n, 0);
3840
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003841 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003842
3843 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003844 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003845 check_cursor_col();
3846
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003847 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003848 return FAIL;
3849
3850 if (len_change)
3851 *len_change = 0;
3852
3853 return OK;
3854 }
3855 else
3856 {
3857 PyErr_BadArgument();
3858 return FAIL;
3859 }
3860}
3861
Bram Moolenaar19e60942011-06-19 00:27:51 +02003862/* Replace a range of lines in the specified buffer. The line numbers are in
3863 * Vim format (1-based). The range is from lo up to, but not including, hi.
3864 * The replacement lines are given as a Python list of string objects. The
3865 * list is checked for validity and correct format. Errors are returned as a
3866 * value of FAIL. The return value is OK on success.
3867 * If OK is returned and len_change is not NULL, *len_change
3868 * is set to the change in the buffer length.
3869 */
3870 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003871SetBufferLineList(
3872 buf_T *buf,
3873 PyInt lo,
3874 PyInt hi,
3875 PyObject *list,
3876 PyInt *len_change)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003877{
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003878 buf_T *save_curbuf = NULL;
3879 win_T *save_curwin = NULL;
3880 tabpage_T *save_curtab = NULL;
3881
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003882 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02003883 * There are three cases:
3884 * 1. NULL, or None - this is a deletion.
3885 * 2. A list - this is a replacement.
3886 * 3. Anything else - this is an error.
3887 */
3888 if (list == Py_None || list == NULL)
3889 {
3890 PyInt i;
3891 PyInt n = (int)(hi - lo);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003892
3893 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003894 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003895 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003896
3897 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003898 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003899 else
3900 {
3901 for (i = 0; i < n; ++i)
3902 {
3903 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3904 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003905 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003906 break;
3907 }
3908 }
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003909 if (buf == curbuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003910 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003911 if (save_curbuf == NULL)
3912 /* Only adjust marks if we managed to switch to a window that
3913 * holds the buffer, otherwise line numbers will be invalid. */
3914 deleted_lines_mark((linenr_T)lo, (long)i);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003915 }
3916
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003917 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003918
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003919 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02003920 return FAIL;
3921
3922 if (len_change)
3923 *len_change = -n;
3924
3925 return OK;
3926 }
3927 else if (PyList_Check(list))
3928 {
3929 PyInt i;
3930 PyInt new_len = PyList_Size(list);
3931 PyInt old_len = hi - lo;
3932 PyInt extra = 0; /* lines added to text, can be negative */
3933 char **array;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003934
3935 if (new_len == 0) /* avoid allocating zero bytes */
3936 array = NULL;
3937 else
3938 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003939 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003940 if (array == NULL)
3941 {
3942 PyErr_NoMemory();
3943 return FAIL;
3944 }
3945 }
3946
3947 for (i = 0; i < new_len; ++i)
3948 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003949 PyObject *line;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003950
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003951 if (!(line = PyList_GetItem(list, i)) ||
3952 !(array[i] = StringToLine(line)))
Bram Moolenaar19e60942011-06-19 00:27:51 +02003953 {
3954 while (i)
3955 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003956 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003957 return FAIL;
3958 }
3959 }
3960
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003961 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02003962 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003963
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003964 /* START of region without "return". Must call restore_buffer()! */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02003965 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003966
3967 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003968 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003969
3970 /* If the size of the range is reducing (ie, new_len < old_len) we
3971 * need to delete some old_len. We do this at the start, by
3972 * repeatedly deleting line "lo".
3973 */
3974 if (!PyErr_Occurred())
3975 {
3976 for (i = 0; i < old_len - new_len; ++i)
3977 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3978 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003979 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003980 break;
3981 }
3982 extra -= i;
3983 }
3984
3985 /* For as long as possible, replace the existing old_len with the
3986 * new old_len. This is a more efficient operation, as it requires
3987 * less memory allocation and freeing.
3988 */
3989 if (!PyErr_Occurred())
3990 {
3991 for (i = 0; i < old_len && i < new_len; ++i)
3992 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
3993 == FAIL)
3994 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003995 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003996 break;
3997 }
3998 }
3999 else
4000 i = 0;
4001
4002 /* Now we may need to insert the remaining new old_len. If we do, we
4003 * must free the strings as we finish with them (we can't pass the
4004 * responsibility to vim in this case).
4005 */
4006 if (!PyErr_Occurred())
4007 {
4008 while (i < new_len)
4009 {
4010 if (ml_append((linenr_T)(lo + i - 1),
4011 (char_u *)array[i], 0, FALSE) == FAIL)
4012 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004013 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004014 break;
4015 }
4016 vim_free(array[i]);
4017 ++i;
4018 ++extra;
4019 }
4020 }
4021
4022 /* Free any left-over old_len, as a result of an error */
4023 while (i < new_len)
4024 {
4025 vim_free(array[i]);
4026 ++i;
4027 }
4028
4029 /* Free the array of old_len. All of its contents have now
4030 * been dealt with (either freed, or the responsibility passed
4031 * to vim.
4032 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004033 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004034
4035 /* Adjust marks. Invalidate any which lie in the
4036 * changed range, and move any in the remainder of the buffer.
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004037 * Only adjust marks if we managed to switch to a window that holds
4038 * the buffer, otherwise line numbers will be invalid. */
4039 if (save_curbuf == NULL)
4040 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
Bram Moolenaar19e60942011-06-19 00:27:51 +02004041 (long)MAXLNUM, (long)extra);
4042 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
4043
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004044 if (buf == curbuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004045 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
4046
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004047 /* END of region without "return". */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004048 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004049
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004050 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02004051 return FAIL;
4052
4053 if (len_change)
4054 *len_change = new_len - old_len;
4055
4056 return OK;
4057 }
4058 else
4059 {
4060 PyErr_BadArgument();
4061 return FAIL;
4062 }
4063}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004064
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004065/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004066 * The line number is in Vim format (1-based). The lines to be inserted are
4067 * given as a Python list of string objects or as a single string. The lines
4068 * to be added are checked for validity and correct format. Errors are
4069 * returned as a value of FAIL. The return value is OK on success.
4070 * If OK is returned and len_change is not NULL, *len_change
4071 * is set to the change in the buffer length.
4072 */
4073 static int
4074InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
4075{
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004076 buf_T *save_curbuf = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004077 win_T *save_curwin = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004078 tabpage_T *save_curtab = NULL;
4079
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004080 /* First of all, we check the type of the supplied Python object.
4081 * It must be a string or a list, or the call is in error.
4082 */
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004083 if (PyBytes_Check(lines) || PyUnicode_Check(lines))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004084 {
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004085 char *str = StringToLine(lines);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004086
4087 if (str == NULL)
4088 return FAIL;
4089
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004090 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004091 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004092 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004093
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004094 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004095 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004096 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004097 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004098 else if (save_curbuf == NULL)
4099 /* Only adjust marks if we managed to switch to a window that
4100 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004101 appended_lines_mark((linenr_T)n, 1L);
4102
4103 vim_free(str);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004104 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004105 update_screen(VALID);
4106
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004107 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004108 return FAIL;
4109
4110 if (len_change)
4111 *len_change = 1;
4112
4113 return OK;
4114 }
4115 else if (PyList_Check(lines))
4116 {
4117 PyInt i;
4118 PyInt size = PyList_Size(lines);
4119 char **array;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004120
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004121 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004122 if (array == NULL)
4123 {
4124 PyErr_NoMemory();
4125 return FAIL;
4126 }
4127
4128 for (i = 0; i < size; ++i)
4129 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004130 PyObject *line;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004131
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004132 if (!(line = PyList_GetItem(lines, i)) ||
4133 !(array[i] = StringToLine(line)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004134 {
4135 while (i)
4136 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004137 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004138 return FAIL;
4139 }
4140 }
4141
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004142 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004143 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004144 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004145
4146 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004147 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004148 else
4149 {
4150 for (i = 0; i < size; ++i)
4151 {
4152 if (ml_append((linenr_T)(n + i),
4153 (char_u *)array[i], 0, FALSE) == FAIL)
4154 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004155 RAISE_INSERT_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004156
4157 /* Free the rest of the lines */
4158 while (i < size)
4159 vim_free(array[i++]);
4160
4161 break;
4162 }
4163 vim_free(array[i]);
4164 }
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004165 if (i > 0 && save_curbuf == NULL)
4166 /* Only adjust marks if we managed to switch to a window that
4167 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004168 appended_lines_mark((linenr_T)n, (long)i);
4169 }
4170
4171 /* Free the array of lines. All of its contents have now
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004172 * been freed. */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004173 PyMem_Free(array);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004174 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004175
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004176 update_screen(VALID);
4177
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004178 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004179 return FAIL;
4180
4181 if (len_change)
4182 *len_change = size;
4183
4184 return OK;
4185 }
4186 else
4187 {
4188 PyErr_BadArgument();
4189 return FAIL;
4190 }
4191}
4192
4193/*
4194 * Common routines for buffers and line ranges
4195 * -------------------------------------------
4196 */
4197
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004198typedef struct
4199{
4200 PyObject_HEAD
4201 buf_T *buf;
4202} BufferObject;
4203
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004204 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02004205CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004206{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004207 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004208 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004209 PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004210 return -1;
4211 }
4212
4213 return 0;
4214}
4215
4216 static PyObject *
4217RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4218{
4219 if (CheckBuffer(self))
4220 return NULL;
4221
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004222 if (end == -1)
4223 end = self->buf->b_ml.ml_line_count;
4224
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004225 if (n < 0)
4226 n += end - start + 1;
4227
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004228 if (n < 0 || n > end - start)
4229 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004230 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004231 return NULL;
4232 }
4233
4234 return GetBufferLine(self->buf, n+start);
4235}
4236
4237 static PyObject *
4238RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4239{
4240 PyInt size;
4241
4242 if (CheckBuffer(self))
4243 return NULL;
4244
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004245 if (end == -1)
4246 end = self->buf->b_ml.ml_line_count;
4247
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004248 size = end - start + 1;
4249
4250 if (lo < 0)
4251 lo = 0;
4252 else if (lo > size)
4253 lo = size;
4254 if (hi < 0)
4255 hi = 0;
4256 if (hi < lo)
4257 hi = lo;
4258 else if (hi > size)
4259 hi = size;
4260
4261 return GetBufferLineList(self->buf, lo+start, hi+start);
4262}
4263
4264 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004265RBAsItem(
4266 BufferObject *self,
4267 PyInt n,
4268 PyObject *valObject,
4269 PyInt start,
4270 PyInt end,
4271 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004272{
4273 PyInt len_change;
4274
4275 if (CheckBuffer(self))
4276 return -1;
4277
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004278 if (end == -1)
4279 end = self->buf->b_ml.ml_line_count;
4280
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004281 if (n < 0)
4282 n += end - start + 1;
4283
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004284 if (n < 0 || n > end - start)
4285 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004286 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004287 return -1;
4288 }
4289
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004290 if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004291 return -1;
4292
4293 if (new_end)
4294 *new_end = end + len_change;
4295
4296 return 0;
4297}
4298
Bram Moolenaar19e60942011-06-19 00:27:51 +02004299 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004300RBAsSlice(
4301 BufferObject *self,
4302 PyInt lo,
4303 PyInt hi,
4304 PyObject *valObject,
4305 PyInt start,
4306 PyInt end,
4307 PyInt *new_end)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004308{
4309 PyInt size;
4310 PyInt len_change;
4311
4312 /* Self must be a valid buffer */
4313 if (CheckBuffer(self))
4314 return -1;
4315
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004316 if (end == -1)
4317 end = self->buf->b_ml.ml_line_count;
4318
Bram Moolenaar19e60942011-06-19 00:27:51 +02004319 /* Sort out the slice range */
4320 size = end - start + 1;
4321
4322 if (lo < 0)
4323 lo = 0;
4324 else if (lo > size)
4325 lo = size;
4326 if (hi < 0)
4327 hi = 0;
4328 if (hi < lo)
4329 hi = lo;
4330 else if (hi > size)
4331 hi = size;
4332
4333 if (SetBufferLineList(self->buf, lo + start, hi + start,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004334 valObject, &len_change) == FAIL)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004335 return -1;
4336
4337 if (new_end)
4338 *new_end = end + len_change;
4339
4340 return 0;
4341}
4342
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004343
4344 static PyObject *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004345RBAppend(
4346 BufferObject *self,
4347 PyObject *args,
4348 PyInt start,
4349 PyInt end,
4350 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004351{
4352 PyObject *lines;
4353 PyInt len_change;
4354 PyInt max;
4355 PyInt n;
4356
4357 if (CheckBuffer(self))
4358 return NULL;
4359
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004360 if (end == -1)
4361 end = self->buf->b_ml.ml_line_count;
4362
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004363 max = n = end - start + 1;
4364
4365 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
4366 return NULL;
4367
4368 if (n < 0 || n > max)
4369 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004370 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004371 return NULL;
4372 }
4373
4374 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
4375 return NULL;
4376
4377 if (new_end)
4378 *new_end = end + len_change;
4379
4380 Py_INCREF(Py_None);
4381 return Py_None;
4382}
4383
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004384/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004385 */
4386
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004387static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004388static PySequenceMethods RangeAsSeq;
4389static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004390
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004391typedef struct
4392{
4393 PyObject_HEAD
4394 BufferObject *buf;
4395 PyInt start;
4396 PyInt end;
4397} RangeObject;
4398
4399 static PyObject *
4400RangeNew(buf_T *buf, PyInt start, PyInt end)
4401{
4402 BufferObject *bufr;
4403 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004404 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004405 if (self == NULL)
4406 return NULL;
4407
4408 bufr = (BufferObject *)BufferNew(buf);
4409 if (bufr == NULL)
4410 {
4411 Py_DECREF(self);
4412 return NULL;
4413 }
4414 Py_INCREF(bufr);
4415
4416 self->buf = bufr;
4417 self->start = start;
4418 self->end = end;
4419
4420 return (PyObject *)(self);
4421}
4422
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004423 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004424RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004425{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004426 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004427 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02004428 PyObject_GC_Del((void *)(self));
4429}
4430
4431 static int
4432RangeTraverse(RangeObject *self, visitproc visit, void *arg)
4433{
4434 Py_VISIT(((PyObject *)(self->buf)));
4435 return 0;
4436}
4437
4438 static int
4439RangeClear(RangeObject *self)
4440{
4441 Py_CLEAR(self->buf);
4442 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004443}
4444
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004445 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004446RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004447{
4448 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004449 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004450 return -1; /* ??? */
4451
Bram Moolenaard6e39182013-05-21 18:30:34 +02004452 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004453}
4454
4455 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004456RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004457{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004458 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004459}
4460
4461 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004462RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004463{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004464 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004465}
4466
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004467static char *RangeAttrs[] = {
4468 "start", "end",
4469 NULL
4470};
4471
4472 static PyObject *
4473RangeDir(PyObject *self)
4474{
4475 return ObjectDir(self, RangeAttrs);
4476}
4477
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004478 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004479RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004480{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004481 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004482}
4483
4484 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004485RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004486{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004487 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004488 return PyString_FromFormat("<range object (for deleted buffer) at %p>",
4489 (self));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004490 else
4491 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02004492 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004493
4494 if (name == NULL)
4495 name = "";
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004496
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004497 return PyString_FromFormat("<range %s (%d:%d)>",
Bram Moolenaarf62d9422013-05-30 19:01:24 +02004498 name, (int)self->start, (int)self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004499 }
4500}
4501
4502static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004503 /* name, function, calling, documentation */
4504 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004505 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
4506 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004507};
4508
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004509static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004510static PySequenceMethods BufferAsSeq;
4511static PyMappingMethods BufferAsMapping;
4512
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004513 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02004514BufferNew(buf_T *buf)
4515{
4516 /* We need to handle deletion of buffers underneath us.
4517 * If we add a "b_python*_ref" field to the buf_T structure,
4518 * then we can get at it in buf_freeall() in vim. We then
4519 * need to create only ONE Python object per buffer - if
4520 * we try to create a second, just INCREF the existing one
4521 * and return it. The (single) Python object referring to
4522 * the buffer is stored in "b_python*_ref".
4523 * Question: what to do on a buf_freeall(). We'll probably
4524 * have to either delete the Python object (DECREF it to
4525 * zero - a bad idea, as it leaves dangling refs!) or
4526 * set the buf_T * value to an invalid value (-1?), which
4527 * means we need checks in all access functions... Bah.
4528 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004529 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02004530 * b_python_ref and b_python3_ref fields respectively.
4531 */
4532
4533 BufferObject *self;
4534
4535 if (BUF_PYTHON_REF(buf) != NULL)
4536 {
4537 self = BUF_PYTHON_REF(buf);
4538 Py_INCREF(self);
4539 }
4540 else
4541 {
4542 self = PyObject_NEW(BufferObject, &BufferType);
4543 if (self == NULL)
4544 return NULL;
4545 self->buf = buf;
4546 BUF_PYTHON_REF(buf) = self;
4547 }
4548
4549 return (PyObject *)(self);
4550}
4551
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004552 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004553BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004554{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004555 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
4556 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004557
4558 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004559}
4560
Bram Moolenaar971db462013-05-12 18:44:48 +02004561 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004562BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02004563{
4564 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004565 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02004566 return -1; /* ??? */
4567
Bram Moolenaard6e39182013-05-21 18:30:34 +02004568 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02004569}
4570
4571 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004572BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02004573{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004574 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004575}
4576
4577 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004578BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02004579{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004580 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004581}
4582
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004583static char *BufferAttrs[] = {
4584 "name", "number", "vars", "options", "valid",
4585 NULL
4586};
4587
4588 static PyObject *
4589BufferDir(PyObject *self)
4590{
4591 return ObjectDir(self, BufferAttrs);
4592}
4593
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004594 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004595BufferAttrValid(BufferObject *self, char *name)
4596{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004597 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004598
4599 if (strcmp(name, "valid") != 0)
4600 return NULL;
4601
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004602 ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
4603 Py_INCREF(ret);
4604 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004605}
4606
4607 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004608BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004609{
4610 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02004611 return PyString_FromString((self->buf->b_ffname == NULL
Bram Moolenaar41009372013-07-01 22:03:04 +02004612 ? "" : (char *)self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004613 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004614 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004615 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02004616 return NEW_DICTIONARY(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004617 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004618 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
4619 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004620 else if (strcmp(name, "__members__") == 0)
4621 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004622 else
4623 return NULL;
4624}
4625
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004626 static int
4627BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
4628{
4629 if (CheckBuffer(self))
4630 return -1;
4631
4632 if (strcmp(name, "name") == 0)
4633 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004634 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004635 aco_save_T aco;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004636 int ren_ret;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004637 PyObject *todecref;
4638
4639 if (!(val = StringToChars(valObject, &todecref)))
4640 return -1;
4641
4642 VimTryStart();
4643 /* Using aucmd_*: autocommands will be executed by rename_buffer */
4644 aucmd_prepbuf(&aco, self->buf);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004645 ren_ret = rename_buffer(val);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004646 aucmd_restbuf(&aco);
4647 Py_XDECREF(todecref);
4648 if (VimTryEnd())
4649 return -1;
4650
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004651 if (ren_ret == FAIL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004652 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004653 PyErr_SET_VIM(N_("failed to rename buffer"));
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004654 return -1;
4655 }
4656 return 0;
4657 }
4658 else
4659 {
4660 PyErr_SetString(PyExc_AttributeError, name);
4661 return -1;
4662 }
4663}
4664
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004665 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004666BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004667{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004668 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004669}
4670
4671 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02004672BufferMark(BufferObject *self, PyObject *pmarkObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004673{
4674 pos_T *posp;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004675 char_u *pmark;
4676 char_u mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02004677 buf_T *savebuf;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004678 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004679
Bram Moolenaard6e39182013-05-21 18:30:34 +02004680 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004681 return NULL;
4682
Bram Moolenaar389a1792013-06-23 13:00:44 +02004683 if (!(pmark = StringToChars(pmarkObject, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004684 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004685
Bram Moolenaar389a1792013-06-23 13:00:44 +02004686 if (pmark[0] == '\0' || pmark[1] != '\0')
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004687 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004688 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004689 N_("mark name must be a single character"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02004690 Py_XDECREF(todecref);
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004691 return NULL;
4692 }
4693
4694 mark = *pmark;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004695
4696 Py_XDECREF(todecref);
4697
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004698 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02004699 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004700 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02004701 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004702 if (VimTryEnd())
4703 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004704
4705 if (posp == NULL)
4706 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004707 PyErr_SET_VIM(N_("invalid mark name"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004708 return NULL;
4709 }
4710
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004711 if (posp->lnum <= 0)
4712 {
4713 /* Or raise an error? */
4714 Py_INCREF(Py_None);
4715 return Py_None;
4716 }
4717
4718 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
4719}
4720
4721 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004722BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004723{
4724 PyInt start;
4725 PyInt end;
4726
Bram Moolenaard6e39182013-05-21 18:30:34 +02004727 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004728 return NULL;
4729
4730 if (!PyArg_ParseTuple(args, "nn", &start, &end))
4731 return NULL;
4732
Bram Moolenaard6e39182013-05-21 18:30:34 +02004733 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004734}
4735
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004736 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004737BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004738{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004739 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004740 return PyString_FromFormat("<buffer object (deleted) at %p>", self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004741 else
4742 {
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004743 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004744
4745 if (name == NULL)
4746 name = "";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004747
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004748 return PyString_FromFormat("<buffer %s>", name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004749 }
4750}
4751
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004752static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004753 /* name, function, calling, documentation */
4754 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02004755 {"mark", (PyCFunction)BufferMark, METH_O, "Return (row,col) representing position of named mark" },
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004756 {"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 +02004757 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
4758 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004759};
4760
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004761/*
4762 * Buffer list object - Implementation
4763 */
4764
4765static PyTypeObject BufMapType;
4766
4767typedef struct
4768{
4769 PyObject_HEAD
4770} BufMapObject;
4771
4772 static PyInt
4773BufMapLength(PyObject *self UNUSED)
4774{
4775 buf_T *b = firstbuf;
4776 PyInt n = 0;
4777
4778 while (b)
4779 {
4780 ++n;
4781 b = b->b_next;
4782 }
4783
4784 return n;
4785}
4786
4787 static PyObject *
4788BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
4789{
4790 buf_T *b;
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004791 long bnr;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004792
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004793 if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004794 return NULL;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004795
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004796 b = buflist_findnr((int) bnr);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004797
4798 if (b)
4799 return BufferNew(b);
4800 else
4801 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02004802 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004803 return NULL;
4804 }
4805}
4806
4807 static void
4808BufMapIterDestruct(PyObject *buffer)
4809{
4810 /* Iteration was stopped before all buffers were processed */
4811 if (buffer)
4812 {
4813 Py_DECREF(buffer);
4814 }
4815}
4816
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004817 static int
4818BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
4819{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004820 if (buffer)
4821 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004822 return 0;
4823}
4824
4825 static int
4826BufMapIterClear(PyObject **buffer)
4827{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004828 if (*buffer)
4829 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004830 return 0;
4831}
4832
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004833 static PyObject *
4834BufMapIterNext(PyObject **buffer)
4835{
4836 PyObject *next;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004837 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004838
4839 if (!*buffer)
4840 return NULL;
4841
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004842 ret = *buffer;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004843
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004844 if (CheckBuffer((BufferObject *)(ret)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004845 {
4846 *buffer = NULL;
4847 return NULL;
4848 }
4849
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004850 if (!((BufferObject *)(ret))->buf->b_next)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004851 next = NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004852 else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004853 return NULL;
4854 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02004855 /* Do not increment reference: we no longer hold it (decref), but whoever
4856 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004857 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004858}
4859
4860 static PyObject *
4861BufMapIter(PyObject *self UNUSED)
4862{
4863 PyObject *buffer;
4864
4865 buffer = BufferNew(firstbuf);
4866 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004867 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
4868 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004869}
4870
4871static PyMappingMethods BufMapAsMapping = {
4872 (lenfunc) BufMapLength,
4873 (binaryfunc) BufMapItem,
4874 (objobjargproc) 0,
4875};
4876
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004877/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004878 */
4879
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004880static char *CurrentAttrs[] = {
4881 "buffer", "window", "line", "range", "tabpage",
4882 NULL
4883};
4884
4885 static PyObject *
4886CurrentDir(PyObject *self)
4887{
4888 return ObjectDir(self, CurrentAttrs);
4889}
4890
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004891 static PyObject *
4892CurrentGetattr(PyObject *self UNUSED, char *name)
4893{
4894 if (strcmp(name, "buffer") == 0)
4895 return (PyObject *)BufferNew(curbuf);
4896 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02004897 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004898 else if (strcmp(name, "tabpage") == 0)
4899 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004900 else if (strcmp(name, "line") == 0)
4901 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
4902 else if (strcmp(name, "range") == 0)
4903 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004904 else if (strcmp(name, "__members__") == 0)
4905 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004906 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004907#if PY_MAJOR_VERSION < 3
4908 return Py_FindMethod(WindowMethods, self, name);
4909#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004910 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004911#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004912}
4913
4914 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004915CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004916{
4917 if (strcmp(name, "line") == 0)
4918 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004919 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
4920 NULL) == FAIL)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004921 return -1;
4922
4923 return 0;
4924 }
Bram Moolenaare7614592013-05-15 15:51:08 +02004925 else if (strcmp(name, "buffer") == 0)
4926 {
4927 int count;
4928
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004929 if (valObject->ob_type != &BufferType)
Bram Moolenaare7614592013-05-15 15:51:08 +02004930 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004931 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004932 N_("expected vim.Buffer object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004933 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02004934 return -1;
4935 }
4936
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004937 if (CheckBuffer((BufferObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02004938 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004939 count = ((BufferObject *)(valObject))->buf->b_fnum;
Bram Moolenaare7614592013-05-15 15:51:08 +02004940
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004941 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004942 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
4943 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004944 if (VimTryEnd())
4945 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004946 PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
Bram Moolenaare7614592013-05-15 15:51:08 +02004947 return -1;
4948 }
4949
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004950 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004951 }
4952 else if (strcmp(name, "window") == 0)
4953 {
4954 int count;
4955
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004956 if (valObject->ob_type != &WindowType)
Bram Moolenaare7614592013-05-15 15:51:08 +02004957 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004958 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004959 N_("expected vim.Window object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004960 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02004961 return -1;
4962 }
4963
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004964 if (CheckWindow((WindowObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02004965 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004966 count = get_win_number(((WindowObject *)(valObject))->win, firstwin);
Bram Moolenaare7614592013-05-15 15:51:08 +02004967
4968 if (!count)
4969 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004970 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004971 N_("failed to find window in the current tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004972 return -1;
4973 }
4974
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004975 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004976 win_goto(((WindowObject *)(valObject))->win);
4977 if (((WindowObject *)(valObject))->win != curwin)
Bram Moolenaare7614592013-05-15 15:51:08 +02004978 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004979 if (VimTryEnd())
4980 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004981 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004982 N_("did not switch to the specified window"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004983 return -1;
4984 }
4985
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004986 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004987 }
4988 else if (strcmp(name, "tabpage") == 0)
4989 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004990 if (valObject->ob_type != &TabPageType)
Bram Moolenaare7614592013-05-15 15:51:08 +02004991 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004992 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004993 N_("expected vim.TabPage object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004994 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02004995 return -1;
4996 }
4997
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004998 if (CheckTabPage((TabPageObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02004999 return -1;
5000
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005001 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005002 goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
5003 if (((TabPageObject *)(valObject))->tab != curtab)
Bram Moolenaare7614592013-05-15 15:51:08 +02005004 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005005 if (VimTryEnd())
5006 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005007 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005008 N_("did not switch to the specified tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005009 return -1;
5010 }
5011
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005012 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005013 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005014 else
5015 {
5016 PyErr_SetString(PyExc_AttributeError, name);
5017 return -1;
5018 }
5019}
5020
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005021static struct PyMethodDef CurrentMethods[] = {
5022 /* name, function, calling, documentation */
5023 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
5024 { NULL, NULL, 0, NULL}
5025};
5026
Bram Moolenaardb913952012-06-29 12:54:53 +02005027 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005028init_range_cmd(exarg_T *eap)
5029{
5030 RangeStart = eap->line1;
5031 RangeEnd = eap->line2;
5032}
5033
5034 static void
5035init_range_eval(typval_T *rettv UNUSED)
5036{
5037 RangeStart = (PyInt) curwin->w_cursor.lnum;
5038 RangeEnd = RangeStart;
5039}
5040
5041 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005042run_cmd(const char *cmd, void *arg UNUSED
5043#ifdef PY_CAN_RECURSE
5044 , PyGILState_STATE *pygilstate UNUSED
5045#endif
5046 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005047{
Bram Moolenaar41009372013-07-01 22:03:04 +02005048 PyObject *run_ret;
5049 run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
5050 if (run_ret != NULL)
5051 {
5052 Py_DECREF(run_ret);
5053 }
5054 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5055 {
5056 EMSG2(_(e_py_systemexit), "python");
5057 PyErr_Clear();
5058 }
5059 else
5060 PyErr_PrintEx(1);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005061}
5062
5063static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
5064static int code_hdr_len = 30;
5065
5066 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005067run_do(const char *cmd, void *arg UNUSED
5068#ifdef PY_CAN_RECURSE
5069 , PyGILState_STATE *pygilstate
5070#endif
5071 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005072{
5073 PyInt lnum;
5074 size_t len;
5075 char *code;
5076 int status;
5077 PyObject *pyfunc, *pymain;
Bram Moolenaar41009372013-07-01 22:03:04 +02005078 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005079
Bram Moolenaar4ac66762013-05-28 22:31:46 +02005080 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005081 {
5082 EMSG(_("cannot save undo information"));
5083 return;
5084 }
5085
5086 len = code_hdr_len + STRLEN(cmd);
5087 code = PyMem_New(char, len + 1);
5088 memcpy(code, code_hdr, code_hdr_len);
5089 STRCPY(code + code_hdr_len, cmd);
Bram Moolenaar41009372013-07-01 22:03:04 +02005090 run_ret = PyRun_String(code, Py_file_input, globals, globals);
5091 status = -1;
5092 if (run_ret != NULL)
5093 {
5094 status = 0;
5095 Py_DECREF(run_ret);
5096 }
5097 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5098 {
5099 PyMem_Free(code);
5100 EMSG2(_(e_py_systemexit), "python");
5101 PyErr_Clear();
5102 return;
5103 }
5104 else
5105 PyErr_PrintEx(1);
5106
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005107 PyMem_Free(code);
5108
5109 if (status)
5110 {
5111 EMSG(_("failed to run the code"));
5112 return;
5113 }
5114
5115 status = 0;
5116 pymain = PyImport_AddModule("__main__");
5117 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005118#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005119 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005120#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005121
5122 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
5123 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005124 PyObject *line;
5125 PyObject *linenr;
5126 PyObject *ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005127
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005128#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005129 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005130#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005131 if (!(line = GetBufferLine(curbuf, lnum)))
5132 goto err;
5133 if (!(linenr = PyInt_FromLong((long) lnum)))
5134 {
5135 Py_DECREF(line);
5136 goto err;
5137 }
5138 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
5139 Py_DECREF(line);
5140 Py_DECREF(linenr);
5141 if (!ret)
5142 goto err;
5143
5144 if (ret != Py_None)
5145 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
5146 goto err;
5147
5148 Py_XDECREF(ret);
5149 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005150#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005151 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005152#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005153 }
5154 goto out;
5155err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005156#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005157 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005158#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005159 PyErr_PrintEx(0);
5160 PythonIO_Flush();
5161 status = 1;
5162out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005163#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005164 if (!status)
5165 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005166#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005167 Py_DECREF(pyfunc);
5168 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
5169 if (status)
5170 return;
5171 check_cursor();
5172 update_curbuf(NOT_VALID);
5173}
5174
5175 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005176run_eval(const char *cmd, typval_T *rettv
5177#ifdef PY_CAN_RECURSE
5178 , PyGILState_STATE *pygilstate UNUSED
5179#endif
5180 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005181{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005182 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005183
Bram Moolenaar41009372013-07-01 22:03:04 +02005184 run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005185 if (run_ret == NULL)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005186 {
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005187 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
Bram Moolenaar41009372013-07-01 22:03:04 +02005188 {
5189 EMSG2(_(e_py_systemexit), "python");
5190 PyErr_Clear();
5191 }
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005192 else
5193 {
5194 if (PyErr_Occurred() && !msg_silent)
5195 PyErr_PrintEx(0);
5196 EMSG(_("E858: Eval did not return a valid python object"));
5197 }
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005198 }
5199 else
5200 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005201 if (ConvertFromPyObject(run_ret, rettv) == -1)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005202 EMSG(_("E859: Failed to convert returned python object to vim value"));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005203 Py_DECREF(run_ret);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005204 }
5205 PyErr_Clear();
5206}
5207
5208 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02005209set_ref_in_py(const int copyID)
5210{
5211 pylinkedlist_T *cur;
5212 dict_T *dd;
5213 list_T *ll;
5214
5215 if (lastdict != NULL)
5216 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
5217 {
5218 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
5219 if (dd->dv_copyID != copyID)
5220 {
5221 dd->dv_copyID = copyID;
5222 set_ref_in_ht(&dd->dv_hashtab, copyID);
5223 }
5224 }
5225
5226 if (lastlist != NULL)
5227 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
5228 {
5229 ll = ((ListObject *) (cur->pll_obj))->list;
5230 if (ll->lv_copyID != copyID)
5231 {
5232 ll->lv_copyID = copyID;
5233 set_ref_in_list(ll, copyID);
5234 }
5235 }
5236}
5237
5238 static int
5239set_string_copy(char_u *str, typval_T *tv)
5240{
5241 tv->vval.v_string = vim_strsave(str);
5242 if (tv->vval.v_string == NULL)
5243 {
5244 PyErr_NoMemory();
5245 return -1;
5246 }
5247 return 0;
5248}
5249
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005250 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005251pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005252{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005253 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005254 char_u *key;
5255 dictitem_T *di;
5256 PyObject *keyObject;
5257 PyObject *valObject;
5258 Py_ssize_t iter = 0;
5259
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005260 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005261 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005262
5263 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005264 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005265
5266 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5267 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005268 PyObject *todecref = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005269
Bram Moolenaara03e6312013-05-29 22:49:26 +02005270 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005271 {
5272 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005273 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005274 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005275
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005276 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005277 {
5278 dict_unref(dict);
5279 return -1;
5280 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005281
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005282 if (*key == NUL)
5283 {
5284 dict_unref(dict);
5285 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005286 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005287 return -1;
5288 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005289
5290 di = dictitem_alloc(key);
5291
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005292 Py_XDECREF(todecref);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005293
5294 if (di == NULL)
5295 {
5296 PyErr_NoMemory();
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005297 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005298 return -1;
5299 }
5300 di->di_tv.v_lock = 0;
5301
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005302 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005303 {
5304 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005305 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005306 return -1;
5307 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005308
5309 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005310 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005311 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara03e6312013-05-29 22:49:26 +02005312 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005313 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005314 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005315 return -1;
5316 }
5317 }
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005318
5319 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005320 return 0;
5321}
5322
5323 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005324pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005325{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005326 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005327 char_u *key;
5328 dictitem_T *di;
5329 PyObject *list;
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005330 PyObject *iterator;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005331 PyObject *keyObject;
5332 PyObject *valObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005333
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005334 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005335 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005336
5337 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005338 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005339
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005340 if (!(list = PyMapping_Keys(obj)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005341 {
5342 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005343 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005344 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005345
5346 if (!(iterator = PyObject_GetIter(list)))
5347 {
5348 dict_unref(dict);
5349 Py_DECREF(list);
5350 return -1;
5351 }
5352 Py_DECREF(list);
5353
5354 while ((keyObject = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005355 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005356 PyObject *todecref;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005357
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005358 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005359 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005360 Py_DECREF(keyObject);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005361 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005362 dict_unref(dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005363 return -1;
5364 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005365
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005366 if (*key == NUL)
5367 {
5368 Py_DECREF(keyObject);
5369 Py_DECREF(iterator);
5370 Py_XDECREF(todecref);
5371 dict_unref(dict);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005372 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005373 return -1;
5374 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005375
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005376 if (!(valObject = PyObject_GetItem(obj, keyObject)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005377 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005378 Py_DECREF(keyObject);
5379 Py_DECREF(iterator);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005380 Py_XDECREF(todecref);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005381 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005382 return -1;
5383 }
5384
5385 di = dictitem_alloc(key);
5386
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005387 Py_DECREF(keyObject);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005388 Py_XDECREF(todecref);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005389
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005390 if (di == NULL)
5391 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005392 Py_DECREF(iterator);
5393 Py_DECREF(valObject);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005394 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005395 PyErr_NoMemory();
5396 return -1;
5397 }
5398 di->di_tv.v_lock = 0;
5399
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005400 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005401 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005402 Py_DECREF(iterator);
5403 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005404 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005405 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005406 return -1;
5407 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02005408
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005409 Py_DECREF(valObject);
5410
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005411 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005412 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005413 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005414 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005415 dictitem_free(di);
5416 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005417 return -1;
5418 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005419 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005420 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005421 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005422 return 0;
5423}
5424
5425 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005426pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005427{
5428 list_T *l;
5429
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005430 if (!(l = py_list_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005431 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005432
5433 tv->v_type = VAR_LIST;
5434 tv->vval.v_list = l;
5435
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005436 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005437 {
5438 list_unref(l);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005439 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005440 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005441
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005442 --l->lv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005443 return 0;
5444}
5445
Bram Moolenaardb913952012-06-29 12:54:53 +02005446typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
5447
5448 static int
5449convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005450 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005451{
5452 PyObject *capsule;
5453 char hexBuf[sizeof(void *) * 2 + 3];
5454
5455 sprintf(hexBuf, "%p", obj);
5456
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005457# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005458 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005459# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005460 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005461# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02005462 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005463 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005464# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02005465 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02005466# else
5467 capsule = PyCObject_FromVoidPtr(tv, NULL);
5468# endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02005469 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
5470 {
5471 Py_DECREF(capsule);
5472 tv->v_type = VAR_UNKNOWN;
5473 return -1;
5474 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005475
5476 Py_DECREF(capsule);
5477
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005478 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005479 {
5480 tv->v_type = VAR_UNKNOWN;
5481 return -1;
5482 }
5483 /* As we are not using copy_tv which increments reference count we must
5484 * do it ourself. */
5485 switch(tv->v_type)
5486 {
5487 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
5488 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
5489 }
5490 }
5491 else
5492 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005493 typval_T *v;
5494
5495# ifdef PY_USE_CAPSULE
5496 v = PyCapsule_GetPointer(capsule, NULL);
5497# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02005498 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005499# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02005500 copy_tv(v, tv);
5501 }
5502 return 0;
5503}
5504
5505 static int
Bram Moolenaara9922d62013-05-30 13:01:18 +02005506ConvertFromPyMapping(PyObject *obj, typval_T *tv)
5507{
5508 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005509 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005510
5511 if (!(lookup_dict = PyDict_New()))
5512 return -1;
5513
5514 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
5515 {
5516 tv->v_type = VAR_DICT;
5517 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5518 ++tv->vval.v_dict->dv_refcount;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005519 ret = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005520 }
5521 else if (PyDict_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005522 ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02005523 else if (PyMapping_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005524 ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02005525 else
5526 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005527 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005528 N_("unable to convert %s to vim dictionary"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02005529 Py_TYPE_NAME(obj));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005530 ret = -1;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005531 }
5532 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005533 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005534}
5535
5536 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02005537ConvertFromPyObject(PyObject *obj, typval_T *tv)
5538{
5539 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005540 int ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02005541
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005542 if (!(lookup_dict = PyDict_New()))
5543 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005544 ret = _ConvertFromPyObject(obj, tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005545 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005546 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02005547}
5548
5549 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005550_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005551{
Bram Moolenaara9922d62013-05-30 13:01:18 +02005552 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005553 {
5554 tv->v_type = VAR_DICT;
5555 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5556 ++tv->vval.v_dict->dv_refcount;
5557 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005558 else if (PyType_IsSubtype(obj->ob_type, &ListType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005559 {
5560 tv->v_type = VAR_LIST;
5561 tv->vval.v_list = (((ListObject *)(obj))->list);
5562 ++tv->vval.v_list->lv_refcount;
5563 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005564 else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005565 {
5566 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
5567 return -1;
5568
5569 tv->v_type = VAR_FUNC;
5570 func_ref(tv->vval.v_string);
5571 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005572 else if (PyBytes_Check(obj))
5573 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005574 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02005575
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005576 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005577 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005578 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005579 return -1;
5580
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005581 if (set_string_copy(str, tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005582 return -1;
5583
5584 tv->v_type = VAR_STRING;
5585 }
5586 else if (PyUnicode_Check(obj))
5587 {
5588 PyObject *bytes;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005589 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02005590
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02005591 bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005592 if (bytes == NULL)
5593 return -1;
5594
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005595 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005596 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005597 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005598 return -1;
5599
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005600 if (set_string_copy(str, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02005601 {
5602 Py_XDECREF(bytes);
5603 return -1;
5604 }
5605 Py_XDECREF(bytes);
5606
5607 tv->v_type = VAR_STRING;
5608 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02005609#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02005610 else if (PyInt_Check(obj))
5611 {
5612 tv->v_type = VAR_NUMBER;
5613 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005614 if (PyErr_Occurred())
5615 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005616 }
5617#endif
5618 else if (PyLong_Check(obj))
5619 {
5620 tv->v_type = VAR_NUMBER;
5621 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005622 if (PyErr_Occurred())
5623 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005624 }
5625 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005626 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005627#ifdef FEAT_FLOAT
5628 else if (PyFloat_Check(obj))
5629 {
5630 tv->v_type = VAR_FLOAT;
5631 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
5632 }
5633#endif
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005634 else if (PyObject_HasAttrString(obj, "keys"))
5635 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardee2e312013-06-23 16:35:47 +02005636 /* PyObject_GetIter can create built-in iterator for any sequence object */
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005637 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005638 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005639 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005640 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005641 else if (PyNumber_Check(obj))
5642 {
5643 PyObject *num;
5644
5645 if (!(num = PyNumber_Long(obj)))
5646 return -1;
5647
5648 tv->v_type = VAR_NUMBER;
5649 tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
5650
5651 Py_DECREF(num);
5652 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005653 else
5654 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005655 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005656 N_("unable to convert %s to vim structure"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02005657 Py_TYPE_NAME(obj));
Bram Moolenaardb913952012-06-29 12:54:53 +02005658 return -1;
5659 }
5660 return 0;
5661}
5662
5663 static PyObject *
5664ConvertToPyObject(typval_T *tv)
5665{
5666 if (tv == NULL)
5667 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005668 PyErr_SET_VIM(N_("internal error: NULL reference passed"));
Bram Moolenaardb913952012-06-29 12:54:53 +02005669 return NULL;
5670 }
5671 switch (tv->v_type)
5672 {
5673 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02005674 return PyBytes_FromString(tv->vval.v_string == NULL
5675 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02005676 case VAR_NUMBER:
5677 return PyLong_FromLong((long) tv->vval.v_number);
5678#ifdef FEAT_FLOAT
5679 case VAR_FLOAT:
5680 return PyFloat_FromDouble((double) tv->vval.v_float);
5681#endif
5682 case VAR_LIST:
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005683 return NEW_LIST(tv->vval.v_list);
Bram Moolenaardb913952012-06-29 12:54:53 +02005684 case VAR_DICT:
Bram Moolenaara9922d62013-05-30 13:01:18 +02005685 return NEW_DICTIONARY(tv->vval.v_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005686 case VAR_FUNC:
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005687 return NEW_FUNCTION(tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02005688 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02005689 case VAR_UNKNOWN:
5690 Py_INCREF(Py_None);
5691 return Py_None;
5692 default:
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005693 PyErr_SET_VIM(N_("internal error: invalid value type"));
Bram Moolenaardb913952012-06-29 12:54:53 +02005694 return NULL;
5695 }
5696}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005697
5698typedef struct
5699{
5700 PyObject_HEAD
5701} CurrentObject;
5702static PyTypeObject CurrentType;
5703
5704 static void
5705init_structs(void)
5706{
5707 vim_memset(&OutputType, 0, sizeof(OutputType));
5708 OutputType.tp_name = "vim.message";
5709 OutputType.tp_basicsize = sizeof(OutputObject);
5710 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
5711 OutputType.tp_doc = "vim message object";
5712 OutputType.tp_methods = OutputMethods;
5713#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005714 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
5715 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005716 OutputType.tp_alloc = call_PyType_GenericAlloc;
5717 OutputType.tp_new = call_PyType_GenericNew;
5718 OutputType.tp_free = call_PyObject_Free;
5719#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005720 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
5721 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005722#endif
5723
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005724 vim_memset(&IterType, 0, sizeof(IterType));
5725 IterType.tp_name = "vim.iter";
5726 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005727 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005728 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005729 IterType.tp_iter = (getiterfunc)IterIter;
5730 IterType.tp_iternext = (iternextfunc)IterNext;
5731 IterType.tp_dealloc = (destructor)IterDestructor;
5732 IterType.tp_traverse = (traverseproc)IterTraverse;
5733 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005734
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005735 vim_memset(&BufferType, 0, sizeof(BufferType));
5736 BufferType.tp_name = "vim.buffer";
5737 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005738 BufferType.tp_dealloc = (destructor)BufferDestructor;
5739 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005740 BufferType.tp_as_sequence = &BufferAsSeq;
5741 BufferType.tp_as_mapping = &BufferAsMapping;
5742 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
5743 BufferType.tp_doc = "vim buffer object";
5744 BufferType.tp_methods = BufferMethods;
5745#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005746 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005747 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005748 BufferType.tp_alloc = call_PyType_GenericAlloc;
5749 BufferType.tp_new = call_PyType_GenericNew;
5750 BufferType.tp_free = call_PyObject_Free;
5751#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005752 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005753 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005754#endif
5755
5756 vim_memset(&WindowType, 0, sizeof(WindowType));
5757 WindowType.tp_name = "vim.window";
5758 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005759 WindowType.tp_dealloc = (destructor)WindowDestructor;
5760 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005761 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005762 WindowType.tp_doc = "vim Window object";
5763 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005764 WindowType.tp_traverse = (traverseproc)WindowTraverse;
5765 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005766#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005767 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
5768 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005769 WindowType.tp_alloc = call_PyType_GenericAlloc;
5770 WindowType.tp_new = call_PyType_GenericNew;
5771 WindowType.tp_free = call_PyObject_Free;
5772#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005773 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
5774 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005775#endif
5776
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005777 vim_memset(&TabPageType, 0, sizeof(TabPageType));
5778 TabPageType.tp_name = "vim.tabpage";
5779 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005780 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
5781 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005782 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
5783 TabPageType.tp_doc = "vim tab page object";
5784 TabPageType.tp_methods = TabPageMethods;
5785#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005786 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005787 TabPageType.tp_alloc = call_PyType_GenericAlloc;
5788 TabPageType.tp_new = call_PyType_GenericNew;
5789 TabPageType.tp_free = call_PyObject_Free;
5790#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005791 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005792#endif
5793
Bram Moolenaardfa38d42013-05-15 13:38:47 +02005794 vim_memset(&BufMapType, 0, sizeof(BufMapType));
5795 BufMapType.tp_name = "vim.bufferlist";
5796 BufMapType.tp_basicsize = sizeof(BufMapObject);
5797 BufMapType.tp_as_mapping = &BufMapAsMapping;
5798 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005799 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005800 BufferType.tp_doc = "vim buffer list";
5801
5802 vim_memset(&WinListType, 0, sizeof(WinListType));
5803 WinListType.tp_name = "vim.windowlist";
5804 WinListType.tp_basicsize = sizeof(WinListType);
5805 WinListType.tp_as_sequence = &WinListAsSeq;
5806 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
5807 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005808 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005809
5810 vim_memset(&TabListType, 0, sizeof(TabListType));
5811 TabListType.tp_name = "vim.tabpagelist";
5812 TabListType.tp_basicsize = sizeof(TabListType);
5813 TabListType.tp_as_sequence = &TabListAsSeq;
5814 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
5815 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005816
5817 vim_memset(&RangeType, 0, sizeof(RangeType));
5818 RangeType.tp_name = "vim.range";
5819 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005820 RangeType.tp_dealloc = (destructor)RangeDestructor;
5821 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005822 RangeType.tp_as_sequence = &RangeAsSeq;
5823 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005824 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005825 RangeType.tp_doc = "vim Range object";
5826 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02005827 RangeType.tp_traverse = (traverseproc)RangeTraverse;
5828 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005829#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005830 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005831 RangeType.tp_alloc = call_PyType_GenericAlloc;
5832 RangeType.tp_new = call_PyType_GenericNew;
5833 RangeType.tp_free = call_PyObject_Free;
5834#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005835 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005836#endif
5837
5838 vim_memset(&CurrentType, 0, sizeof(CurrentType));
5839 CurrentType.tp_name = "vim.currentdata";
5840 CurrentType.tp_basicsize = sizeof(CurrentObject);
5841 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
5842 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005843 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005844#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005845 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
5846 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005847#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005848 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
5849 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005850#endif
5851
5852 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
5853 DictionaryType.tp_name = "vim.dictionary";
5854 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005855 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005856 DictionaryType.tp_as_sequence = &DictionaryAsSeq;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005857 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005858 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005859 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
5860 DictionaryType.tp_methods = DictionaryMethods;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005861 DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
5862 DictionaryType.tp_new = (newfunc)DictionaryConstructor;
5863 DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005864#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005865 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
5866 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005867#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005868 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
5869 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005870#endif
5871
5872 vim_memset(&ListType, 0, sizeof(ListType));
5873 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005874 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005875 ListType.tp_basicsize = sizeof(ListObject);
5876 ListType.tp_as_sequence = &ListAsSeq;
5877 ListType.tp_as_mapping = &ListAsMapping;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005878 ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005879 ListType.tp_doc = "list pushing modifications to vim structure";
5880 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005881 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005882 ListType.tp_new = (newfunc)ListConstructor;
5883 ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005884#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005885 ListType.tp_getattro = (getattrofunc)ListGetattro;
5886 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005887#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005888 ListType.tp_getattr = (getattrfunc)ListGetattr;
5889 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005890#endif
5891
5892 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005893 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005894 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005895 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
5896 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005897 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005898 FunctionType.tp_doc = "object that calls vim function";
5899 FunctionType.tp_methods = FunctionMethods;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02005900 FunctionType.tp_repr = (reprfunc)FunctionRepr;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005901 FunctionType.tp_new = (newfunc)FunctionConstructor;
5902 FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005903#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005904 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005905#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005906 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005907#endif
5908
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005909 vim_memset(&OptionsType, 0, sizeof(OptionsType));
5910 OptionsType.tp_name = "vim.options";
5911 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005912 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005913 OptionsType.tp_doc = "object for manipulating options";
5914 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005915 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
5916 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
5917 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005918
Bram Moolenaar81c40c52013-06-12 14:41:04 +02005919 vim_memset(&LoaderType, 0, sizeof(LoaderType));
5920 LoaderType.tp_name = "vim.Loader";
5921 LoaderType.tp_basicsize = sizeof(LoaderObject);
5922 LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
5923 LoaderType.tp_doc = "vim message object";
5924 LoaderType.tp_methods = LoaderMethods;
5925 LoaderType.tp_dealloc = (destructor)LoaderDestructor;
5926
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005927#if PY_MAJOR_VERSION >= 3
5928 vim_memset(&vimmodule, 0, sizeof(vimmodule));
5929 vimmodule.m_name = "vim";
5930 vimmodule.m_doc = "Vim Python interface\n";
5931 vimmodule.m_size = -1;
5932 vimmodule.m_methods = VimMethods;
5933#endif
5934}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005935
5936#define PYTYPE_READY(type) \
5937 if (PyType_Ready(&type)) \
5938 return -1;
5939
5940 static int
Bram Moolenaarfb97f282013-07-09 17:42:46 +02005941init_types(void)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005942{
5943 PYTYPE_READY(IterType);
5944 PYTYPE_READY(BufferType);
5945 PYTYPE_READY(RangeType);
5946 PYTYPE_READY(WindowType);
5947 PYTYPE_READY(TabPageType);
5948 PYTYPE_READY(BufMapType);
5949 PYTYPE_READY(WinListType);
5950 PYTYPE_READY(TabListType);
5951 PYTYPE_READY(CurrentType);
5952 PYTYPE_READY(DictionaryType);
5953 PYTYPE_READY(ListType);
5954 PYTYPE_READY(FunctionType);
5955 PYTYPE_READY(OptionsType);
5956 PYTYPE_READY(OutputType);
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02005957 PYTYPE_READY(LoaderType);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005958 return 0;
5959}
5960
5961 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02005962init_sys_path(void)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005963{
5964 PyObject *path;
5965 PyObject *path_hook;
5966 PyObject *path_hooks;
5967
5968 if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
5969 return -1;
5970
5971 if (!(path_hooks = PySys_GetObject("path_hooks")))
5972 {
5973 PyErr_Clear();
5974 path_hooks = PyList_New(1);
5975 PyList_SET_ITEM(path_hooks, 0, path_hook);
5976 if (PySys_SetObject("path_hooks", path_hooks))
5977 {
5978 Py_DECREF(path_hooks);
5979 return -1;
5980 }
5981 Py_DECREF(path_hooks);
5982 }
5983 else if (PyList_Check(path_hooks))
5984 {
5985 if (PyList_Append(path_hooks, path_hook))
5986 {
5987 Py_DECREF(path_hook);
5988 return -1;
5989 }
5990 Py_DECREF(path_hook);
5991 }
5992 else
5993 {
5994 VimTryStart();
5995 EMSG(_("Failed to set path hook: sys.path_hooks is not a list\n"
5996 "You should now do the following:\n"
5997 "- append vim.path_hook to sys.path_hooks\n"
5998 "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
5999 VimTryEnd(); /* Discard the error */
6000 Py_DECREF(path_hook);
6001 return 0;
6002 }
6003
6004 if (!(path = PySys_GetObject("path")))
6005 {
6006 PyErr_Clear();
6007 path = PyList_New(1);
6008 Py_INCREF(vim_special_path_object);
6009 PyList_SET_ITEM(path, 0, vim_special_path_object);
6010 if (PySys_SetObject("path", path))
6011 {
6012 Py_DECREF(path);
6013 return -1;
6014 }
6015 Py_DECREF(path);
6016 }
6017 else if (PyList_Check(path))
6018 {
6019 if (PyList_Append(path, vim_special_path_object))
6020 return -1;
6021 }
6022 else
6023 {
6024 VimTryStart();
6025 EMSG(_("Failed to set path: sys.path is not a list\n"
6026 "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
6027 VimTryEnd(); /* Discard the error */
6028 }
6029
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006030 return 0;
6031}
6032
6033static BufMapObject TheBufferMap =
6034{
6035 PyObject_HEAD_INIT(&BufMapType)
6036};
6037
6038static WinListObject TheWindowList =
6039{
6040 PyObject_HEAD_INIT(&WinListType)
6041 NULL
6042};
6043
6044static CurrentObject TheCurrent =
6045{
6046 PyObject_HEAD_INIT(&CurrentType)
6047};
6048
6049static TabListObject TheTabPageList =
6050{
6051 PyObject_HEAD_INIT(&TabListType)
6052};
6053
6054static struct numeric_constant {
6055 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006056 int val;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006057} numeric_constants[] = {
6058 {"VAR_LOCKED", VAR_LOCKED},
6059 {"VAR_FIXED", VAR_FIXED},
6060 {"VAR_SCOPE", VAR_SCOPE},
6061 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
6062};
6063
6064static struct object_constant {
6065 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006066 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006067} object_constants[] = {
6068 {"buffers", (PyObject *)(void *)&TheBufferMap},
6069 {"windows", (PyObject *)(void *)&TheWindowList},
6070 {"tabpages", (PyObject *)(void *)&TheTabPageList},
6071 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02006072
6073 {"Buffer", (PyObject *)&BufferType},
6074 {"Range", (PyObject *)&RangeType},
6075 {"Window", (PyObject *)&WindowType},
6076 {"TabPage", (PyObject *)&TabPageType},
6077 {"Dictionary", (PyObject *)&DictionaryType},
6078 {"List", (PyObject *)&ListType},
6079 {"Function", (PyObject *)&FunctionType},
6080 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006081 {"_Loader", (PyObject *)&LoaderType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006082};
6083
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006084#define ADD_OBJECT(m, name, obj) \
Bram Moolenaardee2e312013-06-23 16:35:47 +02006085 if (PyModule_AddObject(m, name, obj)) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006086 return -1;
6087
6088#define ADD_CHECKED_OBJECT(m, name, obj) \
6089 { \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006090 PyObject *valObject = obj; \
6091 if (!valObject) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006092 return -1; \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006093 ADD_OBJECT(m, name, valObject); \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006094 }
6095
6096 static int
Bram Moolenaardee2e312013-06-23 16:35:47 +02006097populate_module(PyObject *m)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006098{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006099 int i;
6100 PyObject *other_module;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006101 PyObject *attr;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006102 PyObject *imp;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006103
6104 for (i = 0; i < (int)(sizeof(numeric_constants)
6105 / sizeof(struct numeric_constant));
6106 ++i)
6107 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006108 PyInt_FromLong(numeric_constants[i].val));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006109
6110 for (i = 0; i < (int)(sizeof(object_constants)
6111 / sizeof(struct object_constant));
6112 ++i)
6113 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006114 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006115
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006116 valObject = object_constants[i].valObject;
6117 Py_INCREF(valObject);
6118 ADD_OBJECT(m, object_constants[i].name, valObject);
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006119 }
6120
6121 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
6122 return -1;
6123 ADD_OBJECT(m, "error", VimError);
6124
Bram Moolenaara9922d62013-05-30 13:01:18 +02006125 ADD_CHECKED_OBJECT(m, "vars", NEW_DICTIONARY(&globvardict));
6126 ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006127 ADD_CHECKED_OBJECT(m, "options",
6128 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
Bram Moolenaarf4258302013-06-02 18:20:17 +02006129
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006130 if (!(other_module = PyImport_ImportModule("os")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006131 return -1;
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006132 ADD_OBJECT(m, "os", other_module);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006133
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006134 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006135 return -1;
6136 ADD_OBJECT(m, "_getcwd", py_getcwd)
6137
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006138 if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006139 return -1;
6140 ADD_OBJECT(m, "_chdir", py_chdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006141 if (!(attr = PyObject_GetAttrString(m, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006142 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006143 if (PyObject_SetAttrString(other_module, "chdir", attr))
6144 {
6145 Py_DECREF(attr);
6146 return -1;
6147 }
6148 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006149
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006150 if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006151 {
6152 ADD_OBJECT(m, "_fchdir", py_fchdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006153 if (!(attr = PyObject_GetAttrString(m, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006154 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006155 if (PyObject_SetAttrString(other_module, "fchdir", attr))
6156 {
6157 Py_DECREF(attr);
6158 return -1;
6159 }
6160 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006161 }
Bram Moolenaare9056b12013-06-03 20:04:48 +02006162 else
6163 PyErr_Clear();
Bram Moolenaarf4258302013-06-02 18:20:17 +02006164
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006165 if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
6166 return -1;
6167
6168 ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
6169
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006170 if (!(imp = PyImport_ImportModule("imp")))
6171 return -1;
6172
6173 if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
6174 {
6175 Py_DECREF(imp);
6176 return -1;
6177 }
6178
6179 if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
6180 {
6181 Py_DECREF(py_find_module);
6182 Py_DECREF(imp);
6183 return -1;
6184 }
6185
6186 Py_DECREF(imp);
6187
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02006188 ADD_OBJECT(m, "_find_module", py_find_module);
6189 ADD_OBJECT(m, "_load_module", py_load_module);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006190
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006191 return 0;
6192}