blob: e2f4857e42728126259002bc36b9638f255af8ff [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 Moolenaar78cf3f02014-01-10 18:16:07 +010016#ifdef __BORLANDC__
17/* Disable Warning W8060: Possibly incorrect assignment in function ... */
18# pragma warn -8060
19#endif
20
Bram Moolenaar41009372013-07-01 22:03:04 +020021static char_u e_py_systemexit[] = "E880: Can't handle SystemExit of %s exception in vim";
22
Bram Moolenaarc1a995d2012-08-08 16:05:07 +020023#if PY_VERSION_HEX < 0x02050000
24typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
25#endif
26
Bram Moolenaar91805fc2011-06-26 04:01:44 +020027#ifdef FEAT_MBYTE
Bram Moolenaar808c2bc2013-06-23 13:11:18 +020028# define ENC_OPT ((char *)p_enc)
Bram Moolenaar91805fc2011-06-26 04:01:44 +020029#else
30# define ENC_OPT "latin1"
31#endif
Bram Moolenaard620aa92013-05-17 16:40:06 +020032#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020033
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020034static const char *vim_special_path = "_vim_path_";
35
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020036#define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020037#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020038#define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
Bram Moolenaar063a46b2014-01-14 16:36:51 +010039#define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg)
40#define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2)
41#define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg)
Bram Moolenaarc476e522013-06-23 13:46:40 +020042
43#define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
44 ? "(NULL)" \
45 : obj->ob_type->tp_name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020046
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020047#define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020048 N_("empty keys are not allowed"))
49#define RAISE_LOCKED_DICTIONARY PyErr_SET_VIM(N_("dictionary is locked"))
50#define RAISE_LOCKED_LIST PyErr_SET_VIM(N_("list is locked"))
51#define RAISE_UNDO_FAIL PyErr_SET_VIM(N_("cannot save undo information"))
52#define RAISE_DELETE_LINE_FAIL PyErr_SET_VIM(N_("cannot delete line"))
53#define RAISE_INSERT_LINE_FAIL PyErr_SET_VIM(N_("cannot insert line"))
54#define RAISE_REPLACE_LINE_FAIL PyErr_SET_VIM(N_("cannot replace line"))
Bram Moolenaarc476e522013-06-23 13:46:40 +020055#define RAISE_KEY_ADD_FAIL(key) \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020056 PyErr_VIM_FORMAT(N_("failed to add key '%s' to dictionary"), key)
Bram Moolenaarc476e522013-06-23 13:46:40 +020057#define RAISE_INVALID_INDEX_TYPE(idx) \
Bram Moolenaar6f1404f2013-06-23 16:04:08 +020058 PyErr_FORMAT(PyExc_TypeError, N_("index must be int or slice, not %s"), \
Bram Moolenaarc476e522013-06-23 13:46:40 +020059 Py_TYPE_NAME(idx));
Bram Moolenaar35eacd72013-05-30 22:06:33 +020060
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020061#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
62#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020063#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020064
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020065typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020066typedef void (*runner)(const char *, void *
67#ifdef PY_CAN_RECURSE
68 , PyGILState_STATE *
69#endif
70 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020071
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020072static int ConvertFromPyObject(PyObject *, typval_T *);
73static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaara9922d62013-05-30 13:01:18 +020074static int ConvertFromPyMapping(PyObject *, typval_T *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020075static PyObject *WindowNew(win_T *, tabpage_T *);
76static PyObject *BufferNew (buf_T *);
77static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020078
79static PyInt RangeStart;
80static PyInt RangeEnd;
81
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020082static PyObject *globals;
83
Bram Moolenaarf4258302013-06-02 18:20:17 +020084static PyObject *py_chdir;
85static PyObject *py_fchdir;
86static PyObject *py_getcwd;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020087static PyObject *vim_module;
88static PyObject *vim_special_path_object;
Bram Moolenaarf4258302013-06-02 18:20:17 +020089
Bram Moolenaar81c40c52013-06-12 14:41:04 +020090static PyObject *py_find_module;
91static PyObject *py_load_module;
92
93static PyObject *VimError;
94
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020095/*
96 * obtain a lock on the Vim data structures
97 */
98 static void
99Python_Lock_Vim(void)
100{
101}
102
103/*
104 * release a lock on the Vim data structures
105 */
106 static void
107Python_Release_Vim(void)
108{
109}
110
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200111/*
112 * The "todecref" argument holds a pointer to PyObject * that must be
113 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
114 * was needed to generate returned value is object.
115 *
116 * Use Py_XDECREF to decrement reference count.
117 */
118 static char_u *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200119StringToChars(PyObject *obj, PyObject **todecref)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200120{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200121 char_u *str;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200122
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200123 if (PyBytes_Check(obj))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200124 {
125
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200126 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1
127 || str == NULL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200128 return NULL;
129
130 *todecref = NULL;
131 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200132 else if (PyUnicode_Check(obj))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200133 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200134 PyObject *bytes;
135
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200136 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200137 return NULL;
138
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200139 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1
140 || str == NULL)
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200141 {
142 Py_DECREF(bytes);
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200143 return NULL;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200144 }
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200145
146 *todecref = bytes;
147 }
148 else
149 {
Bram Moolenaarc476e522013-06-23 13:46:40 +0200150#if PY_MAJOR_VERSION < 3
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200151 PyErr_FORMAT(PyExc_TypeError,
152 N_("expected str() or unicode() instance, but got %s"),
153 Py_TYPE_NAME(obj));
Bram Moolenaarc476e522013-06-23 13:46:40 +0200154#else
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200155 PyErr_FORMAT(PyExc_TypeError,
156 N_("expected bytes() or str() instance, but got %s"),
157 Py_TYPE_NAME(obj));
Bram Moolenaarc476e522013-06-23 13:46:40 +0200158#endif
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200159 return NULL;
160 }
161
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200162 return (char_u *) str;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200163}
164
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200165#define NUMBER_LONG 1
166#define NUMBER_INT 2
167#define NUMBER_NATURAL 4
168#define NUMBER_UNSIGNED 8
169
170 static int
171NumberToLong(PyObject *obj, long *result, int flags)
172{
173#if PY_MAJOR_VERSION < 3
174 if (PyInt_Check(obj))
175 {
176 *result = PyInt_AsLong(obj);
177 if (PyErr_Occurred())
178 return -1;
179 }
180 else
181#endif
182 if (PyLong_Check(obj))
183 {
184 *result = PyLong_AsLong(obj);
185 if (PyErr_Occurred())
186 return -1;
187 }
188 else if (PyNumber_Check(obj))
189 {
190 PyObject *num;
191
192 if (!(num = PyNumber_Long(obj)))
193 return -1;
194
195 *result = PyLong_AsLong(num);
196
197 Py_DECREF(num);
198
199 if (PyErr_Occurred())
200 return -1;
201 }
202 else
203 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200204#if PY_MAJOR_VERSION < 3
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200205 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200206 N_("expected int(), long() or something supporting "
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200207 "coercing to long(), but got %s"),
208 Py_TYPE_NAME(obj));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200209#else
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200210 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200211 N_("expected int() or something supporting coercing to int(), "
Bram Moolenaarc1c3d682013-06-24 21:21:58 +0200212 "but got %s"),
213 Py_TYPE_NAME(obj));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200214#endif
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200215 return -1;
216 }
217
218 if (flags & NUMBER_INT)
219 {
220 if (*result > INT_MAX)
221 {
222 PyErr_SET_STRING(PyExc_OverflowError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200223 N_("value is too large to fit into C int type"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200224 return -1;
225 }
226 else if (*result < INT_MIN)
227 {
228 PyErr_SET_STRING(PyExc_OverflowError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200229 N_("value is too small to fit into C int type"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200230 return -1;
231 }
232 }
233
234 if (flags & NUMBER_NATURAL)
235 {
236 if (*result <= 0)
237 {
238 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar4de6a212014-03-08 16:13:44 +0100239 N_("number must be greater than zero"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200240 return -1;
241 }
242 }
243 else if (flags & NUMBER_UNSIGNED)
244 {
245 if (*result < 0)
246 {
247 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200248 N_("number must be greater or equal to zero"));
Bram Moolenaar141be8a2013-06-23 14:16:57 +0200249 return -1;
250 }
251 }
252
253 return 0;
254}
255
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200256 static int
257add_string(PyObject *list, char *s)
258{
259 PyObject *string;
260
261 if (!(string = PyString_FromString(s)))
262 return -1;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200263
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200264 if (PyList_Append(list, string))
265 {
266 Py_DECREF(string);
267 return -1;
268 }
269
270 Py_DECREF(string);
271 return 0;
272}
273
274 static PyObject *
275ObjectDir(PyObject *self, char **attributes)
276{
277 PyMethodDef *method;
278 char **attr;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200279 PyObject *ret;
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200280
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200281 if (!(ret = PyList_New(0)))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200282 return NULL;
283
284 if (self)
285 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
Bram Moolenaar41009372013-07-01 22:03:04 +0200286 if (add_string(ret, (char *)method->ml_name))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200287 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200288 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200289 return NULL;
290 }
291
292 for (attr = attributes ; *attr ; ++attr)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200293 if (add_string(ret, *attr))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200294 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200295 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200296 return NULL;
297 }
298
299#if PY_MAJOR_VERSION < 3
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200300 if (add_string(ret, "__members__"))
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200301 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200302 Py_DECREF(ret);
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200303 return NULL;
304 }
305#endif
306
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200307 return ret;
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200308}
309
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200310/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200311 */
312
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200313/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200314typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200315
316static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200317
318typedef struct
319{
320 PyObject_HEAD
321 long softspace;
322 long error;
323} OutputObject;
324
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200325static char *OutputAttrs[] = {
326 "softspace",
327 NULL
328};
329
330 static PyObject *
331OutputDir(PyObject *self)
332{
333 return ObjectDir(self, OutputAttrs);
334}
335
Bram Moolenaar77045652012-09-21 13:46:06 +0200336 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200337OutputSetattr(OutputObject *self, char *name, PyObject *valObject)
Bram Moolenaar77045652012-09-21 13:46:06 +0200338{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200339 if (valObject == NULL)
Bram Moolenaar77045652012-09-21 13:46:06 +0200340 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200341 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200342 N_("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200343 return -1;
344 }
345
346 if (strcmp(name, "softspace") == 0)
347 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200348 if (NumberToLong(valObject, &(self->softspace), NUMBER_UNSIGNED))
Bram Moolenaar77045652012-09-21 13:46:06 +0200349 return -1;
Bram Moolenaar77045652012-09-21 13:46:06 +0200350 return 0;
351 }
352
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200353 PyErr_FORMAT(PyExc_AttributeError, N_("invalid attribute: %s"), name);
Bram Moolenaar77045652012-09-21 13:46:06 +0200354 return -1;
355}
356
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200357/* Buffer IO, we write one whole line at a time. */
358static garray_T io_ga = {0, 0, 1, 80, NULL};
359static writefn old_fn = NULL;
360
361 static void
362PythonIO_Flush(void)
363{
364 if (old_fn != NULL && io_ga.ga_len > 0)
365 {
366 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
367 old_fn((char_u *)io_ga.ga_data);
368 }
369 io_ga.ga_len = 0;
370}
371
372 static void
373writer(writefn fn, char_u *str, PyInt n)
374{
375 char_u *ptr;
376
377 /* Flush when switching output function. */
378 if (fn != old_fn)
379 PythonIO_Flush();
380 old_fn = fn;
381
382 /* Write each NL separated line. Text after the last NL is kept for
383 * writing later. */
384 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
385 {
386 PyInt len = ptr - str;
387
388 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
389 break;
390
391 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
392 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
393 fn((char_u *)io_ga.ga_data);
394 str = ptr + 1;
395 n -= len + 1;
396 io_ga.ga_len = 0;
397 }
398
399 /* Put the remaining text into io_ga for later printing. */
400 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
401 {
402 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
403 io_ga.ga_len += (int)n;
404 }
405}
406
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200407 static int
408write_output(OutputObject *self, PyObject *string)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200409{
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200410 Py_ssize_t len = 0;
411 char *str = NULL;
412 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200413
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200414 if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
415 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200416
417 Py_BEGIN_ALLOW_THREADS
418 Python_Lock_Vim();
419 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
420 Python_Release_Vim();
421 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200422 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200423
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200424 return 0;
425}
426
427 static PyObject *
428OutputWrite(OutputObject *self, PyObject *string)
429{
430 if (write_output(self, string))
431 return NULL;
432
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200433 Py_INCREF(Py_None);
434 return Py_None;
435}
436
437 static PyObject *
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200438OutputWritelines(OutputObject *self, PyObject *seq)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200439{
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200440 PyObject *iterator;
441 PyObject *item;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200442
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200443 if (!(iterator = PyObject_GetIter(seq)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200444 return NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200445
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200446 while ((item = PyIter_Next(iterator)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200447 {
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200448 if (write_output(self, item))
Bram Moolenaardb913952012-06-29 12:54:53 +0200449 {
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200450 Py_DECREF(iterator);
451 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200452 return NULL;
453 }
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200454 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200455 }
456
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200457 Py_DECREF(iterator);
458
459 /* Iterator may have finished due to an exception */
460 if (PyErr_Occurred())
461 return NULL;
462
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200463 Py_INCREF(Py_None);
464 return Py_None;
465}
466
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100467 static PyObject *
Bram Moolenaard4247472015-11-02 13:28:59 +0100468AlwaysNone(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100469{
470 /* do nothing */
471 Py_INCREF(Py_None);
472 return Py_None;
473}
474
Bram Moolenaard4247472015-11-02 13:28:59 +0100475 static PyObject *
476AlwaysFalse(PyObject *self UNUSED)
477{
478 /* do nothing */
479 Py_INCREF(Py_False);
480 return Py_False;
481}
482
483 static PyObject *
484AlwaysTrue(PyObject *self UNUSED)
485{
486 /* do nothing */
487 Py_INCREF(Py_True);
488 return Py_True;
489}
490
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200491/***************/
492
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200493static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200494 /* name, function, calling, doc */
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200495 {"write", (PyCFunction)OutputWrite, METH_O, ""},
496 {"writelines", (PyCFunction)OutputWritelines, METH_O, ""},
Bram Moolenaard4247472015-11-02 13:28:59 +0100497 {"flush", (PyCFunction)AlwaysNone, METH_NOARGS, ""},
498 {"close", (PyCFunction)AlwaysNone, METH_NOARGS, ""},
499 {"isatty", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
500 {"readable", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
501 {"seekable", (PyCFunction)AlwaysFalse, METH_NOARGS, ""},
502 {"writable", (PyCFunction)AlwaysTrue, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200503 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200504 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200505};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200506
507static OutputObject Output =
508{
509 PyObject_HEAD_INIT(&OutputType)
510 0,
511 0
512};
513
514static OutputObject Error =
515{
516 PyObject_HEAD_INIT(&OutputType)
517 0,
518 1
519};
520
521 static int
522PythonIO_Init_io(void)
523{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +0200524 if (PySys_SetObject("stdout", (PyObject *)(void *)&Output))
525 return -1;
526 if (PySys_SetObject("stderr", (PyObject *)(void *)&Error))
527 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200528
529 if (PyErr_Occurred())
530 {
531 EMSG(_("E264: Python: Error initialising I/O objects"));
532 return -1;
533 }
534
535 return 0;
536}
537
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200538typedef struct
539{
540 PyObject_HEAD
541 PyObject *module;
542} LoaderObject;
543static PyTypeObject LoaderType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200544
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200545 static void
546LoaderDestructor(LoaderObject *self)
547{
548 Py_DECREF(self->module);
549 DESTRUCTOR_FINISH(self);
550}
551
552 static PyObject *
553LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
554{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200555 PyObject *ret = self->module;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200556
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200557 Py_INCREF(ret);
558 return ret;
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200559}
560
561static struct PyMethodDef LoaderMethods[] = {
562 /* name, function, calling, doc */
563 {"load_module", (PyCFunction)LoaderLoadModule, METH_VARARGS, ""},
564 { NULL, NULL, 0, NULL}
565};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200566
567/* Check to see whether a Vim error has been reported, or a keyboard
568 * interrupt has been detected.
569 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200570
571 static void
572VimTryStart(void)
573{
574 ++trylevel;
575}
576
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200577 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200578VimTryEnd(void)
579{
580 --trylevel;
Bram Moolenaar41009372013-07-01 22:03:04 +0200581 /* Without this it stops processing all subsequent VimL commands and
582 * generates strange error messages if I e.g. try calling Test() in a
583 * cycle */
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200584 did_emsg = FALSE;
585 /* Keyboard interrupt should be preferred over anything else */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200586 if (got_int)
587 {
Bram Moolenaar4315f262014-01-31 14:54:04 +0100588 if (did_throw)
Bram Moolenaard6b8a522013-11-11 01:05:48 +0100589 discard_current_exception();
Bram Moolenaard6b8a522013-11-11 01:05:48 +0100590 got_int = FALSE;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200591 PyErr_SetNone(PyExc_KeyboardInterrupt);
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200592 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200593 }
Bram Moolenaar9fee7d42013-11-28 17:04:43 +0100594 else if (msg_list != NULL && *msg_list != NULL)
595 {
596 int should_free;
597 char_u *msg;
598
599 msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free);
600
601 if (msg == NULL)
602 {
603 PyErr_NoMemory();
604 return -1;
605 }
606
607 PyErr_SetVim((char *) msg);
608
609 free_global_msglist();
610
611 if (should_free)
612 vim_free(msg);
613
614 return -1;
615 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200616 else if (!did_throw)
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200617 return (PyErr_Occurred() ? -1 : 0);
618 /* Python exception is preferred over vim one; unlikely to occur though */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200619 else if (PyErr_Occurred())
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200620 {
Bram Moolenaar4315f262014-01-31 14:54:04 +0100621 discard_current_exception();
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200622 return -1;
623 }
624 /* Finally transform VimL exception to python one */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200625 else
626 {
Bram Moolenaar41009372013-07-01 22:03:04 +0200627 PyErr_SetVim((char *)current_exception->value);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200628 discard_current_exception();
Bram Moolenaar841fbd22013-06-23 14:37:07 +0200629 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200630 }
631}
632
633 static int
634VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200635{
636 if (got_int)
637 {
638 PyErr_SetNone(PyExc_KeyboardInterrupt);
639 return 1;
640 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200641 return 0;
642}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200643
644/* Vim module - Implementation
645 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200646
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200647 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200648VimCommand(PyObject *self UNUSED, PyObject *string)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200649{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200650 char_u *cmd;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200651 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200652 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200653
Bram Moolenaar389a1792013-06-23 13:00:44 +0200654 if (!(cmd = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200655 return NULL;
656
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200657 Py_BEGIN_ALLOW_THREADS
658 Python_Lock_Vim();
659
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200660 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200661 do_cmdline_cmd(cmd);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200662 update_screen(VALID);
663
664 Python_Release_Vim();
665 Py_END_ALLOW_THREADS
666
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200667 if (VimTryEnd())
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200668 ret = NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200669 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200670 ret = Py_None;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200671
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200672 Py_XINCREF(ret);
Bram Moolenaar389a1792013-06-23 13:00:44 +0200673 Py_XDECREF(todecref);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200674 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200675}
676
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200677/*
678 * Function to translate a typval_T into a PyObject; this will recursively
679 * translate lists/dictionaries into their Python equivalents.
680 *
681 * The depth parameter is to avoid infinite recursion, set it to 1 when
682 * you call VimToPython.
683 */
684 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200685VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200686{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200687 PyObject *ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200688 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200689 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200690
691 /* Avoid infinite recursion */
692 if (depth > 100)
693 {
694 Py_INCREF(Py_None);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200695 ret = Py_None;
696 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200697 }
698
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200699 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200700 * then and we can use it again. */
701 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
702 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
703 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200704 sprintf(ptrBuf, "%p",
705 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
706 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200707
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200708 if ((ret = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200709 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200710 Py_INCREF(ret);
711 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200712 }
713 }
714
715 if (our_tv->v_type == VAR_STRING)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200716 ret = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200717 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200718 else if (our_tv->v_type == VAR_NUMBER)
719 {
720 char buf[NUMBUFLEN];
721
722 /* For backwards compatibility numbers are stored as strings. */
723 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar41009372013-07-01 22:03:04 +0200724 ret = PyString_FromString((char *)buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200725 }
726# ifdef FEAT_FLOAT
727 else if (our_tv->v_type == VAR_FLOAT)
728 {
729 char buf[NUMBUFLEN];
730
731 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar41009372013-07-01 22:03:04 +0200732 ret = PyString_FromString((char *)buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200733 }
734# endif
735 else if (our_tv->v_type == VAR_LIST)
736 {
737 list_T *list = our_tv->vval.v_list;
738 listitem_T *curr;
739
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200740 if (list == NULL)
741 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200742
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200743 if (!(ret = PyList_New(0)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200744 return NULL;
745
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200746 if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200747 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200748 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200749 return NULL;
750 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200751
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200752 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
753 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200754 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200755 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200756 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200757 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200758 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200759 if (PyList_Append(ret, newObj))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200760 {
761 Py_DECREF(newObj);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200762 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200763 return NULL;
764 }
765 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200766 }
767 }
768 else if (our_tv->v_type == VAR_DICT)
769 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200770
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100771 hashtab_T *ht;
772 long_u todo;
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200773 hashitem_T *hi;
774 dictitem_T *di;
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100775
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200776 if (our_tv->vval.v_dict == NULL)
777 return NULL;
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100778 ht = &our_tv->vval.v_dict->dv_hashtab;
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200779
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200780 if (!(ret = PyDict_New()))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200781 return NULL;
782
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200783 if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200784 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200785 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200786 return NULL;
787 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200788
Bram Moolenaar24a6ff82015-02-10 18:41:58 +0100789 todo = ht->ht_used;
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200790 for (hi = ht->ht_array; todo > 0; ++hi)
791 {
792 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200793 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200794 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200795
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200796 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200797 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200798 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200799 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200800 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200801 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200802 if (PyDict_SetItemString(ret, (char *)hi->hi_key, newObj))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200803 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200804 Py_DECREF(ret);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200805 Py_DECREF(newObj);
806 return NULL;
807 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200808 }
809 }
810 }
811 else
812 {
813 Py_INCREF(Py_None);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200814 ret = Py_None;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200815 }
816
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200817 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200818}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200819
820 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200821VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200822{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200823 char_u *expr;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200824 typval_T *our_tv;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200825 PyObject *string;
826 PyObject *todecref;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200827 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200828 PyObject *lookup_dict;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200829
Bram Moolenaar389a1792013-06-23 13:00:44 +0200830 if (!PyArg_ParseTuple(args, "O", &string))
831 return NULL;
832
833 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200834 return NULL;
835
836 Py_BEGIN_ALLOW_THREADS
837 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200838 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200839 our_tv = eval_expr(expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200840 Python_Release_Vim();
841 Py_END_ALLOW_THREADS
842
Bram Moolenaar389a1792013-06-23 13:00:44 +0200843 Py_XDECREF(todecref);
844
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200845 if (VimTryEnd())
846 return NULL;
847
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200848 if (our_tv == NULL)
849 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200850 PyErr_SET_VIM(N_("invalid expression"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200851 return NULL;
852 }
853
854 /* Convert the Vim type into a Python type. Create a dictionary that's
855 * used to check for recursive loops. */
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200856 if (!(lookup_dict = PyDict_New()))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200857 ret = NULL;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200858 else
859 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200860 ret = VimToPython(our_tv, 1, lookup_dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200861 Py_DECREF(lookup_dict);
862 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200863
864
865 Py_BEGIN_ALLOW_THREADS
866 Python_Lock_Vim();
867 free_tv(our_tv);
868 Python_Release_Vim();
869 Py_END_ALLOW_THREADS
870
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200871 return ret;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200872}
873
Bram Moolenaardb913952012-06-29 12:54:53 +0200874static PyObject *ConvertToPyObject(typval_T *);
875
876 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200877VimEvalPy(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200878{
Bram Moolenaardb913952012-06-29 12:54:53 +0200879 typval_T *our_tv;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200880 PyObject *ret;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200881 char_u *expr;
882 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +0200883
Bram Moolenaar389a1792013-06-23 13:00:44 +0200884 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200885 return NULL;
886
887 Py_BEGIN_ALLOW_THREADS
888 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200889 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200890 our_tv = eval_expr(expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200891 Python_Release_Vim();
892 Py_END_ALLOW_THREADS
893
Bram Moolenaar389a1792013-06-23 13:00:44 +0200894 Py_XDECREF(todecref);
895
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200896 if (VimTryEnd())
897 return NULL;
898
Bram Moolenaardb913952012-06-29 12:54:53 +0200899 if (our_tv == NULL)
900 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200901 PyErr_SET_VIM(N_("invalid expression"));
Bram Moolenaardb913952012-06-29 12:54:53 +0200902 return NULL;
903 }
904
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200905 ret = ConvertToPyObject(our_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200906 Py_BEGIN_ALLOW_THREADS
907 Python_Lock_Vim();
908 free_tv(our_tv);
909 Python_Release_Vim();
910 Py_END_ALLOW_THREADS
911
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200912 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +0200913}
914
915 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200916VimStrwidth(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200917{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200918 char_u *str;
919 PyObject *todecref;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200920 int len;
Bram Moolenaardb913952012-06-29 12:54:53 +0200921
Bram Moolenaar389a1792013-06-23 13:00:44 +0200922 if (!(str = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200923 return NULL;
924
Bram Moolenaara54bf402012-12-05 16:30:07 +0100925#ifdef FEAT_MBYTE
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200926 len = mb_string2cells(str, (int)STRLEN(str));
Bram Moolenaara54bf402012-12-05 16:30:07 +0100927#else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200928 len = STRLEN(str);
Bram Moolenaara54bf402012-12-05 16:30:07 +0100929#endif
Bram Moolenaar389a1792013-06-23 13:00:44 +0200930
931 Py_XDECREF(todecref);
932
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200933 return PyLong_FromLong(len);
Bram Moolenaardb913952012-06-29 12:54:53 +0200934}
935
Bram Moolenaarf4258302013-06-02 18:20:17 +0200936 static PyObject *
937_VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
938{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200939 PyObject *ret;
Bram Moolenaarf4258302013-06-02 18:20:17 +0200940 PyObject *newwd;
941 PyObject *todecref;
942 char_u *new_dir;
943
Bram Moolenaard4209d22013-06-05 20:34:15 +0200944 if (_chdir == NULL)
945 return NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200946 if (!(ret = PyObject_Call(_chdir, args, kwargs)))
Bram Moolenaarf4258302013-06-02 18:20:17 +0200947 return NULL;
948
949 if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
950 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200951 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200952 return NULL;
953 }
954
955 if (!(new_dir = StringToChars(newwd, &todecref)))
956 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200957 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200958 Py_DECREF(newwd);
959 return NULL;
960 }
961
962 VimTryStart();
963
964 if (vim_chdir(new_dir))
965 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200966 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200967 Py_DECREF(newwd);
968 Py_XDECREF(todecref);
969
970 if (VimTryEnd())
971 return NULL;
972
Bram Moolenaar6f1404f2013-06-23 16:04:08 +0200973 PyErr_SET_VIM(N_("failed to change directory"));
Bram Moolenaarf4258302013-06-02 18:20:17 +0200974 return NULL;
975 }
976
977 Py_DECREF(newwd);
978 Py_XDECREF(todecref);
979
980 post_chdir(FALSE);
981
982 if (VimTryEnd())
983 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200984 Py_DECREF(ret);
Bram Moolenaarf4258302013-06-02 18:20:17 +0200985 return NULL;
986 }
987
Bram Moolenaarc4b99e02013-06-23 14:30:47 +0200988 return ret;
Bram Moolenaarf4258302013-06-02 18:20:17 +0200989}
990
991 static PyObject *
992VimChdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
993{
994 return _VimChdir(py_chdir, args, kwargs);
995}
996
997 static PyObject *
998VimFchdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
999{
1000 return _VimChdir(py_fchdir, args, kwargs);
1001}
1002
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001003typedef struct {
1004 PyObject *callable;
1005 PyObject *result;
1006} map_rtp_data;
1007
1008 static void
1009map_rtp_callback(char_u *path, void *_data)
1010{
1011 void **data = (void **) _data;
1012 PyObject *pathObject;
1013 map_rtp_data *mr_data = *((map_rtp_data **) data);
1014
Bram Moolenaar41009372013-07-01 22:03:04 +02001015 if (!(pathObject = PyString_FromString((char *)path)))
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001016 {
1017 *data = NULL;
1018 return;
1019 }
1020
1021 mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
1022 pathObject, NULL);
1023
1024 Py_DECREF(pathObject);
1025
1026 if (!mr_data->result || mr_data->result != Py_None)
1027 *data = NULL;
1028 else
1029 {
1030 Py_DECREF(mr_data->result);
1031 mr_data->result = NULL;
1032 }
1033}
1034
1035 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02001036VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001037{
1038 map_rtp_data data;
1039
Bram Moolenaar389a1792013-06-23 13:00:44 +02001040 data.callable = callable;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001041 data.result = NULL;
1042
1043 do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
1044
1045 if (data.result == NULL)
1046 {
1047 if (PyErr_Occurred())
1048 return NULL;
1049 else
1050 {
1051 Py_INCREF(Py_None);
1052 return Py_None;
1053 }
1054 }
1055 return data.result;
1056}
1057
1058/*
1059 * _vim_runtimepath_ special path implementation.
1060 */
1061
1062 static void
1063map_finder_callback(char_u *path, void *_data)
1064{
1065 void **data = (void **) _data;
1066 PyObject *list = *((PyObject **) data);
1067 PyObject *pathObject1, *pathObject2;
1068 char *pathbuf;
1069 size_t pathlen;
1070
1071 pathlen = STRLEN(path);
1072
1073#if PY_MAJOR_VERSION < 3
1074# define PY_MAIN_DIR_STRING "python2"
1075#else
1076# define PY_MAIN_DIR_STRING "python3"
1077#endif
1078#define PY_ALTERNATE_DIR_STRING "pythonx"
1079
1080#define PYTHONX_STRING_LENGTH 7 /* STRLEN("pythonx") */
1081 if (!(pathbuf = PyMem_New(char,
1082 pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
1083 {
1084 PyErr_NoMemory();
1085 *data = NULL;
1086 return;
1087 }
1088
1089 mch_memmove(pathbuf, path, pathlen + 1);
1090 add_pathsep((char_u *) pathbuf);
1091
1092 pathlen = STRLEN(pathbuf);
1093 mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
1094 PYTHONX_STRING_LENGTH + 1);
1095
1096 if (!(pathObject1 = PyString_FromString(pathbuf)))
1097 {
1098 *data = NULL;
1099 PyMem_Free(pathbuf);
1100 return;
1101 }
1102
1103 mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
1104 PYTHONX_STRING_LENGTH + 1);
1105
1106 if (!(pathObject2 = PyString_FromString(pathbuf)))
1107 {
1108 Py_DECREF(pathObject1);
1109 PyMem_Free(pathbuf);
1110 *data = NULL;
1111 return;
1112 }
1113
1114 PyMem_Free(pathbuf);
1115
1116 if (PyList_Append(list, pathObject1)
1117 || PyList_Append(list, pathObject2))
1118 *data = NULL;
1119
1120 Py_DECREF(pathObject1);
1121 Py_DECREF(pathObject2);
1122}
1123
1124 static PyObject *
1125Vim_GetPaths(PyObject *self UNUSED)
1126{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001127 PyObject *ret;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001128
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001129 if (!(ret = PyList_New(0)))
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001130 return NULL;
1131
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001132 do_in_runtimepath(NULL, FALSE, &map_finder_callback, ret);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001133
1134 if (PyErr_Occurred())
1135 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001136 Py_DECREF(ret);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001137 return NULL;
1138 }
1139
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001140 return ret;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001141}
1142
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001143 static PyObject *
1144call_load_module(char *name, int len, PyObject *find_module_result)
1145{
1146 PyObject *fd, *pathname, *description;
1147
Bram Moolenaarc476e522013-06-23 13:46:40 +02001148 if (!PyTuple_Check(find_module_result))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001149 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001150 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001151 N_("expected 3-tuple as imp.find_module() result, but got %s"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02001152 Py_TYPE_NAME(find_module_result));
1153 return NULL;
1154 }
1155 if (PyTuple_GET_SIZE(find_module_result) != 3)
1156 {
1157 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001158 N_("expected 3-tuple as imp.find_module() result, but got "
1159 "tuple of size %d"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02001160 (int) PyTuple_GET_SIZE(find_module_result));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001161 return NULL;
1162 }
1163
1164 if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
1165 || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
1166 || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
1167 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001168 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001169 N_("internal error: imp.find_module returned tuple with NULL"));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001170 return NULL;
1171 }
1172
1173 return PyObject_CallFunction(py_load_module,
1174 "s#OOO", name, len, fd, pathname, description);
1175}
1176
1177 static PyObject *
1178find_module(char *fullname, char *tail, PyObject *new_path)
1179{
1180 PyObject *find_module_result;
1181 PyObject *module;
1182 char *dot;
1183
Bram Moolenaar41009372013-07-01 22:03:04 +02001184 if ((dot = (char *)vim_strchr((char_u *) tail, '.')))
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001185 {
1186 /*
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001187 * There is a dot in the name: call find_module recursively without the
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001188 * first component
1189 */
1190 PyObject *newest_path;
1191 int partlen = (int) (dot - 1 - tail);
1192
1193 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1194 "s#O", tail, partlen, new_path)))
1195 return NULL;
1196
1197 if (!(module = call_load_module(
1198 fullname,
1199 ((int) (tail - fullname)) + partlen,
1200 find_module_result)))
1201 {
1202 Py_DECREF(find_module_result);
1203 return NULL;
1204 }
1205
1206 Py_DECREF(find_module_result);
1207
1208 if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
1209 {
1210 Py_DECREF(module);
1211 return NULL;
1212 }
1213
1214 Py_DECREF(module);
1215
1216 module = find_module(fullname, dot + 1, newest_path);
1217
1218 Py_DECREF(newest_path);
1219
1220 return module;
1221 }
1222 else
1223 {
1224 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1225 "sO", tail, new_path)))
1226 return NULL;
1227
1228 if (!(module = call_load_module(
1229 fullname,
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001230 (int)STRLEN(fullname),
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001231 find_module_result)))
1232 {
1233 Py_DECREF(find_module_result);
1234 return NULL;
1235 }
1236
1237 Py_DECREF(find_module_result);
1238
1239 return module;
1240 }
1241}
1242
1243 static PyObject *
1244FinderFindModule(PyObject *self, PyObject *args)
1245{
1246 char *fullname;
1247 PyObject *module;
1248 PyObject *new_path;
1249 LoaderObject *loader;
1250
1251 if (!PyArg_ParseTuple(args, "s", &fullname))
1252 return NULL;
1253
1254 if (!(new_path = Vim_GetPaths(self)))
1255 return NULL;
1256
1257 module = find_module(fullname, fullname, new_path);
1258
1259 Py_DECREF(new_path);
1260
1261 if (!module)
1262 {
Bram Moolenaar7e85d3d2013-06-23 16:40:39 +02001263 if (PyErr_Occurred())
1264 {
1265 if (PyErr_ExceptionMatches(PyExc_ImportError))
1266 PyErr_Clear();
1267 else
1268 return NULL;
1269 }
1270
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001271 Py_INCREF(Py_None);
1272 return Py_None;
1273 }
1274
1275 if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
1276 {
1277 Py_DECREF(module);
1278 return NULL;
1279 }
1280
1281 loader->module = module;
1282
1283 return (PyObject *) loader;
1284}
1285
1286 static PyObject *
1287VimPathHook(PyObject *self UNUSED, PyObject *args)
1288{
1289 char *path;
1290
1291 if (PyArg_ParseTuple(args, "s", &path)
1292 && STRCMP(path, vim_special_path) == 0)
1293 {
1294 Py_INCREF(vim_module);
1295 return vim_module;
1296 }
1297
1298 PyErr_Clear();
1299 PyErr_SetNone(PyExc_ImportError);
1300 return NULL;
1301}
1302
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001303/*
1304 * Vim module - Definitions
1305 */
1306
1307static struct PyMethodDef VimMethods[] = {
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001308 /* name, function, calling, documentation */
Bram Moolenaar389a1792013-06-23 13:00:44 +02001309 {"command", VimCommand, METH_O, "Execute a Vim ex-mode command" },
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001310 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02001311 {"bindeval", VimEvalPy, METH_O, "Like eval(), but returns objects attached to vim ones"},
1312 {"strwidth", VimStrwidth, METH_O, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001313 {"chdir", (PyCFunction)VimChdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
1314 {"fchdir", (PyCFunction)VimFchdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
Bram Moolenaar389a1792013-06-23 13:00:44 +02001315 {"foreach_rtp", VimForeachRTP, METH_O, "Call given callable for each path in &rtp"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001316 {"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001317 {"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
1318 {"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
1319 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001320};
1321
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001322/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001323 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001324 */
1325
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001326static PyTypeObject IterType;
1327
1328typedef PyObject *(*nextfun)(void **);
1329typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001330typedef int (*traversefun)(void *, visitproc, void *);
1331typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001332
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001333/* Main purpose of this object is removing the need for do python
1334 * initialization (i.e. PyType_Ready and setting type attributes) for a big
1335 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001336
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001337typedef struct
1338{
1339 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001340 void *cur;
1341 nextfun next;
1342 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001343 traversefun traverse;
1344 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001345} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001346
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001347 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001348IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
1349 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001350{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001351 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001352
Bram Moolenaar774267b2013-05-21 20:51:59 +02001353 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001354 self->cur = start;
1355 self->next = next;
1356 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001357 self->traverse = traverse;
1358 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001359
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001360 return (PyObject *)(self);
1361}
1362
1363 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001364IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001365{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001366 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02001367 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +02001368 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001369}
1370
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001371 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001372IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001373{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001374 if (self->traverse != NULL)
1375 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001376 else
1377 return 0;
1378}
1379
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001380/* Mac OSX defines clear() somewhere. */
1381#ifdef clear
1382# undef clear
1383#endif
1384
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001385 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001386IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001387{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001388 if (self->clear != NULL)
1389 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001390 else
1391 return 0;
1392}
1393
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001394 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001395IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001396{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001397 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001398}
1399
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001400 static PyObject *
1401IterIter(PyObject *self)
1402{
Bram Moolenaar1bcabe12013-05-29 22:52:32 +02001403 Py_INCREF(self);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001404 return self;
1405}
Bram Moolenaardfa38d42013-05-15 13:38:47 +02001406
Bram Moolenaardb913952012-06-29 12:54:53 +02001407typedef struct pylinkedlist_S {
1408 struct pylinkedlist_S *pll_next;
1409 struct pylinkedlist_S *pll_prev;
1410 PyObject *pll_obj;
1411} pylinkedlist_T;
1412
1413static pylinkedlist_T *lastdict = NULL;
1414static pylinkedlist_T *lastlist = NULL;
1415
1416 static void
1417pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
1418{
1419 if (ref->pll_prev == NULL)
1420 {
1421 if (ref->pll_next == NULL)
1422 {
1423 *last = NULL;
1424 return;
1425 }
1426 }
1427 else
1428 ref->pll_prev->pll_next = ref->pll_next;
1429
1430 if (ref->pll_next == NULL)
1431 *last = ref->pll_prev;
1432 else
1433 ref->pll_next->pll_prev = ref->pll_prev;
1434}
1435
1436 static void
1437pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
1438{
1439 if (*last == NULL)
1440 ref->pll_prev = NULL;
1441 else
1442 {
1443 (*last)->pll_next = ref;
1444 ref->pll_prev = *last;
1445 }
1446 ref->pll_next = NULL;
1447 ref->pll_obj = self;
1448 *last = ref;
1449}
1450
1451static PyTypeObject DictionaryType;
1452
1453typedef struct
1454{
1455 PyObject_HEAD
1456 dict_T *dict;
1457 pylinkedlist_T ref;
1458} DictionaryObject;
1459
Bram Moolenaara9922d62013-05-30 13:01:18 +02001460static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
1461
1462#define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
1463
Bram Moolenaardb913952012-06-29 12:54:53 +02001464 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001465DictionaryNew(PyTypeObject *subtype, dict_T *dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02001466{
1467 DictionaryObject *self;
1468
Bram Moolenaara9922d62013-05-30 13:01:18 +02001469 self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02001470 if (self == NULL)
1471 return NULL;
1472 self->dict = dict;
1473 ++dict->dv_refcount;
1474
1475 pyll_add((PyObject *)(self), &self->ref, &lastdict);
1476
1477 return (PyObject *)(self);
1478}
1479
Bram Moolenaara9922d62013-05-30 13:01:18 +02001480 static dict_T *
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001481py_dict_alloc(void)
Bram Moolenaara9922d62013-05-30 13:01:18 +02001482{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001483 dict_T *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001484
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001485 if (!(ret = dict_alloc()))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001486 {
1487 PyErr_NoMemory();
1488 return NULL;
1489 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001490 ++ret->dv_refcount;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001491
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001492 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001493}
1494
1495 static PyObject *
1496DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1497{
1498 DictionaryObject *self;
1499 dict_T *dict;
1500
1501 if (!(dict = py_dict_alloc()))
1502 return NULL;
1503
1504 self = (DictionaryObject *) DictionaryNew(subtype, dict);
1505
1506 --dict->dv_refcount;
1507
1508 if (kwargs || PyTuple_Size(args))
1509 {
1510 PyObject *tmp;
1511 if (!(tmp = DictionaryUpdate(self, args, kwargs)))
1512 {
1513 Py_DECREF(self);
1514 return NULL;
1515 }
1516
1517 Py_DECREF(tmp);
1518 }
1519
1520 return (PyObject *)(self);
1521}
1522
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001523 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001524DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001525{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001526 pyll_remove(&self->ref, &lastdict);
1527 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001528
1529 DESTRUCTOR_FINISH(self);
1530}
1531
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001532static char *DictionaryAttrs[] = {
1533 "locked", "scope",
1534 NULL
1535};
1536
1537 static PyObject *
1538DictionaryDir(PyObject *self)
1539{
1540 return ObjectDir(self, DictionaryAttrs);
1541}
1542
Bram Moolenaardb913952012-06-29 12:54:53 +02001543 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001544DictionarySetattr(DictionaryObject *self, char *name, PyObject *valObject)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001545{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001546 if (valObject == NULL)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001547 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001548 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001549 N_("cannot delete vim.Dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001550 return -1;
1551 }
1552
1553 if (strcmp(name, "locked") == 0)
1554 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001555 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001556 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001557 PyErr_SET_STRING(PyExc_TypeError,
1558 N_("cannot modify fixed dictionary"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001559 return -1;
1560 }
1561 else
1562 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001563 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarb983f752013-05-15 16:11:50 +02001564 if (istrue == -1)
1565 return -1;
1566 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001567 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001568 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001569 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001570 }
1571 return 0;
1572 }
1573 else
1574 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001575 PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02001576 return -1;
1577 }
1578}
1579
1580 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001581DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001582{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001583 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +02001584}
1585
Bram Moolenaara9922d62013-05-30 13:01:18 +02001586#define DICT_FLAG_HAS_DEFAULT 0x01
1587#define DICT_FLAG_POP 0x02
1588#define DICT_FLAG_NONE_DEFAULT 0x04
1589#define DICT_FLAG_RETURN_BOOL 0x08 /* Incompatible with DICT_FLAG_POP */
1590#define DICT_FLAG_RETURN_PAIR 0x10
1591
Bram Moolenaardb913952012-06-29 12:54:53 +02001592 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001593_DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
Bram Moolenaardb913952012-06-29 12:54:53 +02001594{
Bram Moolenaara9922d62013-05-30 13:01:18 +02001595 PyObject *keyObject;
1596 PyObject *defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001597 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001598 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001599 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001600 dict_T *dict = self->dict;
1601 hashitem_T *hi;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001602 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001603
Bram Moolenaara9922d62013-05-30 13:01:18 +02001604 if (flags & DICT_FLAG_HAS_DEFAULT)
1605 {
1606 if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1607 return NULL;
1608 }
1609 else
1610 keyObject = args;
1611
1612 if (flags & DICT_FLAG_RETURN_BOOL)
1613 defObject = Py_False;
1614
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001615 if (!(key = StringToChars(keyObject, &todecref)))
1616 return NULL;
1617
1618 if (*key == NUL)
1619 {
1620 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001621 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001622 return NULL;
1623 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001624
Bram Moolenaara9922d62013-05-30 13:01:18 +02001625 hi = hash_find(&dict->dv_hashtab, key);
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001626
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001627 Py_XDECREF(todecref);
Bram Moolenaar696c2112012-09-21 13:43:14 +02001628
Bram Moolenaara9922d62013-05-30 13:01:18 +02001629 if (HASHITEM_EMPTY(hi))
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001630 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001631 if (defObject)
1632 {
1633 Py_INCREF(defObject);
1634 return defObject;
1635 }
1636 else
1637 {
1638 PyErr_SetObject(PyExc_KeyError, keyObject);
1639 return NULL;
1640 }
1641 }
1642 else if (flags & DICT_FLAG_RETURN_BOOL)
1643 {
Bram Moolenaar0e4eebd2014-02-12 22:08:49 +01001644 ret = Py_True;
1645 Py_INCREF(ret);
1646 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001647 }
1648
1649 di = dict_lookup(hi);
1650
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001651 if (!(ret = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001652 return NULL;
1653
1654 if (flags & DICT_FLAG_POP)
1655 {
1656 if (dict->dv_lock)
1657 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001658 RAISE_LOCKED_DICTIONARY;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001659 Py_DECREF(ret);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001660 return NULL;
1661 }
1662
1663 hash_remove(&dict->dv_hashtab, hi);
1664 dictitem_free(di);
1665 }
1666
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001667 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001668}
1669
1670 static PyObject *
1671DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1672{
1673 return _DictionaryItem(self, keyObject, 0);
1674}
1675
1676 static int
1677DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1678{
1679 PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001680 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001681
Bram Moolenaarba2d7ff2013-11-04 00:34:53 +01001682 if (rObj == NULL)
1683 return -1;
1684
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001685 ret = (rObj == Py_True);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001686
Bram Moolenaardee2e312013-06-23 16:35:47 +02001687 Py_DECREF(rObj);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001688
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001689 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001690}
1691
1692typedef struct
1693{
1694 hashitem_T *ht_array;
1695 long_u ht_used;
1696 hashtab_T *ht;
1697 hashitem_T *hi;
Bram Moolenaar99dc19d2013-05-31 20:49:31 +02001698 long_u todo;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001699} dictiterinfo_T;
1700
1701 static PyObject *
1702DictionaryIterNext(dictiterinfo_T **dii)
1703{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001704 PyObject *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001705
1706 if (!(*dii)->todo)
1707 return NULL;
1708
1709 if ((*dii)->ht->ht_array != (*dii)->ht_array ||
1710 (*dii)->ht->ht_used != (*dii)->ht_used)
1711 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001712 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001713 N_("hashtab changed during iteration"));
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001714 return NULL;
1715 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001716
Bram Moolenaara9922d62013-05-30 13:01:18 +02001717 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
1718 ++((*dii)->hi);
1719
1720 --((*dii)->todo);
1721
Bram Moolenaar41009372013-07-01 22:03:04 +02001722 if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001723 return NULL;
1724
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001725 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001726}
1727
1728 static PyObject *
1729DictionaryIter(DictionaryObject *self)
1730{
1731 dictiterinfo_T *dii;
1732 hashtab_T *ht;
1733
1734 if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1735 {
1736 PyErr_NoMemory();
1737 return NULL;
1738 }
1739
1740 ht = &self->dict->dv_hashtab;
1741 dii->ht_array = ht->ht_array;
1742 dii->ht_used = ht->ht_used;
1743 dii->ht = ht;
1744 dii->hi = dii->ht_array;
1745 dii->todo = dii->ht_used;
1746
1747 return IterNew(dii,
1748 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1749 NULL, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02001750}
1751
1752 static PyInt
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001753DictionaryAssItem(
1754 DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +02001755{
1756 char_u *key;
1757 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001758 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001759 dictitem_T *di;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001760 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001761
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001762 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +02001763 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001764 RAISE_LOCKED_DICTIONARY;
Bram Moolenaardb913952012-06-29 12:54:53 +02001765 return -1;
1766 }
1767
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001768 if (!(key = StringToChars(keyObject, &todecref)))
1769 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001770
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001771 if (*key == NUL)
1772 {
1773 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001774 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001775 return -1;
1776 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001777
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001778 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +02001779
1780 if (valObject == NULL)
1781 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +02001782 hashitem_T *hi;
1783
Bram Moolenaardb913952012-06-29 12:54:53 +02001784 if (di == NULL)
1785 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001786 Py_XDECREF(todecref);
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001787 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +02001788 return -1;
1789 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001790 hi = hash_find(&dict->dv_hashtab, di->di_key);
1791 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +02001792 dictitem_free(di);
Bram Moolenaar78b59572013-06-02 18:54:21 +02001793 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001794 return 0;
1795 }
1796
1797 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaar78b59572013-06-02 18:54:21 +02001798 {
1799 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001800 return -1;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001801 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001802
1803 if (di == NULL)
1804 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001805 if (!(di = dictitem_alloc(key)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001806 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001807 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001808 PyErr_NoMemory();
1809 return -1;
1810 }
1811 di->di_tv.v_lock = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001812 di->di_tv.v_type = VAR_UNKNOWN;
Bram Moolenaardb913952012-06-29 12:54:53 +02001813
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001814 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001815 {
1816 vim_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001817 dictitem_free(di);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001818 RAISE_KEY_ADD_FAIL(key);
1819 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001820 return -1;
1821 }
1822 }
1823 else
1824 clear_tv(&di->di_tv);
1825
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001826 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001827
1828 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001829 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001830 return 0;
1831}
1832
Bram Moolenaara9922d62013-05-30 13:01:18 +02001833typedef PyObject *(*hi_to_py)(hashitem_T *);
1834
Bram Moolenaardb913952012-06-29 12:54:53 +02001835 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001836DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
Bram Moolenaardb913952012-06-29 12:54:53 +02001837{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001838 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001839 long_u todo = dict->dv_hashtab.ht_used;
1840 Py_ssize_t i = 0;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001841 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001842 hashitem_T *hi;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001843 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +02001844
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001845 ret = PyList_New(todo);
Bram Moolenaardb913952012-06-29 12:54:53 +02001846 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1847 {
1848 if (!HASHITEM_EMPTY(hi))
1849 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001850 if (!(newObj = hiconvert(hi)))
1851 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001852 Py_DECREF(ret);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001853 return NULL;
1854 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001855 PyList_SET_ITEM(ret, i, newObj);
Bram Moolenaardb913952012-06-29 12:54:53 +02001856 --todo;
1857 ++i;
1858 }
1859 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001860 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02001861}
1862
Bram Moolenaara9922d62013-05-30 13:01:18 +02001863 static PyObject *
1864dict_key(hashitem_T *hi)
1865{
1866 return PyBytes_FromString((char *)(hi->hi_key));
1867}
1868
1869 static PyObject *
1870DictionaryListKeys(DictionaryObject *self)
1871{
1872 return DictionaryListObjects(self, dict_key);
1873}
1874
1875 static PyObject *
1876dict_val(hashitem_T *hi)
1877{
1878 dictitem_T *di;
1879
1880 di = dict_lookup(hi);
1881 return ConvertToPyObject(&di->di_tv);
1882}
1883
1884 static PyObject *
1885DictionaryListValues(DictionaryObject *self)
1886{
1887 return DictionaryListObjects(self, dict_val);
1888}
1889
1890 static PyObject *
1891dict_item(hashitem_T *hi)
1892{
1893 PyObject *keyObject;
1894 PyObject *valObject;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001895 PyObject *ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001896
1897 if (!(keyObject = dict_key(hi)))
1898 return NULL;
1899
1900 if (!(valObject = dict_val(hi)))
1901 {
1902 Py_DECREF(keyObject);
1903 return NULL;
1904 }
1905
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001906 ret = Py_BuildValue("(OO)", keyObject, valObject);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001907
1908 Py_DECREF(keyObject);
1909 Py_DECREF(valObject);
1910
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001911 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001912}
1913
1914 static PyObject *
1915DictionaryListItems(DictionaryObject *self)
1916{
1917 return DictionaryListObjects(self, dict_item);
1918}
1919
1920 static PyObject *
1921DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
1922{
1923 dict_T *dict = self->dict;
1924
1925 if (dict->dv_lock)
1926 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001927 RAISE_LOCKED_DICTIONARY;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001928 return NULL;
1929 }
1930
1931 if (kwargs)
1932 {
1933 typval_T tv;
1934
1935 if (ConvertFromPyMapping(kwargs, &tv) == -1)
1936 return NULL;
1937
1938 VimTryStart();
1939 dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force");
1940 clear_tv(&tv);
1941 if (VimTryEnd())
1942 return NULL;
1943 }
1944 else
1945 {
Bram Moolenaar2d5f38f2014-02-11 18:47:27 +01001946 PyObject *obj = NULL;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001947
Bram Moolenaar2d5f38f2014-02-11 18:47:27 +01001948 if (!PyArg_ParseTuple(args, "|O", &obj))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001949 return NULL;
1950
Bram Moolenaar2d5f38f2014-02-11 18:47:27 +01001951 if (obj == NULL)
1952 {
1953 Py_INCREF(Py_None);
1954 return Py_None;
1955 }
1956
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001957 if (PyObject_HasAttrString(obj, "keys"))
1958 return DictionaryUpdate(self, NULL, obj);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001959 else
1960 {
1961 PyObject *iterator;
1962 PyObject *item;
1963
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02001964 if (!(iterator = PyObject_GetIter(obj)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001965 return NULL;
1966
1967 while ((item = PyIter_Next(iterator)))
1968 {
1969 PyObject *fast;
1970 PyObject *keyObject;
1971 PyObject *valObject;
1972 PyObject *todecref;
1973 char_u *key;
1974 dictitem_T *di;
1975
1976 if (!(fast = PySequence_Fast(item, "")))
1977 {
1978 Py_DECREF(iterator);
1979 Py_DECREF(item);
1980 return NULL;
1981 }
1982
1983 Py_DECREF(item);
1984
1985 if (PySequence_Fast_GET_SIZE(fast) != 2)
1986 {
1987 Py_DECREF(iterator);
1988 Py_DECREF(fast);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001989 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02001990 N_("expected sequence element of size 2, "
1991 "but got sequence of size %d"),
Bram Moolenaardee2e312013-06-23 16:35:47 +02001992 (int) PySequence_Fast_GET_SIZE(fast));
Bram Moolenaara9922d62013-05-30 13:01:18 +02001993 return NULL;
1994 }
1995
1996 keyObject = PySequence_Fast_GET_ITEM(fast, 0);
1997
1998 if (!(key = StringToChars(keyObject, &todecref)))
1999 {
2000 Py_DECREF(iterator);
2001 Py_DECREF(fast);
2002 return NULL;
2003 }
2004
2005 di = dictitem_alloc(key);
2006
2007 Py_XDECREF(todecref);
2008
2009 if (di == NULL)
2010 {
2011 Py_DECREF(fast);
2012 Py_DECREF(iterator);
2013 PyErr_NoMemory();
2014 return NULL;
2015 }
2016 di->di_tv.v_lock = 0;
2017 di->di_tv.v_type = VAR_UNKNOWN;
2018
2019 valObject = PySequence_Fast_GET_ITEM(fast, 1);
2020
2021 if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
2022 {
2023 Py_DECREF(iterator);
2024 Py_DECREF(fast);
2025 dictitem_free(di);
2026 return NULL;
2027 }
2028
2029 Py_DECREF(fast);
2030
2031 if (dict_add(dict, di) == FAIL)
2032 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002033 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002034 Py_DECREF(iterator);
2035 dictitem_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02002036 return NULL;
2037 }
2038 }
2039
2040 Py_DECREF(iterator);
2041
2042 /* Iterator may have finished due to an exception */
2043 if (PyErr_Occurred())
2044 return NULL;
2045 }
2046 }
2047 Py_INCREF(Py_None);
2048 return Py_None;
2049}
2050
2051 static PyObject *
2052DictionaryGet(DictionaryObject *self, PyObject *args)
2053{
2054 return _DictionaryItem(self, args,
2055 DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
2056}
2057
2058 static PyObject *
2059DictionaryPop(DictionaryObject *self, PyObject *args)
2060{
2061 return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
2062}
2063
2064 static PyObject *
Bram Moolenaarde71b562013-06-02 17:41:54 +02002065DictionaryPopItem(DictionaryObject *self)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002066{
Bram Moolenaarde71b562013-06-02 17:41:54 +02002067 hashitem_T *hi;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002068 PyObject *ret;
Bram Moolenaarde71b562013-06-02 17:41:54 +02002069 PyObject *valObject;
2070 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002071
Bram Moolenaarde71b562013-06-02 17:41:54 +02002072 if (self->dict->dv_hashtab.ht_used == 0)
2073 {
2074 PyErr_SetNone(PyExc_KeyError);
2075 return NULL;
2076 }
2077
2078 hi = self->dict->dv_hashtab.ht_array;
2079 while (HASHITEM_EMPTY(hi))
2080 ++hi;
2081
2082 di = dict_lookup(hi);
2083
2084 if (!(valObject = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02002085 return NULL;
2086
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002087 if (!(ret = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
Bram Moolenaarde71b562013-06-02 17:41:54 +02002088 {
2089 Py_DECREF(valObject);
2090 return NULL;
2091 }
2092
2093 hash_remove(&self->dict->dv_hashtab, hi);
2094 dictitem_free(di);
2095
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002096 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02002097}
2098
2099 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02002100DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002101{
Bram Moolenaara9922d62013-05-30 13:01:18 +02002102 return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
2103}
2104
2105static PySequenceMethods DictionaryAsSeq = {
2106 0, /* sq_length */
2107 0, /* sq_concat */
2108 0, /* sq_repeat */
2109 0, /* sq_item */
2110 0, /* sq_slice */
2111 0, /* sq_ass_item */
2112 0, /* sq_ass_slice */
2113 (objobjproc) DictionaryContains, /* sq_contains */
2114 0, /* sq_inplace_concat */
2115 0, /* sq_inplace_repeat */
2116};
2117
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002118static PyMappingMethods DictionaryAsMapping = {
2119 (lenfunc) DictionaryLength,
2120 (binaryfunc) DictionaryItem,
2121 (objobjargproc) DictionaryAssItem,
2122};
2123
Bram Moolenaardb913952012-06-29 12:54:53 +02002124static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02002125 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaara9922d62013-05-30 13:01:18 +02002126 {"values", (PyCFunction)DictionaryListValues, METH_NOARGS, ""},
2127 {"items", (PyCFunction)DictionaryListItems, METH_NOARGS, ""},
2128 {"update", (PyCFunction)DictionaryUpdate, METH_VARARGS|METH_KEYWORDS, ""},
2129 {"get", (PyCFunction)DictionaryGet, METH_VARARGS, ""},
2130 {"pop", (PyCFunction)DictionaryPop, METH_VARARGS, ""},
Bram Moolenaarde71b562013-06-02 17:41:54 +02002131 {"popitem", (PyCFunction)DictionaryPopItem, METH_NOARGS, ""},
Bram Moolenaar389a1792013-06-23 13:00:44 +02002132 {"has_key", (PyCFunction)DictionaryHasKey, METH_O, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002133 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
2134 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002135};
2136
2137static PyTypeObject ListType;
2138
2139typedef struct
2140{
2141 PyObject_HEAD
2142 list_T *list;
2143 pylinkedlist_T ref;
2144} ListObject;
2145
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002146#define NEW_LIST(list) ListNew(&ListType, list)
2147
Bram Moolenaardb913952012-06-29 12:54:53 +02002148 static PyObject *
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002149ListNew(PyTypeObject *subtype, list_T *list)
Bram Moolenaardb913952012-06-29 12:54:53 +02002150{
2151 ListObject *self;
2152
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002153 self = (ListObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02002154 if (self == NULL)
2155 return NULL;
2156 self->list = list;
2157 ++list->lv_refcount;
2158
2159 pyll_add((PyObject *)(self), &self->ref, &lastlist);
2160
2161 return (PyObject *)(self);
2162}
2163
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002164 static list_T *
Bram Moolenaarfb97f282013-07-09 17:42:46 +02002165py_list_alloc(void)
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002166{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002167 list_T *ret;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002168
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002169 if (!(ret = list_alloc()))
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002170 {
2171 PyErr_NoMemory();
2172 return NULL;
2173 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002174 ++ret->lv_refcount;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002175
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002176 return ret;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002177}
2178
2179 static int
2180list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
2181{
2182 PyObject *iterator;
2183 PyObject *item;
2184 listitem_T *li;
2185
2186 if (!(iterator = PyObject_GetIter(obj)))
2187 return -1;
2188
2189 while ((item = PyIter_Next(iterator)))
2190 {
2191 if (!(li = listitem_alloc()))
2192 {
2193 PyErr_NoMemory();
2194 Py_DECREF(item);
2195 Py_DECREF(iterator);
2196 return -1;
2197 }
2198 li->li_tv.v_lock = 0;
2199 li->li_tv.v_type = VAR_UNKNOWN;
2200
2201 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
2202 {
2203 Py_DECREF(item);
2204 Py_DECREF(iterator);
2205 listitem_free(li);
2206 return -1;
2207 }
2208
2209 Py_DECREF(item);
2210
2211 list_append(l, li);
2212 }
2213
2214 Py_DECREF(iterator);
2215
2216 /* Iterator may have finished due to an exception */
2217 if (PyErr_Occurred())
2218 return -1;
2219
2220 return 0;
2221}
2222
2223 static PyObject *
2224ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2225{
2226 list_T *list;
2227 PyObject *obj = NULL;
2228
2229 if (kwargs)
2230 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002231 PyErr_SET_STRING(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002232 N_("list constructor does not accept keyword arguments"));
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002233 return NULL;
2234 }
2235
2236 if (!PyArg_ParseTuple(args, "|O", &obj))
2237 return NULL;
2238
2239 if (!(list = py_list_alloc()))
2240 return NULL;
2241
2242 if (obj)
2243 {
2244 PyObject *lookup_dict;
2245
2246 if (!(lookup_dict = PyDict_New()))
2247 {
2248 list_unref(list);
2249 return NULL;
2250 }
2251
2252 if (list_py_concat(list, obj, lookup_dict) == -1)
2253 {
2254 Py_DECREF(lookup_dict);
2255 list_unref(list);
2256 return NULL;
2257 }
2258
2259 Py_DECREF(lookup_dict);
2260 }
2261
2262 return ListNew(subtype, list);
2263}
2264
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002265 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002266ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002267{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002268 pyll_remove(&self->ref, &lastlist);
2269 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002270
2271 DESTRUCTOR_FINISH(self);
2272}
2273
Bram Moolenaardb913952012-06-29 12:54:53 +02002274 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002275ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02002276{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002277 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02002278}
2279
2280 static PyObject *
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002281ListIndex(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02002282{
2283 listitem_T *li;
2284
Bram Moolenaard6e39182013-05-21 18:30:34 +02002285 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02002286 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002287 PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002288 return NULL;
2289 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02002290 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002291 if (li == NULL)
2292 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002293 /* No more suitable format specifications in python-2.3 */
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002294 PyErr_VIM_FORMAT(N_("internal error: failed to get vim list item %d"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02002295 (int) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002296 return NULL;
2297 }
2298 return ConvertToPyObject(&li->li_tv);
2299}
2300
Bram Moolenaardb913952012-06-29 12:54:53 +02002301 static PyObject *
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002302ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step,
2303 Py_ssize_t slicelen)
Bram Moolenaardb913952012-06-29 12:54:53 +02002304{
2305 PyInt i;
Bram Moolenaardb913952012-06-29 12:54:53 +02002306 PyObject *list;
Bram Moolenaardb913952012-06-29 12:54:53 +02002307
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002308 if (step == 0)
2309 {
2310 PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2311 return NULL;
2312 }
Bram Moolenaardb913952012-06-29 12:54:53 +02002313
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002314 list = PyList_New(slicelen);
Bram Moolenaardb913952012-06-29 12:54:53 +02002315 if (list == NULL)
2316 return NULL;
2317
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002318 for (i = 0; i < slicelen; ++i)
Bram Moolenaardb913952012-06-29 12:54:53 +02002319 {
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002320 PyObject *item;
2321
2322 item = ListIndex(self, first + i*step);
Bram Moolenaardb913952012-06-29 12:54:53 +02002323 if (item == NULL)
2324 {
2325 Py_DECREF(list);
2326 return NULL;
2327 }
2328
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002329 PyList_SET_ITEM(list, i, item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002330 }
2331
2332 return list;
2333}
2334
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002335 static PyObject *
2336ListItem(ListObject *self, PyObject* idx)
2337{
2338#if PY_MAJOR_VERSION < 3
2339 if (PyInt_Check(idx))
2340 {
2341 long _idx = PyInt_AsLong(idx);
2342 return ListIndex(self, _idx);
2343 }
2344 else
2345#endif
2346 if (PyLong_Check(idx))
2347 {
2348 long _idx = PyLong_AsLong(idx);
2349 return ListIndex(self, _idx);
2350 }
2351 else if (PySlice_Check(idx))
2352 {
2353 Py_ssize_t start, stop, step, slicelen;
2354
Bram Moolenaar922a4662014-03-30 16:11:43 +02002355 if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002356 &start, &stop, &step, &slicelen) < 0)
2357 return NULL;
2358 return ListSlice(self, start, step, slicelen);
2359 }
2360 else
2361 {
2362 RAISE_INVALID_INDEX_TYPE(idx);
2363 return NULL;
2364 }
2365}
2366
2367 static void
2368list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen,
2369 list_T *l, listitem_T **lis, listitem_T *lastaddedli)
2370{
2371 while (numreplaced--)
2372 {
2373 list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]);
2374 listitem_remove(l, lis[slicelen + numreplaced]);
2375 }
2376 while (numadded--)
2377 {
2378 listitem_T *next;
2379
2380 next = lastaddedli->li_prev;
2381 listitem_remove(l, lastaddedli);
2382 lastaddedli = next;
2383 }
2384}
2385
2386 static int
2387ListAssSlice(ListObject *self, Py_ssize_t first,
2388 Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj)
2389{
2390 PyObject *iterator;
2391 PyObject *item;
2392 listitem_T *li;
2393 listitem_T *lastaddedli = NULL;
2394 listitem_T *next;
2395 typval_T v;
2396 list_T *l = self->list;
2397 PyInt i;
2398 PyInt j;
2399 PyInt numreplaced = 0;
2400 PyInt numadded = 0;
2401 PyInt size;
Bram Moolenaar3b522612014-02-11 16:00:35 +01002402 listitem_T **lis = NULL;
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002403
2404 size = ListLength(self);
2405
2406 if (l->lv_lock)
2407 {
2408 RAISE_LOCKED_LIST;
2409 return -1;
2410 }
2411
2412 if (step == 0)
2413 {
2414 PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2415 return -1;
2416 }
2417
2418 if (step != 1 && slicelen == 0)
2419 {
2420 /* Nothing to do. Only error out if obj has some items. */
2421 int ret = 0;
2422
2423 if (obj == NULL)
2424 return 0;
2425
2426 if (!(iterator = PyObject_GetIter(obj)))
2427 return -1;
2428
2429 if ((item = PyIter_Next(iterator)))
2430 {
2431 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar4de6a212014-03-08 16:13:44 +01002432 N_("attempt to assign sequence of size greater than %d "
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002433 "to extended slice"), 0);
2434 Py_DECREF(item);
2435 ret = -1;
2436 }
2437 Py_DECREF(iterator);
2438 return ret;
2439 }
2440
2441 if (obj != NULL)
2442 /* XXX May allocate zero bytes. */
2443 if (!(lis = PyMem_New(listitem_T *, slicelen * 2)))
2444 {
2445 PyErr_NoMemory();
2446 return -1;
2447 }
2448
2449 if (first == size)
2450 li = NULL;
2451 else
2452 {
2453 li = list_find(l, (long) first);
2454 if (li == NULL)
2455 {
2456 PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
2457 (int)first);
2458 if (obj != NULL)
2459 PyMem_Free(lis);
2460 return -1;
2461 }
2462 i = slicelen;
2463 while (i-- && li != NULL)
2464 {
2465 j = step;
2466 next = li;
2467 if (step > 0)
2468 while (next != NULL && ((next = next->li_next) != NULL) && --j);
2469 else
2470 while (next != NULL && ((next = next->li_prev) != NULL) && ++j);
2471
2472 if (obj == NULL)
2473 listitem_remove(l, li);
2474 else
2475 lis[slicelen - i - 1] = li;
2476
2477 li = next;
2478 }
2479 if (li == NULL && i != -1)
2480 {
2481 PyErr_SET_VIM(N_("internal error: not enough list items"));
2482 if (obj != NULL)
2483 PyMem_Free(lis);
2484 return -1;
2485 }
2486 }
2487
2488 if (obj == NULL)
2489 return 0;
2490
2491 if (!(iterator = PyObject_GetIter(obj)))
2492 {
2493 PyMem_Free(lis);
2494 return -1;
2495 }
2496
2497 i = 0;
2498 while ((item = PyIter_Next(iterator)))
2499 {
2500 if (ConvertFromPyObject(item, &v) == -1)
2501 {
2502 Py_DECREF(iterator);
2503 Py_DECREF(item);
2504 PyMem_Free(lis);
2505 return -1;
2506 }
2507 Py_DECREF(item);
2508 if (list_insert_tv(l, &v, numreplaced < slicelen
2509 ? lis[numreplaced]
2510 : li) == FAIL)
2511 {
2512 clear_tv(&v);
2513 PyErr_SET_VIM(N_("internal error: failed to add item to list"));
2514 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2515 PyMem_Free(lis);
2516 return -1;
2517 }
2518 if (numreplaced < slicelen)
2519 {
2520 lis[slicelen + numreplaced] = lis[numreplaced]->li_prev;
Bram Moolenaar3ec7f4e2014-05-07 17:31:37 +02002521 vimlist_remove(l, lis[numreplaced], lis[numreplaced]);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002522 numreplaced++;
2523 }
2524 else
2525 {
2526 if (li)
2527 lastaddedli = li->li_prev;
2528 else
2529 lastaddedli = l->lv_last;
2530 numadded++;
2531 }
2532 clear_tv(&v);
2533 if (step != 1 && i >= slicelen)
2534 {
2535 Py_DECREF(iterator);
2536 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar4de6a212014-03-08 16:13:44 +01002537 N_("attempt to assign sequence of size greater than %d "
Bram Moolenaar403b3cf2014-02-15 15:59:03 +01002538 "to extended slice"), (int) slicelen);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002539 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2540 PyMem_Free(lis);
2541 return -1;
2542 }
2543 ++i;
2544 }
2545 Py_DECREF(iterator);
2546
2547 if (step != 1 && i != slicelen)
2548 {
2549 PyErr_FORMAT2(PyExc_ValueError,
Bram Moolenaar403b3cf2014-02-15 15:59:03 +01002550 N_("attempt to assign sequence of size %d to extended slice "
2551 "of size %d"), (int) i, (int) slicelen);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002552 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2553 PyMem_Free(lis);
2554 return -1;
2555 }
2556
2557 if (PyErr_Occurred())
2558 {
2559 list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2560 PyMem_Free(lis);
2561 return -1;
2562 }
2563
2564 for (i = 0; i < numreplaced; i++)
2565 listitem_free(lis[i]);
2566 if (step == 1)
2567 for (i = numreplaced; i < slicelen; i++)
2568 listitem_remove(l, lis[i]);
2569
2570 PyMem_Free(lis);
2571
2572 return 0;
2573}
2574
2575 static int
2576ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
2577{
2578 typval_T tv;
2579 list_T *l = self->list;
2580 listitem_T *li;
2581 Py_ssize_t length = ListLength(self);
2582
2583 if (l->lv_lock)
2584 {
2585 RAISE_LOCKED_LIST;
2586 return -1;
2587 }
2588 if (index > length || (index == length && obj == NULL))
2589 {
2590 PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
2591 return -1;
2592 }
2593
2594 if (obj == NULL)
2595 {
2596 li = list_find(l, (long) index);
Bram Moolenaar3ec7f4e2014-05-07 17:31:37 +02002597 vimlist_remove(l, li, li);
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002598 clear_tv(&li->li_tv);
2599 vim_free(li);
2600 return 0;
2601 }
2602
2603 if (ConvertFromPyObject(obj, &tv) == -1)
2604 return -1;
2605
2606 if (index == length)
2607 {
2608 if (list_append_tv(l, &tv) == FAIL)
2609 {
2610 clear_tv(&tv);
2611 PyErr_SET_VIM(N_("failed to add item to list"));
2612 return -1;
2613 }
2614 }
2615 else
2616 {
2617 li = list_find(l, (long) index);
2618 clear_tv(&li->li_tv);
2619 copy_tv(&tv, &li->li_tv);
2620 clear_tv(&tv);
2621 }
2622 return 0;
2623}
2624
2625 static Py_ssize_t
2626ListAssItem(ListObject *self, PyObject *idx, PyObject *obj)
2627{
2628#if PY_MAJOR_VERSION < 3
2629 if (PyInt_Check(idx))
2630 {
2631 long _idx = PyInt_AsLong(idx);
2632 return ListAssIndex(self, _idx, obj);
2633 }
2634 else
2635#endif
2636 if (PyLong_Check(idx))
2637 {
2638 long _idx = PyLong_AsLong(idx);
2639 return ListAssIndex(self, _idx, obj);
2640 }
2641 else if (PySlice_Check(idx))
2642 {
2643 Py_ssize_t start, stop, step, slicelen;
2644
Bram Moolenaar922a4662014-03-30 16:11:43 +02002645 if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002646 &start, &stop, &step, &slicelen) < 0)
2647 return -1;
2648 return ListAssSlice(self, start, step, slicelen,
2649 obj);
2650 }
2651 else
2652 {
2653 RAISE_INVALID_INDEX_TYPE(idx);
2654 return -1;
2655 }
2656}
2657
2658 static PyObject *
2659ListConcatInPlace(ListObject *self, PyObject *obj)
2660{
2661 list_T *l = self->list;
2662 PyObject *lookup_dict;
2663
2664 if (l->lv_lock)
2665 {
2666 RAISE_LOCKED_LIST;
2667 return NULL;
2668 }
2669
2670 if (!(lookup_dict = PyDict_New()))
2671 return NULL;
2672
2673 if (list_py_concat(l, obj, lookup_dict) == -1)
2674 {
2675 Py_DECREF(lookup_dict);
2676 return NULL;
2677 }
2678 Py_DECREF(lookup_dict);
2679
2680 Py_INCREF(self);
2681 return (PyObject *)(self);
2682}
2683
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002684typedef struct
2685{
2686 listwatch_T lw;
2687 list_T *list;
2688} listiterinfo_T;
2689
2690 static void
2691ListIterDestruct(listiterinfo_T *lii)
2692{
2693 list_rem_watch(lii->list, &lii->lw);
2694 PyMem_Free(lii);
2695}
2696
2697 static PyObject *
2698ListIterNext(listiterinfo_T **lii)
2699{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002700 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002701
2702 if (!((*lii)->lw.lw_item))
2703 return NULL;
2704
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002705 if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002706 return NULL;
2707
2708 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
2709
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002710 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002711}
2712
2713 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002714ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002715{
2716 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002717 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002718
2719 if (!(lii = PyMem_New(listiterinfo_T, 1)))
2720 {
2721 PyErr_NoMemory();
2722 return NULL;
2723 }
2724
2725 list_add_watch(l, &lii->lw);
2726 lii->lw.lw_item = l->lv_first;
2727 lii->list = l;
2728
2729 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002730 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
2731 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002732}
2733
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002734static char *ListAttrs[] = {
2735 "locked",
2736 NULL
2737};
2738
2739 static PyObject *
2740ListDir(PyObject *self)
2741{
2742 return ObjectDir(self, ListAttrs);
2743}
2744
Bram Moolenaar66b79852012-09-21 14:00:35 +02002745 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002746ListSetattr(ListObject *self, char *name, PyObject *valObject)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002747{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002748 if (valObject == NULL)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002749 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002750 PyErr_SET_STRING(PyExc_AttributeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002751 N_("cannot delete vim.List attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02002752 return -1;
2753 }
2754
2755 if (strcmp(name, "locked") == 0)
2756 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002757 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002758 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002759 PyErr_SET_STRING(PyExc_TypeError, N_("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02002760 return -1;
2761 }
2762 else
2763 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002764 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarb983f752013-05-15 16:11:50 +02002765 if (istrue == -1)
2766 return -1;
2767 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002768 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002769 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02002770 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002771 }
2772 return 0;
2773 }
2774 else
2775 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002776 PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02002777 return -1;
2778 }
2779}
2780
Bram Moolenaar063a46b2014-01-14 16:36:51 +01002781static PySequenceMethods ListAsSeq = {
2782 (lenfunc) ListLength, /* sq_length, len(x) */
2783 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
2784 0, /* RangeRepeat, sq_repeat, x*n */
2785 (PyIntArgFunc) ListIndex, /* sq_item, x[i] */
2786 0, /* was_sq_slice, x[i:j] */
2787 (PyIntObjArgProc) ListAssIndex, /* sq_as_item, x[i]=v */
2788 0, /* was_sq_ass_slice, x[i:j]=v */
2789 0, /* sq_contains */
2790 (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */
2791 0, /* sq_inplace_repeat */
2792};
2793
2794static PyMappingMethods ListAsMapping = {
2795 /* mp_length */ (lenfunc) ListLength,
2796 /* mp_subscript */ (binaryfunc) ListItem,
2797 /* mp_ass_subscript */ (objobjargproc) ListAssItem,
2798};
2799
Bram Moolenaardb913952012-06-29 12:54:53 +02002800static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002801 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
2802 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
2803 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002804};
2805
2806typedef struct
2807{
2808 PyObject_HEAD
2809 char_u *name;
2810} FunctionObject;
2811
2812static PyTypeObject FunctionType;
2813
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002814#define NEW_FUNCTION(name) FunctionNew(&FunctionType, name)
2815
Bram Moolenaardb913952012-06-29 12:54:53 +02002816 static PyObject *
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002817FunctionNew(PyTypeObject *subtype, char_u *name)
Bram Moolenaardb913952012-06-29 12:54:53 +02002818{
2819 FunctionObject *self;
2820
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002821 self = (FunctionObject *) subtype->tp_alloc(subtype, 0);
2822
Bram Moolenaardb913952012-06-29 12:54:53 +02002823 if (self == NULL)
2824 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002825
2826 if (isdigit(*name))
Bram Moolenaardb913952012-06-29 12:54:53 +02002827 {
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002828 if (!translated_function_exists(name))
2829 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002830 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002831 N_("unnamed function %s does not exist"), name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002832 return NULL;
2833 }
2834 self->name = vim_strsave(name);
2835 func_ref(self->name);
2836 }
2837 else
Bram Moolenaar018acca2013-05-30 13:37:28 +02002838 if ((self->name = get_expanded_name(name,
2839 vim_strchr(name, AUTOLOAD_CHAR) == NULL))
2840 == NULL)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002841 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002842 PyErr_FORMAT(PyExc_ValueError,
2843 N_("function %s does not exist"), name);
Bram Moolenaar018acca2013-05-30 13:37:28 +02002844 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002845 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002846
2847 return (PyObject *)(self);
2848}
2849
2850 static PyObject *
2851FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2852{
2853 PyObject *self;
2854 char_u *name;
2855
2856 if (kwargs)
2857 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002858 PyErr_SET_STRING(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002859 N_("function constructor does not accept keyword arguments"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002860 return NULL;
2861 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002862
Bram Moolenaar389a1792013-06-23 13:00:44 +02002863 if (!PyArg_ParseTuple(args, "et", "ascii", &name))
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002864 return NULL;
2865
2866 self = FunctionNew(subtype, name);
2867
Bram Moolenaar389a1792013-06-23 13:00:44 +02002868 PyMem_Free(name);
2869
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002870 return self;
Bram Moolenaardb913952012-06-29 12:54:53 +02002871}
2872
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002873 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002874FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002875{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002876 func_unref(self->name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002877 vim_free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002878
2879 DESTRUCTOR_FINISH(self);
2880}
2881
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002882static char *FunctionAttrs[] = {
2883 "softspace",
2884 NULL
2885};
2886
2887 static PyObject *
2888FunctionDir(PyObject *self)
2889{
2890 return ObjectDir(self, FunctionAttrs);
2891}
2892
Bram Moolenaardb913952012-06-29 12:54:53 +02002893 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002894FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02002895{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002896 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02002897 typval_T args;
2898 typval_T selfdicttv;
2899 typval_T rettv;
2900 dict_T *selfdict = NULL;
2901 PyObject *selfdictObject;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002902 PyObject *ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02002903 int error;
2904
2905 if (ConvertFromPyObject(argsObject, &args) == -1)
2906 return NULL;
2907
2908 if (kwargs != NULL)
2909 {
2910 selfdictObject = PyDict_GetItemString(kwargs, "self");
2911 if (selfdictObject != NULL)
2912 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02002913 if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002914 {
2915 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02002916 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002917 }
Bram Moolenaardb913952012-06-29 12:54:53 +02002918 selfdict = selfdicttv.vval.v_dict;
2919 }
2920 }
2921
Bram Moolenaar71700b82013-05-15 17:49:05 +02002922 Py_BEGIN_ALLOW_THREADS
2923 Python_Lock_Vim();
2924
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002925 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02002926 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02002927
2928 Python_Release_Vim();
2929 Py_END_ALLOW_THREADS
2930
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002931 if (VimTryEnd())
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002932 ret = NULL;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002933 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02002934 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002935 ret = NULL;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02002936 PyErr_VIM_FORMAT(N_("failed to run function %s"), (char *)name);
Bram Moolenaardb913952012-06-29 12:54:53 +02002937 }
2938 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002939 ret = ConvertToPyObject(&rettv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002940
Bram Moolenaardb913952012-06-29 12:54:53 +02002941 clear_tv(&args);
2942 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002943 if (selfdict != NULL)
2944 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002945
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02002946 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02002947}
2948
Bram Moolenaara5b725c2013-05-30 12:43:54 +02002949 static PyObject *
2950FunctionRepr(FunctionObject *self)
2951{
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002952#ifdef Py_TRACE_REFS
Bram Moolenaar41009372013-07-01 22:03:04 +02002953 /* For unknown reason self->name may be NULL after calling
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002954 * Finalize */
2955 return PyString_FromFormat("<vim.Function '%s'>",
Bram Moolenaar41009372013-07-01 22:03:04 +02002956 (self->name == NULL ? "<NULL>" : (char *)self->name));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002957#else
Bram Moolenaar41009372013-07-01 22:03:04 +02002958 return PyString_FromFormat("<vim.Function '%s'>", (char *)self->name);
Bram Moolenaar841fbd22013-06-23 14:37:07 +02002959#endif
Bram Moolenaara5b725c2013-05-30 12:43:54 +02002960}
2961
Bram Moolenaardb913952012-06-29 12:54:53 +02002962static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002963 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
2964 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002965};
2966
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002967/*
2968 * Options object
2969 */
2970
2971static PyTypeObject OptionsType;
2972
2973typedef int (*checkfun)(void *);
2974
2975typedef struct
2976{
2977 PyObject_HEAD
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01002978 int opt_type;
2979 void *from;
2980 checkfun Check;
2981 PyObject *fromObj;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002982} OptionsObject;
2983
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002984 static int
2985dummy_check(void *arg UNUSED)
2986{
2987 return 0;
2988}
2989
2990 static PyObject *
2991OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
2992{
2993 OptionsObject *self;
2994
Bram Moolenaar774267b2013-05-21 20:51:59 +02002995 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002996 if (self == NULL)
2997 return NULL;
2998
2999 self->opt_type = opt_type;
3000 self->from = from;
3001 self->Check = Check;
3002 self->fromObj = fromObj;
3003 if (fromObj)
3004 Py_INCREF(fromObj);
3005
3006 return (PyObject *)(self);
3007}
3008
3009 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003010OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003011{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003012 PyObject_GC_UnTrack((void *)(self));
3013 Py_XDECREF(self->fromObj);
3014 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003015}
3016
3017 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003018OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003019{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003020 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003021 return 0;
3022}
3023
3024 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003025OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003026{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003027 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003028 return 0;
3029}
3030
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003031 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003032OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003033{
3034 char_u *key;
3035 int flags;
3036 long numval;
3037 char_u *stringval;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003038 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003039
Bram Moolenaard6e39182013-05-21 18:30:34 +02003040 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003041 return NULL;
3042
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003043 if (!(key = StringToChars(keyObject, &todecref)))
3044 return NULL;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003045
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003046 if (*key == NUL)
3047 {
3048 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003049 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003050 return NULL;
3051 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003052
3053 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003054 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003055
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003056 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003057
3058 if (flags == 0)
3059 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003060 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003061 return NULL;
3062 }
3063
3064 if (flags & SOPT_UNSET)
3065 {
3066 Py_INCREF(Py_None);
3067 return Py_None;
3068 }
3069 else if (flags & SOPT_BOOL)
3070 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003071 PyObject *ret;
3072 ret = numval ? Py_True : Py_False;
3073 Py_INCREF(ret);
3074 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003075 }
3076 else if (flags & SOPT_NUM)
3077 return PyInt_FromLong(numval);
3078 else if (flags & SOPT_STRING)
3079 {
3080 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003081 {
Bram Moolenaar41009372013-07-01 22:03:04 +02003082 PyObject *ret = PyBytes_FromString((char *)stringval);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003083 vim_free(stringval);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003084 return ret;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003085 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003086 else
3087 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003088 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003089 N_("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003090 return NULL;
3091 }
3092 }
3093 else
3094 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003095 PyErr_SET_VIM(N_("internal error: unknown option type"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003096 return NULL;
3097 }
3098}
3099
3100 static int
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01003101OptionsContains(OptionsObject *self, PyObject *keyObject)
3102{
3103 char_u *key;
3104 PyObject *todecref;
3105
3106 if (!(key = StringToChars(keyObject, &todecref)))
3107 return -1;
3108
3109 if (*key == NUL)
3110 {
3111 Py_XDECREF(todecref);
3112 return 0;
3113 }
3114
3115 if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL))
3116 {
3117 Py_XDECREF(todecref);
3118 return 1;
3119 }
3120 else
3121 {
3122 Py_XDECREF(todecref);
3123 return 0;
3124 }
3125}
3126
3127typedef struct
3128{
3129 void *lastoption;
3130 int opt_type;
3131} optiterinfo_T;
3132
3133 static PyObject *
3134OptionsIterNext(optiterinfo_T **oii)
3135{
3136 char_u *name;
3137
3138 if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type)))
3139 return PyString_FromString((char *)name);
3140
3141 return NULL;
3142}
3143
3144 static PyObject *
3145OptionsIter(OptionsObject *self)
3146{
3147 optiterinfo_T *oii;
3148
3149 if (!(oii = PyMem_New(optiterinfo_T, 1)))
3150 {
3151 PyErr_NoMemory();
3152 return NULL;
3153 }
3154
3155 oii->opt_type = self->opt_type;
3156 oii->lastoption = NULL;
3157
3158 return IterNew(oii,
3159 (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
3160 NULL, NULL);
3161}
3162
3163 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02003164set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02003165{
3166 char_u *errmsg;
3167
3168 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
3169 {
3170 if (VimTryEnd())
3171 return FAIL;
3172 PyErr_SetVim((char *)errmsg);
3173 return FAIL;
3174 }
3175 return OK;
3176}
3177
3178 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02003179set_option_value_for(
3180 char_u *key,
3181 int numval,
3182 char_u *stringval,
3183 int opt_flags,
3184 int opt_type,
3185 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003186{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02003187 win_T *save_curwin = NULL;
3188 tabpage_T *save_curtab = NULL;
3189 buf_T *save_curbuf = NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003190 int set_ret = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003191
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003192 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003193 switch (opt_type)
3194 {
3195 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02003196 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
Bram Moolenaard6949742013-06-16 14:18:28 +02003197 win_find_tabpage((win_T *)from), FALSE) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003198 {
Bram Moolenaarae38d052014-12-17 14:46:09 +01003199 restore_win(save_curwin, save_curtab, TRUE);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003200 if (VimTryEnd())
3201 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003202 PyErr_SET_VIM(N_("problem while switching windows"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003203 return -1;
3204 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003205 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3206 restore_win(save_curwin, save_curtab, TRUE);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003207 break;
3208 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02003209 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003210 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003211 restore_buffer(save_curbuf);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003212 break;
3213 case SREQ_GLOBAL:
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003214 set_ret = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003215 break;
3216 }
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003217 if (set_ret == FAIL)
3218 return -1;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003219 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003220}
3221
3222 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003223OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003224{
3225 char_u *key;
3226 int flags;
3227 int opt_flags;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003228 int ret = 0;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003229 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003230
Bram Moolenaard6e39182013-05-21 18:30:34 +02003231 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003232 return -1;
3233
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003234 if (!(key = StringToChars(keyObject, &todecref)))
3235 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003236
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003237 if (*key == NUL)
3238 {
3239 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02003240 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003241 return -1;
3242 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003243
3244 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003245 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003246
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003247 if (flags == 0)
3248 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003249 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003250 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003251 return -1;
3252 }
3253
3254 if (valObject == NULL)
3255 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003256 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003257 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003258 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003259 N_("unable to unset global option %s"), key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003260 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003261 return -1;
3262 }
3263 else if (!(flags & SOPT_GLOBAL))
3264 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003265 PyErr_FORMAT(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003266 N_("unable to unset option %s "
3267 "which does not have global value"), key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003268 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003269 return -1;
3270 }
3271 else
3272 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003273 unset_global_local_option(key, self->from);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003274 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003275 return 0;
3276 }
3277 }
3278
Bram Moolenaard6e39182013-05-21 18:30:34 +02003279 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003280
3281 if (flags & SOPT_BOOL)
3282 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02003283 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02003284
Bram Moolenaarb983f752013-05-15 16:11:50 +02003285 if (istrue == -1)
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003286 ret = -1;
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003287 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003288 ret = set_option_value_for(key, istrue, NULL,
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003289 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003290 }
3291 else if (flags & SOPT_NUM)
3292 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003293 long val;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003294
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003295 if (NumberToLong(valObject, &val, NUMBER_INT))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003296 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003297 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003298 return -1;
3299 }
3300
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003301 ret = set_option_value_for(key, (int) val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003302 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003303 }
3304 else
3305 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003306 char_u *val;
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003307 PyObject *todecref2;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003308
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003309 if ((val = StringToChars(valObject, &todecref2)))
3310 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003311 ret = set_option_value_for(key, 0, val, opt_flags,
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003312 self->opt_type, self->from);
Bram Moolenaarc2401d62013-12-07 14:28:43 +01003313 Py_XDECREF(todecref2);
3314 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003315 else
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003316 ret = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003317 }
3318
Bram Moolenaar35eacd72013-05-30 22:06:33 +02003319 Py_XDECREF(todecref);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02003320
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003321 return ret;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003322}
3323
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01003324static PySequenceMethods OptionsAsSeq = {
3325 0, /* sq_length */
3326 0, /* sq_concat */
3327 0, /* sq_repeat */
3328 0, /* sq_item */
3329 0, /* sq_slice */
3330 0, /* sq_ass_item */
3331 0, /* sq_ass_slice */
3332 (objobjproc) OptionsContains, /* sq_contains */
3333 0, /* sq_inplace_concat */
3334 0, /* sq_inplace_repeat */
3335};
3336
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003337static PyMappingMethods OptionsAsMapping = {
3338 (lenfunc) NULL,
3339 (binaryfunc) OptionsItem,
3340 (objobjargproc) OptionsAssItem,
3341};
3342
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003343/* Tabpage object
3344 */
3345
3346typedef struct
3347{
3348 PyObject_HEAD
3349 tabpage_T *tab;
3350} TabPageObject;
3351
3352static PyObject *WinListNew(TabPageObject *tabObject);
3353
3354static PyTypeObject TabPageType;
3355
3356 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003357CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003358{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003359 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003360 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003361 PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003362 return -1;
3363 }
3364
3365 return 0;
3366}
3367
3368 static PyObject *
3369TabPageNew(tabpage_T *tab)
3370{
3371 TabPageObject *self;
3372
3373 if (TAB_PYTHON_REF(tab))
3374 {
3375 self = TAB_PYTHON_REF(tab);
3376 Py_INCREF(self);
3377 }
3378 else
3379 {
3380 self = PyObject_NEW(TabPageObject, &TabPageType);
3381 if (self == NULL)
3382 return NULL;
3383 self->tab = tab;
3384 TAB_PYTHON_REF(tab) = self;
3385 }
3386
3387 return (PyObject *)(self);
3388}
3389
3390 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003391TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003392{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003393 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
3394 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003395
3396 DESTRUCTOR_FINISH(self);
3397}
3398
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003399static char *TabPageAttrs[] = {
3400 "windows", "number", "vars", "window", "valid",
3401 NULL
3402};
3403
3404 static PyObject *
3405TabPageDir(PyObject *self)
3406{
3407 return ObjectDir(self, TabPageAttrs);
3408}
3409
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003410 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003411TabPageAttrValid(TabPageObject *self, char *name)
3412{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003413 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003414
3415 if (strcmp(name, "valid") != 0)
3416 return NULL;
3417
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003418 ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
3419 Py_INCREF(ret);
3420 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003421}
3422
3423 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003424TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003425{
3426 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003427 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003428 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003429 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003430 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003431 return NEW_DICTIONARY(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003432 else if (strcmp(name, "window") == 0)
3433 {
3434 /* For current tab window.c does not bother to set or update tp_curwin
3435 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003436 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003437 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003438 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02003439 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003440 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003441 else if (strcmp(name, "__members__") == 0)
3442 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003443 return NULL;
3444}
3445
3446 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003447TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003448{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003449 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003450 return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003451 else
3452 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003453 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003454
3455 if (t == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003456 return PyString_FromFormat("<tabpage object (unknown) at %p>",
3457 (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003458 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003459 return PyString_FromFormat("<tabpage %d>", t - 1);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003460 }
3461}
3462
3463static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003464 /* name, function, calling, documentation */
3465 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
3466 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003467};
3468
3469/*
3470 * Window list object
3471 */
3472
3473static PyTypeObject TabListType;
3474static PySequenceMethods TabListAsSeq;
3475
3476typedef struct
3477{
3478 PyObject_HEAD
3479} TabListObject;
3480
3481 static PyInt
3482TabListLength(PyObject *self UNUSED)
3483{
3484 tabpage_T *tp = first_tabpage;
3485 PyInt n = 0;
3486
3487 while (tp != NULL)
3488 {
3489 ++n;
3490 tp = tp->tp_next;
3491 }
3492
3493 return n;
3494}
3495
3496 static PyObject *
3497TabListItem(PyObject *self UNUSED, PyInt n)
3498{
3499 tabpage_T *tp;
3500
3501 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3502 if (n == 0)
3503 return TabPageNew(tp);
3504
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003505 PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003506 return NULL;
3507}
3508
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +02003509/*
3510 * Window object
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003511 */
3512
3513typedef struct
3514{
3515 PyObject_HEAD
3516 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003517 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003518} WindowObject;
3519
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003520static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003521
3522 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003523CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003524{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003525 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003526 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003527 PyErr_SET_VIM(N_("attempt to refer to deleted window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003528 return -1;
3529 }
3530
3531 return 0;
3532}
3533
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003534 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003535WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02003536{
3537 /* We need to handle deletion of windows underneath us.
3538 * If we add a "w_python*_ref" field to the win_T structure,
3539 * then we can get at it in win_free() in vim. We then
3540 * need to create only ONE Python object per window - if
3541 * we try to create a second, just INCREF the existing one
3542 * and return it. The (single) Python object referring to
3543 * the window is stored in "w_python*_ref".
3544 * On a win_free() we set the Python object's win_T* field
3545 * to an invalid value. We trap all uses of a window
3546 * object, and reject them if the win_T* field is invalid.
3547 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003548 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003549 * w_python_ref and w_python3_ref fields respectively.
3550 */
3551
3552 WindowObject *self;
3553
3554 if (WIN_PYTHON_REF(win))
3555 {
3556 self = WIN_PYTHON_REF(win);
3557 Py_INCREF(self);
3558 }
3559 else
3560 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02003561 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02003562 if (self == NULL)
3563 return NULL;
3564 self->win = win;
3565 WIN_PYTHON_REF(win) = self;
3566 }
3567
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003568 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3569
Bram Moolenaar971db462013-05-12 18:44:48 +02003570 return (PyObject *)(self);
3571}
3572
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003573 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003574WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003575{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003576 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02003577 if (self->win && self->win != INVALID_WINDOW_VALUE)
3578 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003579 Py_XDECREF(((PyObject *)(self->tabObject)));
3580 PyObject_GC_Del((void *)(self));
3581}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003582
Bram Moolenaar774267b2013-05-21 20:51:59 +02003583 static int
3584WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3585{
3586 Py_VISIT(((PyObject *)(self->tabObject)));
3587 return 0;
3588}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003589
Bram Moolenaar774267b2013-05-21 20:51:59 +02003590 static int
3591WindowClear(WindowObject *self)
3592{
3593 Py_CLEAR(self->tabObject);
3594 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003595}
3596
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003597 static win_T *
3598get_firstwin(TabPageObject *tabObject)
3599{
3600 if (tabObject)
3601 {
3602 if (CheckTabPage(tabObject))
3603 return NULL;
3604 /* For current tab window.c does not bother to set or update tp_firstwin
3605 */
3606 else if (tabObject->tab == curtab)
3607 return firstwin;
3608 else
3609 return tabObject->tab->tp_firstwin;
3610 }
3611 else
3612 return firstwin;
3613}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003614static char *WindowAttrs[] = {
3615 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
3616 "tabpage", "valid",
3617 NULL
3618};
3619
3620 static PyObject *
3621WindowDir(PyObject *self)
3622{
3623 return ObjectDir(self, WindowAttrs);
3624}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003625
Bram Moolenaar971db462013-05-12 18:44:48 +02003626 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003627WindowAttrValid(WindowObject *self, char *name)
3628{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003629 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003630
3631 if (strcmp(name, "valid") != 0)
3632 return NULL;
3633
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003634 ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3635 Py_INCREF(ret);
3636 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003637}
3638
3639 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003640WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003641{
3642 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003643 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003644 else if (strcmp(name, "cursor") == 0)
3645 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003646 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003647
3648 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
3649 }
3650 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003651 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003652#ifdef FEAT_WINDOWS
3653 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003654 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003655#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003656#ifdef FEAT_VERTSPLIT
3657 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003658 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003659 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003660 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003661#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02003662 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003663 return NEW_DICTIONARY(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003664 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003665 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
3666 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02003667 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003668 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003669 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003670 return NULL;
3671 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003672 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003673 }
3674 else if (strcmp(name, "tabpage") == 0)
3675 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003676 Py_INCREF(self->tabObject);
3677 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003678 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003679 else if (strcmp(name, "__members__") == 0)
3680 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003681 else
3682 return NULL;
3683}
3684
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003685 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003686WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003687{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003688 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003689 return -1;
3690
3691 if (strcmp(name, "buffer") == 0)
3692 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003693 PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003694 return -1;
3695 }
3696 else if (strcmp(name, "cursor") == 0)
3697 {
3698 long lnum;
3699 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003700
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003701 if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003702 return -1;
3703
Bram Moolenaard6e39182013-05-21 18:30:34 +02003704 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003705 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003706 PyErr_SET_VIM(N_("cursor position outside buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003707 return -1;
3708 }
3709
3710 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003711 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003712 return -1;
3713
Bram Moolenaard6e39182013-05-21 18:30:34 +02003714 self->win->w_cursor.lnum = lnum;
3715 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003716#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02003717 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003718#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003719 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003720 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003721
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003722 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003723 return 0;
3724 }
3725 else if (strcmp(name, "height") == 0)
3726 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003727 long height;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003728 win_T *savewin;
3729
Bram Moolenaardee2e312013-06-23 16:35:47 +02003730 if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003731 return -1;
3732
3733#ifdef FEAT_GUI
3734 need_mouse_correct = TRUE;
3735#endif
3736 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003737 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003738
3739 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003740 win_setheight((int) height);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003741 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003742 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003743 return -1;
3744
3745 return 0;
3746 }
3747#ifdef FEAT_VERTSPLIT
3748 else if (strcmp(name, "width") == 0)
3749 {
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003750 long width;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003751 win_T *savewin;
3752
Bram Moolenaardee2e312013-06-23 16:35:47 +02003753 if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003754 return -1;
3755
3756#ifdef FEAT_GUI
3757 need_mouse_correct = TRUE;
3758#endif
3759 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003760 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003761
3762 VimTryStart();
Bram Moolenaar141be8a2013-06-23 14:16:57 +02003763 win_setwidth((int) width);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003764 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003765 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003766 return -1;
3767
3768 return 0;
3769 }
3770#endif
3771 else
3772 {
3773 PyErr_SetString(PyExc_AttributeError, name);
3774 return -1;
3775 }
3776}
3777
3778 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003779WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003780{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003781 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003782 return PyString_FromFormat("<window object (deleted) at %p>", (self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003783 else
3784 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003785 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003786
Bram Moolenaar6d216452013-05-12 19:00:41 +02003787 if (w == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003788 return PyString_FromFormat("<window object (unknown) at %p>",
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003789 (self));
3790 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003791 return PyString_FromFormat("<window %d>", w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003792 }
3793}
3794
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003795static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003796 /* name, function, calling, documentation */
3797 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
3798 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003799};
3800
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003801/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003802 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003803 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003804
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003805static PyTypeObject WinListType;
3806static PySequenceMethods WinListAsSeq;
3807
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003808typedef struct
3809{
3810 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003811 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003812} WinListObject;
3813
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003814 static PyObject *
3815WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003816{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003817 WinListObject *self;
3818
3819 self = PyObject_NEW(WinListObject, &WinListType);
3820 self->tabObject = tabObject;
3821 Py_INCREF(tabObject);
3822
3823 return (PyObject *)(self);
3824}
3825
3826 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003827WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003828{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003829 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003830
3831 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02003832 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003833 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02003834 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003835
3836 DESTRUCTOR_FINISH(self);
3837}
3838
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003839 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003840WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003841{
3842 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003843 PyInt n = 0;
3844
Bram Moolenaard6e39182013-05-21 18:30:34 +02003845 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003846 return -1;
3847
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003848 while (w != NULL)
3849 {
3850 ++n;
3851 w = W_NEXT(w);
3852 }
3853
3854 return n;
3855}
3856
3857 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003858WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003859{
3860 win_T *w;
3861
Bram Moolenaard6e39182013-05-21 18:30:34 +02003862 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003863 return NULL;
3864
3865 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003866 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003867 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003868
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003869 PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003870 return NULL;
3871}
3872
3873/* Convert a Python string into a Vim line.
3874 *
3875 * The result is in allocated memory. All internal nulls are replaced by
3876 * newline characters. It is an error for the string to contain newline
3877 * characters.
3878 *
3879 * On errors, the Python exception data is set, and NULL is returned.
3880 */
3881 static char *
3882StringToLine(PyObject *obj)
3883{
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003884 char *str;
3885 char *save;
3886 PyObject *bytes = NULL;
Bram Moolenaardee2e312013-06-23 16:35:47 +02003887 Py_ssize_t len = 0;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003888 PyInt i;
3889 char *p;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003890
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003891 if (PyBytes_Check(obj))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003892 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003893 if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
3894 || str == NULL)
3895 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003896 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003897 else if (PyUnicode_Check(obj))
3898 {
3899 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
3900 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003901
Bram Moolenaardaa27022013-06-24 22:33:30 +02003902 if (PyBytes_AsStringAndSize(bytes, &str, &len) == -1
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003903 || str == NULL)
3904 {
3905 Py_DECREF(bytes);
3906 return NULL;
3907 }
3908 }
Bram Moolenaardaa27022013-06-24 22:33:30 +02003909 else
3910 {
3911#if PY_MAJOR_VERSION < 3
3912 PyErr_FORMAT(PyExc_TypeError,
3913 N_("expected str() or unicode() instance, but got %s"),
3914 Py_TYPE_NAME(obj));
3915#else
3916 PyErr_FORMAT(PyExc_TypeError,
3917 N_("expected bytes() or str() instance, but got %s"),
3918 Py_TYPE_NAME(obj));
3919#endif
3920 return NULL;
3921 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003922
3923 /*
3924 * Error checking: String must not contain newlines, as we
3925 * are replacing a single line, and we must replace it with
3926 * a single line.
3927 * A trailing newline is removed, so that append(f.readlines()) works.
3928 */
3929 p = memchr(str, '\n', len);
3930 if (p != NULL)
3931 {
3932 if (p == str + len - 1)
3933 --len;
3934 else
3935 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02003936 PyErr_SET_VIM(N_("string cannot contain newlines"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02003937 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003938 return NULL;
3939 }
3940 }
3941
3942 /* Create a copy of the string, with internal nulls replaced by
3943 * newline characters, as is the vim convention.
3944 */
3945 save = (char *)alloc((unsigned)(len+1));
3946 if (save == NULL)
3947 {
3948 PyErr_NoMemory();
Bram Moolenaar841fbd22013-06-23 14:37:07 +02003949 Py_XDECREF(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003950 return NULL;
3951 }
3952
3953 for (i = 0; i < len; ++i)
3954 {
3955 if (str[i] == '\0')
3956 save[i] = '\n';
3957 else
3958 save[i] = str[i];
3959 }
3960
3961 save[i] = '\0';
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003962 Py_XDECREF(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003963
3964 return save;
3965}
3966
3967/* Get a line from the specified buffer. The line number is
3968 * in Vim format (1-based). The line is returned as a Python
3969 * string object.
3970 */
3971 static PyObject *
3972GetBufferLine(buf_T *buf, PyInt n)
3973{
3974 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
3975}
3976
3977
3978/* Get a list of lines from the specified buffer. The line numbers
3979 * are in Vim format (1-based). The range is from lo up to, but not
3980 * including, hi. The list is returned as a Python list of string objects.
3981 */
3982 static PyObject *
3983GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
3984{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003985 PyInt i;
3986 PyInt n = hi - lo;
3987 PyObject *list = PyList_New(n);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003988
3989 if (list == NULL)
3990 return NULL;
3991
3992 for (i = 0; i < n; ++i)
3993 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003994 PyObject *string = LineToString(
3995 (char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003996
3997 /* Error check - was the Python string creation OK? */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02003998 if (string == NULL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003999 {
4000 Py_DECREF(list);
4001 return NULL;
4002 }
4003
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004004 PyList_SET_ITEM(list, i, string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004005 }
4006
4007 /* The ownership of the Python list is passed to the caller (ie,
4008 * the caller should Py_DECREF() the object when it is finished
4009 * with it).
4010 */
4011
4012 return list;
4013}
4014
4015/*
4016 * Check if deleting lines made the cursor position invalid.
4017 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
4018 * deleted).
4019 */
4020 static void
4021py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
4022{
4023 if (curwin->w_cursor.lnum >= lo)
4024 {
4025 /* Adjust the cursor position if it's in/after the changed
4026 * lines. */
4027 if (curwin->w_cursor.lnum >= hi)
4028 {
4029 curwin->w_cursor.lnum += extra;
4030 check_cursor_col();
4031 }
4032 else if (extra < 0)
4033 {
4034 curwin->w_cursor.lnum = lo;
4035 check_cursor();
4036 }
4037 else
4038 check_cursor_col();
4039 changed_cline_bef_curs();
4040 }
4041 invalidate_botline();
4042}
4043
Bram Moolenaar19e60942011-06-19 00:27:51 +02004044/*
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004045 * Find a window that contains "buf" and switch to it.
4046 * If there is no such window, use the current window and change "curbuf".
4047 * Caller must initialize save_curbuf to NULL.
4048 * restore_win_for_buf() MUST be called later!
4049 */
4050 static void
4051switch_to_win_for_buf(
4052 buf_T *buf,
4053 win_T **save_curwinp,
4054 tabpage_T **save_curtabp,
4055 buf_T **save_curbufp)
4056{
4057 win_T *wp;
4058 tabpage_T *tp;
4059
Bram Moolenaarae38d052014-12-17 14:46:09 +01004060 if (find_win_for_buf(buf, &wp, &tp) == FAIL)
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004061 switch_buffer(save_curbufp, buf);
Bram Moolenaarae38d052014-12-17 14:46:09 +01004062 else if (switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL)
4063 {
4064 restore_win(*save_curwinp, *save_curtabp, TRUE);
4065 switch_buffer(save_curbufp, buf);
4066 }
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004067}
4068
4069 static void
4070restore_win_for_buf(
4071 win_T *save_curwin,
4072 tabpage_T *save_curtab,
4073 buf_T *save_curbuf)
4074{
4075 if (save_curbuf == NULL)
4076 restore_win(save_curwin, save_curtab, TRUE);
4077 else
4078 restore_buffer(save_curbuf);
4079}
4080
4081/*
Bram Moolenaar19e60942011-06-19 00:27:51 +02004082 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004083 * in Vim format (1-based). The replacement line is given as
4084 * a Python string object. The object is checked for validity
4085 * and correct format. Errors are returned as a value of FAIL.
4086 * The return value is OK on success.
4087 * If OK is returned and len_change is not NULL, *len_change
4088 * is set to the change in the buffer length.
4089 */
4090 static int
4091SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
4092{
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004093 buf_T *save_curbuf = NULL;
4094 win_T *save_curwin = NULL;
4095 tabpage_T *save_curtab = NULL;
4096
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004097 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004098 * There are three cases:
4099 * 1. NULL, or None - this is a deletion.
4100 * 2. A string - this is a replacement.
4101 * 3. Anything else - this is an error.
4102 */
4103 if (line == Py_None || line == NULL)
4104 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004105 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004106 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004107
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004108 VimTryStart();
4109
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004110 if (u_savedel((linenr_T)n, 1L) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004111 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004112 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004113 RAISE_DELETE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004114 else
4115 {
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004116 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004117 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004118 if (save_curbuf == NULL)
4119 /* Only adjust marks if we managed to switch to a window that
4120 * holds the buffer, otherwise line numbers will be invalid. */
4121 deleted_lines_mark((linenr_T)n, 1L);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004122 }
4123
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004124 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004125
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004126 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004127 return FAIL;
4128
4129 if (len_change)
4130 *len_change = -1;
4131
4132 return OK;
4133 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004134 else if (PyBytes_Check(line) || PyUnicode_Check(line))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004135 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004136 char *save = StringToLine(line);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004137
4138 if (save == NULL)
4139 return FAIL;
4140
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004141 VimTryStart();
4142
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004143 /* We do not need to free "save" if ml_replace() consumes it. */
4144 PyErr_Clear();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004145 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004146
4147 if (u_savesub((linenr_T)n) == FAIL)
4148 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004149 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004150 vim_free(save);
4151 }
4152 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
4153 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004154 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004155 vim_free(save);
4156 }
4157 else
4158 changed_bytes((linenr_T)n, 0);
4159
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004160 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004161
4162 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004163 if (buf == curbuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004164 check_cursor_col();
4165
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004166 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004167 return FAIL;
4168
4169 if (len_change)
4170 *len_change = 0;
4171
4172 return OK;
4173 }
4174 else
4175 {
4176 PyErr_BadArgument();
4177 return FAIL;
4178 }
4179}
4180
Bram Moolenaar19e60942011-06-19 00:27:51 +02004181/* Replace a range of lines in the specified buffer. The line numbers are in
4182 * Vim format (1-based). The range is from lo up to, but not including, hi.
4183 * The replacement lines are given as a Python list of string objects. The
4184 * list is checked for validity and correct format. Errors are returned as a
4185 * value of FAIL. The return value is OK on success.
4186 * If OK is returned and len_change is not NULL, *len_change
4187 * is set to the change in the buffer length.
4188 */
4189 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004190SetBufferLineList(
4191 buf_T *buf,
4192 PyInt lo,
4193 PyInt hi,
4194 PyObject *list,
4195 PyInt *len_change)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004196{
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004197 buf_T *save_curbuf = NULL;
4198 win_T *save_curwin = NULL;
4199 tabpage_T *save_curtab = NULL;
4200
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004201 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02004202 * There are three cases:
4203 * 1. NULL, or None - this is a deletion.
4204 * 2. A list - this is a replacement.
4205 * 3. Anything else - this is an error.
4206 */
4207 if (list == Py_None || list == NULL)
4208 {
4209 PyInt i;
4210 PyInt n = (int)(hi - lo);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004211
4212 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004213 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004214 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004215
4216 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004217 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004218 else
4219 {
4220 for (i = 0; i < n; ++i)
4221 {
4222 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
4223 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004224 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004225 break;
4226 }
4227 }
Bram Moolenaard7408fa2014-08-29 13:49:52 +02004228 if (buf == curbuf && (save_curwin != NULL || save_curbuf == NULL))
4229 /* Using an existing window for the buffer, adjust the cursor
4230 * position. */
Bram Moolenaar19e60942011-06-19 00:27:51 +02004231 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004232 if (save_curbuf == NULL)
4233 /* Only adjust marks if we managed to switch to a window that
4234 * holds the buffer, otherwise line numbers will be invalid. */
4235 deleted_lines_mark((linenr_T)lo, (long)i);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004236 }
4237
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004238 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004239
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004240 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02004241 return FAIL;
4242
4243 if (len_change)
4244 *len_change = -n;
4245
4246 return OK;
4247 }
4248 else if (PyList_Check(list))
4249 {
4250 PyInt i;
4251 PyInt new_len = PyList_Size(list);
4252 PyInt old_len = hi - lo;
4253 PyInt extra = 0; /* lines added to text, can be negative */
4254 char **array;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004255
4256 if (new_len == 0) /* avoid allocating zero bytes */
4257 array = NULL;
4258 else
4259 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004260 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004261 if (array == NULL)
4262 {
4263 PyErr_NoMemory();
4264 return FAIL;
4265 }
4266 }
4267
4268 for (i = 0; i < new_len; ++i)
4269 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004270 PyObject *line;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004271
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004272 if (!(line = PyList_GetItem(list, i)) ||
4273 !(array[i] = StringToLine(line)))
Bram Moolenaar19e60942011-06-19 00:27:51 +02004274 {
4275 while (i)
4276 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004277 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004278 return FAIL;
4279 }
4280 }
4281
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004282 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02004283 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02004284
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004285 /* START of region without "return". Must call restore_buffer()! */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004286 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004287
4288 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004289 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004290
4291 /* If the size of the range is reducing (ie, new_len < old_len) we
4292 * need to delete some old_len. We do this at the start, by
4293 * repeatedly deleting line "lo".
4294 */
4295 if (!PyErr_Occurred())
4296 {
4297 for (i = 0; i < old_len - new_len; ++i)
4298 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
4299 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004300 RAISE_DELETE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004301 break;
4302 }
4303 extra -= i;
4304 }
4305
4306 /* For as long as possible, replace the existing old_len with the
4307 * new old_len. This is a more efficient operation, as it requires
4308 * less memory allocation and freeing.
4309 */
4310 if (!PyErr_Occurred())
4311 {
4312 for (i = 0; i < old_len && i < new_len; ++i)
4313 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
4314 == FAIL)
4315 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004316 RAISE_REPLACE_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004317 break;
4318 }
4319 }
4320 else
4321 i = 0;
4322
4323 /* Now we may need to insert the remaining new old_len. If we do, we
4324 * must free the strings as we finish with them (we can't pass the
4325 * responsibility to vim in this case).
4326 */
4327 if (!PyErr_Occurred())
4328 {
4329 while (i < new_len)
4330 {
4331 if (ml_append((linenr_T)(lo + i - 1),
4332 (char_u *)array[i], 0, FALSE) == FAIL)
4333 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004334 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02004335 break;
4336 }
4337 vim_free(array[i]);
4338 ++i;
4339 ++extra;
4340 }
4341 }
4342
4343 /* Free any left-over old_len, as a result of an error */
4344 while (i < new_len)
4345 {
4346 vim_free(array[i]);
4347 ++i;
4348 }
4349
4350 /* Free the array of old_len. All of its contents have now
4351 * been dealt with (either freed, or the responsibility passed
4352 * to vim.
4353 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004354 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004355
4356 /* Adjust marks. Invalidate any which lie in the
4357 * changed range, and move any in the remainder of the buffer.
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004358 * Only adjust marks if we managed to switch to a window that holds
4359 * the buffer, otherwise line numbers will be invalid. */
4360 if (save_curbuf == NULL)
4361 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
Bram Moolenaar19e60942011-06-19 00:27:51 +02004362 (long)MAXLNUM, (long)extra);
4363 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
4364
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004365 if (buf == curbuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004366 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
4367
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004368 /* END of region without "return". */
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004369 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02004370
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004371 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02004372 return FAIL;
4373
4374 if (len_change)
4375 *len_change = new_len - old_len;
4376
4377 return OK;
4378 }
4379 else
4380 {
4381 PyErr_BadArgument();
4382 return FAIL;
4383 }
4384}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004385
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02004386/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004387 * The line number is in Vim format (1-based). The lines to be inserted are
4388 * given as a Python list of string objects or as a single string. The lines
4389 * to be added are checked for validity and correct format. Errors are
4390 * returned as a value of FAIL. The return value is OK on success.
4391 * If OK is returned and len_change is not NULL, *len_change
4392 * is set to the change in the buffer length.
4393 */
4394 static int
4395InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
4396{
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004397 buf_T *save_curbuf = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004398 win_T *save_curwin = NULL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004399 tabpage_T *save_curtab = NULL;
4400
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004401 /* First of all, we check the type of the supplied Python object.
4402 * It must be a string or a list, or the call is in error.
4403 */
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02004404 if (PyBytes_Check(lines) || PyUnicode_Check(lines))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004405 {
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004406 char *str = StringToLine(lines);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004407
4408 if (str == NULL)
4409 return FAIL;
4410
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004411 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004412 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004413 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004414
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004415 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004416 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004417 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004418 RAISE_INSERT_LINE_FAIL;
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004419 else if (save_curbuf == NULL)
4420 /* Only adjust marks if we managed to switch to a window that
4421 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004422 appended_lines_mark((linenr_T)n, 1L);
4423
4424 vim_free(str);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004425 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004426 update_screen(VALID);
4427
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004428 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004429 return FAIL;
4430
4431 if (len_change)
4432 *len_change = 1;
4433
4434 return OK;
4435 }
4436 else if (PyList_Check(lines))
4437 {
4438 PyInt i;
4439 PyInt size = PyList_Size(lines);
4440 char **array;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004441
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004442 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004443 if (array == NULL)
4444 {
4445 PyErr_NoMemory();
4446 return FAIL;
4447 }
4448
4449 for (i = 0; i < size; ++i)
4450 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004451 PyObject *line;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004452
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004453 if (!(line = PyList_GetItem(lines, i)) ||
4454 !(array[i] = StringToLine(line)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004455 {
4456 while (i)
4457 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004458 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004459 return FAIL;
4460 }
4461 }
4462
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004463 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004464 VimTryStart();
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004465 switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004466
4467 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02004468 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004469 else
4470 {
4471 for (i = 0; i < size; ++i)
4472 {
4473 if (ml_append((linenr_T)(n + i),
4474 (char_u *)array[i], 0, FALSE) == FAIL)
4475 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004476 RAISE_INSERT_LINE_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004477
4478 /* Free the rest of the lines */
4479 while (i < size)
4480 vim_free(array[i++]);
4481
4482 break;
4483 }
4484 vim_free(array[i]);
4485 }
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004486 if (i > 0 && save_curbuf == NULL)
4487 /* Only adjust marks if we managed to switch to a window that
4488 * holds the buffer, otherwise line numbers will be invalid. */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004489 appended_lines_mark((linenr_T)n, (long)i);
4490 }
4491
4492 /* Free the array of lines. All of its contents have now
Bram Moolenaar95064ec2013-07-17 17:15:25 +02004493 * been freed. */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004494 PyMem_Free(array);
Bram Moolenaaraf003f62013-07-24 17:11:46 +02004495 restore_win_for_buf(save_curwin, save_curtab, save_curbuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004496
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004497 update_screen(VALID);
4498
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004499 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004500 return FAIL;
4501
4502 if (len_change)
4503 *len_change = size;
4504
4505 return OK;
4506 }
4507 else
4508 {
4509 PyErr_BadArgument();
4510 return FAIL;
4511 }
4512}
4513
4514/*
4515 * Common routines for buffers and line ranges
4516 * -------------------------------------------
4517 */
4518
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004519typedef struct
4520{
4521 PyObject_HEAD
4522 buf_T *buf;
4523} BufferObject;
4524
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004525 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02004526CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004527{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004528 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004529 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004530 PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004531 return -1;
4532 }
4533
4534 return 0;
4535}
4536
4537 static PyObject *
4538RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4539{
4540 if (CheckBuffer(self))
4541 return NULL;
4542
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004543 if (end == -1)
4544 end = self->buf->b_ml.ml_line_count;
4545
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004546 if (n < 0)
4547 n += end - start + 1;
4548
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004549 if (n < 0 || n > end - start)
4550 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004551 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004552 return NULL;
4553 }
4554
4555 return GetBufferLine(self->buf, n+start);
4556}
4557
4558 static PyObject *
4559RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4560{
4561 PyInt size;
4562
4563 if (CheckBuffer(self))
4564 return NULL;
4565
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004566 if (end == -1)
4567 end = self->buf->b_ml.ml_line_count;
4568
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004569 size = end - start + 1;
4570
4571 if (lo < 0)
4572 lo = 0;
4573 else if (lo > size)
4574 lo = size;
4575 if (hi < 0)
4576 hi = 0;
4577 if (hi < lo)
4578 hi = lo;
4579 else if (hi > size)
4580 hi = size;
4581
4582 return GetBufferLineList(self->buf, lo+start, hi+start);
4583}
4584
4585 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004586RBAsItem(
4587 BufferObject *self,
4588 PyInt n,
4589 PyObject *valObject,
4590 PyInt start,
4591 PyInt end,
4592 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004593{
4594 PyInt len_change;
4595
4596 if (CheckBuffer(self))
4597 return -1;
4598
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004599 if (end == -1)
4600 end = self->buf->b_ml.ml_line_count;
4601
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004602 if (n < 0)
4603 n += end - start + 1;
4604
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004605 if (n < 0 || n > end - start)
4606 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004607 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004608 return -1;
4609 }
4610
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004611 if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004612 return -1;
4613
4614 if (new_end)
4615 *new_end = end + len_change;
4616
4617 return 0;
4618}
4619
Bram Moolenaar19e60942011-06-19 00:27:51 +02004620 static PyInt
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004621RBAsSlice(
4622 BufferObject *self,
4623 PyInt lo,
4624 PyInt hi,
4625 PyObject *valObject,
4626 PyInt start,
4627 PyInt end,
4628 PyInt *new_end)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004629{
4630 PyInt size;
4631 PyInt len_change;
4632
4633 /* Self must be a valid buffer */
4634 if (CheckBuffer(self))
4635 return -1;
4636
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004637 if (end == -1)
4638 end = self->buf->b_ml.ml_line_count;
4639
Bram Moolenaar19e60942011-06-19 00:27:51 +02004640 /* Sort out the slice range */
4641 size = end - start + 1;
4642
4643 if (lo < 0)
4644 lo = 0;
4645 else if (lo > size)
4646 lo = size;
4647 if (hi < 0)
4648 hi = 0;
4649 if (hi < lo)
4650 hi = lo;
4651 else if (hi > size)
4652 hi = size;
4653
4654 if (SetBufferLineList(self->buf, lo + start, hi + start,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004655 valObject, &len_change) == FAIL)
Bram Moolenaar19e60942011-06-19 00:27:51 +02004656 return -1;
4657
4658 if (new_end)
4659 *new_end = end + len_change;
4660
4661 return 0;
4662}
4663
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004664
4665 static PyObject *
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004666RBAppend(
4667 BufferObject *self,
4668 PyObject *args,
4669 PyInt start,
4670 PyInt end,
4671 PyInt *new_end)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004672{
4673 PyObject *lines;
4674 PyInt len_change;
4675 PyInt max;
4676 PyInt n;
4677
4678 if (CheckBuffer(self))
4679 return NULL;
4680
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004681 if (end == -1)
4682 end = self->buf->b_ml.ml_line_count;
4683
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004684 max = n = end - start + 1;
4685
4686 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
4687 return NULL;
4688
4689 if (n < 0 || n > max)
4690 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004691 PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004692 return NULL;
4693 }
4694
4695 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
4696 return NULL;
4697
4698 if (new_end)
4699 *new_end = end + len_change;
4700
4701 Py_INCREF(Py_None);
4702 return Py_None;
4703}
4704
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004705/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004706 */
4707
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004708static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004709static PySequenceMethods RangeAsSeq;
4710static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004711
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004712typedef struct
4713{
4714 PyObject_HEAD
4715 BufferObject *buf;
4716 PyInt start;
4717 PyInt end;
4718} RangeObject;
4719
4720 static PyObject *
4721RangeNew(buf_T *buf, PyInt start, PyInt end)
4722{
4723 BufferObject *bufr;
4724 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004725 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004726 if (self == NULL)
4727 return NULL;
4728
4729 bufr = (BufferObject *)BufferNew(buf);
4730 if (bufr == NULL)
4731 {
4732 Py_DECREF(self);
4733 return NULL;
4734 }
4735 Py_INCREF(bufr);
4736
4737 self->buf = bufr;
4738 self->start = start;
4739 self->end = end;
4740
4741 return (PyObject *)(self);
4742}
4743
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004744 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004745RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004746{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004747 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004748 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02004749 PyObject_GC_Del((void *)(self));
4750}
4751
4752 static int
4753RangeTraverse(RangeObject *self, visitproc visit, void *arg)
4754{
4755 Py_VISIT(((PyObject *)(self->buf)));
4756 return 0;
4757}
4758
4759 static int
4760RangeClear(RangeObject *self)
4761{
4762 Py_CLEAR(self->buf);
4763 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004764}
4765
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004766 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004767RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004768{
4769 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004770 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004771 return -1; /* ??? */
4772
Bram Moolenaard6e39182013-05-21 18:30:34 +02004773 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004774}
4775
4776 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004777RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004778{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004779 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004780}
4781
4782 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004783RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004784{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004785 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004786}
4787
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004788static char *RangeAttrs[] = {
4789 "start", "end",
4790 NULL
4791};
4792
4793 static PyObject *
4794RangeDir(PyObject *self)
4795{
4796 return ObjectDir(self, RangeAttrs);
4797}
4798
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004799 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004800RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004801{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004802 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004803}
4804
4805 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004806RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004807{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004808 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004809 return PyString_FromFormat("<range object (for deleted buffer) at %p>",
4810 (self));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004811 else
4812 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02004813 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004814
4815 if (name == NULL)
4816 name = "";
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004817
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004818 return PyString_FromFormat("<range %s (%d:%d)>",
Bram Moolenaarf62d9422013-05-30 19:01:24 +02004819 name, (int)self->start, (int)self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004820 }
4821}
4822
4823static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004824 /* name, function, calling, documentation */
4825 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004826 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
4827 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004828};
4829
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004830static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004831static PySequenceMethods BufferAsSeq;
4832static PyMappingMethods BufferAsMapping;
4833
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004834 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02004835BufferNew(buf_T *buf)
4836{
4837 /* We need to handle deletion of buffers underneath us.
4838 * If we add a "b_python*_ref" field to the buf_T structure,
4839 * then we can get at it in buf_freeall() in vim. We then
4840 * need to create only ONE Python object per buffer - if
4841 * we try to create a second, just INCREF the existing one
4842 * and return it. The (single) Python object referring to
4843 * the buffer is stored in "b_python*_ref".
4844 * Question: what to do on a buf_freeall(). We'll probably
4845 * have to either delete the Python object (DECREF it to
4846 * zero - a bad idea, as it leaves dangling refs!) or
4847 * set the buf_T * value to an invalid value (-1?), which
4848 * means we need checks in all access functions... Bah.
4849 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004850 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02004851 * b_python_ref and b_python3_ref fields respectively.
4852 */
4853
4854 BufferObject *self;
4855
4856 if (BUF_PYTHON_REF(buf) != NULL)
4857 {
4858 self = BUF_PYTHON_REF(buf);
4859 Py_INCREF(self);
4860 }
4861 else
4862 {
4863 self = PyObject_NEW(BufferObject, &BufferType);
4864 if (self == NULL)
4865 return NULL;
4866 self->buf = buf;
4867 BUF_PYTHON_REF(buf) = self;
4868 }
4869
4870 return (PyObject *)(self);
4871}
4872
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004873 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004874BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004875{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004876 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
4877 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004878
4879 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004880}
4881
Bram Moolenaar971db462013-05-12 18:44:48 +02004882 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004883BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02004884{
4885 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004886 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02004887 return -1; /* ??? */
4888
Bram Moolenaard6e39182013-05-21 18:30:34 +02004889 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02004890}
4891
4892 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004893BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02004894{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004895 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004896}
4897
4898 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004899BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02004900{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004901 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004902}
4903
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004904static char *BufferAttrs[] = {
4905 "name", "number", "vars", "options", "valid",
4906 NULL
4907};
4908
4909 static PyObject *
4910BufferDir(PyObject *self)
4911{
4912 return ObjectDir(self, BufferAttrs);
4913}
4914
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004915 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004916BufferAttrValid(BufferObject *self, char *name)
4917{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004918 PyObject *ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004919
4920 if (strcmp(name, "valid") != 0)
4921 return NULL;
4922
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004923 ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
4924 Py_INCREF(ret);
4925 return ret;
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004926}
4927
4928 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004929BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004930{
4931 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02004932 return PyString_FromString((self->buf->b_ffname == NULL
Bram Moolenaar41009372013-07-01 22:03:04 +02004933 ? "" : (char *)self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004934 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004935 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004936 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02004937 return NEW_DICTIONARY(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004938 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004939 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
4940 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004941 else if (strcmp(name, "__members__") == 0)
4942 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004943 else
4944 return NULL;
4945}
4946
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004947 static int
4948BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
4949{
4950 if (CheckBuffer(self))
4951 return -1;
4952
4953 if (strcmp(name, "name") == 0)
4954 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004955 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004956 aco_save_T aco;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004957 int ren_ret;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004958 PyObject *todecref;
4959
4960 if (!(val = StringToChars(valObject, &todecref)))
4961 return -1;
4962
4963 VimTryStart();
4964 /* Using aucmd_*: autocommands will be executed by rename_buffer */
4965 aucmd_prepbuf(&aco, self->buf);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004966 ren_ret = rename_buffer(val);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004967 aucmd_restbuf(&aco);
4968 Py_XDECREF(todecref);
4969 if (VimTryEnd())
4970 return -1;
4971
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02004972 if (ren_ret == FAIL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004973 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02004974 PyErr_SET_VIM(N_("failed to rename buffer"));
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004975 return -1;
4976 }
4977 return 0;
4978 }
4979 else
4980 {
4981 PyErr_SetString(PyExc_AttributeError, name);
4982 return -1;
4983 }
4984}
4985
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004986 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004987BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004988{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004989 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004990}
4991
4992 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02004993BufferMark(BufferObject *self, PyObject *pmarkObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004994{
4995 pos_T *posp;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004996 char_u *pmark;
4997 char_u mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02004998 buf_T *savebuf;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004999 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005000
Bram Moolenaard6e39182013-05-21 18:30:34 +02005001 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005002 return NULL;
5003
Bram Moolenaar389a1792013-06-23 13:00:44 +02005004 if (!(pmark = StringToChars(pmarkObject, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005005 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005006
Bram Moolenaar389a1792013-06-23 13:00:44 +02005007 if (pmark[0] == '\0' || pmark[1] != '\0')
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02005008 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005009 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005010 N_("mark name must be a single character"));
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005011 Py_XDECREF(todecref);
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02005012 return NULL;
5013 }
5014
5015 mark = *pmark;
Bram Moolenaar389a1792013-06-23 13:00:44 +02005016
5017 Py_XDECREF(todecref);
5018
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005019 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02005020 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005021 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02005022 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005023 if (VimTryEnd())
5024 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005025
5026 if (posp == NULL)
5027 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005028 PyErr_SET_VIM(N_("invalid mark name"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005029 return NULL;
5030 }
5031
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005032 if (posp->lnum <= 0)
5033 {
5034 /* Or raise an error? */
5035 Py_INCREF(Py_None);
5036 return Py_None;
5037 }
5038
5039 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
5040}
5041
5042 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005043BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005044{
5045 PyInt start;
5046 PyInt end;
5047
Bram Moolenaard6e39182013-05-21 18:30:34 +02005048 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005049 return NULL;
5050
5051 if (!PyArg_ParseTuple(args, "nn", &start, &end))
5052 return NULL;
5053
Bram Moolenaard6e39182013-05-21 18:30:34 +02005054 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005055}
5056
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005057 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02005058BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005059{
Bram Moolenaard6e39182013-05-21 18:30:34 +02005060 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005061 return PyString_FromFormat("<buffer object (deleted) at %p>", self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005062 else
5063 {
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005064 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005065
5066 if (name == NULL)
5067 name = "";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005068
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02005069 return PyString_FromFormat("<buffer %s>", name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005070 }
5071}
5072
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005073static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02005074 /* name, function, calling, documentation */
5075 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02005076 {"mark", (PyCFunction)BufferMark, METH_O, "Return (row,col) representing position of named mark" },
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02005077 {"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 +02005078 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
5079 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005080};
5081
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005082/*
5083 * Buffer list object - Implementation
5084 */
5085
5086static PyTypeObject BufMapType;
5087
5088typedef struct
5089{
5090 PyObject_HEAD
5091} BufMapObject;
5092
5093 static PyInt
5094BufMapLength(PyObject *self UNUSED)
5095{
5096 buf_T *b = firstbuf;
5097 PyInt n = 0;
5098
5099 while (b)
5100 {
5101 ++n;
5102 b = b->b_next;
5103 }
5104
5105 return n;
5106}
5107
5108 static PyObject *
5109BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
5110{
5111 buf_T *b;
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005112 long bnr;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005113
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005114 if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005115 return NULL;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005116
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005117 b = buflist_findnr((int) bnr);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005118
5119 if (b)
5120 return BufferNew(b);
5121 else
5122 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02005123 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005124 return NULL;
5125 }
5126}
5127
5128 static void
5129BufMapIterDestruct(PyObject *buffer)
5130{
5131 /* Iteration was stopped before all buffers were processed */
5132 if (buffer)
5133 {
5134 Py_DECREF(buffer);
5135 }
5136}
5137
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005138 static int
5139BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
5140{
Bram Moolenaar774267b2013-05-21 20:51:59 +02005141 if (buffer)
5142 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005143 return 0;
5144}
5145
5146 static int
5147BufMapIterClear(PyObject **buffer)
5148{
Bram Moolenaar774267b2013-05-21 20:51:59 +02005149 if (*buffer)
5150 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005151 return 0;
5152}
5153
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005154 static PyObject *
5155BufMapIterNext(PyObject **buffer)
5156{
5157 PyObject *next;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005158 PyObject *ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005159
5160 if (!*buffer)
5161 return NULL;
5162
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005163 ret = *buffer;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005164
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005165 if (CheckBuffer((BufferObject *)(ret)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005166 {
5167 *buffer = NULL;
5168 return NULL;
5169 }
5170
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005171 if (!((BufferObject *)(ret))->buf->b_next)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005172 next = NULL;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005173 else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005174 return NULL;
5175 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02005176 /* Do not increment reference: we no longer hold it (decref), but whoever
5177 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005178 return ret;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005179}
5180
5181 static PyObject *
5182BufMapIter(PyObject *self UNUSED)
5183{
5184 PyObject *buffer;
5185
5186 buffer = BufferNew(firstbuf);
5187 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02005188 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
5189 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005190}
5191
5192static PyMappingMethods BufMapAsMapping = {
5193 (lenfunc) BufMapLength,
5194 (binaryfunc) BufMapItem,
5195 (objobjargproc) 0,
5196};
5197
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005198/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02005199 */
5200
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005201static char *CurrentAttrs[] = {
5202 "buffer", "window", "line", "range", "tabpage",
5203 NULL
5204};
5205
5206 static PyObject *
5207CurrentDir(PyObject *self)
5208{
5209 return ObjectDir(self, CurrentAttrs);
5210}
5211
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005212 static PyObject *
5213CurrentGetattr(PyObject *self UNUSED, char *name)
5214{
5215 if (strcmp(name, "buffer") == 0)
5216 return (PyObject *)BufferNew(curbuf);
5217 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02005218 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005219 else if (strcmp(name, "tabpage") == 0)
5220 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005221 else if (strcmp(name, "line") == 0)
5222 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
5223 else if (strcmp(name, "range") == 0)
5224 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005225 else if (strcmp(name, "__members__") == 0)
5226 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005227 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005228#if PY_MAJOR_VERSION < 3
5229 return Py_FindMethod(WindowMethods, self, name);
5230#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005231 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005232#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005233}
5234
5235 static int
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005236CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005237{
5238 if (strcmp(name, "line") == 0)
5239 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005240 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
5241 NULL) == FAIL)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005242 return -1;
5243
5244 return 0;
5245 }
Bram Moolenaare7614592013-05-15 15:51:08 +02005246 else if (strcmp(name, "buffer") == 0)
5247 {
5248 int count;
5249
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005250 if (valObject->ob_type != &BufferType)
Bram Moolenaare7614592013-05-15 15:51:08 +02005251 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005252 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005253 N_("expected vim.Buffer object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005254 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02005255 return -1;
5256 }
5257
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005258 if (CheckBuffer((BufferObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005259 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005260 count = ((BufferObject *)(valObject))->buf->b_fnum;
Bram Moolenaare7614592013-05-15 15:51:08 +02005261
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005262 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02005263 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
5264 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005265 if (VimTryEnd())
5266 return -1;
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005267 PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
Bram Moolenaare7614592013-05-15 15:51:08 +02005268 return -1;
5269 }
5270
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005271 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005272 }
5273 else if (strcmp(name, "window") == 0)
5274 {
5275 int count;
5276
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005277 if (valObject->ob_type != &WindowType)
Bram Moolenaare7614592013-05-15 15:51:08 +02005278 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005279 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005280 N_("expected vim.Window object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005281 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02005282 return -1;
5283 }
5284
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005285 if (CheckWindow((WindowObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005286 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005287 count = get_win_number(((WindowObject *)(valObject))->win, firstwin);
Bram Moolenaare7614592013-05-15 15:51:08 +02005288
5289 if (!count)
5290 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005291 PyErr_SET_STRING(PyExc_ValueError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005292 N_("failed to find window in the current tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005293 return -1;
5294 }
5295
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005296 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005297 win_goto(((WindowObject *)(valObject))->win);
5298 if (((WindowObject *)(valObject))->win != curwin)
Bram Moolenaare7614592013-05-15 15:51:08 +02005299 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005300 if (VimTryEnd())
5301 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005302 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005303 N_("did not switch to the specified window"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005304 return -1;
5305 }
5306
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005307 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005308 }
5309 else if (strcmp(name, "tabpage") == 0)
5310 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005311 if (valObject->ob_type != &TabPageType)
Bram Moolenaare7614592013-05-15 15:51:08 +02005312 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005313 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005314 N_("expected vim.TabPage object, but got %s"),
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005315 Py_TYPE_NAME(valObject));
Bram Moolenaare7614592013-05-15 15:51:08 +02005316 return -1;
5317 }
5318
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005319 if (CheckTabPage((TabPageObject *)(valObject)))
Bram Moolenaare7614592013-05-15 15:51:08 +02005320 return -1;
5321
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005322 VimTryStart();
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005323 goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
5324 if (((TabPageObject *)(valObject))->tab != curtab)
Bram Moolenaare7614592013-05-15 15:51:08 +02005325 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005326 if (VimTryEnd())
5327 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005328 PyErr_SET_STRING(PyExc_RuntimeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005329 N_("did not switch to the specified tab page"));
Bram Moolenaare7614592013-05-15 15:51:08 +02005330 return -1;
5331 }
5332
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02005333 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02005334 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005335 else
5336 {
5337 PyErr_SetString(PyExc_AttributeError, name);
5338 return -1;
5339 }
5340}
5341
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005342static struct PyMethodDef CurrentMethods[] = {
5343 /* name, function, calling, documentation */
5344 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
5345 { NULL, NULL, 0, NULL}
5346};
5347
Bram Moolenaardb913952012-06-29 12:54:53 +02005348 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005349init_range_cmd(exarg_T *eap)
5350{
5351 RangeStart = eap->line1;
5352 RangeEnd = eap->line2;
5353}
5354
5355 static void
5356init_range_eval(typval_T *rettv UNUSED)
5357{
5358 RangeStart = (PyInt) curwin->w_cursor.lnum;
5359 RangeEnd = RangeStart;
5360}
5361
5362 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005363run_cmd(const char *cmd, void *arg UNUSED
5364#ifdef PY_CAN_RECURSE
5365 , PyGILState_STATE *pygilstate UNUSED
5366#endif
5367 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005368{
Bram Moolenaar41009372013-07-01 22:03:04 +02005369 PyObject *run_ret;
5370 run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
5371 if (run_ret != NULL)
5372 {
5373 Py_DECREF(run_ret);
5374 }
5375 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5376 {
5377 EMSG2(_(e_py_systemexit), "python");
5378 PyErr_Clear();
5379 }
5380 else
5381 PyErr_PrintEx(1);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005382}
5383
5384static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
5385static int code_hdr_len = 30;
5386
5387 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005388run_do(const char *cmd, void *arg UNUSED
5389#ifdef PY_CAN_RECURSE
5390 , PyGILState_STATE *pygilstate
5391#endif
5392 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005393{
5394 PyInt lnum;
5395 size_t len;
5396 char *code;
5397 int status;
5398 PyObject *pyfunc, *pymain;
Bram Moolenaar41009372013-07-01 22:03:04 +02005399 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005400
Bram Moolenaar4ac66762013-05-28 22:31:46 +02005401 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005402 {
5403 EMSG(_("cannot save undo information"));
5404 return;
5405 }
5406
5407 len = code_hdr_len + STRLEN(cmd);
5408 code = PyMem_New(char, len + 1);
5409 memcpy(code, code_hdr, code_hdr_len);
5410 STRCPY(code + code_hdr_len, cmd);
Bram Moolenaar41009372013-07-01 22:03:04 +02005411 run_ret = PyRun_String(code, Py_file_input, globals, globals);
5412 status = -1;
5413 if (run_ret != NULL)
5414 {
5415 status = 0;
5416 Py_DECREF(run_ret);
5417 }
5418 else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5419 {
5420 PyMem_Free(code);
5421 EMSG2(_(e_py_systemexit), "python");
5422 PyErr_Clear();
5423 return;
5424 }
5425 else
5426 PyErr_PrintEx(1);
5427
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005428 PyMem_Free(code);
5429
5430 if (status)
5431 {
5432 EMSG(_("failed to run the code"));
5433 return;
5434 }
5435
5436 status = 0;
5437 pymain = PyImport_AddModule("__main__");
5438 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005439#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005440 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005441#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005442
5443 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
5444 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005445 PyObject *line;
5446 PyObject *linenr;
5447 PyObject *ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005448
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005449#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005450 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005451#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005452 if (!(line = GetBufferLine(curbuf, lnum)))
5453 goto err;
5454 if (!(linenr = PyInt_FromLong((long) lnum)))
5455 {
5456 Py_DECREF(line);
5457 goto err;
5458 }
5459 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
5460 Py_DECREF(line);
5461 Py_DECREF(linenr);
5462 if (!ret)
5463 goto err;
5464
5465 if (ret != Py_None)
5466 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
5467 goto err;
5468
5469 Py_XDECREF(ret);
5470 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005471#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005472 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005473#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005474 }
5475 goto out;
5476err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005477#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005478 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005479#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005480 PyErr_PrintEx(0);
5481 PythonIO_Flush();
5482 status = 1;
5483out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005484#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005485 if (!status)
5486 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005487#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005488 Py_DECREF(pyfunc);
5489 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
5490 if (status)
5491 return;
5492 check_cursor();
5493 update_curbuf(NOT_VALID);
5494}
5495
5496 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02005497run_eval(const char *cmd, typval_T *rettv
5498#ifdef PY_CAN_RECURSE
5499 , PyGILState_STATE *pygilstate UNUSED
5500#endif
5501 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005502{
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005503 PyObject *run_ret;
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005504
Bram Moolenaar41009372013-07-01 22:03:04 +02005505 run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005506 if (run_ret == NULL)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005507 {
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005508 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
Bram Moolenaar41009372013-07-01 22:03:04 +02005509 {
5510 EMSG2(_(e_py_systemexit), "python");
5511 PyErr_Clear();
5512 }
Bram Moolenaar91aeaf42013-07-06 13:02:30 +02005513 else
5514 {
5515 if (PyErr_Occurred() && !msg_silent)
5516 PyErr_PrintEx(0);
5517 EMSG(_("E858: Eval did not return a valid python object"));
5518 }
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005519 }
5520 else
5521 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005522 if (ConvertFromPyObject(run_ret, rettv) == -1)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005523 EMSG(_("E859: Failed to convert returned python object to vim value"));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005524 Py_DECREF(run_ret);
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02005525 }
5526 PyErr_Clear();
5527}
5528
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005529 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02005530set_ref_in_py(const int copyID)
5531{
5532 pylinkedlist_T *cur;
5533 dict_T *dd;
5534 list_T *ll;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005535 int abort = FALSE;
Bram Moolenaardb913952012-06-29 12:54:53 +02005536
5537 if (lastdict != NULL)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005538 {
5539 for(cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
Bram Moolenaardb913952012-06-29 12:54:53 +02005540 {
5541 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
5542 if (dd->dv_copyID != copyID)
5543 {
5544 dd->dv_copyID = copyID;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005545 abort = abort || set_ref_in_ht(&dd->dv_hashtab, copyID, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005546 }
5547 }
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005548 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005549
5550 if (lastlist != NULL)
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005551 {
5552 for(cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
Bram Moolenaardb913952012-06-29 12:54:53 +02005553 {
5554 ll = ((ListObject *) (cur->pll_obj))->list;
5555 if (ll->lv_copyID != copyID)
5556 {
5557 ll->lv_copyID = copyID;
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005558 abort = abort || set_ref_in_list(ll, copyID, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005559 }
5560 }
Bram Moolenaar2459a5e2015-02-03 12:55:18 +01005561 }
5562
5563 return abort;
Bram Moolenaardb913952012-06-29 12:54:53 +02005564}
5565
5566 static int
5567set_string_copy(char_u *str, typval_T *tv)
5568{
5569 tv->vval.v_string = vim_strsave(str);
5570 if (tv->vval.v_string == NULL)
5571 {
5572 PyErr_NoMemory();
5573 return -1;
5574 }
5575 return 0;
5576}
5577
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005578 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005579pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005580{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005581 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005582 char_u *key;
5583 dictitem_T *di;
5584 PyObject *keyObject;
5585 PyObject *valObject;
5586 Py_ssize_t iter = 0;
5587
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005588 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005589 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005590
5591 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005592 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005593
5594 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5595 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005596 PyObject *todecref = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005597
Bram Moolenaara03e6312013-05-29 22:49:26 +02005598 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005599 {
5600 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005601 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005602 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005603
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005604 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005605 {
5606 dict_unref(dict);
5607 return -1;
5608 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005609
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005610 if (*key == NUL)
5611 {
5612 dict_unref(dict);
5613 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005614 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005615 return -1;
5616 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005617
5618 di = dictitem_alloc(key);
5619
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005620 Py_XDECREF(todecref);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005621
5622 if (di == NULL)
5623 {
5624 PyErr_NoMemory();
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005625 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005626 return -1;
5627 }
5628 di->di_tv.v_lock = 0;
5629
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005630 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005631 {
5632 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005633 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005634 return -1;
5635 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005636
5637 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005638 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005639 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara03e6312013-05-29 22:49:26 +02005640 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005641 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005642 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005643 return -1;
5644 }
5645 }
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005646
5647 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005648 return 0;
5649}
5650
5651 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005652pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005653{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005654 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005655 char_u *key;
5656 dictitem_T *di;
5657 PyObject *list;
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005658 PyObject *iterator;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005659 PyObject *keyObject;
5660 PyObject *valObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005661
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005662 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005663 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005664
5665 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005666 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005667
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005668 if (!(list = PyMapping_Keys(obj)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005669 {
5670 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005671 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005672 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005673
5674 if (!(iterator = PyObject_GetIter(list)))
5675 {
5676 dict_unref(dict);
5677 Py_DECREF(list);
5678 return -1;
5679 }
5680 Py_DECREF(list);
5681
5682 while ((keyObject = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005683 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005684 PyObject *todecref;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005685
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005686 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005687 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005688 Py_DECREF(keyObject);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005689 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005690 dict_unref(dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005691 return -1;
5692 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005693
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005694 if (*key == NUL)
5695 {
5696 Py_DECREF(keyObject);
5697 Py_DECREF(iterator);
5698 Py_XDECREF(todecref);
5699 dict_unref(dict);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005700 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005701 return -1;
5702 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005703
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005704 if (!(valObject = PyObject_GetItem(obj, keyObject)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005705 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005706 Py_DECREF(keyObject);
5707 Py_DECREF(iterator);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005708 Py_XDECREF(todecref);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005709 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005710 return -1;
5711 }
5712
5713 di = dictitem_alloc(key);
5714
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005715 Py_DECREF(keyObject);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005716 Py_XDECREF(todecref);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005717
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005718 if (di == NULL)
5719 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005720 Py_DECREF(iterator);
5721 Py_DECREF(valObject);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005722 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005723 PyErr_NoMemory();
5724 return -1;
5725 }
5726 di->di_tv.v_lock = 0;
5727
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005728 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005729 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005730 Py_DECREF(iterator);
5731 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005732 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005733 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005734 return -1;
5735 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02005736
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005737 Py_DECREF(valObject);
5738
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005739 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005740 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005741 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005742 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005743 dictitem_free(di);
5744 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005745 return -1;
5746 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005747 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005748 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005749 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005750 return 0;
5751}
5752
5753 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005754pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005755{
5756 list_T *l;
5757
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005758 if (!(l = py_list_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005759 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005760
5761 tv->v_type = VAR_LIST;
5762 tv->vval.v_list = l;
5763
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005764 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005765 {
5766 list_unref(l);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005767 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005768 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005769
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005770 --l->lv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005771 return 0;
5772}
5773
Bram Moolenaardb913952012-06-29 12:54:53 +02005774typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
5775
5776 static int
5777convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005778 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005779{
5780 PyObject *capsule;
5781 char hexBuf[sizeof(void *) * 2 + 3];
5782
5783 sprintf(hexBuf, "%p", obj);
5784
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005785# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005786 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005787# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005788 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005789# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02005790 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005791 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005792# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02005793 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02005794# else
5795 capsule = PyCObject_FromVoidPtr(tv, NULL);
5796# endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02005797 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
5798 {
5799 Py_DECREF(capsule);
5800 tv->v_type = VAR_UNKNOWN;
5801 return -1;
5802 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005803
5804 Py_DECREF(capsule);
5805
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005806 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005807 {
5808 tv->v_type = VAR_UNKNOWN;
5809 return -1;
5810 }
5811 /* As we are not using copy_tv which increments reference count we must
5812 * do it ourself. */
5813 switch(tv->v_type)
5814 {
5815 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
5816 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
5817 }
5818 }
5819 else
5820 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005821 typval_T *v;
5822
5823# ifdef PY_USE_CAPSULE
5824 v = PyCapsule_GetPointer(capsule, NULL);
5825# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02005826 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005827# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02005828 copy_tv(v, tv);
5829 }
5830 return 0;
5831}
5832
5833 static int
Bram Moolenaara9922d62013-05-30 13:01:18 +02005834ConvertFromPyMapping(PyObject *obj, typval_T *tv)
5835{
5836 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005837 int ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005838
5839 if (!(lookup_dict = PyDict_New()))
5840 return -1;
5841
5842 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
5843 {
5844 tv->v_type = VAR_DICT;
5845 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5846 ++tv->vval.v_dict->dv_refcount;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005847 ret = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005848 }
5849 else if (PyDict_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005850 ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02005851 else if (PyMapping_Check(obj))
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005852 ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaara9922d62013-05-30 13:01:18 +02005853 else
5854 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005855 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005856 N_("unable to convert %s to vim dictionary"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02005857 Py_TYPE_NAME(obj));
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005858 ret = -1;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005859 }
5860 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005861 return ret;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005862}
5863
5864 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02005865ConvertFromPyObject(PyObject *obj, typval_T *tv)
5866{
5867 PyObject *lookup_dict;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005868 int ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02005869
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005870 if (!(lookup_dict = PyDict_New()))
5871 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005872 ret = _ConvertFromPyObject(obj, tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005873 Py_DECREF(lookup_dict);
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005874 return ret;
Bram Moolenaardb913952012-06-29 12:54:53 +02005875}
5876
5877 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005878_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005879{
Bram Moolenaara9922d62013-05-30 13:01:18 +02005880 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005881 {
5882 tv->v_type = VAR_DICT;
5883 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5884 ++tv->vval.v_dict->dv_refcount;
5885 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005886 else if (PyType_IsSubtype(obj->ob_type, &ListType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005887 {
5888 tv->v_type = VAR_LIST;
5889 tv->vval.v_list = (((ListObject *)(obj))->list);
5890 ++tv->vval.v_list->lv_refcount;
5891 }
Bram Moolenaar841fbd22013-06-23 14:37:07 +02005892 else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005893 {
5894 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
5895 return -1;
5896
5897 tv->v_type = VAR_FUNC;
5898 func_ref(tv->vval.v_string);
5899 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005900 else if (PyBytes_Check(obj))
5901 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005902 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02005903
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005904 if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005905 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005906 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005907 return -1;
5908
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005909 if (set_string_copy(str, tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005910 return -1;
5911
5912 tv->v_type = VAR_STRING;
5913 }
5914 else if (PyUnicode_Check(obj))
5915 {
5916 PyObject *bytes;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005917 char_u *str;
Bram Moolenaardb913952012-06-29 12:54:53 +02005918
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02005919 bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005920 if (bytes == NULL)
5921 return -1;
5922
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005923 if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005924 return -1;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005925 if (str == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005926 return -1;
5927
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02005928 if (set_string_copy(str, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02005929 {
5930 Py_XDECREF(bytes);
5931 return -1;
5932 }
5933 Py_XDECREF(bytes);
5934
5935 tv->v_type = VAR_STRING;
5936 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02005937#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02005938 else if (PyInt_Check(obj))
5939 {
5940 tv->v_type = VAR_NUMBER;
5941 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005942 if (PyErr_Occurred())
5943 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005944 }
5945#endif
5946 else if (PyLong_Check(obj))
5947 {
5948 tv->v_type = VAR_NUMBER;
5949 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005950 if (PyErr_Occurred())
5951 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005952 }
5953 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005954 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005955#ifdef FEAT_FLOAT
5956 else if (PyFloat_Check(obj))
5957 {
5958 tv->v_type = VAR_FLOAT;
5959 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
5960 }
5961#endif
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005962 else if (PyObject_HasAttrString(obj, "keys"))
5963 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardee2e312013-06-23 16:35:47 +02005964 /* PyObject_GetIter can create built-in iterator for any sequence object */
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005965 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005966 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005967 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005968 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaar141be8a2013-06-23 14:16:57 +02005969 else if (PyNumber_Check(obj))
5970 {
5971 PyObject *num;
5972
5973 if (!(num = PyNumber_Long(obj)))
5974 return -1;
5975
5976 tv->v_type = VAR_NUMBER;
5977 tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
5978
5979 Py_DECREF(num);
5980 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005981 else
5982 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005983 PyErr_FORMAT(PyExc_TypeError,
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005984 N_("unable to convert %s to vim structure"),
Bram Moolenaarc476e522013-06-23 13:46:40 +02005985 Py_TYPE_NAME(obj));
Bram Moolenaardb913952012-06-29 12:54:53 +02005986 return -1;
5987 }
5988 return 0;
5989}
5990
5991 static PyObject *
5992ConvertToPyObject(typval_T *tv)
5993{
5994 if (tv == NULL)
5995 {
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02005996 PyErr_SET_VIM(N_("internal error: NULL reference passed"));
Bram Moolenaardb913952012-06-29 12:54:53 +02005997 return NULL;
5998 }
5999 switch (tv->v_type)
6000 {
6001 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02006002 return PyBytes_FromString(tv->vval.v_string == NULL
6003 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02006004 case VAR_NUMBER:
6005 return PyLong_FromLong((long) tv->vval.v_number);
6006#ifdef FEAT_FLOAT
6007 case VAR_FLOAT:
6008 return PyFloat_FromDouble((double) tv->vval.v_float);
6009#endif
6010 case VAR_LIST:
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006011 return NEW_LIST(tv->vval.v_list);
Bram Moolenaardb913952012-06-29 12:54:53 +02006012 case VAR_DICT:
Bram Moolenaara9922d62013-05-30 13:01:18 +02006013 return NEW_DICTIONARY(tv->vval.v_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02006014 case VAR_FUNC:
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02006015 return NEW_FUNCTION(tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02006016 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02006017 case VAR_UNKNOWN:
6018 Py_INCREF(Py_None);
6019 return Py_None;
6020 default:
Bram Moolenaar6f1404f2013-06-23 16:04:08 +02006021 PyErr_SET_VIM(N_("internal error: invalid value type"));
Bram Moolenaardb913952012-06-29 12:54:53 +02006022 return NULL;
6023 }
6024}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006025
6026typedef struct
6027{
6028 PyObject_HEAD
6029} CurrentObject;
6030static PyTypeObject CurrentType;
6031
6032 static void
6033init_structs(void)
6034{
6035 vim_memset(&OutputType, 0, sizeof(OutputType));
6036 OutputType.tp_name = "vim.message";
6037 OutputType.tp_basicsize = sizeof(OutputObject);
6038 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
6039 OutputType.tp_doc = "vim message object";
6040 OutputType.tp_methods = OutputMethods;
6041#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006042 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
6043 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006044 OutputType.tp_alloc = call_PyType_GenericAlloc;
6045 OutputType.tp_new = call_PyType_GenericNew;
6046 OutputType.tp_free = call_PyObject_Free;
6047#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006048 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
6049 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006050#endif
6051
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006052 vim_memset(&IterType, 0, sizeof(IterType));
6053 IterType.tp_name = "vim.iter";
6054 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02006055 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006056 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02006057 IterType.tp_iter = (getiterfunc)IterIter;
6058 IterType.tp_iternext = (iternextfunc)IterNext;
6059 IterType.tp_dealloc = (destructor)IterDestructor;
6060 IterType.tp_traverse = (traverseproc)IterTraverse;
6061 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006062
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006063 vim_memset(&BufferType, 0, sizeof(BufferType));
6064 BufferType.tp_name = "vim.buffer";
6065 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006066 BufferType.tp_dealloc = (destructor)BufferDestructor;
6067 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006068 BufferType.tp_as_sequence = &BufferAsSeq;
6069 BufferType.tp_as_mapping = &BufferAsMapping;
6070 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
6071 BufferType.tp_doc = "vim buffer object";
6072 BufferType.tp_methods = BufferMethods;
6073#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006074 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02006075 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006076 BufferType.tp_alloc = call_PyType_GenericAlloc;
6077 BufferType.tp_new = call_PyType_GenericNew;
6078 BufferType.tp_free = call_PyObject_Free;
6079#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006080 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02006081 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006082#endif
6083
6084 vim_memset(&WindowType, 0, sizeof(WindowType));
6085 WindowType.tp_name = "vim.window";
6086 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006087 WindowType.tp_dealloc = (destructor)WindowDestructor;
6088 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02006089 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006090 WindowType.tp_doc = "vim Window object";
6091 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02006092 WindowType.tp_traverse = (traverseproc)WindowTraverse;
6093 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006094#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006095 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
6096 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006097 WindowType.tp_alloc = call_PyType_GenericAlloc;
6098 WindowType.tp_new = call_PyType_GenericNew;
6099 WindowType.tp_free = call_PyObject_Free;
6100#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006101 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
6102 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006103#endif
6104
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006105 vim_memset(&TabPageType, 0, sizeof(TabPageType));
6106 TabPageType.tp_name = "vim.tabpage";
6107 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006108 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
6109 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006110 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
6111 TabPageType.tp_doc = "vim tab page object";
6112 TabPageType.tp_methods = TabPageMethods;
6113#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006114 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006115 TabPageType.tp_alloc = call_PyType_GenericAlloc;
6116 TabPageType.tp_new = call_PyType_GenericNew;
6117 TabPageType.tp_free = call_PyObject_Free;
6118#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006119 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006120#endif
6121
Bram Moolenaardfa38d42013-05-15 13:38:47 +02006122 vim_memset(&BufMapType, 0, sizeof(BufMapType));
6123 BufMapType.tp_name = "vim.bufferlist";
6124 BufMapType.tp_basicsize = sizeof(BufMapObject);
6125 BufMapType.tp_as_mapping = &BufMapAsMapping;
6126 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006127 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006128 BufferType.tp_doc = "vim buffer list";
6129
6130 vim_memset(&WinListType, 0, sizeof(WinListType));
6131 WinListType.tp_name = "vim.windowlist";
6132 WinListType.tp_basicsize = sizeof(WinListType);
6133 WinListType.tp_as_sequence = &WinListAsSeq;
6134 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
6135 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02006136 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02006137
6138 vim_memset(&TabListType, 0, sizeof(TabListType));
6139 TabListType.tp_name = "vim.tabpagelist";
6140 TabListType.tp_basicsize = sizeof(TabListType);
6141 TabListType.tp_as_sequence = &TabListAsSeq;
6142 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
6143 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006144
6145 vim_memset(&RangeType, 0, sizeof(RangeType));
6146 RangeType.tp_name = "vim.range";
6147 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006148 RangeType.tp_dealloc = (destructor)RangeDestructor;
6149 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006150 RangeType.tp_as_sequence = &RangeAsSeq;
6151 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02006152 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006153 RangeType.tp_doc = "vim Range object";
6154 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02006155 RangeType.tp_traverse = (traverseproc)RangeTraverse;
6156 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006157#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006158 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006159 RangeType.tp_alloc = call_PyType_GenericAlloc;
6160 RangeType.tp_new = call_PyType_GenericNew;
6161 RangeType.tp_free = call_PyObject_Free;
6162#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006163 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006164#endif
6165
6166 vim_memset(&CurrentType, 0, sizeof(CurrentType));
6167 CurrentType.tp_name = "vim.currentdata";
6168 CurrentType.tp_basicsize = sizeof(CurrentObject);
6169 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
6170 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02006171 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006172#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006173 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
6174 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006175#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006176 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
6177 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006178#endif
6179
6180 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
6181 DictionaryType.tp_name = "vim.dictionary";
6182 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006183 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006184 DictionaryType.tp_as_sequence = &DictionaryAsSeq;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006185 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006186 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006187 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
6188 DictionaryType.tp_methods = DictionaryMethods;
Bram Moolenaara9922d62013-05-30 13:01:18 +02006189 DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
6190 DictionaryType.tp_new = (newfunc)DictionaryConstructor;
6191 DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006192#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006193 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
6194 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006195#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006196 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
6197 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006198#endif
6199
6200 vim_memset(&ListType, 0, sizeof(ListType));
6201 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02006202 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006203 ListType.tp_basicsize = sizeof(ListObject);
6204 ListType.tp_as_sequence = &ListAsSeq;
6205 ListType.tp_as_mapping = &ListAsMapping;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006206 ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006207 ListType.tp_doc = "list pushing modifications to vim structure";
6208 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02006209 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02006210 ListType.tp_new = (newfunc)ListConstructor;
6211 ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006212#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006213 ListType.tp_getattro = (getattrofunc)ListGetattro;
6214 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006215#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006216 ListType.tp_getattr = (getattrfunc)ListGetattr;
6217 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006218#endif
6219
6220 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02006221 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006222 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02006223 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
6224 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02006225 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006226 FunctionType.tp_doc = "object that calls vim function";
6227 FunctionType.tp_methods = FunctionMethods;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02006228 FunctionType.tp_repr = (reprfunc)FunctionRepr;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02006229 FunctionType.tp_new = (newfunc)FunctionConstructor;
6230 FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006231#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02006232 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006233#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02006234 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006235#endif
6236
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006237 vim_memset(&OptionsType, 0, sizeof(OptionsType));
6238 OptionsType.tp_name = "vim.options";
6239 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01006240 OptionsType.tp_as_sequence = &OptionsAsSeq;
Bram Moolenaar07b88642013-05-29 22:58:32 +02006241 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006242 OptionsType.tp_doc = "object for manipulating options";
Bram Moolenaar1028f4d2014-01-14 16:55:00 +01006243 OptionsType.tp_iter = (getiterfunc)OptionsIter;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006244 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02006245 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
6246 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
6247 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02006248
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006249 vim_memset(&LoaderType, 0, sizeof(LoaderType));
6250 LoaderType.tp_name = "vim.Loader";
6251 LoaderType.tp_basicsize = sizeof(LoaderObject);
6252 LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
6253 LoaderType.tp_doc = "vim message object";
6254 LoaderType.tp_methods = LoaderMethods;
6255 LoaderType.tp_dealloc = (destructor)LoaderDestructor;
6256
Bram Moolenaar4d1da492013-04-24 13:39:15 +02006257#if PY_MAJOR_VERSION >= 3
6258 vim_memset(&vimmodule, 0, sizeof(vimmodule));
6259 vimmodule.m_name = "vim";
6260 vimmodule.m_doc = "Vim Python interface\n";
6261 vimmodule.m_size = -1;
6262 vimmodule.m_methods = VimMethods;
6263#endif
6264}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006265
6266#define PYTYPE_READY(type) \
6267 if (PyType_Ready(&type)) \
6268 return -1;
6269
6270 static int
Bram Moolenaarfb97f282013-07-09 17:42:46 +02006271init_types(void)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006272{
6273 PYTYPE_READY(IterType);
6274 PYTYPE_READY(BufferType);
6275 PYTYPE_READY(RangeType);
6276 PYTYPE_READY(WindowType);
6277 PYTYPE_READY(TabPageType);
6278 PYTYPE_READY(BufMapType);
6279 PYTYPE_READY(WinListType);
6280 PYTYPE_READY(TabListType);
6281 PYTYPE_READY(CurrentType);
6282 PYTYPE_READY(DictionaryType);
6283 PYTYPE_READY(ListType);
6284 PYTYPE_READY(FunctionType);
6285 PYTYPE_READY(OptionsType);
6286 PYTYPE_READY(OutputType);
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02006287 PYTYPE_READY(LoaderType);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006288 return 0;
6289}
6290
6291 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02006292init_sys_path(void)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006293{
6294 PyObject *path;
6295 PyObject *path_hook;
6296 PyObject *path_hooks;
6297
6298 if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
6299 return -1;
6300
6301 if (!(path_hooks = PySys_GetObject("path_hooks")))
6302 {
6303 PyErr_Clear();
6304 path_hooks = PyList_New(1);
6305 PyList_SET_ITEM(path_hooks, 0, path_hook);
6306 if (PySys_SetObject("path_hooks", path_hooks))
6307 {
6308 Py_DECREF(path_hooks);
6309 return -1;
6310 }
6311 Py_DECREF(path_hooks);
6312 }
6313 else if (PyList_Check(path_hooks))
6314 {
6315 if (PyList_Append(path_hooks, path_hook))
6316 {
6317 Py_DECREF(path_hook);
6318 return -1;
6319 }
6320 Py_DECREF(path_hook);
6321 }
6322 else
6323 {
6324 VimTryStart();
6325 EMSG(_("Failed to set path hook: sys.path_hooks is not a list\n"
6326 "You should now do the following:\n"
6327 "- append vim.path_hook to sys.path_hooks\n"
6328 "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
6329 VimTryEnd(); /* Discard the error */
6330 Py_DECREF(path_hook);
6331 return 0;
6332 }
6333
6334 if (!(path = PySys_GetObject("path")))
6335 {
6336 PyErr_Clear();
6337 path = PyList_New(1);
6338 Py_INCREF(vim_special_path_object);
6339 PyList_SET_ITEM(path, 0, vim_special_path_object);
6340 if (PySys_SetObject("path", path))
6341 {
6342 Py_DECREF(path);
6343 return -1;
6344 }
6345 Py_DECREF(path);
6346 }
6347 else if (PyList_Check(path))
6348 {
6349 if (PyList_Append(path, vim_special_path_object))
6350 return -1;
6351 }
6352 else
6353 {
6354 VimTryStart();
6355 EMSG(_("Failed to set path: sys.path is not a list\n"
6356 "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
6357 VimTryEnd(); /* Discard the error */
6358 }
6359
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006360 return 0;
6361}
6362
6363static BufMapObject TheBufferMap =
6364{
6365 PyObject_HEAD_INIT(&BufMapType)
6366};
6367
6368static WinListObject TheWindowList =
6369{
6370 PyObject_HEAD_INIT(&WinListType)
6371 NULL
6372};
6373
6374static CurrentObject TheCurrent =
6375{
6376 PyObject_HEAD_INIT(&CurrentType)
6377};
6378
6379static TabListObject TheTabPageList =
6380{
6381 PyObject_HEAD_INIT(&TabListType)
6382};
6383
6384static struct numeric_constant {
6385 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006386 int val;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006387} numeric_constants[] = {
6388 {"VAR_LOCKED", VAR_LOCKED},
6389 {"VAR_FIXED", VAR_FIXED},
6390 {"VAR_SCOPE", VAR_SCOPE},
6391 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
6392};
6393
6394static struct object_constant {
6395 char *name;
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006396 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006397} object_constants[] = {
6398 {"buffers", (PyObject *)(void *)&TheBufferMap},
6399 {"windows", (PyObject *)(void *)&TheWindowList},
6400 {"tabpages", (PyObject *)(void *)&TheTabPageList},
6401 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02006402
6403 {"Buffer", (PyObject *)&BufferType},
6404 {"Range", (PyObject *)&RangeType},
6405 {"Window", (PyObject *)&WindowType},
6406 {"TabPage", (PyObject *)&TabPageType},
6407 {"Dictionary", (PyObject *)&DictionaryType},
6408 {"List", (PyObject *)&ListType},
6409 {"Function", (PyObject *)&FunctionType},
6410 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006411 {"_Loader", (PyObject *)&LoaderType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006412};
6413
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006414#define ADD_OBJECT(m, name, obj) \
Bram Moolenaardee2e312013-06-23 16:35:47 +02006415 if (PyModule_AddObject(m, name, obj)) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006416 return -1;
6417
6418#define ADD_CHECKED_OBJECT(m, name, obj) \
6419 { \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006420 PyObject *valObject = obj; \
6421 if (!valObject) \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006422 return -1; \
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006423 ADD_OBJECT(m, name, valObject); \
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006424 }
6425
6426 static int
Bram Moolenaardee2e312013-06-23 16:35:47 +02006427populate_module(PyObject *m)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006428{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006429 int i;
6430 PyObject *other_module;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006431 PyObject *attr;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006432 PyObject *imp;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006433
6434 for (i = 0; i < (int)(sizeof(numeric_constants)
6435 / sizeof(struct numeric_constant));
6436 ++i)
6437 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006438 PyInt_FromLong(numeric_constants[i].val));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006439
6440 for (i = 0; i < (int)(sizeof(object_constants)
6441 / sizeof(struct object_constant));
6442 ++i)
6443 {
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006444 PyObject *valObject;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006445
Bram Moolenaarc4b99e02013-06-23 14:30:47 +02006446 valObject = object_constants[i].valObject;
6447 Py_INCREF(valObject);
6448 ADD_OBJECT(m, object_constants[i].name, valObject);
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006449 }
6450
6451 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
6452 return -1;
6453 ADD_OBJECT(m, "error", VimError);
6454
Bram Moolenaara9922d62013-05-30 13:01:18 +02006455 ADD_CHECKED_OBJECT(m, "vars", NEW_DICTIONARY(&globvardict));
6456 ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006457 ADD_CHECKED_OBJECT(m, "options",
6458 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
Bram Moolenaarf4258302013-06-02 18:20:17 +02006459
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006460 if (!(other_module = PyImport_ImportModule("os")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006461 return -1;
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006462 ADD_OBJECT(m, "os", other_module);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006463
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006464 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006465 return -1;
6466 ADD_OBJECT(m, "_getcwd", py_getcwd)
6467
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006468 if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006469 return -1;
6470 ADD_OBJECT(m, "_chdir", py_chdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006471 if (!(attr = PyObject_GetAttrString(m, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006472 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006473 if (PyObject_SetAttrString(other_module, "chdir", attr))
6474 {
6475 Py_DECREF(attr);
6476 return -1;
6477 }
6478 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006479
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02006480 if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006481 {
6482 ADD_OBJECT(m, "_fchdir", py_fchdir);
Bram Moolenaardee2e312013-06-23 16:35:47 +02006483 if (!(attr = PyObject_GetAttrString(m, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02006484 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02006485 if (PyObject_SetAttrString(other_module, "fchdir", attr))
6486 {
6487 Py_DECREF(attr);
6488 return -1;
6489 }
6490 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02006491 }
Bram Moolenaare9056b12013-06-03 20:04:48 +02006492 else
6493 PyErr_Clear();
Bram Moolenaarf4258302013-06-02 18:20:17 +02006494
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006495 if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
6496 return -1;
6497
6498 ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
6499
Bram Moolenaar81c40c52013-06-12 14:41:04 +02006500 if (!(imp = PyImport_ImportModule("imp")))
6501 return -1;
6502
6503 if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
6504 {
6505 Py_DECREF(imp);
6506 return -1;
6507 }
6508
6509 if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
6510 {
6511 Py_DECREF(py_find_module);
6512 Py_DECREF(imp);
6513 return -1;
6514 }
6515
6516 Py_DECREF(imp);
6517
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02006518 ADD_OBJECT(m, "_find_module", py_find_module);
6519 ADD_OBJECT(m, "_load_module", py_load_module);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02006520
Bram Moolenaar1dc28782013-05-21 19:11:01 +02006521 return 0;
6522}