blob: 4e1a42a3cf606106e805ce3b4b183278e26a899e [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 Moolenaar264b74f2019-01-24 17:18:42 +010022#define ENC_OPT ((char *)p_enc)
Bram Moolenaard620aa92013-05-17 16:40:06 +020023#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020024
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020025static const char *vim_special_path = "_vim_path_";
26
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020027#define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020028#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020029#define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
Bram Moolenaar063a46b2014-01-14 16:36:51 +010030#define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg)
31#define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2)
32#define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg)
Bram Moolenaarc476e522013-06-23 13:46:40 +020033
34#define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
35 ? "(NULL)" \
36 : obj->ob_type->tp_name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020037
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020038#define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020039 N_("empty keys are not allowed"))
40#define RAISE_LOCKED_DICTIONARY PyErr_SET_VIM(N_("dictionary is locked"))
41#define RAISE_LOCKED_LIST PyErr_SET_VIM(N_("list is locked"))
42#define RAISE_UNDO_FAIL PyErr_SET_VIM(N_("cannot save undo information"))
43#define RAISE_DELETE_LINE_FAIL PyErr_SET_VIM(N_("cannot delete line"))
44#define RAISE_INSERT_LINE_FAIL PyErr_SET_VIM(N_("cannot insert line"))
45#define RAISE_REPLACE_LINE_FAIL PyErr_SET_VIM(N_("cannot replace line"))
Bram Moolenaarc476e522013-06-23 13:46:40 +020046#define RAISE_KEY_ADD_FAIL(key) \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020047 PyErr_VIM_FORMAT(N_("failed to add key '%s' to dictionary"), key)
Bram Moolenaarc476e522013-06-23 13:46:40 +020048#define RAISE_INVALID_INDEX_TYPE(idx) \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020049 PyErr_FORMAT(PyExc_TypeError, N_("index must be int or slice, not %s"), \
Bram Moolenaarc476e522013-06-23 13:46:40 +020050 Py_TYPE_NAME(idx));
Bram Moolenaar35eacd72013-05-30 22:06:33 +020051
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020052#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
53#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020054#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020055
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020056typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020057typedef void (*runner)(const char *, void *
58#ifdef PY_CAN_RECURSE
59 , PyGILState_STATE *
60#endif
61 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020062
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020063static int ConvertFromPyObject(PyObject *, typval_T *);
64static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaara9922d62013-05-30 13:01:18 +020065static int ConvertFromPyMapping(PyObject *, typval_T *);
Bram Moolenaar8110a092016-04-14 15:56:09 +020066static int ConvertFromPySequence(PyObject *, typval_T *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020067static PyObject *WindowNew(win_T *, tabpage_T *);
68static PyObject *BufferNew (buf_T *);
69static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020070
71static PyInt RangeStart;
72static PyInt RangeEnd;
73
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020074static PyObject *globals;
75
Bram Moolenaarf4258302013-06-02 18:20:17 +020076static PyObject *py_chdir;
77static PyObject *py_fchdir;
78static PyObject *py_getcwd;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020079static PyObject *vim_module;
80static PyObject *vim_special_path_object;
Bram Moolenaarf4258302013-06-02 18:20:17 +020081
Bram Moolenaar79a494d2018-07-22 04:30:21 +020082#if PY_VERSION_HEX >= 0x030700f0
83static PyObject *py_find_spec;
84#else
Bram Moolenaar81c40c52013-06-12 14:41:04 +020085static PyObject *py_load_module;
Bram Moolenaar79a494d2018-07-22 04:30:21 +020086#endif
Bram Moolenaarb999ba22019-02-14 13:28:45 +010087static PyObject *py_find_module;
Bram Moolenaar81c40c52013-06-12 14:41:04 +020088
89static PyObject *VimError;
90
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020091/*
92 * obtain a lock on the Vim data structures
93 */
94 static void
95Python_Lock_Vim(void)
96{
97}
98
99/*
100 * release a lock on the Vim data structures
101 */
102 static void
103Python_Release_Vim(void)
104{
105}
106
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200107/*
108 * The "todecref" argument holds a pointer to PyObject * that must be
109 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
110 * was needed to generate returned value is object.
111 *
112 * Use Py_XDECREF to decrement reference count.
113 */
114 static char_u *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200115StringToChars(PyObject *obj, PyObject **todecref)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200116{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200117 char_u *str;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200118
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200119 if (PyBytes_Check(obj))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200120 {
121
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200122 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1
123 || str == NULL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200124 return NULL;
125
126 *todecref = NULL;
127 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200128 else if (PyUnicode_Check(obj))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200129 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200130 PyObject *bytes;
131
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200132 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200133 return NULL;
134
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200135 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1
136 || str == NULL)
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200137 {
138 Py_DECREF(bytes);
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200139 return NULL;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200140 }
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200141
142 *todecref = bytes;
143 }
144 else
145 {
Bram Moolenaarc476e522013-06-23 13:46:40 +0200146#if PY_MAJOR_VERSION < 3
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200147 PyErr_FORMAT(PyExc_TypeError,
148 N_("expected str() or unicode() instance, but got %s"),
149 Py_TYPE_NAME(obj));
Bram Moolenaarc476e522013-06-23 13:46:40 +0200150#else
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200151 PyErr_FORMAT(PyExc_TypeError,
152 N_("expected bytes() or str() instance, but got %s"),
153 Py_TYPE_NAME(obj));
Bram Moolenaarc476e522013-06-23 13:46:40 +0200154#endif
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200155 return NULL;
156 }
157
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200158 return (char_u *) str;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200159}
160
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200161#define NUMBER_LONG 1
162#define NUMBER_INT 2
163#define NUMBER_NATURAL 4
164#define NUMBER_UNSIGNED 8
165
166 static int
167NumberToLong(PyObject *obj, long *result, int flags)
168{
169#if PY_MAJOR_VERSION < 3
170 if (PyInt_Check(obj))
171 {
172 *result = PyInt_AsLong(obj);
173 if (PyErr_Occurred())
174 return -1;
175 }
176 else
177#endif
178 if (PyLong_Check(obj))
179 {
180 *result = PyLong_AsLong(obj);
181 if (PyErr_Occurred())
182 return -1;
183 }
184 else if (PyNumber_Check(obj))
185 {
186 PyObject *num;
187
188 if (!(num = PyNumber_Long(obj)))
189 return -1;
190
191 *result = PyLong_AsLong(num);
192
193 Py_DECREF(num);
194
195 if (PyErr_Occurred())
196 return -1;
197 }
198 else
199 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200200#if PY_MAJOR_VERSION < 3
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200201 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200202 N_("expected int(), long() or something supporting "
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200203 "coercing to long(), but got %s"),
204 Py_TYPE_NAME(obj));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200205#else
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200206 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200207 N_("expected int() or something supporting coercing to int(), "
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200208 "but got %s"),
209 Py_TYPE_NAME(obj));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200210#endif
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200211 return -1;
212 }
213
214 if (flags & NUMBER_INT)
215 {
216 if (*result > INT_MAX)
217 {
218 PyErr_SET_STRING(PyExc_OverflowError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200219 N_("value is too large to fit into C int type"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200220 return -1;
221 }
222 else if (*result < INT_MIN)
223 {
224 PyErr_SET_STRING(PyExc_OverflowError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200225 N_("value is too small to fit into C int type"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200226 return -1;
227 }
228 }
229
230 if (flags & NUMBER_NATURAL)
231 {
232 if (*result <= 0)
233 {
234 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar4de6a212014-03-08 16:13:44 +0100235 N_("number must be greater than zero"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200236 return -1;
237 }
238 }
239 else if (flags & NUMBER_UNSIGNED)
240 {
241 if (*result < 0)
242 {
243 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200244 N_("number must be greater or equal to zero"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200245 return -1;
246 }
247 }
248
249 return 0;
250}
251
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200252 static int
253add_string(PyObject *list, char *s)
254{
255 PyObject *string;
256
257 if (!(string = PyString_FromString(s)))
258 return -1;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200259
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200260 if (PyList_Append(list, string))
261 {
262 Py_DECREF(string);
263 return -1;
264 }
265
266 Py_DECREF(string);
267 return 0;
268}
269
270 static PyObject *
271ObjectDir(PyObject *self, char **attributes)
272{
273 PyMethodDef *method;
274 char **attr;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200275 PyObject *ret;
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200276
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200277 if (!(ret = PyList_New(0)))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200278 return NULL;
279
280 if (self)
281 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
Bram Moolenaar41009372013-07-01 22:03:04 +0200282 if (add_string(ret, (char *)method->ml_name))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200283 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200284 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200285 return NULL;
286 }
287
288 for (attr = attributes ; *attr ; ++attr)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200289 if (add_string(ret, *attr))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200290 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200291 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200292 return NULL;
293 }
294
295#if PY_MAJOR_VERSION < 3
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200296 if (add_string(ret, "__members__"))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200297 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200298 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200299 return NULL;
300 }
301#endif
302
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200303 return ret;
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200304}
305
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200306/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200307 */
308
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200309/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200310typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200311
312static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200313
314typedef struct
315{
316 PyObject_HEAD
317 long softspace;
318 long error;
319} OutputObject;
320
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200321static char *OutputAttrs[] = {
322 "softspace",
323 NULL
324};
325
326 static PyObject *
327OutputDir(PyObject *self)
328{
329 return ObjectDir(self, OutputAttrs);
330}
331
Bram Moolenaar77045652012-09-21 13:46:06 +0200332 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200333OutputSetattr(OutputObject *self, char *name, PyObject *valObject)
Bram Moolenaar77045652012-09-21 13:46:06 +0200334{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200335 if (valObject == NULL)
Bram Moolenaar77045652012-09-21 13:46:06 +0200336 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200337 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200338 N_("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200339 return -1;
340 }
341
342 if (strcmp(name, "softspace") == 0)
343 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200344 if (NumberToLong(valObject, &(self->softspace), NUMBER_UNSIGNED))
Bram Moolenaar77045652012-09-21 13:46:06 +0200345 return -1;
Bram Moolenaar77045652012-09-21 13:46:06 +0200346 return 0;
347 }
348
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200349 PyErr_FORMAT(PyExc_AttributeError, N_("invalid attribute: %s"), name);
Bram Moolenaar77045652012-09-21 13:46:06 +0200350 return -1;
351}
352
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200353/* Buffer IO, we write one whole line at a time. */
354static garray_T io_ga = {0, 0, 1, 80, NULL};
355static writefn old_fn = NULL;
356
357 static void
358PythonIO_Flush(void)
359{
360 if (old_fn != NULL && io_ga.ga_len > 0)
361 {
362 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
363 old_fn((char_u *)io_ga.ga_data);
364 }
365 io_ga.ga_len = 0;
366}
367
368 static void
369writer(writefn fn, char_u *str, PyInt n)
370{
371 char_u *ptr;
372
373 /* Flush when switching output function. */
374 if (fn != old_fn)
375 PythonIO_Flush();
376 old_fn = fn;
377
378 /* Write each NL separated line. Text after the last NL is kept for
379 * writing later. */
380 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
381 {
382 PyInt len = ptr - str;
383
384 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
385 break;
386
387 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
388 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
389 fn((char_u *)io_ga.ga_data);
390 str = ptr + 1;
391 n -= len + 1;
392 io_ga.ga_len = 0;
393 }
394
395 /* Put the remaining text into io_ga for later printing. */
396 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
397 {
398 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
399 io_ga.ga_len += (int)n;
400 }
401}
402
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200403 static int
404write_output(OutputObject *self, PyObject *string)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200405{
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200406 Py_ssize_t len = 0;
407 char *str = NULL;
408 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200409
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200410 if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
411 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200412
413 Py_BEGIN_ALLOW_THREADS
414 Python_Lock_Vim();
Bram Moolenaar32526b32019-01-19 17:43:09 +0100415 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200416 Python_Release_Vim();
417 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200418 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200419
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200420 return 0;
421}
422
423 static PyObject *
424OutputWrite(OutputObject *self, PyObject *string)
425{
426 if (write_output(self, string))
427 return NULL;
428
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200429 Py_INCREF(Py_None);
430 return Py_None;
431}
432
433 static PyObject *
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200434OutputWritelines(OutputObject *self, PyObject *seq)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200435{
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200436 PyObject *iterator;
437 PyObject *item;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200438
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200439 if (!(iterator = PyObject_GetIter(seq)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200440 return NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200441
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200442 while ((item = PyIter_Next(iterator)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200443 {
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200444 if (write_output(self, item))
Bram Moolenaardb913952012-06-29 12:54:53 +0200445 {
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200446 Py_DECREF(iterator);
447 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200448 return NULL;
449 }
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200450 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200451 }
452
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200453 Py_DECREF(iterator);
454
455 /* Iterator may have finished due to an exception */
456 if (PyErr_Occurred())
457 return NULL;
458
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200459 Py_INCREF(Py_None);
460 return Py_None;
461}
462
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100463 static PyObject *
Bram Moolenaard4247472015-11-02 13:28:59 +0100464AlwaysNone(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100465{
466 /* do nothing */
467 Py_INCREF(Py_None);
468 return Py_None;
469}
470
Bram Moolenaard4247472015-11-02 13:28:59 +0100471 static PyObject *
472AlwaysFalse(PyObject *self UNUSED)
473{
474 /* do nothing */
Bram Moolenaare7427f42015-11-10 13:24:20 +0100475 PyObject *ret = Py_False;
476 Py_INCREF(ret);
477 return ret;
Bram Moolenaard4247472015-11-02 13:28:59 +0100478}
479
480 static PyObject *
481AlwaysTrue(PyObject *self UNUSED)
482{
483 /* do nothing */
Bram Moolenaare7427f42015-11-10 13:24:20 +0100484 PyObject *ret = Py_True;
485 Py_INCREF(ret);
486 return ret;
Bram Moolenaard4247472015-11-02 13:28:59 +0100487}
488
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200489/***************/
490
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200491static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200492 /* name, function, calling, doc */
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200493 {"write", (PyCFunction)OutputWrite, METH_O, ""},
494 {"writelines", (PyCFunction)OutputWritelines, METH_O, ""},
Bram Moolenaard4247472015-11-02 13:28:59 +0100495 {"flush", (PyCFunction)AlwaysNone, METH_NOARGS, ""},
496 {"close", (PyCFunction)AlwaysNone, METH_NOARGS, ""},
497 {"isatty", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
498 {"readable", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
499 {"seekable", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
500 {"writable", (PyCFunction)AlwaysTrue, METH_NOARGS, ""},
Bram Moolenaar6d4431e2016-04-21 20:00:56 +0200501 {"closed", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200502 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200503 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200504};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200505
506static OutputObject Output =
507{
508 PyObject_HEAD_INIT(&OutputType)
509 0,
510 0
511};
512
513static OutputObject Error =
514{
515 PyObject_HEAD_INIT(&OutputType)
516 0,
517 1
518};
519
520 static int
521PythonIO_Init_io(void)
522{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +0200523 if (PySys_SetObject("stdout", (PyObject *)(void *)&Output))
524 return -1;
525 if (PySys_SetObject("stderr", (PyObject *)(void *)&Error))
526 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200527
528 if (PyErr_Occurred())
529 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +0100530 emsg(_("E264: Python: Error initialising I/O objects"));
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200531 return -1;
532 }
533
534 return 0;
535}
536
Bram Moolenaar79a494d2018-07-22 04:30:21 +0200537#if PY_VERSION_HEX < 0x030700f0
Bram Moolenaar447bd5a2018-08-07 19:45:27 +0200538static PyObject *call_load_module(char *name, int len, PyObject *find_module_result);
539
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200540typedef struct
541{
542 PyObject_HEAD
Bram Moolenaar447bd5a2018-08-07 19:45:27 +0200543 char *fullname;
544 PyObject *result;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200545} LoaderObject;
546static PyTypeObject LoaderType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200547
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200548 static void
549LoaderDestructor(LoaderObject *self)
550{
Bram Moolenaar447bd5a2018-08-07 19:45:27 +0200551 vim_free(self->fullname);
552 Py_XDECREF(self->result);
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200553 DESTRUCTOR_FINISH(self);
554}
555
556 static PyObject *
557LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
558{
Bram Moolenaar447bd5a2018-08-07 19:45:27 +0200559 char *fullname = self->fullname;
560 PyObject *result = self->result;
561 PyObject *module;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200562
Bram Moolenaar447bd5a2018-08-07 19:45:27 +0200563 if (!fullname)
564 {
565 module = result ? result : Py_None;
566 Py_INCREF(module);
567 return module;
568 }
569
570 module = call_load_module(fullname, (int)STRLEN(fullname), result);
571
572 self->fullname = NULL;
573 self->result = module;
574
575 vim_free(fullname);
576 Py_DECREF(result);
577
578 if (!module)
579 {
580 if (PyErr_Occurred())
581 return NULL;
582
583 Py_INCREF(Py_None);
584 return Py_None;
585 }
586
587 Py_INCREF(module);
588 return module;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200589}
590
591static struct PyMethodDef LoaderMethods[] = {
592 /* name, function, calling, doc */
593 {"load_module", (PyCFunction)LoaderLoadModule, METH_VARARGS, ""},
594 { NULL, NULL, 0, NULL}
595};
Bram Moolenaar79a494d2018-07-22 04:30:21 +0200596#endif
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200597
598/* Check to see whether a Vim error has been reported, or a keyboard
599 * interrupt has been detected.
600 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200601
602 static void
603VimTryStart(void)
604{
605 ++trylevel;
606}
607
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200608 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200609VimTryEnd(void)
610{
611 --trylevel;
Bram Moolenaarb544f3c2017-02-23 19:03:28 +0100612 /* Without this it stops processing all subsequent Vim script commands and
613 * generates strange error messages if I e.g. try calling Test() in a cycle
614 */
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200615 did_emsg = FALSE;
616 /* Keyboard interrupt should be preferred over anything else */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200617 if (got_int)
618 {
Bram Moolenaar4315f262014-01-31 14:54:04 +0100619 if (did_throw)
Bram Moolenaard6b8a522013-11-11 01:05:48 +0100620 discard_current_exception();
Bram Moolenaard6b8a522013-11-11 01:05:48 +0100621 got_int = FALSE;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200622 PyErr_SetNone(PyExc_KeyboardInterrupt);
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200623 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200624 }
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100625 else if (msg_list != NULL && *msg_list != NULL)
626 {
627 int should_free;
Bram Moolenaarb1443b42019-01-13 23:51:14 +0100628 char *msg;
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100629
630 msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free);
631
632 if (msg == NULL)
633 {
634 PyErr_NoMemory();
635 return -1;
636 }
637
Bram Moolenaarb1443b42019-01-13 23:51:14 +0100638 PyErr_SetVim(msg);
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100639
640 free_global_msglist();
641
642 if (should_free)
643 vim_free(msg);
644
645 return -1;
646 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200647 else if (!did_throw)
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200648 return (PyErr_Occurred() ? -1 : 0);
649 /* Python exception is preferred over vim one; unlikely to occur though */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200650 else if (PyErr_Occurred())
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200651 {
Bram Moolenaar4315f262014-01-31 14:54:04 +0100652 discard_current_exception();
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200653 return -1;
654 }
Bram Moolenaarb544f3c2017-02-23 19:03:28 +0100655 /* Finally transform Vim script exception to python one */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200656 else
657 {
Bram Moolenaar41009372013-07-01 22:03:04 +0200658 PyErr_SetVim((char *)current_exception->value);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200659 discard_current_exception();
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200660 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200661 }
662}
663
664 static int
665VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200666{
667 if (got_int)
668 {
669 PyErr_SetNone(PyExc_KeyboardInterrupt);
670 return 1;
671 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200672 return 0;
673}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200674
675/* Vim module - Implementation
676 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200677
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200678 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200679VimCommand(PyObject *self UNUSED, PyObject *string)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200680{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200681 char_u *cmd;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200682 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200683 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200684
Bram Moolenaar389a1792013-06-23 13:00:44 +0200685 if (!(cmd = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200686 return NULL;
687
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200688 Py_BEGIN_ALLOW_THREADS
689 Python_Lock_Vim();
690
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200691 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200692 do_cmdline_cmd(cmd);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200693 update_screen(VALID);
694
695 Python_Release_Vim();
696 Py_END_ALLOW_THREADS
697
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200698 if (VimTryEnd())
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200699 ret = NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200700 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200701 ret = Py_None;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200702
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200703 Py_XINCREF(ret);
Bram Moolenaar389a1792013-06-23 13:00:44 +0200704 Py_XDECREF(todecref);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200705 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200706}
707
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200708/*
709 * Function to translate a typval_T into a PyObject; this will recursively
710 * translate lists/dictionaries into their Python equivalents.
711 *
712 * The depth parameter is to avoid infinite recursion, set it to 1 when
713 * you call VimToPython.
714 */
715 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200716VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200717{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200718 PyObject *ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200719 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200720 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200721
722 /* Avoid infinite recursion */
723 if (depth > 100)
724 {
725 Py_INCREF(Py_None);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200726 ret = Py_None;
727 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200728 }
729
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200730 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200731 * then and we can use it again. */
732 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
733 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
734 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200735 sprintf(ptrBuf, "%p",
736 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
737 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200738
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200739 if ((ret = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200740 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200741 Py_INCREF(ret);
742 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200743 }
744 }
745
746 if (our_tv->v_type == VAR_STRING)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200747 ret = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200748 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200749 else if (our_tv->v_type == VAR_NUMBER)
750 {
751 char buf[NUMBUFLEN];
752
753 /* For backwards compatibility numbers are stored as strings. */
754 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar41009372013-07-01 22:03:04 +0200755 ret = PyString_FromString((char *)buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200756 }
Bram Moolenaarb999ba22019-02-14 13:28:45 +0100757#ifdef FEAT_FLOAT
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200758 else if (our_tv->v_type == VAR_FLOAT)
759 {
760 char buf[NUMBUFLEN];
761
762 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar41009372013-07-01 22:03:04 +0200763 ret = PyString_FromString((char *)buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200764 }
Bram Moolenaarb999ba22019-02-14 13:28:45 +0100765#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200766 else if (our_tv->v_type == VAR_LIST)
767 {
768 list_T *list = our_tv->vval.v_list;
769 listitem_T *curr;
770
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200771 if (list == NULL)
772 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200773
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200774 if (!(ret = PyList_New(0)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200775 return NULL;
776
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200777 if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200778 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200779 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200780 return NULL;
781 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200782
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200783 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
784 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200785 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200786 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200787 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200788 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200789 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200790 if (PyList_Append(ret, newObj))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200791 {
792 Py_DECREF(newObj);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200793 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200794 return NULL;
795 }
796 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200797 }
798 }
799 else if (our_tv->v_type == VAR_DICT)
800 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200801
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100802 hashtab_T *ht;
803 long_u todo;
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200804 hashitem_T *hi;
805 dictitem_T *di;
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100806
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200807 if (our_tv->vval.v_dict == NULL)
808 return NULL;
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100809 ht = &our_tv->vval.v_dict->dv_hashtab;
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200810
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200811 if (!(ret = PyDict_New()))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200812 return NULL;
813
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200814 if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200815 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200816 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200817 return NULL;
818 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200819
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100820 todo = ht->ht_used;
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200821 for (hi = ht->ht_array; todo > 0; ++hi)
822 {
823 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200824 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200825 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200826
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200827 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200828 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200829 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200830 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200831 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200832 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200833 if (PyDict_SetItemString(ret, (char *)hi->hi_key, newObj))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200834 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200835 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200836 Py_DECREF(newObj);
837 return NULL;
838 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200839 }
840 }
841 }
Bram Moolenaar520e1e42016-01-23 19:46:28 +0100842 else if (our_tv->v_type == VAR_SPECIAL)
843 {
844 if (our_tv->vval.v_number == VVAL_FALSE)
845 {
846 ret = Py_False;
847 Py_INCREF(ret);
848 }
849 else if (our_tv->vval.v_number == VVAL_TRUE)
850 {
851 ret = Py_True;
852 Py_INCREF(ret);
853 }
854 else
855 {
856 Py_INCREF(Py_None);
857 ret = Py_None;
858 }
859 return ret;
860 }
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +0100861 else if (our_tv->v_type == VAR_BLOB)
862 ret = PyBytes_FromStringAndSize(
863 (char*) our_tv->vval.v_blob->bv_ga.ga_data,
864 (Py_ssize_t) our_tv->vval.v_blob->bv_ga.ga_len);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200865 else
866 {
867 Py_INCREF(Py_None);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200868 ret = Py_None;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200869 }
870
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200871 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200872}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200873
874 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200875VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200876{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200877 char_u *expr;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200878 typval_T *our_tv;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200879 PyObject *string;
880 PyObject *todecref;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200881 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200882 PyObject *lookup_dict;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200883
Bram Moolenaar389a1792013-06-23 13:00:44 +0200884 if (!PyArg_ParseTuple(args, "O", &string))
885 return NULL;
886
887 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200888 return NULL;
889
890 Py_BEGIN_ALLOW_THREADS
891 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200892 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200893 our_tv = eval_expr(expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200894 Python_Release_Vim();
895 Py_END_ALLOW_THREADS
896
Bram Moolenaar389a1792013-06-23 13:00:44 +0200897 Py_XDECREF(todecref);
898
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200899 if (VimTryEnd())
900 return NULL;
901
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200902 if (our_tv == NULL)
903 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200904 PyErr_SET_VIM(N_("invalid expression"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200905 return NULL;
906 }
907
908 /* Convert the Vim type into a Python type. Create a dictionary that's
909 * used to check for recursive loops. */
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200910 if (!(lookup_dict = PyDict_New()))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200911 ret = NULL;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200912 else
913 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200914 ret = VimToPython(our_tv, 1, lookup_dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200915 Py_DECREF(lookup_dict);
916 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200917
918
919 Py_BEGIN_ALLOW_THREADS
920 Python_Lock_Vim();
921 free_tv(our_tv);
922 Python_Release_Vim();
923 Py_END_ALLOW_THREADS
924
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200925 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200926}
927
Bram Moolenaardb913952012-06-29 12:54:53 +0200928static PyObject *ConvertToPyObject(typval_T *);
929
930 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200931VimEvalPy(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200932{
Bram Moolenaardb913952012-06-29 12:54:53 +0200933 typval_T *our_tv;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200934 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200935 char_u *expr;
936 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +0200937
Bram Moolenaar389a1792013-06-23 13:00:44 +0200938 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200939 return NULL;
940
941 Py_BEGIN_ALLOW_THREADS
942 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200943 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200944 our_tv = eval_expr(expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200945 Python_Release_Vim();
946 Py_END_ALLOW_THREADS
947
Bram Moolenaar389a1792013-06-23 13:00:44 +0200948 Py_XDECREF(todecref);
949
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200950 if (VimTryEnd())
951 return NULL;
952
Bram Moolenaardb913952012-06-29 12:54:53 +0200953 if (our_tv == NULL)
954 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200955 PyErr_SET_VIM(N_("invalid expression"));
Bram Moolenaardb913952012-06-29 12:54:53 +0200956 return NULL;
957 }
958
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200959 ret = ConvertToPyObject(our_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200960 Py_BEGIN_ALLOW_THREADS
961 Python_Lock_Vim();
962 free_tv(our_tv);
963 Python_Release_Vim();
964 Py_END_ALLOW_THREADS
965
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200966 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +0200967}
968
969 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200970VimStrwidth(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200971{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200972 char_u *str;
973 PyObject *todecref;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200974 int len;
Bram Moolenaardb913952012-06-29 12:54:53 +0200975
Bram Moolenaar389a1792013-06-23 13:00:44 +0200976 if (!(str = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200977 return NULL;
978
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200979 len = mb_string2cells(str, (int)STRLEN(str));
Bram Moolenaar389a1792013-06-23 13:00:44 +0200980
981 Py_XDECREF(todecref);
982
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200983 return PyLong_FromLong(len);
Bram Moolenaardb913952012-06-29 12:54:53 +0200984}
985
Bram Moolenaarf4258302013-06-02 18:20:17 +0200986 static PyObject *
987_VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
988{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200989 PyObject *ret;
Bram Moolenaarf4258302013-06-02 18:20:17 +0200990 PyObject *newwd;
991 PyObject *todecref;
992 char_u *new_dir;
993
Bram Moolenaard4209d22013-06-05 20:34:15 +0200994 if (_chdir == NULL)
995 return NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200996 if (!(ret = PyObject_Call(_chdir, args, kwargs)))
Bram Moolenaarf4258302013-06-02 18:20:17 +0200997 return NULL;
998
999 if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
1000 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001001 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +02001002 return NULL;
1003 }
1004
1005 if (!(new_dir = StringToChars(newwd, &todecref)))
1006 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001007 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +02001008 Py_DECREF(newwd);
1009 return NULL;
1010 }
1011
1012 VimTryStart();
1013
1014 if (vim_chdir(new_dir))
1015 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001016 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +02001017 Py_DECREF(newwd);
1018 Py_XDECREF(todecref);
1019
1020 if (VimTryEnd())
1021 return NULL;
1022
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001023 PyErr_SET_VIM(N_("failed to change directory"));
Bram Moolenaarf4258302013-06-02 18:20:17 +02001024 return NULL;
1025 }
1026
1027 Py_DECREF(newwd);
1028 Py_XDECREF(todecref);
1029
Bram Moolenaar1063f3d2019-05-07 22:06:52 +02001030 post_chdir(CDSCOPE_GLOBAL);
Bram Moolenaarf4258302013-06-02 18:20:17 +02001031
1032 if (VimTryEnd())
1033 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001034 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +02001035 return NULL;
1036 }
1037
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001038 return ret;
Bram Moolenaarf4258302013-06-02 18:20:17 +02001039}
1040
1041 static PyObject *
1042VimChdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
1043{
1044 return _VimChdir(py_chdir, args, kwargs);
1045}
1046
1047 static PyObject *
1048VimFchdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
1049{
1050 return _VimChdir(py_fchdir, args, kwargs);
1051}
1052
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001053typedef struct {
1054 PyObject *callable;
1055 PyObject *result;
1056} map_rtp_data;
1057
1058 static void
1059map_rtp_callback(char_u *path, void *_data)
1060{
1061 void **data = (void **) _data;
1062 PyObject *pathObject;
1063 map_rtp_data *mr_data = *((map_rtp_data **) data);
1064
Bram Moolenaar41009372013-07-01 22:03:04 +02001065 if (!(pathObject = PyString_FromString((char *)path)))
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001066 {
1067 *data = NULL;
1068 return;
1069 }
1070
1071 mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
1072 pathObject, NULL);
1073
1074 Py_DECREF(pathObject);
1075
1076 if (!mr_data->result || mr_data->result != Py_None)
1077 *data = NULL;
1078 else
1079 {
1080 Py_DECREF(mr_data->result);
1081 mr_data->result = NULL;
1082 }
1083}
1084
1085 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02001086VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001087{
1088 map_rtp_data data;
1089
Bram Moolenaar389a1792013-06-23 13:00:44 +02001090 data.callable = callable;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001091 data.result = NULL;
1092
Bram Moolenaar7f8989d2016-03-12 22:11:39 +01001093 do_in_runtimepath(NULL, 0, &map_rtp_callback, &data);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001094
1095 if (data.result == NULL)
1096 {
1097 if (PyErr_Occurred())
1098 return NULL;
1099 else
1100 {
1101 Py_INCREF(Py_None);
1102 return Py_None;
1103 }
1104 }
1105 return data.result;
1106}
1107
1108/*
1109 * _vim_runtimepath_ special path implementation.
1110 */
1111
1112 static void
1113map_finder_callback(char_u *path, void *_data)
1114{
1115 void **data = (void **) _data;
1116 PyObject *list = *((PyObject **) data);
1117 PyObject *pathObject1, *pathObject2;
1118 char *pathbuf;
1119 size_t pathlen;
1120
1121 pathlen = STRLEN(path);
1122
1123#if PY_MAJOR_VERSION < 3
1124# define PY_MAIN_DIR_STRING "python2"
1125#else
1126# define PY_MAIN_DIR_STRING "python3"
1127#endif
1128#define PY_ALTERNATE_DIR_STRING "pythonx"
1129
1130#define PYTHONX_STRING_LENGTH 7 /* STRLEN("pythonx") */
1131 if (!(pathbuf = PyMem_New(char,
1132 pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
1133 {
1134 PyErr_NoMemory();
1135 *data = NULL;
1136 return;
1137 }
1138
1139 mch_memmove(pathbuf, path, pathlen + 1);
1140 add_pathsep((char_u *) pathbuf);
1141
1142 pathlen = STRLEN(pathbuf);
1143 mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
1144 PYTHONX_STRING_LENGTH + 1);
1145
1146 if (!(pathObject1 = PyString_FromString(pathbuf)))
1147 {
1148 *data = NULL;
1149 PyMem_Free(pathbuf);
1150 return;
1151 }
1152
1153 mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
1154 PYTHONX_STRING_LENGTH + 1);
1155
1156 if (!(pathObject2 = PyString_FromString(pathbuf)))
1157 {
1158 Py_DECREF(pathObject1);
1159 PyMem_Free(pathbuf);
1160 *data = NULL;
1161 return;
1162 }
1163
1164 PyMem_Free(pathbuf);
1165
1166 if (PyList_Append(list, pathObject1)
1167 || PyList_Append(list, pathObject2))
1168 *data = NULL;
1169
1170 Py_DECREF(pathObject1);
1171 Py_DECREF(pathObject2);
1172}
1173
1174 static PyObject *
1175Vim_GetPaths(PyObject *self UNUSED)
1176{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001177 PyObject *ret;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001178
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001179 if (!(ret = PyList_New(0)))
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001180 return NULL;
1181
Bram Moolenaar7f8989d2016-03-12 22:11:39 +01001182 do_in_runtimepath(NULL, 0, &map_finder_callback, ret);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001183
1184 if (PyErr_Occurred())
1185 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001186 Py_DECREF(ret);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001187 return NULL;
1188 }
1189
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001190 return ret;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001191}
1192
Bram Moolenaar79a494d2018-07-22 04:30:21 +02001193#if PY_VERSION_HEX >= 0x030700f0
1194 static PyObject *
1195FinderFindSpec(PyObject *self, PyObject *args)
1196{
1197 char *fullname;
1198 PyObject *paths;
1199 PyObject *target = Py_None;
1200 PyObject *spec;
1201
1202 if (!PyArg_ParseTuple(args, "s|O", &fullname, &target))
1203 return NULL;
1204
1205 if (!(paths = Vim_GetPaths(self)))
1206 return NULL;
1207
Bram Moolenaarde5b3802019-03-30 12:51:22 +01001208 spec = PyObject_CallFunction(py_find_spec, "sOO", fullname, paths, target);
Bram Moolenaar79a494d2018-07-22 04:30:21 +02001209
1210 Py_DECREF(paths);
1211
1212 if (!spec)
1213 {
1214 if (PyErr_Occurred())
1215 return NULL;
1216
1217 Py_INCREF(Py_None);
1218 return Py_None;
1219 }
1220
1221 return spec;
1222}
1223#else
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001224 static PyObject *
1225call_load_module(char *name, int len, PyObject *find_module_result)
1226{
1227 PyObject *fd, *pathname, *description;
1228
Bram Moolenaarc476e522013-06-23 13:46:40 +02001229 if (!PyTuple_Check(find_module_result))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001230 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001231 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001232 N_("expected 3-tuple as imp.find_module() result, but got %s"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02001233 Py_TYPE_NAME(find_module_result));
1234 return NULL;
1235 }
1236 if (PyTuple_GET_SIZE(find_module_result) != 3)
1237 {
1238 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001239 N_("expected 3-tuple as imp.find_module() result, but got "
1240 "tuple of size %d"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02001241 (int) PyTuple_GET_SIZE(find_module_result));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001242 return NULL;
1243 }
1244
1245 if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
1246 || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
1247 || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
1248 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001249 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001250 N_("internal error: imp.find_module returned tuple with NULL"));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001251 return NULL;
1252 }
1253
1254 return PyObject_CallFunction(py_load_module,
1255 "s#OOO", name, len, fd, pathname, description);
1256}
1257
1258 static PyObject *
1259find_module(char *fullname, char *tail, PyObject *new_path)
1260{
1261 PyObject *find_module_result;
1262 PyObject *module;
1263 char *dot;
1264
Bram Moolenaar41009372013-07-01 22:03:04 +02001265 if ((dot = (char *)vim_strchr((char_u *) tail, '.')))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001266 {
1267 /*
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001268 * There is a dot in the name: call find_module recursively without the
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001269 * first component
1270 */
1271 PyObject *newest_path;
1272 int partlen = (int) (dot - 1 - tail);
1273
1274 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1275 "s#O", tail, partlen, new_path)))
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001276 {
1277 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1278 PyErr_Clear();
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001279 return NULL;
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001280 }
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001281
1282 if (!(module = call_load_module(
1283 fullname,
1284 ((int) (tail - fullname)) + partlen,
1285 find_module_result)))
1286 {
1287 Py_DECREF(find_module_result);
1288 return NULL;
1289 }
1290
1291 Py_DECREF(find_module_result);
1292
1293 if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
1294 {
1295 Py_DECREF(module);
1296 return NULL;
1297 }
1298
1299 Py_DECREF(module);
1300
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001301 find_module_result = find_module(fullname, dot + 1, newest_path);
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001302
1303 Py_DECREF(newest_path);
1304
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001305 return find_module_result;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001306 }
1307 else
1308 {
1309 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1310 "sO", tail, new_path)))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001311 {
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001312 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1313 PyErr_Clear();
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001314 return NULL;
1315 }
1316
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001317 return find_module_result;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001318 }
1319}
1320
1321 static PyObject *
1322FinderFindModule(PyObject *self, PyObject *args)
1323{
1324 char *fullname;
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001325 PyObject *result;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001326 PyObject *new_path;
1327 LoaderObject *loader;
1328
1329 if (!PyArg_ParseTuple(args, "s", &fullname))
1330 return NULL;
1331
1332 if (!(new_path = Vim_GetPaths(self)))
1333 return NULL;
1334
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001335 result = find_module(fullname, fullname, new_path);
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001336
1337 Py_DECREF(new_path);
1338
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001339 if (!result)
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001340 {
Bram Moolenaar7e85d3d2013-06-23 16:40:39 +02001341 if (PyErr_Occurred())
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001342 return NULL;
Bram Moolenaar7e85d3d2013-06-23 16:40:39 +02001343
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001344 Py_INCREF(Py_None);
1345 return Py_None;
1346 }
1347
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001348 if (!(fullname = (char *)vim_strsave((char_u *)fullname)))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001349 {
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001350 Py_DECREF(result);
1351 PyErr_NoMemory();
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001352 return NULL;
1353 }
1354
Bram Moolenaar447bd5a2018-08-07 19:45:27 +02001355 if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
1356 {
1357 vim_free(fullname);
1358 Py_DECREF(result);
1359 return NULL;
1360 }
1361
1362 loader->fullname = fullname;
1363 loader->result = result;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001364
1365 return (PyObject *) loader;
1366}
Bram Moolenaar79a494d2018-07-22 04:30:21 +02001367#endif
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001368
1369 static PyObject *
1370VimPathHook(PyObject *self UNUSED, PyObject *args)
1371{
1372 char *path;
1373
1374 if (PyArg_ParseTuple(args, "s", &path)
1375 && STRCMP(path, vim_special_path) == 0)
1376 {
1377 Py_INCREF(vim_module);
1378 return vim_module;
1379 }
1380
1381 PyErr_Clear();
1382 PyErr_SetNone(PyExc_ImportError);
1383 return NULL;
1384}
1385
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001386/*
1387 * Vim module - Definitions
1388 */
1389
1390static struct PyMethodDef VimMethods[] = {
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001391 /* name, function, calling, documentation */
Bram Moolenaar389a1792013-06-23 13:00:44 +02001392 {"command", VimCommand, METH_O, "Execute a Vim ex-mode command" },
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001393 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02001394 {"bindeval", VimEvalPy, METH_O, "Like eval(), but returns objects attached to vim ones"},
1395 {"strwidth", VimStrwidth, METH_O, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001396 {"chdir", (PyCFunction)VimChdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
1397 {"fchdir", (PyCFunction)VimFchdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
Bram Moolenaar389a1792013-06-23 13:00:44 +02001398 {"foreach_rtp", VimForeachRTP, METH_O, "Call given callable for each path in &rtp"},
Bram Moolenaar79a494d2018-07-22 04:30:21 +02001399#if PY_VERSION_HEX >= 0x030700f0
1400 {"find_spec", FinderFindSpec, METH_VARARGS, "Internal use only, returns spec object for any input it receives"},
1401#else
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001402 {"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
Bram Moolenaar79a494d2018-07-22 04:30:21 +02001403#endif
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001404 {"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
1405 {"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
1406 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001407};
1408
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001409/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001410 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001411 */
1412
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001413static PyTypeObject IterType;
1414
1415typedef PyObject *(*nextfun)(void **);
1416typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001417typedef int (*traversefun)(void *, visitproc, void *);
1418typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001419
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001420/* Main purpose of this object is removing the need for do python
1421 * initialization (i.e. PyType_Ready and setting type attributes) for a big
1422 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001423
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001424typedef struct
1425{
1426 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001427 void *cur;
1428 nextfun next;
1429 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001430 traversefun traverse;
1431 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001432} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001433
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001434 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001435IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
1436 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001437{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001438 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001439
Bram Moolenaar774267b2013-05-21 20:51:59 +02001440 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001441 self->cur = start;
1442 self->next = next;
1443 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001444 self->traverse = traverse;
1445 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001446
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001447 return (PyObject *)(self);
1448}
1449
1450 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001451IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001452{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001453 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02001454 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +02001455 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001456}
1457
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001458 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001459IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001460{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001461 if (self->traverse != NULL)
1462 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001463 else
1464 return 0;
1465}
1466
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001467/* Mac OSX defines clear() somewhere. */
1468#ifdef clear
1469# undef clear
1470#endif
1471
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001472 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001473IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001474{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001475 if (self->clear != NULL)
1476 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001477 else
1478 return 0;
1479}
1480
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001481 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001482IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001483{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001484 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001485}
1486
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001487 static PyObject *
1488IterIter(PyObject *self)
1489{
Bram Moolenaar1bcabe12013-05-29 22:52:32 +02001490 Py_INCREF(self);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001491 return self;
1492}
Bram Moolenaardfa38d42013-05-15 13:38:47 +02001493
Bram Moolenaardb913952012-06-29 12:54:53 +02001494typedef struct pylinkedlist_S {
1495 struct pylinkedlist_S *pll_next;
1496 struct pylinkedlist_S *pll_prev;
1497 PyObject *pll_obj;
1498} pylinkedlist_T;
1499
1500static pylinkedlist_T *lastdict = NULL;
1501static pylinkedlist_T *lastlist = NULL;
Bram Moolenaar8110a092016-04-14 15:56:09 +02001502static pylinkedlist_T *lastfunc = NULL;
Bram Moolenaardb913952012-06-29 12:54:53 +02001503
1504 static void
1505pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
1506{
1507 if (ref->pll_prev == NULL)
1508 {
1509 if (ref->pll_next == NULL)
1510 {
1511 *last = NULL;
1512 return;
1513 }
1514 }
1515 else
1516 ref->pll_prev->pll_next = ref->pll_next;
1517
1518 if (ref->pll_next == NULL)
1519 *last = ref->pll_prev;
1520 else
1521 ref->pll_next->pll_prev = ref->pll_prev;
1522}
1523
1524 static void
1525pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
1526{
1527 if (*last == NULL)
1528 ref->pll_prev = NULL;
1529 else
1530 {
1531 (*last)->pll_next = ref;
1532 ref->pll_prev = *last;
1533 }
1534 ref->pll_next = NULL;
1535 ref->pll_obj = self;
1536 *last = ref;
1537}
1538
1539static PyTypeObject DictionaryType;
1540
1541typedef struct
1542{
1543 PyObject_HEAD
1544 dict_T *dict;
1545 pylinkedlist_T ref;
1546} DictionaryObject;
1547
Bram Moolenaara9922d62013-05-30 13:01:18 +02001548static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
1549
1550#define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
1551
Bram Moolenaardb913952012-06-29 12:54:53 +02001552 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001553DictionaryNew(PyTypeObject *subtype, dict_T *dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02001554{
1555 DictionaryObject *self;
1556
Bram Moolenaara9922d62013-05-30 13:01:18 +02001557 self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02001558 if (self == NULL)
1559 return NULL;
1560 self->dict = dict;
1561 ++dict->dv_refcount;
1562
1563 pyll_add((PyObject *)(self), &self->ref, &lastdict);
1564
1565 return (PyObject *)(self);
1566}
1567
Bram Moolenaara9922d62013-05-30 13:01:18 +02001568 static dict_T *
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001569py_dict_alloc(void)
Bram Moolenaara9922d62013-05-30 13:01:18 +02001570{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001571 dict_T *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001572
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001573 if (!(ret = dict_alloc()))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001574 {
1575 PyErr_NoMemory();
1576 return NULL;
1577 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001578 ++ret->dv_refcount;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001579
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001580 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001581}
1582
1583 static PyObject *
1584DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1585{
1586 DictionaryObject *self;
1587 dict_T *dict;
1588
1589 if (!(dict = py_dict_alloc()))
1590 return NULL;
1591
1592 self = (DictionaryObject *) DictionaryNew(subtype, dict);
1593
1594 --dict->dv_refcount;
1595
1596 if (kwargs || PyTuple_Size(args))
1597 {
1598 PyObject *tmp;
1599 if (!(tmp = DictionaryUpdate(self, args, kwargs)))
1600 {
1601 Py_DECREF(self);
1602 return NULL;
1603 }
1604
1605 Py_DECREF(tmp);
1606 }
1607
1608 return (PyObject *)(self);
1609}
1610
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001611 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001612DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001613{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001614 pyll_remove(&self->ref, &lastdict);
1615 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001616
1617 DESTRUCTOR_FINISH(self);
1618}
1619
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001620static char *DictionaryAttrs[] = {
1621 "locked", "scope",
1622 NULL
1623};
1624
1625 static PyObject *
1626DictionaryDir(PyObject *self)
1627{
1628 return ObjectDir(self, DictionaryAttrs);
1629}
1630
Bram Moolenaardb913952012-06-29 12:54:53 +02001631 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001632DictionarySetattr(DictionaryObject *self, char *name, PyObject *valObject)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001633{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001634 if (valObject == NULL)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001635 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001636 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001637 N_("cannot delete vim.Dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001638 return -1;
1639 }
1640
1641 if (strcmp(name, "locked") == 0)
1642 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001643 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001644 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001645 PyErr_SET_STRING(PyExc_TypeError,
1646 N_("cannot modify fixed dictionary"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001647 return -1;
1648 }
1649 else
1650 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001651 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarb983f752013-05-15 16:11:50 +02001652 if (istrue == -1)
1653 return -1;
1654 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001655 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001656 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001657 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001658 }
1659 return 0;
1660 }
1661 else
1662 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001663 PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02001664 return -1;
1665 }
1666}
1667
1668 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001669DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001670{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001671 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +02001672}
1673
Bram Moolenaara9922d62013-05-30 13:01:18 +02001674#define DICT_FLAG_HAS_DEFAULT 0x01
1675#define DICT_FLAG_POP 0x02
1676#define DICT_FLAG_NONE_DEFAULT 0x04
1677#define DICT_FLAG_RETURN_BOOL 0x08 /* Incompatible with DICT_FLAG_POP */
1678#define DICT_FLAG_RETURN_PAIR 0x10
1679
Bram Moolenaardb913952012-06-29 12:54:53 +02001680 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001681_DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
Bram Moolenaardb913952012-06-29 12:54:53 +02001682{
Bram Moolenaara9922d62013-05-30 13:01:18 +02001683 PyObject *keyObject;
1684 PyObject *defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001685 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001686 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001687 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001688 dict_T *dict = self->dict;
1689 hashitem_T *hi;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001690 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001691
Bram Moolenaara9922d62013-05-30 13:01:18 +02001692 if (flags & DICT_FLAG_HAS_DEFAULT)
1693 {
1694 if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1695 return NULL;
1696 }
1697 else
1698 keyObject = args;
1699
1700 if (flags & DICT_FLAG_RETURN_BOOL)
1701 defObject = Py_False;
1702
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001703 if (!(key = StringToChars(keyObject, &todecref)))
1704 return NULL;
1705
1706 if (*key == NUL)
1707 {
1708 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001709 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001710 return NULL;
1711 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001712
Bram Moolenaara9922d62013-05-30 13:01:18 +02001713 hi = hash_find(&dict->dv_hashtab, key);
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001714
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001715 Py_XDECREF(todecref);
Bram Moolenaar696c2112012-09-21 13:43:14 +02001716
Bram Moolenaara9922d62013-05-30 13:01:18 +02001717 if (HASHITEM_EMPTY(hi))
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001718 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001719 if (defObject)
1720 {
1721 Py_INCREF(defObject);
1722 return defObject;
1723 }
1724 else
1725 {
1726 PyErr_SetObject(PyExc_KeyError, keyObject);
1727 return NULL;
1728 }
1729 }
1730 else if (flags & DICT_FLAG_RETURN_BOOL)
1731 {
Bram Moolenaar0e4eebd2014-02-12 22:08:49 +01001732 ret = Py_True;
1733 Py_INCREF(ret);
1734 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001735 }
1736
1737 di = dict_lookup(hi);
1738
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001739 if (!(ret = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001740 return NULL;
1741
1742 if (flags & DICT_FLAG_POP)
1743 {
1744 if (dict->dv_lock)
1745 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001746 RAISE_LOCKED_DICTIONARY;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001747 Py_DECREF(ret);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001748 return NULL;
1749 }
1750
1751 hash_remove(&dict->dv_hashtab, hi);
1752 dictitem_free(di);
1753 }
1754
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001755 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001756}
1757
1758 static PyObject *
1759DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1760{
1761 return _DictionaryItem(self, keyObject, 0);
1762}
1763
1764 static int
1765DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1766{
1767 PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001768 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001769
Bram Moolenaarba2d7ff2013-11-04 00:34:53 +01001770 if (rObj == NULL)
1771 return -1;
1772
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001773 ret = (rObj == Py_True);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001774
Bram Moolenaardee2e312013-06-23 16:35:47 +02001775 Py_DECREF(rObj);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001776
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001777 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001778}
1779
1780typedef struct
1781{
1782 hashitem_T *ht_array;
1783 long_u ht_used;
1784 hashtab_T *ht;
1785 hashitem_T *hi;
Bram Moolenaar99dc19d2013-05-31 20:49:31 +02001786 long_u todo;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001787} dictiterinfo_T;
1788
1789 static PyObject *
1790DictionaryIterNext(dictiterinfo_T **dii)
1791{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001792 PyObject *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001793
1794 if (!(*dii)->todo)
1795 return NULL;
1796
1797 if ((*dii)->ht->ht_array != (*dii)->ht_array ||
1798 (*dii)->ht->ht_used != (*dii)->ht_used)
1799 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001800 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001801 N_("hashtab changed during iteration"));
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001802 return NULL;
1803 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001804
Bram Moolenaara9922d62013-05-30 13:01:18 +02001805 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
1806 ++((*dii)->hi);
1807
1808 --((*dii)->todo);
1809
Bram Moolenaar41009372013-07-01 22:03:04 +02001810 if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001811 return NULL;
1812
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001813 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001814}
1815
1816 static PyObject *
1817DictionaryIter(DictionaryObject *self)
1818{
1819 dictiterinfo_T *dii;
1820 hashtab_T *ht;
1821
1822 if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1823 {
1824 PyErr_NoMemory();
1825 return NULL;
1826 }
1827
1828 ht = &self->dict->dv_hashtab;
1829 dii->ht_array = ht->ht_array;
1830 dii->ht_used = ht->ht_used;
1831 dii->ht = ht;
1832 dii->hi = dii->ht_array;
1833 dii->todo = dii->ht_used;
1834
1835 return IterNew(dii,
1836 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1837 NULL, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02001838}
1839
1840 static PyInt
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001841DictionaryAssItem(
1842 DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +02001843{
1844 char_u *key;
1845 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001846 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001847 dictitem_T *di;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001848 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001849
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001850 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +02001851 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001852 RAISE_LOCKED_DICTIONARY;
Bram Moolenaardb913952012-06-29 12:54:53 +02001853 return -1;
1854 }
1855
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001856 if (!(key = StringToChars(keyObject, &todecref)))
1857 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001858
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001859 if (*key == NUL)
1860 {
1861 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001862 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001863 return -1;
1864 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001865
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001866 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +02001867
1868 if (valObject == NULL)
1869 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +02001870 hashitem_T *hi;
1871
Bram Moolenaardb913952012-06-29 12:54:53 +02001872 if (di == NULL)
1873 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001874 Py_XDECREF(todecref);
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001875 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +02001876 return -1;
1877 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001878 hi = hash_find(&dict->dv_hashtab, di->di_key);
1879 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +02001880 dictitem_free(di);
Bram Moolenaar78b59572013-06-02 18:54:21 +02001881 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001882 return 0;
1883 }
1884
1885 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaar78b59572013-06-02 18:54:21 +02001886 {
1887 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001888 return -1;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001889 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001890
1891 if (di == NULL)
1892 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001893 if (!(di = dictitem_alloc(key)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001894 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001895 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001896 PyErr_NoMemory();
1897 return -1;
1898 }
Bram Moolenaara9922d62013-05-30 13:01:18 +02001899 di->di_tv.v_type = VAR_UNKNOWN;
Bram Moolenaardb913952012-06-29 12:54:53 +02001900
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001901 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001902 {
1903 vim_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001904 dictitem_free(di);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001905 RAISE_KEY_ADD_FAIL(key);
1906 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001907 return -1;
1908 }
1909 }
1910 else
1911 clear_tv(&di->di_tv);
1912
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001913 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001914
1915 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001916 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001917 return 0;
1918}
1919
Bram Moolenaara9922d62013-05-30 13:01:18 +02001920typedef PyObject *(*hi_to_py)(hashitem_T *);
1921
Bram Moolenaardb913952012-06-29 12:54:53 +02001922 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001923DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
Bram Moolenaardb913952012-06-29 12:54:53 +02001924{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001925 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001926 long_u todo = dict->dv_hashtab.ht_used;
1927 Py_ssize_t i = 0;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001928 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001929 hashitem_T *hi;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001930 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +02001931
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001932 ret = PyList_New(todo);
Bram Moolenaardb913952012-06-29 12:54:53 +02001933 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1934 {
1935 if (!HASHITEM_EMPTY(hi))
1936 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001937 if (!(newObj = hiconvert(hi)))
1938 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001939 Py_DECREF(ret);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001940 return NULL;
1941 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001942 PyList_SET_ITEM(ret, i, newObj);
Bram Moolenaardb913952012-06-29 12:54:53 +02001943 --todo;
1944 ++i;
1945 }
1946 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001947 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001948}
1949
Bram Moolenaara9922d62013-05-30 13:01:18 +02001950 static PyObject *
1951dict_key(hashitem_T *hi)
1952{
1953 return PyBytes_FromString((char *)(hi->hi_key));
1954}
1955
1956 static PyObject *
1957DictionaryListKeys(DictionaryObject *self)
1958{
1959 return DictionaryListObjects(self, dict_key);
1960}
1961
1962 static PyObject *
1963dict_val(hashitem_T *hi)
1964{
1965 dictitem_T *di;
1966
1967 di = dict_lookup(hi);
1968 return ConvertToPyObject(&di->di_tv);
1969}
1970
1971 static PyObject *
1972DictionaryListValues(DictionaryObject *self)
1973{
1974 return DictionaryListObjects(self, dict_val);
1975}
1976
1977 static PyObject *
1978dict_item(hashitem_T *hi)
1979{
1980 PyObject *keyObject;
1981 PyObject *valObject;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001982 PyObject *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001983
1984 if (!(keyObject = dict_key(hi)))
1985 return NULL;
1986
1987 if (!(valObject = dict_val(hi)))
1988 {
1989 Py_DECREF(keyObject);
1990 return NULL;
1991 }
1992
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001993 ret = Py_BuildValue("(OO)", keyObject, valObject);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001994
1995 Py_DECREF(keyObject);
1996 Py_DECREF(valObject);
1997
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001998 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001999}
2000
2001 static PyObject *
2002DictionaryListItems(DictionaryObject *self)
2003{
2004 return DictionaryListObjects(self, dict_item);
2005}
2006
2007 static PyObject *
2008DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
2009{
2010 dict_T *dict = self->dict;
2011
2012 if (dict->dv_lock)
2013 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002014 RAISE_LOCKED_DICTIONARY;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002015 return NULL;
2016 }
2017
2018 if (kwargs)
2019 {
2020 typval_T tv;
2021
2022 if (ConvertFromPyMapping(kwargs, &tv) == -1)
2023 return NULL;
2024
2025 VimTryStart();
2026 dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force");
2027 clear_tv(&tv);
2028 if (VimTryEnd())
2029 return NULL;
2030 }
2031 else
2032 {
Bram Moolenaar2d5f38f2014-02-11 18:47:27 +01002033 PyObject *obj = NULL;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002034
Bram Moolenaar2d5f38f2014-02-11 18:47:27 +01002035 if (!PyArg_ParseTuple(args, "|O", &obj))
Bram Moolenaara9922d62013-05-30 13:01:18 +02002036 return NULL;
2037
Bram Moolenaar2d5f38f2014-02-11 18:47:27 +01002038 if (obj == NULL)
2039 {
2040 Py_INCREF(Py_None);
2041 return Py_None;
2042 }
2043
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002044 if (PyObject_HasAttrString(obj, "keys"))
2045 return DictionaryUpdate(self, NULL, obj);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002046 else
2047 {
2048 PyObject *iterator;
2049 PyObject *item;
2050
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002051 if (!(iterator = PyObject_GetIter(obj)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02002052 return NULL;
2053
2054 while ((item = PyIter_Next(iterator)))
2055 {
2056 PyObject *fast;
2057 PyObject *keyObject;
2058 PyObject *valObject;
2059 PyObject *todecref;
2060 char_u *key;
2061 dictitem_T *di;
Bram Moolenaar9ed7d342017-11-09 22:10:33 +01002062 hashitem_T *hi;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002063
2064 if (!(fast = PySequence_Fast(item, "")))
2065 {
2066 Py_DECREF(iterator);
2067 Py_DECREF(item);
2068 return NULL;
2069 }
2070
2071 Py_DECREF(item);
2072
2073 if (PySequence_Fast_GET_SIZE(fast) != 2)
2074 {
2075 Py_DECREF(iterator);
2076 Py_DECREF(fast);
Bram Moolenaarc476e522013-06-23 13:46:40 +02002077 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002078 N_("expected sequence element of size 2, "
2079 "but got sequence of size %d"),
Bram Moolenaardee2e312013-06-23 16:35:47 +02002080 (int) PySequence_Fast_GET_SIZE(fast));
Bram Moolenaara9922d62013-05-30 13:01:18 +02002081 return NULL;
2082 }
2083
2084 keyObject = PySequence_Fast_GET_ITEM(fast, 0);
2085
2086 if (!(key = StringToChars(keyObject, &todecref)))
2087 {
2088 Py_DECREF(iterator);
2089 Py_DECREF(fast);
2090 return NULL;
2091 }
2092
2093 di = dictitem_alloc(key);
2094
2095 Py_XDECREF(todecref);
2096
2097 if (di == NULL)
2098 {
2099 Py_DECREF(fast);
2100 Py_DECREF(iterator);
2101 PyErr_NoMemory();
2102 return NULL;
2103 }
Bram Moolenaara9922d62013-05-30 13:01:18 +02002104 di->di_tv.v_type = VAR_UNKNOWN;
2105
2106 valObject = PySequence_Fast_GET_ITEM(fast, 1);
2107
2108 if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
2109 {
2110 Py_DECREF(iterator);
2111 Py_DECREF(fast);
2112 dictitem_free(di);
2113 return NULL;
2114 }
2115
2116 Py_DECREF(fast);
2117
Bram Moolenaar9ed7d342017-11-09 22:10:33 +01002118 hi = hash_find(&dict->dv_hashtab, di->di_key);
2119 if (!HASHITEM_EMPTY(hi) || dict_add(dict, di) == FAIL)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002120 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002121 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002122 Py_DECREF(iterator);
2123 dictitem_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002124 return NULL;
2125 }
2126 }
2127
2128 Py_DECREF(iterator);
2129
2130 /* Iterator may have finished due to an exception */
2131 if (PyErr_Occurred())
2132 return NULL;
2133 }
2134 }
2135 Py_INCREF(Py_None);
2136 return Py_None;
2137}
2138
2139 static PyObject *
2140DictionaryGet(DictionaryObject *self, PyObject *args)
2141{
2142 return _DictionaryItem(self, args,
2143 DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
2144}
2145
2146 static PyObject *
2147DictionaryPop(DictionaryObject *self, PyObject *args)
2148{
2149 return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
2150}
2151
2152 static PyObject *
Bram Moolenaarde71b562013-06-02 17:41:54 +02002153DictionaryPopItem(DictionaryObject *self)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002154{
Bram Moolenaarde71b562013-06-02 17:41:54 +02002155 hashitem_T *hi;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002156 PyObject *ret;
Bram Moolenaarde71b562013-06-02 17:41:54 +02002157 PyObject *valObject;
2158 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002159
Bram Moolenaarde71b562013-06-02 17:41:54 +02002160 if (self->dict->dv_hashtab.ht_used == 0)
2161 {
2162 PyErr_SetNone(PyExc_KeyError);
2163 return NULL;
2164 }
2165
2166 hi = self->dict->dv_hashtab.ht_array;
2167 while (HASHITEM_EMPTY(hi))
2168 ++hi;
2169
2170 di = dict_lookup(hi);
2171
2172 if (!(valObject = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02002173 return NULL;
2174
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002175 if (!(ret = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
Bram Moolenaarde71b562013-06-02 17:41:54 +02002176 {
2177 Py_DECREF(valObject);
2178 return NULL;
2179 }
2180
2181 hash_remove(&self->dict->dv_hashtab, hi);
2182 dictitem_free(di);
2183
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002184 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002185}
2186
2187 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02002188DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002189{
Bram Moolenaara9922d62013-05-30 13:01:18 +02002190 return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
2191}
2192
2193static PySequenceMethods DictionaryAsSeq = {
2194 0, /* sq_length */
2195 0, /* sq_concat */
2196 0, /* sq_repeat */
2197 0, /* sq_item */
2198 0, /* sq_slice */
2199 0, /* sq_ass_item */
2200 0, /* sq_ass_slice */
2201 (objobjproc) DictionaryContains, /* sq_contains */
2202 0, /* sq_inplace_concat */
2203 0, /* sq_inplace_repeat */
2204};
2205
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002206static PyMappingMethods DictionaryAsMapping = {
2207 (lenfunc) DictionaryLength,
2208 (binaryfunc) DictionaryItem,
2209 (objobjargproc) DictionaryAssItem,
2210};
2211
Bram Moolenaardb913952012-06-29 12:54:53 +02002212static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02002213 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaara9922d62013-05-30 13:01:18 +02002214 {"values", (PyCFunction)DictionaryListValues, METH_NOARGS, ""},
2215 {"items", (PyCFunction)DictionaryListItems, METH_NOARGS, ""},
2216 {"update", (PyCFunction)DictionaryUpdate, METH_VARARGS|METH_KEYWORDS, ""},
2217 {"get", (PyCFunction)DictionaryGet, METH_VARARGS, ""},
2218 {"pop", (PyCFunction)DictionaryPop, METH_VARARGS, ""},
Bram Moolenaarde71b562013-06-02 17:41:54 +02002219 {"popitem", (PyCFunction)DictionaryPopItem, METH_NOARGS, ""},
Bram Moolenaar389a1792013-06-23 13:00:44 +02002220 {"has_key", (PyCFunction)DictionaryHasKey, METH_O, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002221 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
2222 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002223};
2224
2225static PyTypeObject ListType;
2226
2227typedef struct
2228{
2229 PyObject_HEAD
2230 list_T *list;
2231 pylinkedlist_T ref;
2232} ListObject;
2233
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002234#define NEW_LIST(list) ListNew(&ListType, list)
2235
Bram Moolenaardb913952012-06-29 12:54:53 +02002236 static PyObject *
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002237ListNew(PyTypeObject *subtype, list_T *list)
Bram Moolenaardb913952012-06-29 12:54:53 +02002238{
2239 ListObject *self;
2240
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002241 self = (ListObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02002242 if (self == NULL)
2243 return NULL;
2244 self->list = list;
2245 ++list->lv_refcount;
2246
2247 pyll_add((PyObject *)(self), &self->ref, &lastlist);
2248
2249 return (PyObject *)(self);
2250}
2251
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002252 static list_T *
Bram Moolenaarfb97f282013-07-09 17:42:46 +02002253py_list_alloc(void)
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002254{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002255 list_T *ret;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002256
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002257 if (!(ret = list_alloc()))
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002258 {
2259 PyErr_NoMemory();
2260 return NULL;
2261 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002262 ++ret->lv_refcount;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002263
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002264 return ret;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002265}
2266
2267 static int
2268list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
2269{
2270 PyObject *iterator;
2271 PyObject *item;
2272 listitem_T *li;
2273
2274 if (!(iterator = PyObject_GetIter(obj)))
2275 return -1;
2276
2277 while ((item = PyIter_Next(iterator)))
2278 {
2279 if (!(li = listitem_alloc()))
2280 {
2281 PyErr_NoMemory();
2282 Py_DECREF(item);
2283 Py_DECREF(iterator);
2284 return -1;
2285 }
2286 li->li_tv.v_lock = 0;
2287 li->li_tv.v_type = VAR_UNKNOWN;
2288
2289 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
2290 {
2291 Py_DECREF(item);
2292 Py_DECREF(iterator);
2293 listitem_free(li);
2294 return -1;
2295 }
2296
2297 Py_DECREF(item);
2298
2299 list_append(l, li);
2300 }
2301
2302 Py_DECREF(iterator);
2303
2304 /* Iterator may have finished due to an exception */
2305 if (PyErr_Occurred())
2306 return -1;
2307
2308 return 0;
2309}
2310
2311 static PyObject *
2312ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2313{
2314 list_T *list;
2315 PyObject *obj = NULL;
2316
2317 if (kwargs)
2318 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002319 PyErr_SET_STRING(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002320 N_("list constructor does not accept keyword arguments"));
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002321 return NULL;
2322 }
2323
2324 if (!PyArg_ParseTuple(args, "|O", &obj))
2325 return NULL;
2326
2327 if (!(list = py_list_alloc()))
2328 return NULL;
2329
2330 if (obj)
2331 {
2332 PyObject *lookup_dict;
2333
2334 if (!(lookup_dict = PyDict_New()))
2335 {
2336 list_unref(list);
2337 return NULL;
2338 }
2339
2340 if (list_py_concat(list, obj, lookup_dict) == -1)
2341 {
2342 Py_DECREF(lookup_dict);
2343 list_unref(list);
2344 return NULL;
2345 }
2346
2347 Py_DECREF(lookup_dict);
2348 }
2349
2350 return ListNew(subtype, list);
2351}
2352
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002353 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002354ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002355{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002356 pyll_remove(&self->ref, &lastlist);
2357 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002358
2359 DESTRUCTOR_FINISH(self);
2360}
2361
Bram Moolenaardb913952012-06-29 12:54:53 +02002362 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002363ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02002364{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002365 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02002366}
2367
2368 static PyObject *
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002369ListIndex(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02002370{
2371 listitem_T *li;
2372
Bram Moolenaard6e39182013-05-21 18:30:34 +02002373 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02002374 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002375 PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002376 return NULL;
2377 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02002378 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002379 if (li == NULL)
2380 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002381 /* No more suitable format specifications in python-2.3 */
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002382 PyErr_VIM_FORMAT(N_("internal error: failed to get vim list item %d"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02002383 (int) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002384 return NULL;
2385 }
2386 return ConvertToPyObject(&li->li_tv);
2387}
2388
Bram Moolenaardb913952012-06-29 12:54:53 +02002389 static PyObject *
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002390ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step,
2391 Py_ssize_t slicelen)
Bram Moolenaardb913952012-06-29 12:54:53 +02002392{
2393 PyInt i;
Bram Moolenaardb913952012-06-29 12:54:53 +02002394 PyObject *list;
Bram Moolenaardb913952012-06-29 12:54:53 +02002395
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002396 if (step == 0)
2397 {
2398 PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2399 return NULL;
2400 }
Bram Moolenaardb913952012-06-29 12:54:53 +02002401
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002402 list = PyList_New(slicelen);
Bram Moolenaardb913952012-06-29 12:54:53 +02002403 if (list == NULL)
2404 return NULL;
2405
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002406 for (i = 0; i < slicelen; ++i)
Bram Moolenaardb913952012-06-29 12:54:53 +02002407 {
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002408 PyObject *item;
2409
2410 item = ListIndex(self, first + i*step);
Bram Moolenaardb913952012-06-29 12:54:53 +02002411 if (item == NULL)
2412 {
2413 Py_DECREF(list);
2414 return NULL;
2415 }
2416
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002417 PyList_SET_ITEM(list, i, item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002418 }
2419
2420 return list;
2421}
2422
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002423 static PyObject *
2424ListItem(ListObject *self, PyObject* idx)
2425{
2426#if PY_MAJOR_VERSION < 3
2427 if (PyInt_Check(idx))
2428 {
2429 long _idx = PyInt_AsLong(idx);
2430 return ListIndex(self, _idx);
2431 }
2432 else
2433#endif
2434 if (PyLong_Check(idx))
2435 {
2436 long _idx = PyLong_AsLong(idx);
2437 return ListIndex(self, _idx);
2438 }
2439 else if (PySlice_Check(idx))
2440 {
2441 Py_ssize_t start, stop, step, slicelen;
2442
Bram Moolenaar922a4662014-03-30 16:11:43 +02002443 if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002444 &start, &stop, &step, &slicelen) < 0)
2445 return NULL;
2446 return ListSlice(self, start, step, slicelen);
2447 }
2448 else
2449 {
2450 RAISE_INVALID_INDEX_TYPE(idx);
2451 return NULL;
2452 }
2453}
2454
2455 static void
2456list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen,
2457 list_T *l, listitem_T **lis, listitem_T *lastaddedli)
2458{
2459 while (numreplaced--)
2460 {
2461 list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]);
2462 listitem_remove(l, lis[slicelen + numreplaced]);
2463 }
2464 while (numadded--)
2465 {
2466 listitem_T *next;
2467
2468 next = lastaddedli->li_prev;
2469 listitem_remove(l, lastaddedli);
2470 lastaddedli = next;
2471 }
2472}
2473
2474 static int
2475ListAssSlice(ListObject *self, Py_ssize_t first,
2476 Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj)
2477{
2478 PyObject *iterator;
2479 PyObject *item;
2480 listitem_T *li;
2481 listitem_T *lastaddedli = NULL;
2482 listitem_T *next;
2483 typval_T v;
2484 list_T *l = self->list;
2485 PyInt i;
2486 PyInt j;
2487 PyInt numreplaced = 0;
2488 PyInt numadded = 0;
2489 PyInt size;
Bram Moolenaar3b522612014-02-11 16:00:35 +01002490 listitem_T **lis = NULL;
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002491
2492 size = ListLength(self);
2493
2494 if (l->lv_lock)
2495 {
2496 RAISE_LOCKED_LIST;
2497 return -1;
2498 }
2499
2500 if (step == 0)
2501 {
2502 PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2503 return -1;
2504 }
2505
2506 if (step != 1 && slicelen == 0)
2507 {
2508 /* Nothing to do. Only error out if obj has some items. */
2509 int ret = 0;
2510
2511 if (obj == NULL)
2512 return 0;
2513
2514 if (!(iterator = PyObject_GetIter(obj)))
2515 return -1;
2516
2517 if ((item = PyIter_Next(iterator)))
2518 {
2519 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar4de6a212014-03-08 16:13:44 +01002520 N_("attempt to assign sequence of size greater than %d "
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002521 "to extended slice"), 0);
2522 Py_DECREF(item);
2523 ret = -1;
2524 }
2525 Py_DECREF(iterator);
2526 return ret;
2527 }
2528
2529 if (obj != NULL)
2530 /* XXX May allocate zero bytes. */
2531 if (!(lis = PyMem_New(listitem_T *, slicelen * 2)))
2532 {
2533 PyErr_NoMemory();
2534 return -1;
2535 }
2536
2537 if (first == size)
2538 li = NULL;
2539 else
2540 {
2541 li = list_find(l, (long) first);
2542 if (li == NULL)
2543 {
2544 PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
2545 (int)first);
2546 if (obj != NULL)
2547 PyMem_Free(lis);
2548 return -1;
2549 }
2550 i = slicelen;
2551 while (i-- && li != NULL)
2552 {
2553 j = step;
2554 next = li;
2555 if (step > 0)
2556 while (next != NULL && ((next = next->li_next) != NULL) && --j);
2557 else
2558 while (next != NULL && ((next = next->li_prev) != NULL) && ++j);
2559
2560 if (obj == NULL)
2561 listitem_remove(l, li);
2562 else
2563 lis[slicelen - i - 1] = li;
2564
2565 li = next;
2566 }
2567 if (li == NULL && i != -1)
2568 {
2569 PyErr_SET_VIM(N_("internal error: not enough list items"));
2570 if (obj != NULL)
2571 PyMem_Free(lis);
2572 return -1;
2573 }
2574 }
2575
2576 if (obj == NULL)
2577 return 0;
2578
2579 if (!(iterator = PyObject_GetIter(obj)))
2580 {
2581 PyMem_Free(lis);
2582 return -1;
2583 }
2584
2585 i = 0;
2586 while ((item = PyIter_Next(iterator)))
2587 {
2588 if (ConvertFromPyObject(item, &v) == -1)
2589 {
2590 Py_DECREF(iterator);
2591 Py_DECREF(item);
2592 PyMem_Free(lis);
2593 return -1;
2594 }
2595 Py_DECREF(item);
2596 if (list_insert_tv(l, &v, numreplaced < slicelen
2597 ? lis[numreplaced]
2598 : li) == FAIL)
2599 {
2600 clear_tv(&v);
2601 PyErr_SET_VIM(N_("internal error: failed to add item to list"));
2602 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2603 PyMem_Free(lis);
2604 return -1;
2605 }
2606 if (numreplaced < slicelen)
2607 {
2608 lis[slicelen + numreplaced] = lis[numreplaced]->li_prev;
Bram Moolenaar3ec7f4e2014-05-07 17:31:37 +02002609 vimlist_remove(l, lis[numreplaced], lis[numreplaced]);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002610 numreplaced++;
2611 }
2612 else
2613 {
2614 if (li)
2615 lastaddedli = li->li_prev;
2616 else
2617 lastaddedli = l->lv_last;
2618 numadded++;
2619 }
2620 clear_tv(&v);
2621 if (step != 1 && i >= slicelen)
2622 {
2623 Py_DECREF(iterator);
2624 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar4de6a212014-03-08 16:13:44 +01002625 N_("attempt to assign sequence of size greater than %d "
Bram Moolenaar403b3cf2014-02-15 15:59:03 +01002626 "to extended slice"), (int) slicelen);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002627 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2628 PyMem_Free(lis);
2629 return -1;
2630 }
2631 ++i;
2632 }
2633 Py_DECREF(iterator);
2634
2635 if (step != 1 && i != slicelen)
2636 {
2637 PyErr_FORMAT2(PyExc_ValueError,
Bram Moolenaar403b3cf2014-02-15 15:59:03 +01002638 N_("attempt to assign sequence of size %d to extended slice "
2639 "of size %d"), (int) i, (int) slicelen);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002640 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2641 PyMem_Free(lis);
2642 return -1;
2643 }
2644
2645 if (PyErr_Occurred())
2646 {
2647 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2648 PyMem_Free(lis);
2649 return -1;
2650 }
2651
2652 for (i = 0; i < numreplaced; i++)
2653 listitem_free(lis[i]);
2654 if (step == 1)
2655 for (i = numreplaced; i < slicelen; i++)
2656 listitem_remove(l, lis[i]);
2657
2658 PyMem_Free(lis);
2659
2660 return 0;
2661}
2662
2663 static int
2664ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
2665{
2666 typval_T tv;
2667 list_T *l = self->list;
2668 listitem_T *li;
2669 Py_ssize_t length = ListLength(self);
2670
2671 if (l->lv_lock)
2672 {
2673 RAISE_LOCKED_LIST;
2674 return -1;
2675 }
2676 if (index > length || (index == length && obj == NULL))
2677 {
2678 PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
2679 return -1;
2680 }
2681
2682 if (obj == NULL)
2683 {
2684 li = list_find(l, (long) index);
Bram Moolenaar3ec7f4e2014-05-07 17:31:37 +02002685 vimlist_remove(l, li, li);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002686 clear_tv(&li->li_tv);
2687 vim_free(li);
2688 return 0;
2689 }
2690
2691 if (ConvertFromPyObject(obj, &tv) == -1)
2692 return -1;
2693
2694 if (index == length)
2695 {
2696 if (list_append_tv(l, &tv) == FAIL)
2697 {
2698 clear_tv(&tv);
2699 PyErr_SET_VIM(N_("failed to add item to list"));
2700 return -1;
2701 }
2702 }
2703 else
2704 {
2705 li = list_find(l, (long) index);
2706 clear_tv(&li->li_tv);
2707 copy_tv(&tv, &li->li_tv);
2708 clear_tv(&tv);
2709 }
2710 return 0;
2711}
2712
2713 static Py_ssize_t
2714ListAssItem(ListObject *self, PyObject *idx, PyObject *obj)
2715{
2716#if PY_MAJOR_VERSION < 3
2717 if (PyInt_Check(idx))
2718 {
2719 long _idx = PyInt_AsLong(idx);
2720 return ListAssIndex(self, _idx, obj);
2721 }
2722 else
2723#endif
2724 if (PyLong_Check(idx))
2725 {
2726 long _idx = PyLong_AsLong(idx);
2727 return ListAssIndex(self, _idx, obj);
2728 }
2729 else if (PySlice_Check(idx))
2730 {
2731 Py_ssize_t start, stop, step, slicelen;
2732
Bram Moolenaar922a4662014-03-30 16:11:43 +02002733 if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002734 &start, &stop, &step, &slicelen) < 0)
2735 return -1;
2736 return ListAssSlice(self, start, step, slicelen,
2737 obj);
2738 }
2739 else
2740 {
2741 RAISE_INVALID_INDEX_TYPE(idx);
2742 return -1;
2743 }
2744}
2745
2746 static PyObject *
2747ListConcatInPlace(ListObject *self, PyObject *obj)
2748{
2749 list_T *l = self->list;
2750 PyObject *lookup_dict;
2751
2752 if (l->lv_lock)
2753 {
2754 RAISE_LOCKED_LIST;
2755 return NULL;
2756 }
2757
2758 if (!(lookup_dict = PyDict_New()))
2759 return NULL;
2760
2761 if (list_py_concat(l, obj, lookup_dict) == -1)
2762 {
2763 Py_DECREF(lookup_dict);
2764 return NULL;
2765 }
2766 Py_DECREF(lookup_dict);
2767
2768 Py_INCREF(self);
2769 return (PyObject *)(self);
2770}
2771
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002772typedef struct
2773{
2774 listwatch_T lw;
2775 list_T *list;
2776} listiterinfo_T;
2777
2778 static void
2779ListIterDestruct(listiterinfo_T *lii)
2780{
2781 list_rem_watch(lii->list, &lii->lw);
2782 PyMem_Free(lii);
2783}
2784
2785 static PyObject *
2786ListIterNext(listiterinfo_T **lii)
2787{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002788 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002789
2790 if (!((*lii)->lw.lw_item))
2791 return NULL;
2792
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002793 if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002794 return NULL;
2795
2796 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
2797
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002798 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002799}
2800
2801 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002802ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002803{
2804 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002805 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002806
2807 if (!(lii = PyMem_New(listiterinfo_T, 1)))
2808 {
2809 PyErr_NoMemory();
2810 return NULL;
2811 }
2812
2813 list_add_watch(l, &lii->lw);
2814 lii->lw.lw_item = l->lv_first;
2815 lii->list = l;
2816
2817 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002818 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
2819 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002820}
2821
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002822static char *ListAttrs[] = {
2823 "locked",
2824 NULL
2825};
2826
2827 static PyObject *
2828ListDir(PyObject *self)
2829{
2830 return ObjectDir(self, ListAttrs);
2831}
2832
Bram Moolenaar66b79852012-09-21 14:00:35 +02002833 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002834ListSetattr(ListObject *self, char *name, PyObject *valObject)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002835{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002836 if (valObject == NULL)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002837 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002838 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002839 N_("cannot delete vim.List attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02002840 return -1;
2841 }
2842
2843 if (strcmp(name, "locked") == 0)
2844 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002845 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002846 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002847 PyErr_SET_STRING(PyExc_TypeError, N_("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02002848 return -1;
2849 }
2850 else
2851 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002852 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarb983f752013-05-15 16:11:50 +02002853 if (istrue == -1)
2854 return -1;
2855 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002856 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002857 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02002858 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002859 }
2860 return 0;
2861 }
2862 else
2863 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002864 PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02002865 return -1;
2866 }
2867}
2868
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002869static PySequenceMethods ListAsSeq = {
2870 (lenfunc) ListLength, /* sq_length, len(x) */
2871 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
2872 0, /* RangeRepeat, sq_repeat, x*n */
2873 (PyIntArgFunc) ListIndex, /* sq_item, x[i] */
2874 0, /* was_sq_slice, x[i:j] */
2875 (PyIntObjArgProc) ListAssIndex, /* sq_as_item, x[i]=v */
2876 0, /* was_sq_ass_slice, x[i:j]=v */
2877 0, /* sq_contains */
2878 (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */
2879 0, /* sq_inplace_repeat */
2880};
2881
2882static PyMappingMethods ListAsMapping = {
2883 /* mp_length */ (lenfunc) ListLength,
2884 /* mp_subscript */ (binaryfunc) ListItem,
2885 /* mp_ass_subscript */ (objobjargproc) ListAssItem,
2886};
2887
Bram Moolenaardb913952012-06-29 12:54:53 +02002888static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002889 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
2890 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
2891 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002892};
2893
2894typedef struct
2895{
2896 PyObject_HEAD
2897 char_u *name;
Bram Moolenaar8110a092016-04-14 15:56:09 +02002898 int argc;
2899 typval_T *argv;
2900 dict_T *self;
2901 pylinkedlist_T ref;
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02002902 int auto_rebind;
Bram Moolenaardb913952012-06-29 12:54:53 +02002903} FunctionObject;
2904
2905static PyTypeObject FunctionType;
2906
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02002907#define NEW_FUNCTION(name, argc, argv, self, pt_auto) \
2908 FunctionNew(&FunctionType, (name), (argc), (argv), (self), (pt_auto))
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002909
Bram Moolenaardb913952012-06-29 12:54:53 +02002910 static PyObject *
Bram Moolenaar8110a092016-04-14 15:56:09 +02002911FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02002912 dict_T *selfdict, int auto_rebind)
Bram Moolenaardb913952012-06-29 12:54:53 +02002913{
2914 FunctionObject *self;
2915
Bram Moolenaar9123c0b2018-12-22 18:59:06 +01002916 self = (FunctionObject *)subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02002917 if (self == NULL)
2918 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002919
2920 if (isdigit(*name))
Bram Moolenaardb913952012-06-29 12:54:53 +02002921 {
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002922 if (!translated_function_exists(name))
2923 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002924 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002925 N_("unnamed function %s does not exist"), name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002926 return NULL;
2927 }
2928 self->name = vim_strsave(name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002929 }
2930 else
Bram Moolenaar9123c0b2018-12-22 18:59:06 +01002931 {
2932 char_u *p;
2933
2934 if ((p = get_expanded_name(name,
2935 vim_strchr(name, AUTOLOAD_CHAR) == NULL)) == NULL)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002936 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002937 PyErr_FORMAT(PyExc_ValueError,
2938 N_("function %s does not exist"), name);
Bram Moolenaar018acca2013-05-30 13:37:28 +02002939 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002940 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002941
Bram Moolenaar9123c0b2018-12-22 18:59:06 +01002942 if (p[0] == K_SPECIAL && p[1] == KS_EXTRA && p[2] == (int)KE_SNR)
2943 {
2944 char_u *np;
2945 size_t len = STRLEN(p) + 1;
2946
Bram Moolenaar80dae042018-12-23 13:36:40 +01002947 if ((np = alloc((int)len + 2)) == NULL)
Bram Moolenaar9123c0b2018-12-22 18:59:06 +01002948 {
2949 vim_free(p);
2950 return NULL;
2951 }
2952 mch_memmove(np, "<SNR>", 5);
2953 mch_memmove(np + 5, p + 3, len - 3);
2954 vim_free(p);
2955 self->name = np;
2956 }
2957 else
2958 self->name = p;
2959 }
2960
Bram Moolenaar2d3d60a2016-08-01 16:27:23 +02002961 func_ref(self->name);
Bram Moolenaar8110a092016-04-14 15:56:09 +02002962 self->argc = argc;
2963 self->argv = argv;
2964 self->self = selfdict;
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02002965 self->auto_rebind = selfdict == NULL ? TRUE : auto_rebind;
Bram Moolenaar8110a092016-04-14 15:56:09 +02002966
2967 if (self->argv || self->self)
2968 pyll_add((PyObject *)(self), &self->ref, &lastfunc);
2969
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002970 return (PyObject *)(self);
2971}
2972
2973 static PyObject *
2974FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2975{
2976 PyObject *self;
Bram Moolenaar8110a092016-04-14 15:56:09 +02002977 PyObject *selfdictObject;
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02002978 PyObject *autoRebindObject;
Bram Moolenaar8110a092016-04-14 15:56:09 +02002979 PyObject *argsObject = NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002980 char_u *name;
Bram Moolenaar8110a092016-04-14 15:56:09 +02002981 typval_T selfdicttv;
2982 typval_T argstv;
2983 list_T *argslist = NULL;
2984 dict_T *selfdict = NULL;
2985 int argc = 0;
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02002986 int auto_rebind = TRUE;
Bram Moolenaar8110a092016-04-14 15:56:09 +02002987 typval_T *argv = NULL;
2988 typval_T *curtv;
2989 listitem_T *li;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002990
Bram Moolenaar8110a092016-04-14 15:56:09 +02002991 if (kwargs != NULL)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002992 {
Bram Moolenaar8110a092016-04-14 15:56:09 +02002993 selfdictObject = PyDict_GetItemString(kwargs, "self");
2994 if (selfdictObject != NULL)
2995 {
2996 if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
2997 return NULL;
2998 selfdict = selfdicttv.vval.v_dict;
2999 }
3000 argsObject = PyDict_GetItemString(kwargs, "args");
3001 if (argsObject != NULL)
3002 {
3003 if (ConvertFromPySequence(argsObject, &argstv) == -1)
3004 {
3005 dict_unref(selfdict);
3006 return NULL;
3007 }
3008 argslist = argstv.vval.v_list;
3009
3010 argc = argslist->lv_len;
3011 if (argc != 0)
3012 {
3013 argv = PyMem_New(typval_T, (size_t) argc);
Bram Moolenaarfe4b1862016-04-15 21:47:54 +02003014 if (argv == NULL)
3015 {
3016 PyErr_NoMemory();
3017 dict_unref(selfdict);
3018 list_unref(argslist);
3019 return NULL;
3020 }
Bram Moolenaar8110a092016-04-14 15:56:09 +02003021 curtv = argv;
3022 for (li = argslist->lv_first; li != NULL; li = li->li_next)
3023 copy_tv(&li->li_tv, curtv++);
3024 }
3025 list_unref(argslist);
3026 }
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003027 if (selfdict != NULL)
3028 {
3029 auto_rebind = FALSE;
3030 autoRebindObject = PyDict_GetItemString(kwargs, "auto_rebind");
3031 if (autoRebindObject != NULL)
3032 {
3033 auto_rebind = PyObject_IsTrue(autoRebindObject);
3034 if (auto_rebind == -1)
3035 {
3036 dict_unref(selfdict);
3037 list_unref(argslist);
3038 return NULL;
3039 }
3040 }
3041 }
Bram Moolenaardb913952012-06-29 12:54:53 +02003042 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02003043
Bram Moolenaar389a1792013-06-23 13:00:44 +02003044 if (!PyArg_ParseTuple(args, "et", "ascii", &name))
Bram Moolenaar8110a092016-04-14 15:56:09 +02003045 {
3046 dict_unref(selfdict);
3047 while (argc--)
3048 clear_tv(&argv[argc]);
3049 PyMem_Free(argv);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02003050 return NULL;
Bram Moolenaar8110a092016-04-14 15:56:09 +02003051 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02003052
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003053 self = FunctionNew(subtype, name, argc, argv, selfdict, auto_rebind);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02003054
Bram Moolenaar389a1792013-06-23 13:00:44 +02003055 PyMem_Free(name);
3056
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02003057 return self;
Bram Moolenaardb913952012-06-29 12:54:53 +02003058}
3059
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003060 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003061FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003062{
Bram Moolenaar8110a092016-04-14 15:56:09 +02003063 int i;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003064 func_unref(self->name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02003065 vim_free(self->name);
Bram Moolenaar8110a092016-04-14 15:56:09 +02003066 for (i = 0; i < self->argc; ++i)
3067 clear_tv(&self->argv[i]);
3068 PyMem_Free(self->argv);
3069 dict_unref(self->self);
3070 if (self->argv || self->self)
3071 pyll_remove(&self->ref, &lastfunc);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003072
3073 DESTRUCTOR_FINISH(self);
3074}
3075
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003076static char *FunctionAttrs[] = {
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003077 "softspace", "args", "self", "auto_rebind",
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003078 NULL
3079};
3080
3081 static PyObject *
3082FunctionDir(PyObject *self)
3083{
3084 return ObjectDir(self, FunctionAttrs);
3085}
3086
Bram Moolenaardb913952012-06-29 12:54:53 +02003087 static PyObject *
Bram Moolenaar8110a092016-04-14 15:56:09 +02003088FunctionAttr(FunctionObject *self, char *name)
3089{
3090 list_T *list;
3091 int i;
3092 if (strcmp(name, "name") == 0)
3093 return PyString_FromString((char *)(self->name));
3094 else if (strcmp(name, "args") == 0)
3095 {
Bram Moolenaar9f289532016-08-26 16:39:03 +02003096 if (self->argv == NULL || (list = list_alloc()) == NULL)
Bram Moolenaar8110a092016-04-14 15:56:09 +02003097 return AlwaysNone(NULL);
Bram Moolenaar9f289532016-08-26 16:39:03 +02003098
Bram Moolenaar8110a092016-04-14 15:56:09 +02003099 for (i = 0; i < self->argc; ++i)
3100 list_append_tv(list, &self->argv[i]);
3101 return NEW_LIST(list);
3102 }
3103 else if (strcmp(name, "self") == 0)
3104 return self->self == NULL
3105 ? AlwaysNone(NULL)
3106 : NEW_DICTIONARY(self->self);
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003107 else if (strcmp(name, "auto_rebind") == 0)
3108 return self->auto_rebind
3109 ? AlwaysTrue(NULL)
3110 : AlwaysFalse(NULL);
Bram Moolenaar8110a092016-04-14 15:56:09 +02003111 else if (strcmp(name, "__members__") == 0)
3112 return ObjectDir(NULL, FunctionAttrs);
3113 return NULL;
3114}
3115
3116/* Populate partial_T given function object.
3117 *
3118 * "exported" should be set to true when it is needed to construct a partial
3119 * that may be stored in a variable (i.e. may be freed by Vim).
3120 */
3121 static void
3122set_partial(FunctionObject *self, partial_T *pt, int exported)
3123{
Bram Moolenaar8110a092016-04-14 15:56:09 +02003124 int i;
3125
3126 pt->pt_name = self->name;
3127 if (self->argv)
3128 {
3129 pt->pt_argc = self->argc;
3130 if (exported)
3131 {
3132 pt->pt_argv = (typval_T *)alloc_clear(
3133 sizeof(typval_T) * self->argc);
3134 for (i = 0; i < pt->pt_argc; ++i)
3135 copy_tv(&self->argv[i], &pt->pt_argv[i]);
3136 }
3137 else
3138 pt->pt_argv = self->argv;
3139 }
3140 else
3141 {
3142 pt->pt_argc = 0;
3143 pt->pt_argv = NULL;
3144 }
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003145 pt->pt_auto = self->auto_rebind || !exported;
Bram Moolenaar8110a092016-04-14 15:56:09 +02003146 pt->pt_dict = self->self;
3147 if (exported && self->self)
3148 ++pt->pt_dict->dv_refcount;
3149 if (exported)
3150 pt->pt_name = vim_strsave(pt->pt_name);
3151 pt->pt_refcount = 1;
3152}
3153
3154 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003155FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02003156{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003157 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02003158 typval_T args;
3159 typval_T selfdicttv;
3160 typval_T rettv;
3161 dict_T *selfdict = NULL;
3162 PyObject *selfdictObject;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003163 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02003164 int error;
Bram Moolenaar8110a092016-04-14 15:56:09 +02003165 partial_T pt;
3166 partial_T *pt_ptr = NULL;
Bram Moolenaardb913952012-06-29 12:54:53 +02003167
Bram Moolenaar8110a092016-04-14 15:56:09 +02003168 if (ConvertFromPySequence(argsObject, &args) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02003169 return NULL;
3170
3171 if (kwargs != NULL)
3172 {
3173 selfdictObject = PyDict_GetItemString(kwargs, "self");
3174 if (selfdictObject != NULL)
3175 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02003176 if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003177 {
3178 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02003179 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003180 }
Bram Moolenaardb913952012-06-29 12:54:53 +02003181 selfdict = selfdicttv.vval.v_dict;
3182 }
3183 }
3184
Bram Moolenaar8110a092016-04-14 15:56:09 +02003185 if (self->argv || self->self)
3186 {
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003187 vim_memset(&pt, 0, sizeof(partial_T));
Bram Moolenaar8110a092016-04-14 15:56:09 +02003188 set_partial(self, &pt, FALSE);
3189 pt_ptr = &pt;
3190 }
3191
Bram Moolenaar71700b82013-05-15 17:49:05 +02003192 Py_BEGIN_ALLOW_THREADS
3193 Python_Lock_Vim();
3194
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003195 VimTryStart();
Bram Moolenaar8110a092016-04-14 15:56:09 +02003196 error = func_call(name, &args, pt_ptr, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02003197
3198 Python_Release_Vim();
3199 Py_END_ALLOW_THREADS
3200
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003201 if (VimTryEnd())
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003202 ret = NULL;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003203 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02003204 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003205 ret = NULL;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003206 PyErr_VIM_FORMAT(N_("failed to run function %s"), (char *)name);
Bram Moolenaardb913952012-06-29 12:54:53 +02003207 }
3208 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003209 ret = ConvertToPyObject(&rettv);
Bram Moolenaardb913952012-06-29 12:54:53 +02003210
Bram Moolenaardb913952012-06-29 12:54:53 +02003211 clear_tv(&args);
3212 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003213 if (selfdict != NULL)
3214 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02003215
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003216 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02003217}
3218
Bram Moolenaara5b725c2013-05-30 12:43:54 +02003219 static PyObject *
3220FunctionRepr(FunctionObject *self)
3221{
Bram Moolenaar8110a092016-04-14 15:56:09 +02003222 PyObject *ret;
3223 garray_T repr_ga;
3224 int i;
3225 char_u *tofree = NULL;
3226 typval_T tv;
3227 char_u numbuf[NUMBUFLEN];
3228
3229 ga_init2(&repr_ga, (int)sizeof(char), 70);
3230 ga_concat(&repr_ga, (char_u *)"<vim.Function '");
3231 if (self->name)
3232 ga_concat(&repr_ga, self->name);
3233 else
3234 ga_concat(&repr_ga, (char_u *)"<NULL>");
3235 ga_append(&repr_ga, '\'');
3236 if (self->argv)
3237 {
3238 ga_concat(&repr_ga, (char_u *)", args=[");
3239 ++emsg_silent;
3240 for (i = 0; i < self->argc; i++)
3241 {
3242 if (i != 0)
3243 ga_concat(&repr_ga, (char_u *)", ");
3244 ga_concat(&repr_ga, tv2string(&self->argv[i], &tofree, numbuf,
3245 get_copyID()));
3246 vim_free(tofree);
3247 }
3248 --emsg_silent;
3249 ga_append(&repr_ga, ']');
3250 }
3251 if (self->self)
3252 {
3253 ga_concat(&repr_ga, (char_u *)", self=");
3254 tv.v_type = VAR_DICT;
3255 tv.vval.v_dict = self->self;
3256 ++emsg_silent;
3257 ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID()));
3258 --emsg_silent;
3259 vim_free(tofree);
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02003260 if (self->auto_rebind)
3261 ga_concat(&repr_ga, (char_u *)", auto_rebind=True");
Bram Moolenaar8110a092016-04-14 15:56:09 +02003262 }
3263 ga_append(&repr_ga, '>');
3264 ret = PyString_FromString((char *)repr_ga.ga_data);
3265 ga_clear(&repr_ga);
3266 return ret;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02003267}
3268
Bram Moolenaardb913952012-06-29 12:54:53 +02003269static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003270 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
3271 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02003272};
3273
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003274/*
3275 * Options object
3276 */
3277
3278static PyTypeObject OptionsType;
3279
3280typedef int (*checkfun)(void *);
3281
3282typedef struct
3283{
3284 PyObject_HEAD
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01003285 int opt_type;
3286 void *from;
3287 checkfun Check;
3288 PyObject *fromObj;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003289} OptionsObject;
3290
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003291 static int
3292dummy_check(void *arg UNUSED)
3293{
3294 return 0;
3295}
3296
3297 static PyObject *
3298OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
3299{
3300 OptionsObject *self;
3301
Bram Moolenaar774267b2013-05-21 20:51:59 +02003302 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003303 if (self == NULL)
3304 return NULL;
3305
3306 self->opt_type = opt_type;
3307 self->from = from;
3308 self->Check = Check;
3309 self->fromObj = fromObj;
3310 if (fromObj)
3311 Py_INCREF(fromObj);
3312
3313 return (PyObject *)(self);
3314}
3315
3316 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003317OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003318{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003319 PyObject_GC_UnTrack((void *)(self));
3320 Py_XDECREF(self->fromObj);
3321 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003322}
3323
3324 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003325OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003326{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003327 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003328 return 0;
3329}
3330
3331 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003332OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003333{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003334 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003335 return 0;
3336}
3337
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003338 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003339OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003340{
3341 char_u *key;
3342 int flags;
3343 long numval;
3344 char_u *stringval;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003345 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003346
Bram Moolenaard6e39182013-05-21 18:30:34 +02003347 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003348 return NULL;
3349
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003350 if (!(key = StringToChars(keyObject, &todecref)))
3351 return NULL;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003352
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003353 if (*key == NUL)
3354 {
3355 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003356 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003357 return NULL;
3358 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003359
3360 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003361 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003362
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003363 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003364
3365 if (flags == 0)
3366 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003367 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003368 return NULL;
3369 }
3370
3371 if (flags & SOPT_UNSET)
3372 {
3373 Py_INCREF(Py_None);
3374 return Py_None;
3375 }
3376 else if (flags & SOPT_BOOL)
3377 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003378 PyObject *ret;
3379 ret = numval ? Py_True : Py_False;
3380 Py_INCREF(ret);
3381 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003382 }
3383 else if (flags & SOPT_NUM)
3384 return PyInt_FromLong(numval);
3385 else if (flags & SOPT_STRING)
3386 {
3387 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003388 {
Bram Moolenaar41009372013-07-01 22:03:04 +02003389 PyObject *ret = PyBytes_FromString((char *)stringval);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003390 vim_free(stringval);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003391 return ret;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003392 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003393 else
3394 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003395 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003396 N_("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003397 return NULL;
3398 }
3399 }
3400 else
3401 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003402 PyErr_SET_VIM(N_("internal error: unknown option type"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003403 return NULL;
3404 }
3405}
3406
3407 static int
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01003408OptionsContains(OptionsObject *self, PyObject *keyObject)
3409{
3410 char_u *key;
3411 PyObject *todecref;
3412
3413 if (!(key = StringToChars(keyObject, &todecref)))
3414 return -1;
3415
3416 if (*key == NUL)
3417 {
3418 Py_XDECREF(todecref);
3419 return 0;
3420 }
3421
3422 if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL))
3423 {
3424 Py_XDECREF(todecref);
3425 return 1;
3426 }
3427 else
3428 {
3429 Py_XDECREF(todecref);
3430 return 0;
3431 }
3432}
3433
3434typedef struct
3435{
3436 void *lastoption;
3437 int opt_type;
3438} optiterinfo_T;
3439
3440 static PyObject *
3441OptionsIterNext(optiterinfo_T **oii)
3442{
3443 char_u *name;
3444
3445 if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type)))
3446 return PyString_FromString((char *)name);
3447
3448 return NULL;
3449}
3450
3451 static PyObject *
3452OptionsIter(OptionsObject *self)
3453{
3454 optiterinfo_T *oii;
3455
3456 if (!(oii = PyMem_New(optiterinfo_T, 1)))
3457 {
3458 PyErr_NoMemory();
3459 return NULL;
3460 }
3461
3462 oii->opt_type = self->opt_type;
3463 oii->lastoption = NULL;
3464
3465 return IterNew(oii,
3466 (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
3467 NULL, NULL);
3468}
3469
3470 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02003471set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02003472{
Bram Moolenaarb1443b42019-01-13 23:51:14 +01003473 char *errmsg;
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02003474
3475 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
3476 {
3477 if (VimTryEnd())
3478 return FAIL;
Bram Moolenaarb1443b42019-01-13 23:51:14 +01003479 PyErr_SetVim(errmsg);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02003480 return FAIL;
3481 }
3482 return OK;
3483}
3484
3485 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02003486set_option_value_for(
3487 char_u *key,
3488 int numval,
3489 char_u *stringval,
3490 int opt_flags,
3491 int opt_type,
3492 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003493{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003494 win_T *save_curwin = NULL;
3495 tabpage_T *save_curtab = NULL;
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02003496 bufref_T save_curbuf;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003497 int set_ret = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003498
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003499 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003500 switch (opt_type)
3501 {
3502 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02003503 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
Bram Moolenaard6949742013-06-16 14:18:28 +02003504 win_find_tabpage((win_T *)from), FALSE) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003505 {
Bram Moolenaarae38d052014-12-17 14:46:09 +01003506 restore_win(save_curwin, save_curtab, TRUE);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003507 if (VimTryEnd())
3508 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003509 PyErr_SET_VIM(N_("problem while switching windows"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003510 return -1;
3511 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003512 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3513 restore_win(save_curwin, save_curtab, TRUE);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003514 break;
3515 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02003516 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003517 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02003518 restore_buffer(&save_curbuf);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003519 break;
3520 case SREQ_GLOBAL:
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003521 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003522 break;
3523 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003524 if (set_ret == FAIL)
3525 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003526 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003527}
3528
3529 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003530OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003531{
3532 char_u *key;
3533 int flags;
3534 int opt_flags;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003535 int ret = 0;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003536 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003537
Bram Moolenaard6e39182013-05-21 18:30:34 +02003538 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003539 return -1;
3540
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003541 if (!(key = StringToChars(keyObject, &todecref)))
3542 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003543
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003544 if (*key == NUL)
3545 {
3546 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003547 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003548 return -1;
3549 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003550
3551 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003552 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003553
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003554 if (flags == 0)
3555 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003556 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003557 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003558 return -1;
3559 }
3560
3561 if (valObject == NULL)
3562 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003563 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003564 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003565 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003566 N_("unable to unset global option %s"), key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003567 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003568 return -1;
3569 }
3570 else if (!(flags & SOPT_GLOBAL))
3571 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003572 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003573 N_("unable to unset option %s "
3574 "which does not have global value"), key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003575 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003576 return -1;
3577 }
3578 else
3579 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003580 unset_global_local_option(key, self->from);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003581 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003582 return 0;
3583 }
3584 }
3585
Bram Moolenaard6e39182013-05-21 18:30:34 +02003586 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003587
3588 if (flags & SOPT_BOOL)
3589 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02003590 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02003591
Bram Moolenaarb983f752013-05-15 16:11:50 +02003592 if (istrue == -1)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003593 ret = -1;
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003594 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003595 ret = set_option_value_for(key, istrue, NULL,
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003596 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003597 }
3598 else if (flags & SOPT_NUM)
3599 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003600 long val;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003601
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003602 if (NumberToLong(valObject, &val, NUMBER_INT))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003603 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003604 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003605 return -1;
3606 }
3607
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003608 ret = set_option_value_for(key, (int) val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003609 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003610 }
3611 else
3612 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003613 char_u *val;
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003614 PyObject *todecref2;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003615
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003616 if ((val = StringToChars(valObject, &todecref2)))
3617 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003618 ret = set_option_value_for(key, 0, val, opt_flags,
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003619 self->opt_type, self->from);
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003620 Py_XDECREF(todecref2);
3621 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003622 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003623 ret = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003624 }
3625
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003626 Py_XDECREF(todecref);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003627
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003628 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003629}
3630
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01003631static PySequenceMethods OptionsAsSeq = {
3632 0, /* sq_length */
3633 0, /* sq_concat */
3634 0, /* sq_repeat */
3635 0, /* sq_item */
3636 0, /* sq_slice */
3637 0, /* sq_ass_item */
3638 0, /* sq_ass_slice */
3639 (objobjproc) OptionsContains, /* sq_contains */
3640 0, /* sq_inplace_concat */
3641 0, /* sq_inplace_repeat */
3642};
3643
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003644static PyMappingMethods OptionsAsMapping = {
3645 (lenfunc) NULL,
3646 (binaryfunc) OptionsItem,
3647 (objobjargproc) OptionsAssItem,
3648};
3649
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003650/* Tabpage object
3651 */
3652
3653typedef struct
3654{
3655 PyObject_HEAD
3656 tabpage_T *tab;
3657} TabPageObject;
3658
3659static PyObject *WinListNew(TabPageObject *tabObject);
3660
3661static PyTypeObject TabPageType;
3662
3663 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003664CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003665{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003666 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003667 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003668 PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003669 return -1;
3670 }
3671
3672 return 0;
3673}
3674
3675 static PyObject *
3676TabPageNew(tabpage_T *tab)
3677{
3678 TabPageObject *self;
3679
3680 if (TAB_PYTHON_REF(tab))
3681 {
3682 self = TAB_PYTHON_REF(tab);
3683 Py_INCREF(self);
3684 }
3685 else
3686 {
3687 self = PyObject_NEW(TabPageObject, &TabPageType);
3688 if (self == NULL)
3689 return NULL;
3690 self->tab = tab;
3691 TAB_PYTHON_REF(tab) = self;
3692 }
3693
3694 return (PyObject *)(self);
3695}
3696
3697 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003698TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003699{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003700 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
3701 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003702
3703 DESTRUCTOR_FINISH(self);
3704}
3705
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003706static char *TabPageAttrs[] = {
3707 "windows", "number", "vars", "window", "valid",
3708 NULL
3709};
3710
3711 static PyObject *
3712TabPageDir(PyObject *self)
3713{
3714 return ObjectDir(self, TabPageAttrs);
3715}
3716
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003717 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003718TabPageAttrValid(TabPageObject *self, char *name)
3719{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003720 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003721
3722 if (strcmp(name, "valid") != 0)
3723 return NULL;
3724
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003725 ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
3726 Py_INCREF(ret);
3727 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003728}
3729
3730 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003731TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003732{
3733 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003734 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003735 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003736 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003737 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003738 return NEW_DICTIONARY(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003739 else if (strcmp(name, "window") == 0)
3740 {
3741 /* For current tab window.c does not bother to set or update tp_curwin
3742 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003743 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003744 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003745 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02003746 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003747 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003748 else if (strcmp(name, "__members__") == 0)
3749 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003750 return NULL;
3751}
3752
3753 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003754TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003755{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003756 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003757 return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003758 else
3759 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003760 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003761
3762 if (t == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003763 return PyString_FromFormat("<tabpage object (unknown) at %p>",
3764 (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003765 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003766 return PyString_FromFormat("<tabpage %d>", t - 1);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003767 }
3768}
3769
3770static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003771 /* name, function, calling, documentation */
3772 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
3773 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003774};
3775
3776/*
3777 * Window list object
3778 */
3779
3780static PyTypeObject TabListType;
3781static PySequenceMethods TabListAsSeq;
3782
3783typedef struct
3784{
3785 PyObject_HEAD
3786} TabListObject;
3787
3788 static PyInt
3789TabListLength(PyObject *self UNUSED)
3790{
3791 tabpage_T *tp = first_tabpage;
3792 PyInt n = 0;
3793
3794 while (tp != NULL)
3795 {
3796 ++n;
3797 tp = tp->tp_next;
3798 }
3799
3800 return n;
3801}
3802
3803 static PyObject *
3804TabListItem(PyObject *self UNUSED, PyInt n)
3805{
3806 tabpage_T *tp;
3807
3808 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3809 if (n == 0)
3810 return TabPageNew(tp);
3811
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003812 PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003813 return NULL;
3814}
3815
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +02003816/*
3817 * Window object
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003818 */
3819
3820typedef struct
3821{
3822 PyObject_HEAD
3823 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003824 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003825} WindowObject;
3826
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003827static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003828
3829 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003830CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003831{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003832 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003833 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003834 PyErr_SET_VIM(N_("attempt to refer to deleted window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003835 return -1;
3836 }
3837
3838 return 0;
3839}
3840
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003841 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003842WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02003843{
3844 /* We need to handle deletion of windows underneath us.
3845 * If we add a "w_python*_ref" field to the win_T structure,
3846 * then we can get at it in win_free() in vim. We then
3847 * need to create only ONE Python object per window - if
3848 * we try to create a second, just INCREF the existing one
3849 * and return it. The (single) Python object referring to
3850 * the window is stored in "w_python*_ref".
3851 * On a win_free() we set the Python object's win_T* field
3852 * to an invalid value. We trap all uses of a window
3853 * object, and reject them if the win_T* field is invalid.
3854 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003855 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003856 * w_python_ref and w_python3_ref fields respectively.
3857 */
3858
3859 WindowObject *self;
3860
3861 if (WIN_PYTHON_REF(win))
3862 {
3863 self = WIN_PYTHON_REF(win);
3864 Py_INCREF(self);
3865 }
3866 else
3867 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02003868 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02003869 if (self == NULL)
3870 return NULL;
3871 self->win = win;
3872 WIN_PYTHON_REF(win) = self;
3873 }
3874
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003875 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3876
Bram Moolenaar971db462013-05-12 18:44:48 +02003877 return (PyObject *)(self);
3878}
3879
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003880 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003881WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003882{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003883 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02003884 if (self->win && self->win != INVALID_WINDOW_VALUE)
3885 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003886 Py_XDECREF(((PyObject *)(self->tabObject)));
3887 PyObject_GC_Del((void *)(self));
3888}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003889
Bram Moolenaar774267b2013-05-21 20:51:59 +02003890 static int
3891WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3892{
3893 Py_VISIT(((PyObject *)(self->tabObject)));
3894 return 0;
3895}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003896
Bram Moolenaar774267b2013-05-21 20:51:59 +02003897 static int
3898WindowClear(WindowObject *self)
3899{
3900 Py_CLEAR(self->tabObject);
3901 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003902}
3903
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003904 static win_T *
3905get_firstwin(TabPageObject *tabObject)
3906{
3907 if (tabObject)
3908 {
3909 if (CheckTabPage(tabObject))
3910 return NULL;
3911 /* For current tab window.c does not bother to set or update tp_firstwin
3912 */
3913 else if (tabObject->tab == curtab)
3914 return firstwin;
3915 else
3916 return tabObject->tab->tp_firstwin;
3917 }
3918 else
3919 return firstwin;
3920}
Bram Moolenaare950f992018-06-10 13:55:55 +02003921
3922// Use the same order as in the WindowAttr() function.
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003923static char *WindowAttrs[] = {
Bram Moolenaare950f992018-06-10 13:55:55 +02003924 "buffer",
3925 "cursor",
3926 "height",
3927 "row",
3928 "width",
3929 "col",
3930 "vars",
3931 "options",
3932 "number",
3933 "tabpage",
3934 "valid",
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003935 NULL
3936};
3937
3938 static PyObject *
3939WindowDir(PyObject *self)
3940{
3941 return ObjectDir(self, WindowAttrs);
3942}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003943
Bram Moolenaar971db462013-05-12 18:44:48 +02003944 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003945WindowAttrValid(WindowObject *self, char *name)
3946{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003947 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003948
3949 if (strcmp(name, "valid") != 0)
3950 return NULL;
3951
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003952 ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3953 Py_INCREF(ret);
3954 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003955}
3956
3957 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003958WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003959{
3960 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003961 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003962 else if (strcmp(name, "cursor") == 0)
3963 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003964 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003965
3966 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
3967 }
3968 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003969 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003970 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003971 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003972 else if (strcmp(name, "width") == 0)
Bram Moolenaar02631462017-09-22 15:20:32 +02003973 return PyLong_FromLong((long)(self->win->w_width));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003974 else if (strcmp(name, "col") == 0)
Bram Moolenaar53f81742017-09-22 14:35:51 +02003975 return PyLong_FromLong((long)(self->win->w_wincol));
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02003976 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003977 return NEW_DICTIONARY(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003978 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003979 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
3980 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02003981 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003982 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003983 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003984 return NULL;
3985 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003986 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003987 }
3988 else if (strcmp(name, "tabpage") == 0)
3989 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003990 Py_INCREF(self->tabObject);
3991 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003992 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003993 else if (strcmp(name, "__members__") == 0)
3994 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003995 else
3996 return NULL;
3997}
3998
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003999 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004000WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004001{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004002 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004003 return -1;
4004
4005 if (strcmp(name, "buffer") == 0)
4006 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004007 PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004008 return -1;
4009 }
4010 else if (strcmp(name, "cursor") == 0)
4011 {
4012 long lnum;
4013 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004014
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004015 if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004016 return -1;
4017
Bram Moolenaard6e39182013-05-21 18:30:34 +02004018 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004019 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004020 PyErr_SET_VIM(N_("cursor position outside buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004021 return -1;
4022 }
4023
4024 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004025 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004026 return -1;
4027
Bram Moolenaard6e39182013-05-21 18:30:34 +02004028 self->win->w_cursor.lnum = lnum;
4029 self->win->w_cursor.col = col;
Bram Moolenaar53901442018-07-25 22:02:36 +02004030 self->win->w_set_curswant = TRUE;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004031 self->win->w_cursor.coladd = 0;
Bram Moolenaar03a807a2011-07-07 15:08:58 +02004032 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004033 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004034
Bram Moolenaar03a807a2011-07-07 15:08:58 +02004035 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004036 return 0;
4037 }
4038 else if (strcmp(name, "height") == 0)
4039 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004040 long height;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004041 win_T *savewin;
4042
Bram Moolenaardee2e312013-06-23 16:35:47 +02004043 if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004044 return -1;
4045
4046#ifdef FEAT_GUI
4047 need_mouse_correct = TRUE;
4048#endif
4049 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004050 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004051
4052 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004053 win_setheight((int) height);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004054 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004055 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004056 return -1;
4057
4058 return 0;
4059 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004060 else if (strcmp(name, "width") == 0)
4061 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004062 long width;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004063 win_T *savewin;
4064
Bram Moolenaardee2e312013-06-23 16:35:47 +02004065 if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004066 return -1;
4067
4068#ifdef FEAT_GUI
4069 need_mouse_correct = TRUE;
4070#endif
4071 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004072 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004073
4074 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02004075 win_setwidth((int) width);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004076 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004077 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004078 return -1;
4079
4080 return 0;
4081 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004082 else
4083 {
4084 PyErr_SetString(PyExc_AttributeError, name);
4085 return -1;
4086 }
4087}
4088
4089 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004090WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004091{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004092 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004093 return PyString_FromFormat("<window object (deleted) at %p>", (self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004094 else
4095 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02004096 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004097
Bram Moolenaar6d216452013-05-12 19:00:41 +02004098 if (w == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004099 return PyString_FromFormat("<window object (unknown) at %p>",
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004100 (self));
4101 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004102 return PyString_FromFormat("<window %d>", w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004103 }
4104}
4105
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004106static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004107 /* name, function, calling, documentation */
4108 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
4109 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004110};
4111
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004112/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004113 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004114 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004115
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004116static PyTypeObject WinListType;
4117static PySequenceMethods WinListAsSeq;
4118
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004119typedef struct
4120{
4121 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004122 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004123} WinListObject;
4124
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004125 static PyObject *
4126WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004127{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004128 WinListObject *self;
4129
4130 self = PyObject_NEW(WinListObject, &WinListType);
4131 self->tabObject = tabObject;
4132 Py_INCREF(tabObject);
4133
4134 return (PyObject *)(self);
4135}
4136
4137 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004138WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004139{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004140 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004141
4142 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02004143 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004144 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02004145 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004146
4147 DESTRUCTOR_FINISH(self);
4148}
4149
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004150 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004151WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004152{
4153 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004154 PyInt n = 0;
4155
Bram Moolenaard6e39182013-05-21 18:30:34 +02004156 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004157 return -1;
4158
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004159 while (w != NULL)
4160 {
4161 ++n;
4162 w = W_NEXT(w);
4163 }
4164
4165 return n;
4166}
4167
4168 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004169WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004170{
4171 win_T *w;
4172
Bram Moolenaard6e39182013-05-21 18:30:34 +02004173 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004174 return NULL;
4175
4176 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004177 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004178 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004179
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004180 PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004181 return NULL;
4182}
4183
4184/* Convert a Python string into a Vim line.
4185 *
4186 * The result is in allocated memory. All internal nulls are replaced by
4187 * newline characters. It is an error for the string to contain newline
4188 * characters.
4189 *
4190 * On errors, the Python exception data is set, and NULL is returned.
4191 */
4192 static char *
4193StringToLine(PyObject *obj)
4194{
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004195 char *str;
4196 char *save;
4197 PyObject *bytes = NULL;
Bram Moolenaardee2e312013-06-23 16:35:47 +02004198 Py_ssize_t len = 0;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004199 PyInt i;
4200 char *p;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004201
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004202 if (PyBytes_Check(obj))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004203 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004204 if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
4205 || str == NULL)
4206 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004207 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004208 else if (PyUnicode_Check(obj))
4209 {
4210 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
4211 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004212
Bram Moolenaardaa27022013-06-24 22:33:30 +02004213 if (PyBytes_AsStringAndSize(bytes, &str, &len) == -1
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004214 || str == NULL)
4215 {
4216 Py_DECREF(bytes);
4217 return NULL;
4218 }
4219 }
Bram Moolenaardaa27022013-06-24 22:33:30 +02004220 else
4221 {
4222#if PY_MAJOR_VERSION < 3
4223 PyErr_FORMAT(PyExc_TypeError,
4224 N_("expected str() or unicode() instance, but got %s"),
4225 Py_TYPE_NAME(obj));
4226#else
4227 PyErr_FORMAT(PyExc_TypeError,
4228 N_("expected bytes() or str() instance, but got %s"),
4229 Py_TYPE_NAME(obj));
4230#endif
4231 return NULL;
4232 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004233
4234 /*
4235 * Error checking: String must not contain newlines, as we
4236 * are replacing a single line, and we must replace it with
4237 * a single line.
4238 * A trailing newline is removed, so that append(f.readlines()) works.
4239 */
4240 p = memchr(str, '\n', len);
4241 if (p != NULL)
4242 {
4243 if (p == str + len - 1)
4244 --len;
4245 else
4246 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004247 PyErr_SET_VIM(N_("string cannot contain newlines"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02004248 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004249 return NULL;
4250 }
4251 }
4252
4253 /* Create a copy of the string, with internal nulls replaced by
4254 * newline characters, as is the vim convention.
4255 */
4256 save = (char *)alloc((unsigned)(len+1));
4257 if (save == NULL)
4258 {
4259 PyErr_NoMemory();
Bram Moolenaar841fbd22013-06-23 14:37:07 +02004260 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004261 return NULL;
4262 }
4263
4264 for (i = 0; i < len; ++i)
4265 {
4266 if (str[i] == '\0')
4267 save[i] = '\n';
4268 else
4269 save[i] = str[i];
4270 }
4271
4272 save[i] = '\0';
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004273 Py_XDECREF(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004274
4275 return save;
4276}
4277
4278/* Get a line from the specified buffer. The line number is
4279 * in Vim format (1-based). The line is returned as a Python
4280 * string object.
4281 */
4282 static PyObject *
4283GetBufferLine(buf_T *buf, PyInt n)
4284{
4285 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
4286}
4287
4288
4289/* Get a list of lines from the specified buffer. The line numbers
4290 * are in Vim format (1-based). The range is from lo up to, but not
4291 * including, hi. The list is returned as a Python list of string objects.
4292 */
4293 static PyObject *
4294GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
4295{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004296 PyInt i;
4297 PyInt n = hi - lo;
4298 PyObject *list = PyList_New(n);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004299
4300 if (list == NULL)
4301 return NULL;
4302
4303 for (i = 0; i < n; ++i)
4304 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004305 PyObject *string = LineToString(
4306 (char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004307
4308 /* Error check - was the Python string creation OK? */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004309 if (string == NULL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004310 {
4311 Py_DECREF(list);
4312 return NULL;
4313 }
4314
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004315 PyList_SET_ITEM(list, i, string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004316 }
4317
4318 /* The ownership of the Python list is passed to the caller (ie,
4319 * the caller should Py_DECREF() the object when it is finished
4320 * with it).
4321 */
4322
4323 return list;
4324}
4325
4326/*
4327 * Check if deleting lines made the cursor position invalid.
4328 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
4329 * deleted).
4330 */
4331 static void
4332py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
4333{
4334 if (curwin->w_cursor.lnum >= lo)
4335 {
4336 /* Adjust the cursor position if it's in/after the changed
4337 * lines. */
4338 if (curwin->w_cursor.lnum >= hi)
4339 {
4340 curwin->w_cursor.lnum += extra;
4341 check_cursor_col();
4342 }
4343 else if (extra < 0)
4344 {
4345 curwin->w_cursor.lnum = lo;
4346 check_cursor();
4347 }
4348 else
4349 check_cursor_col();
4350 changed_cline_bef_curs();
4351 }
4352 invalidate_botline();
4353}
4354
Bram Moolenaar19e60942011-06-19 00:27:51 +02004355/*
4356 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004357 * in Vim format (1-based). The replacement line is given as
4358 * a Python string object. The object is checked for validity
4359 * and correct format. Errors are returned as a value of FAIL.
4360 * The return value is OK on success.
4361 * If OK is returned and len_change is not NULL, *len_change
4362 * is set to the change in the buffer length.
4363 */
4364 static int
4365SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
4366{
Bram Moolenaar45e5fd12017-06-04 14:58:02 +02004367 bufref_T save_curbuf = {NULL, 0, 0};
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004368 win_T *save_curwin = NULL;
4369 tabpage_T *save_curtab = NULL;
4370
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004371 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004372 * There are three cases:
4373 * 1. NULL, or None - this is a deletion.
4374 * 2. A string - this is a replacement.
4375 * 3. Anything else - this is an error.
4376 */
4377 if (line == Py_None || line == NULL)
4378 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004379 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004380 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004381
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004382 VimTryStart();
4383
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004384 if (u_savedel((linenr_T)n, 1L) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004385 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004386 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004387 RAISE_DELETE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004388 else
4389 {
Bram Moolenaar63dbfd32019-03-23 17:41:59 +01004390 if (buf == curbuf && (save_curwin != NULL
4391 || save_curbuf.br_buf == NULL))
4392 // Using an existing window for the buffer, adjust the cursor
4393 // position.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004394 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004395 if (save_curbuf.br_buf == NULL)
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004396 /* Only adjust marks if we managed to switch to a window that
4397 * holds the buffer, otherwise line numbers will be invalid. */
4398 deleted_lines_mark((linenr_T)n, 1L);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004399 }
4400
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004401 restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004402
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004403 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004404 return FAIL;
4405
4406 if (len_change)
4407 *len_change = -1;
4408
4409 return OK;
4410 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004411 else if (PyBytes_Check(line) || PyUnicode_Check(line))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004412 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004413 char *save = StringToLine(line);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004414
4415 if (save == NULL)
4416 return FAIL;
4417
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004418 VimTryStart();
4419
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004420 /* We do not need to free "save" if ml_replace() consumes it. */
4421 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004422 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004423
4424 if (u_savesub((linenr_T)n) == FAIL)
4425 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004426 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004427 vim_free(save);
4428 }
4429 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
4430 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004431 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004432 vim_free(save);
4433 }
4434 else
4435 changed_bytes((linenr_T)n, 0);
4436
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004437 restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004438
4439 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004440 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004441 check_cursor_col();
4442
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004443 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004444 return FAIL;
4445
4446 if (len_change)
4447 *len_change = 0;
4448
4449 return OK;
4450 }
4451 else
4452 {
4453 PyErr_BadArgument();
4454 return FAIL;
4455 }
4456}
4457
Bram Moolenaar19e60942011-06-19 00:27:51 +02004458/* Replace a range of lines in the specified buffer. The line numbers are in
4459 * Vim format (1-based). The range is from lo up to, but not including, hi.
4460 * The replacement lines are given as a Python list of string objects. The
4461 * list is checked for validity and correct format. Errors are returned as a
4462 * value of FAIL. The return value is OK on success.
4463 * If OK is returned and len_change is not NULL, *len_change
4464 * is set to the change in the buffer length.
4465 */
4466 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004467SetBufferLineList(
4468 buf_T *buf,
4469 PyInt lo,
4470 PyInt hi,
4471 PyObject *list,
4472 PyInt *len_change)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004473{
Bram Moolenaar45e5fd12017-06-04 14:58:02 +02004474 bufref_T save_curbuf = {NULL, 0, 0};
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004475 win_T *save_curwin = NULL;
4476 tabpage_T *save_curtab = NULL;
4477
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004478 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02004479 * There are three cases:
4480 * 1. NULL, or None - this is a deletion.
4481 * 2. A list - this is a replacement.
4482 * 3. Anything else - this is an error.
4483 */
4484 if (list == Py_None || list == NULL)
4485 {
4486 PyInt i;
4487 PyInt n = (int)(hi - lo);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004488
4489 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004490 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004491 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004492
4493 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004494 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004495 else
4496 {
4497 for (i = 0; i < n; ++i)
4498 {
4499 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
4500 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004501 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004502 break;
4503 }
4504 }
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004505 if (buf == curbuf && (save_curwin != NULL
4506 || save_curbuf.br_buf == NULL))
Bram Moolenaard7408fa2014-08-29 13:49:52 +02004507 /* Using an existing window for the buffer, adjust the cursor
4508 * position. */
Bram Moolenaar19e60942011-06-19 00:27:51 +02004509 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004510 if (save_curbuf.br_buf == NULL)
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004511 /* Only adjust marks if we managed to switch to a window that
4512 * holds the buffer, otherwise line numbers will be invalid. */
4513 deleted_lines_mark((linenr_T)lo, (long)i);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004514 }
4515
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004516 restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004517
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004518 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02004519 return FAIL;
4520
4521 if (len_change)
4522 *len_change = -n;
4523
4524 return OK;
4525 }
4526 else if (PyList_Check(list))
4527 {
4528 PyInt i;
4529 PyInt new_len = PyList_Size(list);
4530 PyInt old_len = hi - lo;
4531 PyInt extra = 0; /* lines added to text, can be negative */
4532 char **array;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004533
4534 if (new_len == 0) /* avoid allocating zero bytes */
4535 array = NULL;
4536 else
4537 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004538 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004539 if (array == NULL)
4540 {
4541 PyErr_NoMemory();
4542 return FAIL;
4543 }
4544 }
4545
4546 for (i = 0; i < new_len; ++i)
4547 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004548 PyObject *line;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004549
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004550 if (!(line = PyList_GetItem(list, i)) ||
4551 !(array[i] = StringToLine(line)))
Bram Moolenaar19e60942011-06-19 00:27:51 +02004552 {
4553 while (i)
4554 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004555 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004556 return FAIL;
4557 }
4558 }
4559
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004560 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02004561 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02004562
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004563 /* START of region without "return". Must call restore_buffer()! */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004564 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004565
4566 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004567 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004568
4569 /* If the size of the range is reducing (ie, new_len < old_len) we
4570 * need to delete some old_len. We do this at the start, by
4571 * repeatedly deleting line "lo".
4572 */
4573 if (!PyErr_Occurred())
4574 {
4575 for (i = 0; i < old_len - new_len; ++i)
4576 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
4577 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004578 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004579 break;
4580 }
4581 extra -= i;
4582 }
4583
4584 /* For as long as possible, replace the existing old_len with the
4585 * new old_len. This is a more efficient operation, as it requires
4586 * less memory allocation and freeing.
4587 */
4588 if (!PyErr_Occurred())
4589 {
4590 for (i = 0; i < old_len && i < new_len; ++i)
4591 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
4592 == FAIL)
4593 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004594 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004595 break;
4596 }
4597 }
4598 else
4599 i = 0;
4600
4601 /* Now we may need to insert the remaining new old_len. If we do, we
4602 * must free the strings as we finish with them (we can't pass the
4603 * responsibility to vim in this case).
4604 */
4605 if (!PyErr_Occurred())
4606 {
4607 while (i < new_len)
4608 {
4609 if (ml_append((linenr_T)(lo + i - 1),
4610 (char_u *)array[i], 0, FALSE) == FAIL)
4611 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004612 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004613 break;
4614 }
4615 vim_free(array[i]);
4616 ++i;
4617 ++extra;
4618 }
4619 }
4620
4621 /* Free any left-over old_len, as a result of an error */
4622 while (i < new_len)
4623 {
4624 vim_free(array[i]);
4625 ++i;
4626 }
4627
4628 /* Free the array of old_len. All of its contents have now
4629 * been dealt with (either freed, or the responsibility passed
4630 * to vim.
4631 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004632 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004633
4634 /* Adjust marks. Invalidate any which lie in the
4635 * changed range, and move any in the remainder of the buffer.
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004636 * Only adjust marks if we managed to switch to a window that holds
4637 * the buffer, otherwise line numbers will be invalid. */
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004638 if (save_curbuf.br_buf == NULL)
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004639 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
Bram Moolenaar19e60942011-06-19 00:27:51 +02004640 (long)MAXLNUM, (long)extra);
4641 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
4642
Bram Moolenaar63dbfd32019-03-23 17:41:59 +01004643 if (buf == curbuf && (save_curwin != NULL
4644 || save_curbuf.br_buf == NULL))
4645 // Using an existing window for the buffer, adjust the cursor
4646 // position.
Bram Moolenaar19e60942011-06-19 00:27:51 +02004647 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
4648
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004649 /* END of region without "return". */
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004650 restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004651
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004652 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02004653 return FAIL;
4654
4655 if (len_change)
4656 *len_change = new_len - old_len;
4657
4658 return OK;
4659 }
4660 else
4661 {
4662 PyErr_BadArgument();
4663 return FAIL;
4664 }
4665}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004666
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004667/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004668 * The line number is in Vim format (1-based). The lines to be inserted are
4669 * given as a Python list of string objects or as a single string. The lines
4670 * to be added are checked for validity and correct format. Errors are
4671 * returned as a value of FAIL. The return value is OK on success.
4672 * If OK is returned and len_change is not NULL, *len_change
4673 * is set to the change in the buffer length.
4674 */
4675 static int
4676InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
4677{
Bram Moolenaar45e5fd12017-06-04 14:58:02 +02004678 bufref_T save_curbuf = {NULL, 0, 0};
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004679 win_T *save_curwin = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004680 tabpage_T *save_curtab = NULL;
4681
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004682 /* First of all, we check the type of the supplied Python object.
4683 * It must be a string or a list, or the call is in error.
4684 */
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004685 if (PyBytes_Check(lines) || PyUnicode_Check(lines))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004686 {
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004687 char *str = StringToLine(lines);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004688
4689 if (str == NULL)
4690 return FAIL;
4691
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004692 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004693 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004694 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004695
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004696 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004697 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004698 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004699 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004700 else if (save_curbuf.br_buf == NULL)
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004701 /* Only adjust marks if we managed to switch to a window that
4702 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004703 appended_lines_mark((linenr_T)n, 1L);
4704
4705 vim_free(str);
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004706 restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004707 update_screen(VALID);
4708
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004709 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004710 return FAIL;
4711
4712 if (len_change)
4713 *len_change = 1;
4714
4715 return OK;
4716 }
4717 else if (PyList_Check(lines))
4718 {
4719 PyInt i;
4720 PyInt size = PyList_Size(lines);
4721 char **array;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004722
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004723 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004724 if (array == NULL)
4725 {
4726 PyErr_NoMemory();
4727 return FAIL;
4728 }
4729
4730 for (i = 0; i < size; ++i)
4731 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004732 PyObject *line;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004733
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004734 if (!(line = PyList_GetItem(lines, i)) ||
4735 !(array[i] = StringToLine(line)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004736 {
4737 while (i)
4738 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004739 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004740 return FAIL;
4741 }
4742 }
4743
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004744 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004745 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004746 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004747
4748 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004749 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004750 else
4751 {
4752 for (i = 0; i < size; ++i)
4753 {
4754 if (ml_append((linenr_T)(n + i),
4755 (char_u *)array[i], 0, FALSE) == FAIL)
4756 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004757 RAISE_INSERT_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004758
4759 /* Free the rest of the lines */
4760 while (i < size)
4761 vim_free(array[i++]);
4762
4763 break;
4764 }
4765 vim_free(array[i]);
4766 }
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004767 if (i > 0 && save_curbuf.br_buf == NULL)
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004768 /* Only adjust marks if we managed to switch to a window that
4769 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004770 appended_lines_mark((linenr_T)n, (long)i);
4771 }
4772
4773 /* Free the array of lines. All of its contents have now
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004774 * been freed. */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004775 PyMem_Free(array);
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02004776 restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004777
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004778 update_screen(VALID);
4779
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004780 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004781 return FAIL;
4782
4783 if (len_change)
4784 *len_change = size;
4785
4786 return OK;
4787 }
4788 else
4789 {
4790 PyErr_BadArgument();
4791 return FAIL;
4792 }
4793}
4794
4795/*
4796 * Common routines for buffers and line ranges
4797 * -------------------------------------------
4798 */
4799
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004800typedef struct
4801{
4802 PyObject_HEAD
4803 buf_T *buf;
4804} BufferObject;
4805
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004806 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02004807CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004808{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004809 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004810 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004811 PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004812 return -1;
4813 }
4814
4815 return 0;
4816}
4817
4818 static PyObject *
4819RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4820{
4821 if (CheckBuffer(self))
4822 return NULL;
4823
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004824 if (end == -1)
4825 end = self->buf->b_ml.ml_line_count;
4826
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004827 if (n < 0)
4828 n += end - start + 1;
4829
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004830 if (n < 0 || n > end - start)
4831 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004832 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004833 return NULL;
4834 }
4835
4836 return GetBufferLine(self->buf, n+start);
4837}
4838
4839 static PyObject *
4840RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4841{
4842 PyInt size;
4843
4844 if (CheckBuffer(self))
4845 return NULL;
4846
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004847 if (end == -1)
4848 end = self->buf->b_ml.ml_line_count;
4849
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004850 size = end - start + 1;
4851
4852 if (lo < 0)
4853 lo = 0;
4854 else if (lo > size)
4855 lo = size;
4856 if (hi < 0)
4857 hi = 0;
4858 if (hi < lo)
4859 hi = lo;
4860 else if (hi > size)
4861 hi = size;
4862
4863 return GetBufferLineList(self->buf, lo+start, hi+start);
4864}
4865
4866 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004867RBAsItem(
4868 BufferObject *self,
4869 PyInt n,
4870 PyObject *valObject,
4871 PyInt start,
4872 PyInt end,
4873 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004874{
4875 PyInt len_change;
4876
4877 if (CheckBuffer(self))
4878 return -1;
4879
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004880 if (end == -1)
4881 end = self->buf->b_ml.ml_line_count;
4882
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004883 if (n < 0)
4884 n += end - start + 1;
4885
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004886 if (n < 0 || n > end - start)
4887 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004888 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004889 return -1;
4890 }
4891
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004892 if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004893 return -1;
4894
4895 if (new_end)
4896 *new_end = end + len_change;
4897
4898 return 0;
4899}
4900
Bram Moolenaar19e60942011-06-19 00:27:51 +02004901 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004902RBAsSlice(
4903 BufferObject *self,
4904 PyInt lo,
4905 PyInt hi,
4906 PyObject *valObject,
4907 PyInt start,
4908 PyInt end,
4909 PyInt *new_end)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004910{
4911 PyInt size;
4912 PyInt len_change;
4913
4914 /* Self must be a valid buffer */
4915 if (CheckBuffer(self))
4916 return -1;
4917
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004918 if (end == -1)
4919 end = self->buf->b_ml.ml_line_count;
4920
Bram Moolenaar19e60942011-06-19 00:27:51 +02004921 /* Sort out the slice range */
4922 size = end - start + 1;
4923
4924 if (lo < 0)
4925 lo = 0;
4926 else if (lo > size)
4927 lo = size;
4928 if (hi < 0)
4929 hi = 0;
4930 if (hi < lo)
4931 hi = lo;
4932 else if (hi > size)
4933 hi = size;
4934
4935 if (SetBufferLineList(self->buf, lo + start, hi + start,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004936 valObject, &len_change) == FAIL)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004937 return -1;
4938
4939 if (new_end)
4940 *new_end = end + len_change;
4941
4942 return 0;
4943}
4944
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004945
4946 static PyObject *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004947RBAppend(
4948 BufferObject *self,
4949 PyObject *args,
4950 PyInt start,
4951 PyInt end,
4952 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004953{
4954 PyObject *lines;
4955 PyInt len_change;
4956 PyInt max;
4957 PyInt n;
4958
4959 if (CheckBuffer(self))
4960 return NULL;
4961
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004962 if (end == -1)
4963 end = self->buf->b_ml.ml_line_count;
4964
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004965 max = n = end - start + 1;
4966
4967 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
4968 return NULL;
4969
4970 if (n < 0 || n > max)
4971 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004972 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004973 return NULL;
4974 }
4975
4976 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
4977 return NULL;
4978
4979 if (new_end)
4980 *new_end = end + len_change;
4981
4982 Py_INCREF(Py_None);
4983 return Py_None;
4984}
4985
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004986/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004987 */
4988
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004989static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004990static PySequenceMethods RangeAsSeq;
4991static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004992
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004993typedef struct
4994{
4995 PyObject_HEAD
4996 BufferObject *buf;
4997 PyInt start;
4998 PyInt end;
4999} RangeObject;
5000
5001 static PyObject *
5002RangeNew(buf_T *buf, PyInt start, PyInt end)
5003{
5004 BufferObject *bufr;
5005 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02005006 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005007 if (self == NULL)
5008 return NULL;
5009
5010 bufr = (BufferObject *)BufferNew(buf);
5011 if (bufr == NULL)
5012 {
5013 Py_DECREF(self);
5014 return NULL;
5015 }
5016 Py_INCREF(bufr);
5017
5018 self->buf = bufr;
5019 self->start = start;
5020 self->end = end;
5021
5022 return (PyObject *)(self);
5023}
5024
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005025 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02005026RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005027{
Bram Moolenaar774267b2013-05-21 20:51:59 +02005028 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005029 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02005030 PyObject_GC_Del((void *)(self));
5031}
5032
5033 static int
5034RangeTraverse(RangeObject *self, visitproc visit, void *arg)
5035{
5036 Py_VISIT(((PyObject *)(self->buf)));
5037 return 0;
5038}
5039
5040 static int
5041RangeClear(RangeObject *self)
5042{
5043 Py_CLEAR(self->buf);
5044 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005045}
5046
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005047 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02005048RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005049{
5050 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02005051 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005052 return -1; /* ??? */
5053
Bram Moolenaard6e39182013-05-21 18:30:34 +02005054 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005055}
5056
5057 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005058RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005059{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005060 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005061}
5062
5063 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005064RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005065{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005066 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005067}
5068
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005069static char *RangeAttrs[] = {
5070 "start", "end",
5071 NULL
5072};
5073
5074 static PyObject *
5075RangeDir(PyObject *self)
5076{
5077 return ObjectDir(self, RangeAttrs);
5078}
5079
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005080 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005081RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005082{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005083 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005084}
5085
5086 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005087RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005088{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005089 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005090 return PyString_FromFormat("<range object (for deleted buffer) at %p>",
5091 (self));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005092 else
5093 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02005094 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005095
5096 if (name == NULL)
5097 name = "";
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005098
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005099 return PyString_FromFormat("<range %s (%d:%d)>",
Bram Moolenaarf62d9422013-05-30 19:01:24 +02005100 name, (int)self->start, (int)self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005101 }
5102}
5103
5104static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02005105 /* name, function, calling, documentation */
5106 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005107 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
5108 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005109};
5110
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005111static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005112static PySequenceMethods BufferAsSeq;
5113static PyMappingMethods BufferAsMapping;
5114
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005115 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02005116BufferNew(buf_T *buf)
5117{
5118 /* We need to handle deletion of buffers underneath us.
5119 * If we add a "b_python*_ref" field to the buf_T structure,
5120 * then we can get at it in buf_freeall() in vim. We then
5121 * need to create only ONE Python object per buffer - if
5122 * we try to create a second, just INCREF the existing one
5123 * and return it. The (single) Python object referring to
5124 * the buffer is stored in "b_python*_ref".
5125 * Question: what to do on a buf_freeall(). We'll probably
5126 * have to either delete the Python object (DECREF it to
5127 * zero - a bad idea, as it leaves dangling refs!) or
5128 * set the buf_T * value to an invalid value (-1?), which
5129 * means we need checks in all access functions... Bah.
5130 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005131 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02005132 * b_python_ref and b_python3_ref fields respectively.
5133 */
5134
5135 BufferObject *self;
5136
5137 if (BUF_PYTHON_REF(buf) != NULL)
5138 {
5139 self = BUF_PYTHON_REF(buf);
5140 Py_INCREF(self);
5141 }
5142 else
5143 {
5144 self = PyObject_NEW(BufferObject, &BufferType);
5145 if (self == NULL)
5146 return NULL;
5147 self->buf = buf;
5148 BUF_PYTHON_REF(buf) = self;
5149 }
5150
5151 return (PyObject *)(self);
5152}
5153
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005154 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02005155BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005156{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005157 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
5158 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005159
5160 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005161}
5162
Bram Moolenaar971db462013-05-12 18:44:48 +02005163 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02005164BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02005165{
5166 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02005167 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02005168 return -1; /* ??? */
5169
Bram Moolenaard6e39182013-05-21 18:30:34 +02005170 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02005171}
5172
5173 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005174BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02005175{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005176 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02005177}
5178
5179 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005180BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02005181{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005182 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02005183}
5184
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005185static char *BufferAttrs[] = {
5186 "name", "number", "vars", "options", "valid",
5187 NULL
5188};
5189
5190 static PyObject *
5191BufferDir(PyObject *self)
5192{
5193 return ObjectDir(self, BufferAttrs);
5194}
5195
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005196 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02005197BufferAttrValid(BufferObject *self, char *name)
5198{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005199 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02005200
5201 if (strcmp(name, "valid") != 0)
5202 return NULL;
5203
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005204 ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
5205 Py_INCREF(ret);
5206 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02005207}
5208
5209 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005210BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005211{
5212 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02005213 return PyString_FromString((self->buf->b_ffname == NULL
Bram Moolenaar41009372013-07-01 22:03:04 +02005214 ? "" : (char *)self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005215 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02005216 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005217 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02005218 return NEW_DICTIONARY(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005219 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02005220 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
5221 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005222 else if (strcmp(name, "__members__") == 0)
5223 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005224 else
5225 return NULL;
5226}
5227
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005228 static int
5229BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
5230{
5231 if (CheckBuffer(self))
5232 return -1;
5233
5234 if (strcmp(name, "name") == 0)
5235 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005236 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005237 aco_save_T aco;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005238 int ren_ret;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005239 PyObject *todecref;
5240
5241 if (!(val = StringToChars(valObject, &todecref)))
5242 return -1;
5243
5244 VimTryStart();
5245 /* Using aucmd_*: autocommands will be executed by rename_buffer */
5246 aucmd_prepbuf(&aco, self->buf);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005247 ren_ret = rename_buffer(val);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005248 aucmd_restbuf(&aco);
5249 Py_XDECREF(todecref);
5250 if (VimTryEnd())
5251 return -1;
5252
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005253 if (ren_ret == FAIL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005254 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005255 PyErr_SET_VIM(N_("failed to rename buffer"));
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005256 return -1;
5257 }
5258 return 0;
5259 }
5260 else
5261 {
5262 PyErr_SetString(PyExc_AttributeError, name);
5263 return -1;
5264 }
5265}
5266
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005267 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005268BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005269{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005270 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005271}
5272
5273 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02005274BufferMark(BufferObject *self, PyObject *pmarkObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005275{
5276 pos_T *posp;
Bram Moolenaar389a1792013-06-23 13:00:44 +02005277 char_u *pmark;
5278 char_u mark;
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02005279 bufref_T savebuf;
Bram Moolenaar389a1792013-06-23 13:00:44 +02005280 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005281
Bram Moolenaard6e39182013-05-21 18:30:34 +02005282 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005283 return NULL;
5284
Bram Moolenaar389a1792013-06-23 13:00:44 +02005285 if (!(pmark = StringToChars(pmarkObject, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005286 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005287
Bram Moolenaar389a1792013-06-23 13:00:44 +02005288 if (pmark[0] == '\0' || pmark[1] != '\0')
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02005289 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005290 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005291 N_("mark name must be a single character"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005292 Py_XDECREF(todecref);
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02005293 return NULL;
5294 }
5295
5296 mark = *pmark;
Bram Moolenaar389a1792013-06-23 13:00:44 +02005297
5298 Py_XDECREF(todecref);
5299
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005300 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02005301 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005302 posp = getmark(mark, FALSE);
Bram Moolenaar7c0a2f32016-07-10 22:11:16 +02005303 restore_buffer(&savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005304 if (VimTryEnd())
5305 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005306
5307 if (posp == NULL)
5308 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005309 PyErr_SET_VIM(N_("invalid mark name"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005310 return NULL;
5311 }
5312
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005313 if (posp->lnum <= 0)
5314 {
5315 /* Or raise an error? */
5316 Py_INCREF(Py_None);
5317 return Py_None;
5318 }
5319
5320 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
5321}
5322
5323 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005324BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005325{
5326 PyInt start;
5327 PyInt end;
5328
Bram Moolenaard6e39182013-05-21 18:30:34 +02005329 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005330 return NULL;
5331
5332 if (!PyArg_ParseTuple(args, "nn", &start, &end))
5333 return NULL;
5334
Bram Moolenaard6e39182013-05-21 18:30:34 +02005335 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005336}
5337
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005338 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005339BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005340{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005341 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005342 return PyString_FromFormat("<buffer object (deleted) at %p>", self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005343 else
5344 {
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005345 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005346
5347 if (name == NULL)
5348 name = "";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005349
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005350 return PyString_FromFormat("<buffer %s>", name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005351 }
5352}
5353
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005354static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02005355 /* name, function, calling, documentation */
5356 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02005357 {"mark", (PyCFunction)BufferMark, METH_O, "Return (row,col) representing position of named mark" },
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02005358 {"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 +02005359 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
5360 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005361};
5362
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005363/*
5364 * Buffer list object - Implementation
5365 */
5366
5367static PyTypeObject BufMapType;
5368
5369typedef struct
5370{
5371 PyObject_HEAD
5372} BufMapObject;
5373
5374 static PyInt
5375BufMapLength(PyObject *self UNUSED)
5376{
5377 buf_T *b = firstbuf;
5378 PyInt n = 0;
5379
5380 while (b)
5381 {
5382 ++n;
5383 b = b->b_next;
5384 }
5385
5386 return n;
5387}
5388
5389 static PyObject *
5390BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
5391{
5392 buf_T *b;
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005393 long bnr;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005394
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005395 if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005396 return NULL;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005397
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005398 b = buflist_findnr((int) bnr);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005399
5400 if (b)
5401 return BufferNew(b);
5402 else
5403 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02005404 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005405 return NULL;
5406 }
5407}
5408
5409 static void
5410BufMapIterDestruct(PyObject *buffer)
5411{
5412 /* Iteration was stopped before all buffers were processed */
5413 if (buffer)
5414 {
5415 Py_DECREF(buffer);
5416 }
5417}
5418
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005419 static int
5420BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
5421{
Bram Moolenaar774267b2013-05-21 20:51:59 +02005422 if (buffer)
5423 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005424 return 0;
5425}
5426
5427 static int
5428BufMapIterClear(PyObject **buffer)
5429{
Bram Moolenaar774267b2013-05-21 20:51:59 +02005430 if (*buffer)
5431 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005432 return 0;
5433}
5434
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005435 static PyObject *
5436BufMapIterNext(PyObject **buffer)
5437{
5438 PyObject *next;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005439 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005440
5441 if (!*buffer)
5442 return NULL;
5443
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005444 ret = *buffer;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005445
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005446 if (CheckBuffer((BufferObject *)(ret)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005447 {
5448 *buffer = NULL;
5449 return NULL;
5450 }
5451
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005452 if (!((BufferObject *)(ret))->buf->b_next)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005453 next = NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005454 else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005455 return NULL;
5456 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02005457 /* Do not increment reference: we no longer hold it (decref), but whoever
5458 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005459 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005460}
5461
5462 static PyObject *
5463BufMapIter(PyObject *self UNUSED)
5464{
5465 PyObject *buffer;
5466
5467 buffer = BufferNew(firstbuf);
5468 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005469 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
5470 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005471}
5472
5473static PyMappingMethods BufMapAsMapping = {
5474 (lenfunc) BufMapLength,
5475 (binaryfunc) BufMapItem,
5476 (objobjargproc) 0,
5477};
5478
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005479/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005480 */
5481
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005482static char *CurrentAttrs[] = {
5483 "buffer", "window", "line", "range", "tabpage",
5484 NULL
5485};
5486
5487 static PyObject *
5488CurrentDir(PyObject *self)
5489{
5490 return ObjectDir(self, CurrentAttrs);
5491}
5492
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005493 static PyObject *
5494CurrentGetattr(PyObject *self UNUSED, char *name)
5495{
5496 if (strcmp(name, "buffer") == 0)
5497 return (PyObject *)BufferNew(curbuf);
5498 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02005499 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005500 else if (strcmp(name, "tabpage") == 0)
5501 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005502 else if (strcmp(name, "line") == 0)
5503 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
5504 else if (strcmp(name, "range") == 0)
5505 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005506 else if (strcmp(name, "__members__") == 0)
5507 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005508 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005509#if PY_MAJOR_VERSION < 3
5510 return Py_FindMethod(WindowMethods, self, name);
5511#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005512 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005513#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005514}
5515
5516 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005517CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005518{
5519 if (strcmp(name, "line") == 0)
5520 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005521 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
5522 NULL) == FAIL)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005523 return -1;
5524
5525 return 0;
5526 }
Bram Moolenaare7614592013-05-15 15:51:08 +02005527 else if (strcmp(name, "buffer") == 0)
5528 {
5529 int count;
5530
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005531 if (valObject->ob_type != &BufferType)
Bram Moolenaare7614592013-05-15 15:51:08 +02005532 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005533 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005534 N_("expected vim.Buffer object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005535 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02005536 return -1;
5537 }
5538
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005539 if (CheckBuffer((BufferObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005540 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005541 count = ((BufferObject *)(valObject))->buf->b_fnum;
Bram Moolenaare7614592013-05-15 15:51:08 +02005542
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005543 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02005544 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
5545 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005546 if (VimTryEnd())
5547 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005548 PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
Bram Moolenaare7614592013-05-15 15:51:08 +02005549 return -1;
5550 }
5551
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005552 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005553 }
5554 else if (strcmp(name, "window") == 0)
5555 {
5556 int count;
5557
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005558 if (valObject->ob_type != &WindowType)
Bram Moolenaare7614592013-05-15 15:51:08 +02005559 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005560 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005561 N_("expected vim.Window object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005562 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02005563 return -1;
5564 }
5565
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005566 if (CheckWindow((WindowObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005567 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005568 count = get_win_number(((WindowObject *)(valObject))->win, firstwin);
Bram Moolenaare7614592013-05-15 15:51:08 +02005569
5570 if (!count)
5571 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005572 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005573 N_("failed to find window in the current tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005574 return -1;
5575 }
5576
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005577 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005578 win_goto(((WindowObject *)(valObject))->win);
5579 if (((WindowObject *)(valObject))->win != curwin)
Bram Moolenaare7614592013-05-15 15:51:08 +02005580 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005581 if (VimTryEnd())
5582 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005583 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005584 N_("did not switch to the specified window"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005585 return -1;
5586 }
5587
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005588 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005589 }
5590 else if (strcmp(name, "tabpage") == 0)
5591 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005592 if (valObject->ob_type != &TabPageType)
Bram Moolenaare7614592013-05-15 15:51:08 +02005593 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005594 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005595 N_("expected vim.TabPage object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005596 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02005597 return -1;
5598 }
5599
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005600 if (CheckTabPage((TabPageObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005601 return -1;
5602
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005603 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005604 goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
5605 if (((TabPageObject *)(valObject))->tab != curtab)
Bram Moolenaare7614592013-05-15 15:51:08 +02005606 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005607 if (VimTryEnd())
5608 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005609 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005610 N_("did not switch to the specified tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005611 return -1;
5612 }
5613
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005614 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005615 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005616 else
5617 {
5618 PyErr_SetString(PyExc_AttributeError, name);
5619 return -1;
5620 }
5621}
5622
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005623static struct PyMethodDef CurrentMethods[] = {
5624 /* name, function, calling, documentation */
5625 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
5626 { NULL, NULL, 0, NULL}
5627};
5628
Bram Moolenaardb913952012-06-29 12:54:53 +02005629 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005630init_range_cmd(exarg_T *eap)
5631{
5632 RangeStart = eap->line1;
5633 RangeEnd = eap->line2;
5634}
5635
5636 static void
5637init_range_eval(typval_T *rettv UNUSED)
5638{
5639 RangeStart = (PyInt) curwin->w_cursor.lnum;
5640 RangeEnd = RangeStart;
5641}
5642
5643 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005644run_cmd(const char *cmd, void *arg UNUSED
5645#ifdef PY_CAN_RECURSE
5646 , PyGILState_STATE *pygilstate UNUSED
5647#endif
5648 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005649{
Bram Moolenaar41009372013-07-01 22:03:04 +02005650 PyObject *run_ret;
5651 run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
5652 if (run_ret != NULL)
5653 {
5654 Py_DECREF(run_ret);
5655 }
5656 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5657 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005658 semsg(_(e_py_systemexit), "python");
Bram Moolenaar41009372013-07-01 22:03:04 +02005659 PyErr_Clear();
5660 }
5661 else
5662 PyErr_PrintEx(1);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005663}
5664
5665static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
5666static int code_hdr_len = 30;
5667
5668 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005669run_do(const char *cmd, void *arg UNUSED
5670#ifdef PY_CAN_RECURSE
5671 , PyGILState_STATE *pygilstate
5672#endif
5673 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005674{
5675 PyInt lnum;
5676 size_t len;
5677 char *code;
5678 int status;
5679 PyObject *pyfunc, *pymain;
Bram Moolenaar41009372013-07-01 22:03:04 +02005680 PyObject *run_ret;
Bram Moolenaara58883b2017-01-29 21:31:09 +01005681 buf_T *was_curbuf = curbuf;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005682
Bram Moolenaar4ac66762013-05-28 22:31:46 +02005683 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005684 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005685 emsg(_("cannot save undo information"));
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005686 return;
5687 }
5688
5689 len = code_hdr_len + STRLEN(cmd);
5690 code = PyMem_New(char, len + 1);
5691 memcpy(code, code_hdr, code_hdr_len);
5692 STRCPY(code + code_hdr_len, cmd);
Bram Moolenaar41009372013-07-01 22:03:04 +02005693 run_ret = PyRun_String(code, Py_file_input, globals, globals);
5694 status = -1;
5695 if (run_ret != NULL)
5696 {
5697 status = 0;
5698 Py_DECREF(run_ret);
5699 }
5700 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5701 {
5702 PyMem_Free(code);
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005703 semsg(_(e_py_systemexit), "python");
Bram Moolenaar41009372013-07-01 22:03:04 +02005704 PyErr_Clear();
5705 return;
5706 }
5707 else
5708 PyErr_PrintEx(1);
5709
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005710 PyMem_Free(code);
5711
5712 if (status)
5713 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005714 emsg(_("failed to run the code"));
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005715 return;
5716 }
5717
5718 status = 0;
5719 pymain = PyImport_AddModule("__main__");
5720 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005721#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005722 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005723#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005724
5725 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
5726 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005727 PyObject *line;
5728 PyObject *linenr;
5729 PyObject *ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005730
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005731#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005732 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005733#endif
Bram Moolenaara58883b2017-01-29 21:31:09 +01005734 /* Check the line number, the command my have deleted lines. */
5735 if (lnum > curbuf->b_ml.ml_line_count
5736 || !(line = GetBufferLine(curbuf, lnum)))
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005737 goto err;
5738 if (!(linenr = PyInt_FromLong((long) lnum)))
5739 {
5740 Py_DECREF(line);
5741 goto err;
5742 }
5743 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
5744 Py_DECREF(line);
5745 Py_DECREF(linenr);
5746 if (!ret)
5747 goto err;
5748
Bram Moolenaara58883b2017-01-29 21:31:09 +01005749 /* Check that the command didn't switch to another buffer. */
5750 if (curbuf != was_curbuf)
5751 {
5752 Py_XDECREF(ret);
5753 goto err;
5754 }
5755
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005756 if (ret != Py_None)
5757 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
Bram Moolenaara58883b2017-01-29 21:31:09 +01005758 {
5759 Py_XDECREF(ret);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005760 goto err;
Bram Moolenaara58883b2017-01-29 21:31:09 +01005761 }
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005762
5763 Py_XDECREF(ret);
5764 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005765#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005766 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005767#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005768 }
5769 goto out;
5770err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005771#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005772 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005773#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005774 PyErr_PrintEx(0);
5775 PythonIO_Flush();
5776 status = 1;
5777out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005778#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005779 if (!status)
5780 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005781#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005782 Py_DECREF(pyfunc);
5783 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
5784 if (status)
5785 return;
5786 check_cursor();
5787 update_curbuf(NOT_VALID);
5788}
5789
5790 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005791run_eval(const char *cmd, typval_T *rettv
5792#ifdef PY_CAN_RECURSE
5793 , PyGILState_STATE *pygilstate UNUSED
5794#endif
5795 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005796{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005797 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005798
Bram Moolenaar41009372013-07-01 22:03:04 +02005799 run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005800 if (run_ret == NULL)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005801 {
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005802 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
Bram Moolenaar41009372013-07-01 22:03:04 +02005803 {
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005804 semsg(_(e_py_systemexit), "python");
Bram Moolenaar41009372013-07-01 22:03:04 +02005805 PyErr_Clear();
5806 }
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005807 else
5808 {
5809 if (PyErr_Occurred() && !msg_silent)
5810 PyErr_PrintEx(0);
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005811 emsg(_("E858: Eval did not return a valid python object"));
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005812 }
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005813 }
5814 else
5815 {
Bram Moolenaarde323092017-11-09 19:56:08 +01005816 if (ConvertFromPyObject(run_ret, rettv) == -1)
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01005817 emsg(_("E859: Failed to convert returned python object to vim value"));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005818 Py_DECREF(run_ret);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005819 }
5820 PyErr_Clear();
5821}
5822
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005823 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02005824set_ref_in_py(const int copyID)
5825{
5826 pylinkedlist_T *cur;
5827 dict_T *dd;
5828 list_T *ll;
Bram Moolenaar8110a092016-04-14 15:56:09 +02005829 int i;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005830 int abort = FALSE;
Bram Moolenaar8110a092016-04-14 15:56:09 +02005831 FunctionObject *func;
Bram Moolenaardb913952012-06-29 12:54:53 +02005832
5833 if (lastdict != NULL)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005834 {
Bram Moolenaar8110a092016-04-14 15:56:09 +02005835 for (cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
Bram Moolenaardb913952012-06-29 12:54:53 +02005836 {
5837 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
5838 if (dd->dv_copyID != copyID)
5839 {
5840 dd->dv_copyID = copyID;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005841 abort = abort || set_ref_in_ht(&dd->dv_hashtab, copyID, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005842 }
5843 }
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005844 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005845
5846 if (lastlist != NULL)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005847 {
Bram Moolenaar8110a092016-04-14 15:56:09 +02005848 for (cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
Bram Moolenaardb913952012-06-29 12:54:53 +02005849 {
5850 ll = ((ListObject *) (cur->pll_obj))->list;
5851 if (ll->lv_copyID != copyID)
5852 {
5853 ll->lv_copyID = copyID;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005854 abort = abort || set_ref_in_list(ll, copyID, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005855 }
5856 }
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005857 }
5858
Bram Moolenaar8110a092016-04-14 15:56:09 +02005859 if (lastfunc != NULL)
5860 {
5861 for (cur = lastfunc ; !abort && cur != NULL ; cur = cur->pll_prev)
5862 {
5863 func = (FunctionObject *) cur->pll_obj;
5864 if (func->self != NULL && func->self->dv_copyID != copyID)
5865 {
5866 func->self->dv_copyID = copyID;
5867 abort = abort || set_ref_in_ht(
5868 &func->self->dv_hashtab, copyID, NULL);
5869 }
5870 if (func->argc)
5871 for (i = 0; !abort && i < func->argc; ++i)
5872 abort = abort
5873 || set_ref_in_item(&func->argv[i], copyID, NULL, NULL);
5874 }
5875 }
5876
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005877 return abort;
Bram Moolenaardb913952012-06-29 12:54:53 +02005878}
5879
5880 static int
5881set_string_copy(char_u *str, typval_T *tv)
5882{
5883 tv->vval.v_string = vim_strsave(str);
5884 if (tv->vval.v_string == NULL)
5885 {
5886 PyErr_NoMemory();
5887 return -1;
5888 }
5889 return 0;
5890}
5891
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005892 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005893pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005894{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005895 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005896 char_u *key;
5897 dictitem_T *di;
5898 PyObject *keyObject;
5899 PyObject *valObject;
5900 Py_ssize_t iter = 0;
5901
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005902 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005903 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005904
5905 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005906 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005907
5908 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5909 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005910 PyObject *todecref = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005911
Bram Moolenaara03e6312013-05-29 22:49:26 +02005912 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005913 {
5914 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005915 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005916 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005917
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005918 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005919 {
5920 dict_unref(dict);
5921 return -1;
5922 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005923
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005924 if (*key == NUL)
5925 {
5926 dict_unref(dict);
5927 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005928 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005929 return -1;
5930 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005931
5932 di = dictitem_alloc(key);
5933
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005934 Py_XDECREF(todecref);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005935
5936 if (di == NULL)
5937 {
5938 PyErr_NoMemory();
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005939 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005940 return -1;
5941 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005942
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005943 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005944 {
5945 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005946 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005947 return -1;
5948 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005949
5950 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005951 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005952 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara03e6312013-05-29 22:49:26 +02005953 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005954 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005955 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005956 return -1;
5957 }
5958 }
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005959
5960 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005961 return 0;
5962}
5963
5964 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005965pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005966{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005967 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005968 char_u *key;
5969 dictitem_T *di;
5970 PyObject *list;
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005971 PyObject *iterator;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005972 PyObject *keyObject;
5973 PyObject *valObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005974
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005975 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005976 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005977
5978 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005979 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005980
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005981 if (!(list = PyMapping_Keys(obj)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005982 {
5983 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005984 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005985 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005986
5987 if (!(iterator = PyObject_GetIter(list)))
5988 {
5989 dict_unref(dict);
5990 Py_DECREF(list);
5991 return -1;
5992 }
5993 Py_DECREF(list);
5994
5995 while ((keyObject = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005996 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005997 PyObject *todecref;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005998
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005999 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006000 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02006001 Py_DECREF(keyObject);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006002 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006003 dict_unref(dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006004 return -1;
6005 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02006006
Bram Moolenaarfc714b32013-05-30 14:52:37 +02006007 if (*key == NUL)
6008 {
6009 Py_DECREF(keyObject);
6010 Py_DECREF(iterator);
6011 Py_XDECREF(todecref);
6012 dict_unref(dict);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02006013 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02006014 return -1;
6015 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006016
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006017 if (!(valObject = PyObject_GetItem(obj, keyObject)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006018 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006019 Py_DECREF(keyObject);
6020 Py_DECREF(iterator);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02006021 Py_XDECREF(todecref);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006022 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006023 return -1;
6024 }
6025
6026 di = dictitem_alloc(key);
6027
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006028 Py_DECREF(keyObject);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02006029 Py_XDECREF(todecref);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006030
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006031 if (di == NULL)
6032 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006033 Py_DECREF(iterator);
6034 Py_DECREF(valObject);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006035 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006036 PyErr_NoMemory();
6037 return -1;
6038 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006039
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006040 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006041 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006042 Py_DECREF(iterator);
6043 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006044 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006045 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006046 return -1;
6047 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02006048
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006049 Py_DECREF(valObject);
6050
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006051 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006052 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02006053 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006054 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006055 dictitem_free(di);
6056 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006057 return -1;
6058 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006059 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006060 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006061 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006062 return 0;
6063}
6064
6065 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006066pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006067{
6068 list_T *l;
6069
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006070 if (!(l = py_list_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006071 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006072
6073 tv->v_type = VAR_LIST;
6074 tv->vval.v_list = l;
6075
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006076 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006077 {
6078 list_unref(l);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006079 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006080 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006081
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006082 --l->lv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02006083 return 0;
6084}
6085
Bram Moolenaardb913952012-06-29 12:54:53 +02006086typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
6087
6088 static int
6089convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006090 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02006091{
6092 PyObject *capsule;
6093 char hexBuf[sizeof(void *) * 2 + 3];
6094
Bram Moolenaar792f0e32018-02-27 17:27:13 +01006095 sprintf(hexBuf, "%p", (void *)obj);
Bram Moolenaardb913952012-06-29 12:54:53 +02006096
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006097#ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006098 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006099#else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006100 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006101#endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02006102 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02006103 {
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006104#ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02006105 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006106#else
Bram Moolenaar221d6872012-06-30 13:34:34 +02006107 capsule = PyCObject_FromVoidPtr(tv, NULL);
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006108#endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02006109 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
6110 {
6111 Py_DECREF(capsule);
6112 tv->v_type = VAR_UNKNOWN;
6113 return -1;
6114 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02006115
6116 Py_DECREF(capsule);
6117
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006118 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02006119 {
6120 tv->v_type = VAR_UNKNOWN;
6121 return -1;
6122 }
6123 /* As we are not using copy_tv which increments reference count we must
6124 * do it ourself. */
Bram Moolenaar81e7a9c2016-02-06 19:57:20 +01006125 if (tv->v_type == VAR_DICT)
6126 ++tv->vval.v_dict->dv_refcount;
6127 else if (tv->v_type == VAR_LIST)
6128 ++tv->vval.v_list->lv_refcount;
Bram Moolenaardb913952012-06-29 12:54:53 +02006129 }
6130 else
6131 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02006132 typval_T *v;
6133
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006134#ifdef PY_USE_CAPSULE
Bram Moolenaar2afa3232012-06-29 16:28:28 +02006135 v = PyCapsule_GetPointer(capsule, NULL);
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006136#else
Bram Moolenaar221d6872012-06-30 13:34:34 +02006137 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006138#endif
Bram Moolenaardb913952012-06-29 12:54:53 +02006139 copy_tv(v, tv);
6140 }
6141 return 0;
6142}
6143
6144 static int
Bram Moolenaara9922d62013-05-30 13:01:18 +02006145ConvertFromPyMapping(PyObject *obj, typval_T *tv)
6146{
6147 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006148 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006149
6150 if (!(lookup_dict = PyDict_New()))
6151 return -1;
6152
6153 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
6154 {
6155 tv->v_type = VAR_DICT;
6156 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
6157 ++tv->vval.v_dict->dv_refcount;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006158 ret = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006159 }
6160 else if (PyDict_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006161 ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02006162 else if (PyMapping_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006163 ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02006164 else
6165 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02006166 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02006167 N_("unable to convert %s to vim dictionary"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02006168 Py_TYPE_NAME(obj));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006169 ret = -1;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006170 }
6171 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006172 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006173}
6174
6175 static int
Bram Moolenaar8110a092016-04-14 15:56:09 +02006176ConvertFromPySequence(PyObject *obj, typval_T *tv)
6177{
6178 PyObject *lookup_dict;
Bram Moolenaar66210042016-04-15 20:40:41 +02006179 int ret;
Bram Moolenaar8110a092016-04-14 15:56:09 +02006180
6181 if (!(lookup_dict = PyDict_New()))
6182 return -1;
6183
6184 if (PyType_IsSubtype(obj->ob_type, &ListType))
6185 {
6186 tv->v_type = VAR_LIST;
6187 tv->vval.v_list = (((ListObject *)(obj))->list);
6188 ++tv->vval.v_list->lv_refcount;
Bram Moolenaar66210042016-04-15 20:40:41 +02006189 ret = 0;
Bram Moolenaar8110a092016-04-14 15:56:09 +02006190 }
6191 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaar66210042016-04-15 20:40:41 +02006192 ret = convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaar8110a092016-04-14 15:56:09 +02006193 else
6194 {
6195 PyErr_FORMAT(PyExc_TypeError,
6196 N_("unable to convert %s to vim list"),
6197 Py_TYPE_NAME(obj));
6198 ret = -1;
6199 }
6200 Py_DECREF(lookup_dict);
6201 return ret;
6202}
6203
6204 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02006205ConvertFromPyObject(PyObject *obj, typval_T *tv)
6206{
6207 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006208 int ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02006209
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02006210 if (!(lookup_dict = PyDict_New()))
6211 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006212 ret = _ConvertFromPyObject(obj, tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02006213 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006214 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02006215}
6216
6217 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006218_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02006219{
Bram Moolenaara9922d62013-05-30 13:01:18 +02006220 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
Bram Moolenaardb913952012-06-29 12:54:53 +02006221 {
6222 tv->v_type = VAR_DICT;
6223 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
6224 ++tv->vval.v_dict->dv_refcount;
6225 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02006226 else if (PyType_IsSubtype(obj->ob_type, &ListType))
Bram Moolenaardb913952012-06-29 12:54:53 +02006227 {
6228 tv->v_type = VAR_LIST;
6229 tv->vval.v_list = (((ListObject *)(obj))->list);
6230 ++tv->vval.v_list->lv_refcount;
6231 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02006232 else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
Bram Moolenaardb913952012-06-29 12:54:53 +02006233 {
Bram Moolenaar8110a092016-04-14 15:56:09 +02006234 FunctionObject *func = (FunctionObject *) obj;
6235 if (func->self != NULL || func->argv != NULL)
6236 {
6237 partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
6238 set_partial(func, pt, TRUE);
6239 tv->vval.v_partial = pt;
6240 tv->v_type = VAR_PARTIAL;
6241 }
6242 else
6243 {
6244 if (set_string_copy(func->name, tv) == -1)
6245 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02006246
Bram Moolenaar8110a092016-04-14 15:56:09 +02006247 tv->v_type = VAR_FUNC;
6248 }
6249 func_ref(func->name);
Bram Moolenaardb913952012-06-29 12:54:53 +02006250 }
Bram Moolenaardb913952012-06-29 12:54:53 +02006251 else if (PyBytes_Check(obj))
6252 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006253 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02006254
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006255 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02006256 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006257 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02006258 return -1;
6259
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006260 if (set_string_copy(str, tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02006261 return -1;
6262
6263 tv->v_type = VAR_STRING;
6264 }
6265 else if (PyUnicode_Check(obj))
6266 {
6267 PyObject *bytes;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006268 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02006269
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02006270 bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02006271 if (bytes == NULL)
6272 return -1;
6273
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006274 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02006275 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006276 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02006277 return -1;
6278
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006279 if (set_string_copy(str, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02006280 {
6281 Py_XDECREF(bytes);
6282 return -1;
6283 }
6284 Py_XDECREF(bytes);
6285
6286 tv->v_type = VAR_STRING;
6287 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02006288#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02006289 else if (PyInt_Check(obj))
6290 {
6291 tv->v_type = VAR_NUMBER;
6292 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02006293 if (PyErr_Occurred())
6294 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02006295 }
6296#endif
6297 else if (PyLong_Check(obj))
6298 {
6299 tv->v_type = VAR_NUMBER;
6300 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02006301 if (PyErr_Occurred())
6302 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02006303 }
6304 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006305 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02006306#ifdef FEAT_FLOAT
6307 else if (PyFloat_Check(obj))
6308 {
6309 tv->v_type = VAR_FLOAT;
6310 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
6311 }
6312#endif
Bram Moolenaarbcb40972013-05-30 13:22:13 +02006313 else if (PyObject_HasAttrString(obj, "keys"))
6314 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006315 /* PyObject_GetIter can create built-in iterator for any sequence object */
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006316 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006317 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02006318 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02006319 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02006320 else if (PyNumber_Check(obj))
6321 {
6322 PyObject *num;
6323
6324 if (!(num = PyNumber_Long(obj)))
6325 return -1;
6326
6327 tv->v_type = VAR_NUMBER;
6328 tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
6329
6330 Py_DECREF(num);
6331 }
Bram Moolenaarde323092017-11-09 19:56:08 +01006332 else if (obj == Py_None)
6333 {
6334 tv->v_type = VAR_SPECIAL;
6335 tv->vval.v_number = VVAL_NONE;
6336 }
Bram Moolenaardb913952012-06-29 12:54:53 +02006337 else
6338 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02006339 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02006340 N_("unable to convert %s to vim structure"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02006341 Py_TYPE_NAME(obj));
Bram Moolenaardb913952012-06-29 12:54:53 +02006342 return -1;
6343 }
6344 return 0;
6345}
6346
6347 static PyObject *
6348ConvertToPyObject(typval_T *tv)
6349{
Bram Moolenaar8110a092016-04-14 15:56:09 +02006350 typval_T *argv;
6351 int i;
Bram Moolenaardb913952012-06-29 12:54:53 +02006352 if (tv == NULL)
6353 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02006354 PyErr_SET_VIM(N_("internal error: NULL reference passed"));
Bram Moolenaardb913952012-06-29 12:54:53 +02006355 return NULL;
6356 }
6357 switch (tv->v_type)
6358 {
6359 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02006360 return PyBytes_FromString(tv->vval.v_string == NULL
6361 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02006362 case VAR_NUMBER:
6363 return PyLong_FromLong((long) tv->vval.v_number);
6364#ifdef FEAT_FLOAT
6365 case VAR_FLOAT:
6366 return PyFloat_FromDouble((double) tv->vval.v_float);
6367#endif
6368 case VAR_LIST:
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006369 return NEW_LIST(tv->vval.v_list);
Bram Moolenaardb913952012-06-29 12:54:53 +02006370 case VAR_DICT:
Bram Moolenaara9922d62013-05-30 13:01:18 +02006371 return NEW_DICTIONARY(tv->vval.v_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02006372 case VAR_FUNC:
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02006373 return NEW_FUNCTION(tv->vval.v_string == NULL
Bram Moolenaar8110a092016-04-14 15:56:09 +02006374 ? (char_u *)"" : tv->vval.v_string,
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02006375 0, NULL, NULL, TRUE);
Bram Moolenaar4c908612016-03-24 21:58:12 +01006376 case VAR_PARTIAL:
Bram Moolenaar8110a092016-04-14 15:56:09 +02006377 if (tv->vval.v_partial->pt_argc)
6378 {
6379 argv = PyMem_New(typval_T, (size_t)tv->vval.v_partial->pt_argc);
6380 for (i = 0; i < tv->vval.v_partial->pt_argc; i++)
6381 copy_tv(&tv->vval.v_partial->pt_argv[i], &argv[i]);
6382 }
6383 else
6384 argv = NULL;
6385 if (tv->vval.v_partial->pt_dict != NULL)
6386 tv->vval.v_partial->pt_dict->dv_refcount++;
Bram Moolenaar4c908612016-03-24 21:58:12 +01006387 return NEW_FUNCTION(tv->vval.v_partial == NULL
Bram Moolenaar437bafe2016-08-01 15:40:54 +02006388 ? (char_u *)"" : partial_name(tv->vval.v_partial),
Bram Moolenaar8110a092016-04-14 15:56:09 +02006389 tv->vval.v_partial->pt_argc, argv,
Bram Moolenaar2177f9f2016-05-25 20:39:09 +02006390 tv->vval.v_partial->pt_dict,
6391 tv->vval.v_partial->pt_auto);
Bram Moolenaar6e5ea8d2019-01-12 22:47:31 +01006392 case VAR_BLOB:
6393 return PyBytes_FromStringAndSize(
6394 (char*) tv->vval.v_blob->bv_ga.ga_data,
6395 (Py_ssize_t) tv->vval.v_blob->bv_ga.ga_len);
Bram Moolenaardb913952012-06-29 12:54:53 +02006396 case VAR_UNKNOWN:
Bram Moolenaar4c908612016-03-24 21:58:12 +01006397 case VAR_CHANNEL:
6398 case VAR_JOB:
Bram Moolenaardb913952012-06-29 12:54:53 +02006399 Py_INCREF(Py_None);
6400 return Py_None;
Bram Moolenaar4c908612016-03-24 21:58:12 +01006401 case VAR_SPECIAL:
6402 switch (tv->vval.v_number)
6403 {
6404 case VVAL_FALSE: return AlwaysFalse(NULL);
6405 case VVAL_TRUE: return AlwaysTrue(NULL);
6406 case VVAL_NONE:
6407 case VVAL_NULL: return AlwaysNone(NULL);
6408 }
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02006409 PyErr_SET_VIM(N_("internal error: invalid value type"));
Bram Moolenaardb913952012-06-29 12:54:53 +02006410 return NULL;
6411 }
Bram Moolenaar4c908612016-03-24 21:58:12 +01006412 return NULL;
Bram Moolenaardb913952012-06-29 12:54:53 +02006413}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006414
6415typedef struct
6416{
6417 PyObject_HEAD
6418} CurrentObject;
6419static PyTypeObject CurrentType;
6420
6421 static void
6422init_structs(void)
6423{
6424 vim_memset(&OutputType, 0, sizeof(OutputType));
6425 OutputType.tp_name = "vim.message";
6426 OutputType.tp_basicsize = sizeof(OutputObject);
6427 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
6428 OutputType.tp_doc = "vim message object";
6429 OutputType.tp_methods = OutputMethods;
6430#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006431 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
6432 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006433 OutputType.tp_alloc = call_PyType_GenericAlloc;
6434 OutputType.tp_new = call_PyType_GenericNew;
6435 OutputType.tp_free = call_PyObject_Free;
Bram Moolenaard4a8c982018-05-15 22:31:18 +02006436 OutputType.tp_base = &PyStdPrinter_Type;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006437#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006438 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
6439 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaard4a8c982018-05-15 22:31:18 +02006440 // Disabled, because this causes a crash in test86
6441 // OutputType.tp_base = &PyFile_Type;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006442#endif
6443
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006444 vim_memset(&IterType, 0, sizeof(IterType));
6445 IterType.tp_name = "vim.iter";
6446 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02006447 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006448 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02006449 IterType.tp_iter = (getiterfunc)IterIter;
6450 IterType.tp_iternext = (iternextfunc)IterNext;
6451 IterType.tp_dealloc = (destructor)IterDestructor;
6452 IterType.tp_traverse = (traverseproc)IterTraverse;
6453 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006454
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006455 vim_memset(&BufferType, 0, sizeof(BufferType));
6456 BufferType.tp_name = "vim.buffer";
6457 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006458 BufferType.tp_dealloc = (destructor)BufferDestructor;
6459 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006460 BufferType.tp_as_sequence = &BufferAsSeq;
6461 BufferType.tp_as_mapping = &BufferAsMapping;
6462 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
6463 BufferType.tp_doc = "vim buffer object";
6464 BufferType.tp_methods = BufferMethods;
6465#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006466 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02006467 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006468 BufferType.tp_alloc = call_PyType_GenericAlloc;
6469 BufferType.tp_new = call_PyType_GenericNew;
6470 BufferType.tp_free = call_PyObject_Free;
6471#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006472 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02006473 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006474#endif
6475
6476 vim_memset(&WindowType, 0, sizeof(WindowType));
6477 WindowType.tp_name = "vim.window";
6478 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006479 WindowType.tp_dealloc = (destructor)WindowDestructor;
6480 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02006481 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006482 WindowType.tp_doc = "vim Window object";
6483 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02006484 WindowType.tp_traverse = (traverseproc)WindowTraverse;
6485 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006486#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006487 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
6488 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006489 WindowType.tp_alloc = call_PyType_GenericAlloc;
6490 WindowType.tp_new = call_PyType_GenericNew;
6491 WindowType.tp_free = call_PyObject_Free;
6492#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006493 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
6494 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006495#endif
6496
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006497 vim_memset(&TabPageType, 0, sizeof(TabPageType));
6498 TabPageType.tp_name = "vim.tabpage";
6499 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006500 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
6501 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006502 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
6503 TabPageType.tp_doc = "vim tab page object";
6504 TabPageType.tp_methods = TabPageMethods;
6505#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006506 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006507 TabPageType.tp_alloc = call_PyType_GenericAlloc;
6508 TabPageType.tp_new = call_PyType_GenericNew;
6509 TabPageType.tp_free = call_PyObject_Free;
6510#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006511 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006512#endif
6513
Bram Moolenaardfa38d42013-05-15 13:38:47 +02006514 vim_memset(&BufMapType, 0, sizeof(BufMapType));
6515 BufMapType.tp_name = "vim.bufferlist";
6516 BufMapType.tp_basicsize = sizeof(BufMapObject);
6517 BufMapType.tp_as_mapping = &BufMapAsMapping;
6518 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006519 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006520 BufferType.tp_doc = "vim buffer list";
6521
6522 vim_memset(&WinListType, 0, sizeof(WinListType));
6523 WinListType.tp_name = "vim.windowlist";
6524 WinListType.tp_basicsize = sizeof(WinListType);
6525 WinListType.tp_as_sequence = &WinListAsSeq;
6526 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
6527 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02006528 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006529
6530 vim_memset(&TabListType, 0, sizeof(TabListType));
6531 TabListType.tp_name = "vim.tabpagelist";
6532 TabListType.tp_basicsize = sizeof(TabListType);
6533 TabListType.tp_as_sequence = &TabListAsSeq;
6534 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
6535 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006536
6537 vim_memset(&RangeType, 0, sizeof(RangeType));
6538 RangeType.tp_name = "vim.range";
6539 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006540 RangeType.tp_dealloc = (destructor)RangeDestructor;
6541 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006542 RangeType.tp_as_sequence = &RangeAsSeq;
6543 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02006544 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006545 RangeType.tp_doc = "vim Range object";
6546 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02006547 RangeType.tp_traverse = (traverseproc)RangeTraverse;
6548 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006549#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006550 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006551 RangeType.tp_alloc = call_PyType_GenericAlloc;
6552 RangeType.tp_new = call_PyType_GenericNew;
6553 RangeType.tp_free = call_PyObject_Free;
6554#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006555 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006556#endif
6557
6558 vim_memset(&CurrentType, 0, sizeof(CurrentType));
6559 CurrentType.tp_name = "vim.currentdata";
6560 CurrentType.tp_basicsize = sizeof(CurrentObject);
6561 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
6562 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02006563 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006564#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006565 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
6566 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006567#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006568 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
6569 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006570#endif
6571
6572 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
6573 DictionaryType.tp_name = "vim.dictionary";
6574 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006575 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006576 DictionaryType.tp_as_sequence = &DictionaryAsSeq;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006577 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006578 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006579 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
6580 DictionaryType.tp_methods = DictionaryMethods;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006581 DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
6582 DictionaryType.tp_new = (newfunc)DictionaryConstructor;
6583 DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006584#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006585 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
6586 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006587#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006588 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
6589 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006590#endif
6591
6592 vim_memset(&ListType, 0, sizeof(ListType));
6593 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02006594 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006595 ListType.tp_basicsize = sizeof(ListObject);
6596 ListType.tp_as_sequence = &ListAsSeq;
6597 ListType.tp_as_mapping = &ListAsMapping;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006598 ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006599 ListType.tp_doc = "list pushing modifications to vim structure";
6600 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02006601 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006602 ListType.tp_new = (newfunc)ListConstructor;
6603 ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006604#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006605 ListType.tp_getattro = (getattrofunc)ListGetattro;
6606 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006607#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006608 ListType.tp_getattr = (getattrfunc)ListGetattr;
6609 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006610#endif
6611
6612 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006613 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006614 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006615 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
6616 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02006617 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006618 FunctionType.tp_doc = "object that calls vim function";
6619 FunctionType.tp_methods = FunctionMethods;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02006620 FunctionType.tp_repr = (reprfunc)FunctionRepr;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02006621 FunctionType.tp_new = (newfunc)FunctionConstructor;
6622 FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006623#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006624 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006625#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006626 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006627#endif
6628
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006629 vim_memset(&OptionsType, 0, sizeof(OptionsType));
6630 OptionsType.tp_name = "vim.options";
6631 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01006632 OptionsType.tp_as_sequence = &OptionsAsSeq;
Bram Moolenaar07b88642013-05-29 22:58:32 +02006633 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006634 OptionsType.tp_doc = "object for manipulating options";
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01006635 OptionsType.tp_iter = (getiterfunc)OptionsIter;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006636 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02006637 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
6638 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
6639 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006640
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006641#if PY_VERSION_HEX < 0x030700f0
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006642 vim_memset(&LoaderType, 0, sizeof(LoaderType));
6643 LoaderType.tp_name = "vim.Loader";
6644 LoaderType.tp_basicsize = sizeof(LoaderObject);
6645 LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
6646 LoaderType.tp_doc = "vim message object";
6647 LoaderType.tp_methods = LoaderMethods;
6648 LoaderType.tp_dealloc = (destructor)LoaderDestructor;
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006649#endif
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006650
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006651#if PY_MAJOR_VERSION >= 3
6652 vim_memset(&vimmodule, 0, sizeof(vimmodule));
6653 vimmodule.m_name = "vim";
6654 vimmodule.m_doc = "Vim Python interface\n";
6655 vimmodule.m_size = -1;
6656 vimmodule.m_methods = VimMethods;
6657#endif
6658}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006659
6660#define PYTYPE_READY(type) \
6661 if (PyType_Ready(&type)) \
6662 return -1;
6663
6664 static int
Bram Moolenaarfb97f282013-07-09 17:42:46 +02006665init_types(void)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006666{
6667 PYTYPE_READY(IterType);
6668 PYTYPE_READY(BufferType);
6669 PYTYPE_READY(RangeType);
6670 PYTYPE_READY(WindowType);
6671 PYTYPE_READY(TabPageType);
6672 PYTYPE_READY(BufMapType);
6673 PYTYPE_READY(WinListType);
6674 PYTYPE_READY(TabListType);
6675 PYTYPE_READY(CurrentType);
6676 PYTYPE_READY(DictionaryType);
6677 PYTYPE_READY(ListType);
6678 PYTYPE_READY(FunctionType);
6679 PYTYPE_READY(OptionsType);
6680 PYTYPE_READY(OutputType);
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006681#if PY_VERSION_HEX < 0x030700f0
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02006682 PYTYPE_READY(LoaderType);
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006683#endif
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006684 return 0;
6685}
6686
6687 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02006688init_sys_path(void)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006689{
6690 PyObject *path;
6691 PyObject *path_hook;
6692 PyObject *path_hooks;
6693
6694 if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
6695 return -1;
6696
6697 if (!(path_hooks = PySys_GetObject("path_hooks")))
6698 {
6699 PyErr_Clear();
6700 path_hooks = PyList_New(1);
6701 PyList_SET_ITEM(path_hooks, 0, path_hook);
6702 if (PySys_SetObject("path_hooks", path_hooks))
6703 {
6704 Py_DECREF(path_hooks);
6705 return -1;
6706 }
6707 Py_DECREF(path_hooks);
6708 }
6709 else if (PyList_Check(path_hooks))
6710 {
6711 if (PyList_Append(path_hooks, path_hook))
6712 {
6713 Py_DECREF(path_hook);
6714 return -1;
6715 }
6716 Py_DECREF(path_hook);
6717 }
6718 else
6719 {
6720 VimTryStart();
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006721 emsg(_("Failed to set path hook: sys.path_hooks is not a list\n"
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006722 "You should now do the following:\n"
6723 "- append vim.path_hook to sys.path_hooks\n"
6724 "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
6725 VimTryEnd(); /* Discard the error */
6726 Py_DECREF(path_hook);
6727 return 0;
6728 }
6729
6730 if (!(path = PySys_GetObject("path")))
6731 {
6732 PyErr_Clear();
6733 path = PyList_New(1);
6734 Py_INCREF(vim_special_path_object);
6735 PyList_SET_ITEM(path, 0, vim_special_path_object);
6736 if (PySys_SetObject("path", path))
6737 {
6738 Py_DECREF(path);
6739 return -1;
6740 }
6741 Py_DECREF(path);
6742 }
6743 else if (PyList_Check(path))
6744 {
6745 if (PyList_Append(path, vim_special_path_object))
6746 return -1;
6747 }
6748 else
6749 {
6750 VimTryStart();
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01006751 emsg(_("Failed to set path: sys.path is not a list\n"
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006752 "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
6753 VimTryEnd(); /* Discard the error */
6754 }
6755
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006756 return 0;
6757}
6758
6759static BufMapObject TheBufferMap =
6760{
6761 PyObject_HEAD_INIT(&BufMapType)
6762};
6763
6764static WinListObject TheWindowList =
6765{
6766 PyObject_HEAD_INIT(&WinListType)
6767 NULL
6768};
6769
6770static CurrentObject TheCurrent =
6771{
6772 PyObject_HEAD_INIT(&CurrentType)
6773};
6774
6775static TabListObject TheTabPageList =
6776{
6777 PyObject_HEAD_INIT(&TabListType)
6778};
6779
6780static struct numeric_constant {
6781 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006782 int val;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006783} numeric_constants[] = {
6784 {"VAR_LOCKED", VAR_LOCKED},
6785 {"VAR_FIXED", VAR_FIXED},
6786 {"VAR_SCOPE", VAR_SCOPE},
6787 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
6788};
6789
6790static struct object_constant {
6791 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006792 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006793} object_constants[] = {
6794 {"buffers", (PyObject *)(void *)&TheBufferMap},
6795 {"windows", (PyObject *)(void *)&TheWindowList},
6796 {"tabpages", (PyObject *)(void *)&TheTabPageList},
6797 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02006798
6799 {"Buffer", (PyObject *)&BufferType},
6800 {"Range", (PyObject *)&RangeType},
6801 {"Window", (PyObject *)&WindowType},
6802 {"TabPage", (PyObject *)&TabPageType},
6803 {"Dictionary", (PyObject *)&DictionaryType},
6804 {"List", (PyObject *)&ListType},
6805 {"Function", (PyObject *)&FunctionType},
6806 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006807#if PY_VERSION_HEX < 0x030700f0
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006808 {"_Loader", (PyObject *)&LoaderType},
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006809#endif
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006810};
6811
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006812#define ADD_OBJECT(m, name, obj) \
Bram Moolenaardee2e312013-06-23 16:35:47 +02006813 if (PyModule_AddObject(m, name, obj)) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006814 return -1;
6815
6816#define ADD_CHECKED_OBJECT(m, name, obj) \
6817 { \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006818 PyObject *valObject = obj; \
6819 if (!valObject) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006820 return -1; \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006821 ADD_OBJECT(m, name, valObject); \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006822 }
6823
6824 static int
Bram Moolenaardee2e312013-06-23 16:35:47 +02006825populate_module(PyObject *m)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006826{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006827 int i;
6828 PyObject *other_module;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006829 PyObject *attr;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006830 PyObject *imp;
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006831#if PY_VERSION_HEX >= 0x030700f0
6832 PyObject *dict;
6833 PyObject *cls;
6834#endif
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006835
6836 for (i = 0; i < (int)(sizeof(numeric_constants)
6837 / sizeof(struct numeric_constant));
6838 ++i)
6839 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006840 PyInt_FromLong(numeric_constants[i].val));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006841
6842 for (i = 0; i < (int)(sizeof(object_constants)
6843 / sizeof(struct object_constant));
6844 ++i)
6845 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006846 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006847
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006848 valObject = object_constants[i].valObject;
6849 Py_INCREF(valObject);
6850 ADD_OBJECT(m, object_constants[i].name, valObject);
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006851 }
6852
6853 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
6854 return -1;
6855 ADD_OBJECT(m, "error", VimError);
6856
Bram Moolenaara9922d62013-05-30 13:01:18 +02006857 ADD_CHECKED_OBJECT(m, "vars", NEW_DICTIONARY(&globvardict));
6858 ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006859 ADD_CHECKED_OBJECT(m, "options",
6860 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
Bram Moolenaarf4258302013-06-02 18:20:17 +02006861
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006862 if (!(other_module = PyImport_ImportModule("os")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006863 return -1;
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006864 ADD_OBJECT(m, "os", other_module);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006865
Bram Moolenaar22081f42016-06-01 20:38:34 +02006866#if PY_MAJOR_VERSION >= 3
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006867 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006868 return -1;
Bram Moolenaar22081f42016-06-01 20:38:34 +02006869#else
6870 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwdu")))
6871 return -1;
6872#endif
Bram Moolenaarf4258302013-06-02 18:20:17 +02006873 ADD_OBJECT(m, "_getcwd", py_getcwd)
6874
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006875 if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006876 return -1;
6877 ADD_OBJECT(m, "_chdir", py_chdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006878 if (!(attr = PyObject_GetAttrString(m, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006879 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006880 if (PyObject_SetAttrString(other_module, "chdir", attr))
6881 {
6882 Py_DECREF(attr);
6883 return -1;
6884 }
6885 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006886
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006887 if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006888 {
6889 ADD_OBJECT(m, "_fchdir", py_fchdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006890 if (!(attr = PyObject_GetAttrString(m, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006891 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006892 if (PyObject_SetAttrString(other_module, "fchdir", attr))
6893 {
6894 Py_DECREF(attr);
6895 return -1;
6896 }
6897 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006898 }
Bram Moolenaare9056b12013-06-03 20:04:48 +02006899 else
6900 PyErr_Clear();
Bram Moolenaarf4258302013-06-02 18:20:17 +02006901
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006902 if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
6903 return -1;
6904
6905 ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
6906
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006907#if PY_VERSION_HEX >= 0x030700f0
6908 if (!(imp = PyImport_ImportModule("importlib.machinery")))
6909 return -1;
6910
6911 dict = PyModule_GetDict(imp);
6912
6913 if (!(cls = PyDict_GetItemString(dict, "PathFinder")))
6914 {
6915 Py_DECREF(imp);
6916 return -1;
6917 }
6918
6919 if (!(py_find_spec = PyObject_GetAttrString(cls, "find_spec")))
6920 {
6921 Py_DECREF(imp);
6922 return -1;
6923 }
6924
Bram Moolenaarb999ba22019-02-14 13:28:45 +01006925 if ((py_find_module = PyObject_GetAttrString(cls, "find_module")))
6926 {
6927 // find_module() is deprecated, this may stop working in some later
6928 // version.
6929 ADD_OBJECT(m, "_find_module", py_find_module);
6930 }
6931
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006932 Py_DECREF(imp);
6933
6934 ADD_OBJECT(m, "_find_spec", py_find_spec);
6935#else
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006936 if (!(imp = PyImport_ImportModule("imp")))
6937 return -1;
6938
6939 if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
6940 {
6941 Py_DECREF(imp);
6942 return -1;
6943 }
6944
6945 if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
6946 {
6947 Py_DECREF(py_find_module);
6948 Py_DECREF(imp);
6949 return -1;
6950 }
6951
6952 Py_DECREF(imp);
6953
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02006954 ADD_OBJECT(m, "_find_module", py_find_module);
6955 ADD_OBJECT(m, "_load_module", py_load_module);
Bram Moolenaar79a494d2018-07-22 04:30:21 +02006956#endif
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006957
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006958 return 0;
6959}