blob: df2af8cd8b2989acea6055967e8f457b0532cae6 [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 Moolenaarc1a995d2012-08-08 16:05:07 +020016#if PY_VERSION_HEX < 0x02050000
17typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
18#endif
19
Bram Moolenaar91805fc2011-06-26 04:01:44 +020020#ifdef FEAT_MBYTE
21# define ENC_OPT p_enc
22#else
23# define ENC_OPT "latin1"
24#endif
Bram Moolenaard620aa92013-05-17 16:40:06 +020025#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020026
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020027#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
28
29#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
30#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020031#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020032
Bram Moolenaare9ba5162013-05-29 22:02:22 +020033#define DICTKEY_DECL \
Bram Moolenaara9922d62013-05-30 13:01:18 +020034 PyObject *dictkey_todecref = NULL;
Bram Moolenaara03e6312013-05-29 22:49:26 +020035#define DICTKEY_GET(err, decref) \
Bram Moolenaarfc714b32013-05-30 14:52:37 +020036 if (!(key = StringToChars(keyObject, &dictkey_todecref))) \
Bram Moolenaara03e6312013-05-29 22:49:26 +020037 { \
38 if (decref) \
39 { \
40 Py_DECREF(keyObject); \
41 } \
Bram Moolenaarc37b6ec2013-05-29 22:43:37 +020042 return err; \
Bram Moolenaara03e6312013-05-29 22:49:26 +020043 } \
44 if (decref && !dictkey_todecref) \
45 dictkey_todecref = keyObject; \
Bram Moolenaarfc714b32013-05-30 14:52:37 +020046 if (*key == NUL) \
47 { \
48 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
49 return err; \
50 }
Bram Moolenaare9ba5162013-05-29 22:02:22 +020051#define DICTKEY_UNREF \
52 Py_XDECREF(dictkey_todecref);
53
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020054typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020055typedef void (*runner)(const char *, void *
56#ifdef PY_CAN_RECURSE
57 , PyGILState_STATE *
58#endif
59 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020060
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020061static int ConvertFromPyObject(PyObject *, typval_T *);
62static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaara9922d62013-05-30 13:01:18 +020063static int ConvertFromPyMapping(PyObject *, typval_T *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020064static PyObject *WindowNew(win_T *, tabpage_T *);
65static PyObject *BufferNew (buf_T *);
66static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020067
68static PyInt RangeStart;
69static PyInt RangeEnd;
70
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020071static PyObject *globals;
72
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020073/*
74 * obtain a lock on the Vim data structures
75 */
76 static void
77Python_Lock_Vim(void)
78{
79}
80
81/*
82 * release a lock on the Vim data structures
83 */
84 static void
85Python_Release_Vim(void)
86{
87}
88
Bram Moolenaare9ba5162013-05-29 22:02:22 +020089/*
90 * The "todecref" argument holds a pointer to PyObject * that must be
91 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
92 * was needed to generate returned value is object.
93 *
94 * Use Py_XDECREF to decrement reference count.
95 */
96 static char_u *
97StringToChars(PyObject *object, PyObject **todecref)
98{
99 char_u *p;
100 PyObject *bytes = NULL;
101
102 if (PyBytes_Check(object))
103 {
104
105 if (PyString_AsStringAndSize(object, (char **) &p, NULL) == -1)
106 return NULL;
107 if (p == NULL)
108 return NULL;
109
110 *todecref = NULL;
111 }
112 else if (PyUnicode_Check(object))
113 {
114 bytes = PyUnicode_AsEncodedString(object, (char *)ENC_OPT, NULL);
115 if (bytes == NULL)
116 return NULL;
117
118 if(PyString_AsStringAndSize(bytes, (char **) &p, NULL) == -1)
119 return NULL;
120 if (p == NULL)
121 return NULL;
122
123 *todecref = bytes;
124 }
125 else
126 {
127 PyErr_SetString(PyExc_TypeError, _("object must be string"));
128 return NULL;
129 }
130
131 return (char_u *) p;
132}
133
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200134 static int
135add_string(PyObject *list, char *s)
136{
137 PyObject *string;
138
139 if (!(string = PyString_FromString(s)))
140 return -1;
141 if (PyList_Append(list, string))
142 {
143 Py_DECREF(string);
144 return -1;
145 }
146
147 Py_DECREF(string);
148 return 0;
149}
150
151 static PyObject *
152ObjectDir(PyObject *self, char **attributes)
153{
154 PyMethodDef *method;
155 char **attr;
156 PyObject *r;
157
158 if (!(r = PyList_New(0)))
159 return NULL;
160
161 if (self)
162 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
163 if (add_string(r, (char *) method->ml_name))
164 {
165 Py_DECREF(r);
166 return NULL;
167 }
168
169 for (attr = attributes ; *attr ; ++attr)
170 if (add_string(r, *attr))
171 {
172 Py_DECREF(r);
173 return NULL;
174 }
175
176#if PY_MAJOR_VERSION < 3
177 if (add_string(r, "__members__"))
178 {
179 Py_DECREF(r);
180 return NULL;
181 }
182#endif
183
184 return r;
185}
186
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200187/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200188 */
189
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200190/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200191typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200192
193static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200194
195typedef struct
196{
197 PyObject_HEAD
198 long softspace;
199 long error;
200} OutputObject;
201
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200202static char *OutputAttrs[] = {
203 "softspace",
204 NULL
205};
206
207 static PyObject *
208OutputDir(PyObject *self)
209{
210 return ObjectDir(self, OutputAttrs);
211}
212
Bram Moolenaar77045652012-09-21 13:46:06 +0200213 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200214OutputSetattr(OutputObject *self, char *name, PyObject *val)
Bram Moolenaar77045652012-09-21 13:46:06 +0200215{
216 if (val == NULL)
217 {
Bram Moolenaar8661b172013-05-15 15:44:28 +0200218 PyErr_SetString(PyExc_AttributeError,
219 _("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200220 return -1;
221 }
222
223 if (strcmp(name, "softspace") == 0)
224 {
225 if (!PyInt_Check(val))
226 {
227 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
228 return -1;
229 }
230
Bram Moolenaard6e39182013-05-21 18:30:34 +0200231 self->softspace = PyInt_AsLong(val);
Bram Moolenaar77045652012-09-21 13:46:06 +0200232 return 0;
233 }
234
235 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
236 return -1;
237}
238
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200239/* Buffer IO, we write one whole line at a time. */
240static garray_T io_ga = {0, 0, 1, 80, NULL};
241static writefn old_fn = NULL;
242
243 static void
244PythonIO_Flush(void)
245{
246 if (old_fn != NULL && io_ga.ga_len > 0)
247 {
248 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
249 old_fn((char_u *)io_ga.ga_data);
250 }
251 io_ga.ga_len = 0;
252}
253
254 static void
255writer(writefn fn, char_u *str, PyInt n)
256{
257 char_u *ptr;
258
259 /* Flush when switching output function. */
260 if (fn != old_fn)
261 PythonIO_Flush();
262 old_fn = fn;
263
264 /* Write each NL separated line. Text after the last NL is kept for
265 * writing later. */
266 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
267 {
268 PyInt len = ptr - str;
269
270 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
271 break;
272
273 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
274 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
275 fn((char_u *)io_ga.ga_data);
276 str = ptr + 1;
277 n -= len + 1;
278 io_ga.ga_len = 0;
279 }
280
281 /* Put the remaining text into io_ga for later printing. */
282 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
283 {
284 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
285 io_ga.ga_len += (int)n;
286 }
287}
288
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200289 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200290OutputWrite(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200291{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200292 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200293 char *str = NULL;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200294 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200295
Bram Moolenaar27564802011-09-07 19:30:21 +0200296 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200297 return NULL;
298
299 Py_BEGIN_ALLOW_THREADS
300 Python_Lock_Vim();
301 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
302 Python_Release_Vim();
303 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200304 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200305
306 Py_INCREF(Py_None);
307 return Py_None;
308}
309
310 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200311OutputWritelines(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200312{
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200313 PyObject *seq;
314 PyObject *iterator;
315 PyObject *item;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200316 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200317
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200318 if (!PyArg_ParseTuple(args, "O", &seq))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200319 return NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200320
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200321 if (!(iterator = PyObject_GetIter(seq)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200322 return NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200323
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200324 while ((item = PyIter_Next(iterator)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200325 {
Bram Moolenaar19e60942011-06-19 00:27:51 +0200326 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200327 PyInt len;
328
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200329 if (!PyArg_Parse(item, "et#", ENC_OPT, &str, &len))
Bram Moolenaardb913952012-06-29 12:54:53 +0200330 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200331 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200332 Py_DECREF(iterator);
333 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200334 return NULL;
335 }
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200336 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200337
338 Py_BEGIN_ALLOW_THREADS
339 Python_Lock_Vim();
340 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
341 Python_Release_Vim();
342 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200343 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200344 }
345
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200346 Py_DECREF(iterator);
347
348 /* Iterator may have finished due to an exception */
349 if (PyErr_Occurred())
350 return NULL;
351
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200352 Py_INCREF(Py_None);
353 return Py_None;
354}
355
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100356 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200357OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100358{
359 /* do nothing */
360 Py_INCREF(Py_None);
361 return Py_None;
362}
363
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200364/***************/
365
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200366static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200367 /* name, function, calling, doc */
368 {"write", (PyCFunction)OutputWrite, METH_VARARGS, ""},
369 {"writelines", (PyCFunction)OutputWritelines, METH_VARARGS, ""},
370 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200371 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200372 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200373};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200374
375static OutputObject Output =
376{
377 PyObject_HEAD_INIT(&OutputType)
378 0,
379 0
380};
381
382static OutputObject Error =
383{
384 PyObject_HEAD_INIT(&OutputType)
385 0,
386 1
387};
388
389 static int
390PythonIO_Init_io(void)
391{
392 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
393 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
394
395 if (PyErr_Occurred())
396 {
397 EMSG(_("E264: Python: Error initialising I/O objects"));
398 return -1;
399 }
400
401 return 0;
402}
403
404
405static PyObject *VimError;
406
407/* Check to see whether a Vim error has been reported, or a keyboard
408 * interrupt has been detected.
409 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200410
411 static void
412VimTryStart(void)
413{
414 ++trylevel;
415}
416
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200417 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200418VimTryEnd(void)
419{
420 --trylevel;
421 if (got_int)
422 {
423 PyErr_SetNone(PyExc_KeyboardInterrupt);
424 return 1;
425 }
426 else if (!did_throw)
427 return 0;
428 else if (PyErr_Occurred())
429 return 1;
430 else
431 {
432 PyErr_SetVim((char *) current_exception->value);
433 discard_current_exception();
434 return 1;
435 }
436}
437
438 static int
439VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200440{
441 if (got_int)
442 {
443 PyErr_SetNone(PyExc_KeyboardInterrupt);
444 return 1;
445 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200446 return 0;
447}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200448
449/* Vim module - Implementation
450 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200451
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200452 static PyObject *
453VimCommand(PyObject *self UNUSED, PyObject *args)
454{
455 char *cmd;
456 PyObject *result;
457
458 if (!PyArg_ParseTuple(args, "s", &cmd))
459 return NULL;
460
461 PyErr_Clear();
462
463 Py_BEGIN_ALLOW_THREADS
464 Python_Lock_Vim();
465
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200466 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200467 do_cmdline_cmd((char_u *)cmd);
468 update_screen(VALID);
469
470 Python_Release_Vim();
471 Py_END_ALLOW_THREADS
472
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200473 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200474 result = NULL;
475 else
476 result = Py_None;
477
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200478
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200479 Py_XINCREF(result);
480 return result;
481}
482
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200483/*
484 * Function to translate a typval_T into a PyObject; this will recursively
485 * translate lists/dictionaries into their Python equivalents.
486 *
487 * The depth parameter is to avoid infinite recursion, set it to 1 when
488 * you call VimToPython.
489 */
490 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200491VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200492{
493 PyObject *result;
494 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200495 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200496
497 /* Avoid infinite recursion */
498 if (depth > 100)
499 {
500 Py_INCREF(Py_None);
501 result = Py_None;
502 return result;
503 }
504
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200505 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200506 * then and we can use it again. */
507 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
508 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
509 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200510 sprintf(ptrBuf, "%p",
511 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
512 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200513
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200514 if ((result = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200515 {
516 Py_INCREF(result);
517 return result;
518 }
519 }
520
521 if (our_tv->v_type == VAR_STRING)
522 {
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200523 result = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200524 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200525 }
526 else if (our_tv->v_type == VAR_NUMBER)
527 {
528 char buf[NUMBUFLEN];
529
530 /* For backwards compatibility numbers are stored as strings. */
531 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200532 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200533 }
534# ifdef FEAT_FLOAT
535 else if (our_tv->v_type == VAR_FLOAT)
536 {
537 char buf[NUMBUFLEN];
538
539 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200540 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200541 }
542# endif
543 else if (our_tv->v_type == VAR_LIST)
544 {
545 list_T *list = our_tv->vval.v_list;
546 listitem_T *curr;
547
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200548 if (list == NULL)
549 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200550
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200551 if (!(result = PyList_New(0)))
552 return NULL;
553
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200554 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200555 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200556 Py_DECREF(result);
557 return NULL;
558 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200559
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200560 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
561 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200562 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200563 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200564 Py_DECREF(result);
565 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200566 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200567 if (PyList_Append(result, newObj))
568 {
569 Py_DECREF(newObj);
570 Py_DECREF(result);
571 return NULL;
572 }
573 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200574 }
575 }
576 else if (our_tv->v_type == VAR_DICT)
577 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200578
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200579 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
580 long_u todo = ht->ht_used;
581 hashitem_T *hi;
582 dictitem_T *di;
583 if (our_tv->vval.v_dict == NULL)
584 return NULL;
585
586 if (!(result = PyDict_New()))
587 return NULL;
588
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200589 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200590 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200591 Py_DECREF(result);
592 return NULL;
593 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200594
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200595 for (hi = ht->ht_array; todo > 0; ++hi)
596 {
597 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200598 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200599 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200600
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200601 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200602 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200603 {
604 Py_DECREF(result);
605 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200606 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200607 if (PyDict_SetItemString(result, (char *)hi->hi_key, newObj))
608 {
609 Py_DECREF(result);
610 Py_DECREF(newObj);
611 return NULL;
612 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200613 }
614 }
615 }
616 else
617 {
618 Py_INCREF(Py_None);
619 result = Py_None;
620 }
621
622 return result;
623}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200624
625 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200626VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200627{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200628 char *expr;
629 typval_T *our_tv;
630 PyObject *result;
631 PyObject *lookup_dict;
632
633 if (!PyArg_ParseTuple(args, "s", &expr))
634 return NULL;
635
636 Py_BEGIN_ALLOW_THREADS
637 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200638 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200639 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200640 Python_Release_Vim();
641 Py_END_ALLOW_THREADS
642
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200643 if (VimTryEnd())
644 return NULL;
645
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200646 if (our_tv == NULL)
647 {
648 PyErr_SetVim(_("invalid expression"));
649 return NULL;
650 }
651
652 /* Convert the Vim type into a Python type. Create a dictionary that's
653 * used to check for recursive loops. */
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200654 if (!(lookup_dict = PyDict_New()))
655 result = NULL;
656 else
657 {
658 result = VimToPython(our_tv, 1, lookup_dict);
659 Py_DECREF(lookup_dict);
660 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200661
662
663 Py_BEGIN_ALLOW_THREADS
664 Python_Lock_Vim();
665 free_tv(our_tv);
666 Python_Release_Vim();
667 Py_END_ALLOW_THREADS
668
669 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200670}
671
Bram Moolenaardb913952012-06-29 12:54:53 +0200672static PyObject *ConvertToPyObject(typval_T *);
673
674 static PyObject *
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200675VimEvalPy(PyObject *self UNUSED, PyObject *args)
Bram Moolenaardb913952012-06-29 12:54:53 +0200676{
Bram Moolenaardb913952012-06-29 12:54:53 +0200677 char *expr;
678 typval_T *our_tv;
679 PyObject *result;
680
681 if (!PyArg_ParseTuple(args, "s", &expr))
682 return NULL;
683
684 Py_BEGIN_ALLOW_THREADS
685 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200686 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +0200687 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200688 Python_Release_Vim();
689 Py_END_ALLOW_THREADS
690
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200691 if (VimTryEnd())
692 return NULL;
693
Bram Moolenaardb913952012-06-29 12:54:53 +0200694 if (our_tv == NULL)
695 {
696 PyErr_SetVim(_("invalid expression"));
697 return NULL;
698 }
699
700 result = ConvertToPyObject(our_tv);
701 Py_BEGIN_ALLOW_THREADS
702 Python_Lock_Vim();
703 free_tv(our_tv);
704 Python_Release_Vim();
705 Py_END_ALLOW_THREADS
706
707 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200708}
709
710 static PyObject *
711VimStrwidth(PyObject *self UNUSED, PyObject *args)
712{
713 char *expr;
714
715 if (!PyArg_ParseTuple(args, "s", &expr))
716 return NULL;
717
Bram Moolenaara54bf402012-12-05 16:30:07 +0100718 return PyLong_FromLong(
719#ifdef FEAT_MBYTE
720 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
721#else
722 STRLEN(expr)
723#endif
724 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200725}
726
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200727/*
728 * Vim module - Definitions
729 */
730
731static struct PyMethodDef VimMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200732 /* name, function, calling, documentation */
733 {"command", VimCommand, METH_VARARGS, "Execute a Vim ex-mode command" },
734 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
735 {"bindeval", VimEvalPy, METH_VARARGS, "Like eval(), but returns objects attached to vim ones"},
736 {"strwidth", VimStrwidth, METH_VARARGS, "Screen string width, counts <Tab> as having width 1"},
737 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200738};
739
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200740/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200741 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200742 */
743
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200744static PyTypeObject IterType;
745
746typedef PyObject *(*nextfun)(void **);
747typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200748typedef int (*traversefun)(void *, visitproc, void *);
749typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200750
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200751/* Main purpose of this object is removing the need for do python
752 * initialization (i.e. PyType_Ready and setting type attributes) for a big
753 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200754
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200755typedef struct
756{
757 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200758 void *cur;
759 nextfun next;
760 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200761 traversefun traverse;
762 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200763} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200764
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200765 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200766IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
767 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200768{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200769 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200770
Bram Moolenaar774267b2013-05-21 20:51:59 +0200771 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200772 self->cur = start;
773 self->next = next;
774 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200775 self->traverse = traverse;
776 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200777
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200778 return (PyObject *)(self);
779}
780
781 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200782IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200783{
Bram Moolenaar774267b2013-05-21 20:51:59 +0200784 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +0200785 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +0200786 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200787}
788
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200789 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200790IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200791{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200792 if (self->traverse != NULL)
793 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200794 else
795 return 0;
796}
797
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200798/* Mac OSX defines clear() somewhere. */
799#ifdef clear
800# undef clear
801#endif
802
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200803 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200804IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200805{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200806 if (self->clear != NULL)
807 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200808 else
809 return 0;
810}
811
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200812 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200813IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200814{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200815 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200816}
817
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200818 static PyObject *
819IterIter(PyObject *self)
820{
Bram Moolenaar1bcabe12013-05-29 22:52:32 +0200821 Py_INCREF(self);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200822 return self;
823}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200824
Bram Moolenaardb913952012-06-29 12:54:53 +0200825typedef struct pylinkedlist_S {
826 struct pylinkedlist_S *pll_next;
827 struct pylinkedlist_S *pll_prev;
828 PyObject *pll_obj;
829} pylinkedlist_T;
830
831static pylinkedlist_T *lastdict = NULL;
832static pylinkedlist_T *lastlist = NULL;
833
834 static void
835pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
836{
837 if (ref->pll_prev == NULL)
838 {
839 if (ref->pll_next == NULL)
840 {
841 *last = NULL;
842 return;
843 }
844 }
845 else
846 ref->pll_prev->pll_next = ref->pll_next;
847
848 if (ref->pll_next == NULL)
849 *last = ref->pll_prev;
850 else
851 ref->pll_next->pll_prev = ref->pll_prev;
852}
853
854 static void
855pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
856{
857 if (*last == NULL)
858 ref->pll_prev = NULL;
859 else
860 {
861 (*last)->pll_next = ref;
862 ref->pll_prev = *last;
863 }
864 ref->pll_next = NULL;
865 ref->pll_obj = self;
866 *last = ref;
867}
868
869static PyTypeObject DictionaryType;
870
871typedef struct
872{
873 PyObject_HEAD
874 dict_T *dict;
875 pylinkedlist_T ref;
876} DictionaryObject;
877
Bram Moolenaara9922d62013-05-30 13:01:18 +0200878static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
879
880#define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
881
Bram Moolenaardb913952012-06-29 12:54:53 +0200882 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +0200883DictionaryNew(PyTypeObject *subtype, dict_T *dict)
Bram Moolenaardb913952012-06-29 12:54:53 +0200884{
885 DictionaryObject *self;
886
Bram Moolenaara9922d62013-05-30 13:01:18 +0200887 self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +0200888 if (self == NULL)
889 return NULL;
890 self->dict = dict;
891 ++dict->dv_refcount;
892
893 pyll_add((PyObject *)(self), &self->ref, &lastdict);
894
895 return (PyObject *)(self);
896}
897
Bram Moolenaara9922d62013-05-30 13:01:18 +0200898 static dict_T *
899py_dict_alloc()
900{
901 dict_T *r;
902
903 if (!(r = dict_alloc()))
904 {
905 PyErr_NoMemory();
906 return NULL;
907 }
908 ++r->dv_refcount;
909
910 return r;
911}
912
913 static PyObject *
914DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
915{
916 DictionaryObject *self;
917 dict_T *dict;
918
919 if (!(dict = py_dict_alloc()))
920 return NULL;
921
922 self = (DictionaryObject *) DictionaryNew(subtype, dict);
923
924 --dict->dv_refcount;
925
926 if (kwargs || PyTuple_Size(args))
927 {
928 PyObject *tmp;
929 if (!(tmp = DictionaryUpdate(self, args, kwargs)))
930 {
931 Py_DECREF(self);
932 return NULL;
933 }
934
935 Py_DECREF(tmp);
936 }
937
938 return (PyObject *)(self);
939}
940
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200941 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200942DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200943{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200944 pyll_remove(&self->ref, &lastdict);
945 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200946
947 DESTRUCTOR_FINISH(self);
948}
949
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200950static char *DictionaryAttrs[] = {
951 "locked", "scope",
952 NULL
953};
954
955 static PyObject *
956DictionaryDir(PyObject *self)
957{
958 return ObjectDir(self, DictionaryAttrs);
959}
960
Bram Moolenaardb913952012-06-29 12:54:53 +0200961 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200962DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200963{
964 if (val == NULL)
965 {
Bram Moolenaara9922d62013-05-30 13:01:18 +0200966 PyErr_SetString(PyExc_AttributeError,
967 _("cannot delete vim.Dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +0200968 return -1;
969 }
970
971 if (strcmp(name, "locked") == 0)
972 {
Bram Moolenaard6e39182013-05-21 18:30:34 +0200973 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200974 {
Bram Moolenaara9922d62013-05-30 13:01:18 +0200975 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed dictionary"));
Bram Moolenaar66b79852012-09-21 14:00:35 +0200976 return -1;
977 }
978 else
979 {
Bram Moolenaarb983f752013-05-15 16:11:50 +0200980 int istrue = PyObject_IsTrue(val);
981 if (istrue == -1)
982 return -1;
983 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +0200984 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200985 else
Bram Moolenaard6e39182013-05-21 18:30:34 +0200986 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200987 }
988 return 0;
989 }
990 else
991 {
Bram Moolenaara9922d62013-05-30 13:01:18 +0200992 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +0200993 return -1;
994 }
995}
996
997 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200998DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200999{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001000 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +02001001}
1002
Bram Moolenaara9922d62013-05-30 13:01:18 +02001003#define DICT_FLAG_HAS_DEFAULT 0x01
1004#define DICT_FLAG_POP 0x02
1005#define DICT_FLAG_NONE_DEFAULT 0x04
1006#define DICT_FLAG_RETURN_BOOL 0x08 /* Incompatible with DICT_FLAG_POP */
1007#define DICT_FLAG_RETURN_PAIR 0x10
1008
Bram Moolenaardb913952012-06-29 12:54:53 +02001009 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001010_DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
Bram Moolenaardb913952012-06-29 12:54:53 +02001011{
Bram Moolenaara9922d62013-05-30 13:01:18 +02001012 PyObject *keyObject;
1013 PyObject *defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
1014 PyObject *r;
Bram Moolenaardb913952012-06-29 12:54:53 +02001015 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001016 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001017 dict_T *dict = self->dict;
1018 hashitem_T *hi;
1019
Bram Moolenaardb913952012-06-29 12:54:53 +02001020 DICTKEY_DECL
1021
Bram Moolenaara9922d62013-05-30 13:01:18 +02001022 if (flags & DICT_FLAG_HAS_DEFAULT)
1023 {
1024 if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1025 return NULL;
1026 }
1027 else
1028 keyObject = args;
1029
1030 if (flags & DICT_FLAG_RETURN_BOOL)
1031 defObject = Py_False;
1032
Bram Moolenaara03e6312013-05-29 22:49:26 +02001033 DICTKEY_GET(NULL, 0)
Bram Moolenaardb913952012-06-29 12:54:53 +02001034
Bram Moolenaara9922d62013-05-30 13:01:18 +02001035 hi = hash_find(&dict->dv_hashtab, key);
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001036
Bram Moolenaar696c2112012-09-21 13:43:14 +02001037 DICTKEY_UNREF
1038
Bram Moolenaara9922d62013-05-30 13:01:18 +02001039 if (HASHITEM_EMPTY(hi))
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001040 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001041 if (defObject)
1042 {
1043 Py_INCREF(defObject);
1044 return defObject;
1045 }
1046 else
1047 {
1048 PyErr_SetObject(PyExc_KeyError, keyObject);
1049 return NULL;
1050 }
1051 }
1052 else if (flags & DICT_FLAG_RETURN_BOOL)
1053 {
1054 Py_INCREF(Py_True);
1055 return Py_True;
1056 }
1057
1058 di = dict_lookup(hi);
1059
1060 if (!(r = ConvertToPyObject(&di->di_tv)))
1061 return NULL;
1062
1063 if (flags & DICT_FLAG_POP)
1064 {
1065 if (dict->dv_lock)
1066 {
1067 PyErr_SetVim(_("dict is locked"));
1068 Py_DECREF(r);
1069 return NULL;
1070 }
1071
1072 hash_remove(&dict->dv_hashtab, hi);
1073 dictitem_free(di);
1074 }
1075
1076 if (flags & DICT_FLAG_RETURN_PAIR)
1077 {
1078 PyObject *tmp = r;
1079
1080 if (!(r = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, tmp)))
1081 {
1082 Py_DECREF(tmp);
1083 return NULL;
1084 }
1085 }
1086
1087 return r;
1088}
1089
1090 static PyObject *
1091DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1092{
1093 return _DictionaryItem(self, keyObject, 0);
1094}
1095
1096 static int
1097DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1098{
1099 PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
1100 int r;
1101
1102 r = (rObj == Py_True);
1103
1104 Py_DECREF(Py_True);
1105
1106 return r;
1107}
1108
1109typedef struct
1110{
1111 hashitem_T *ht_array;
1112 long_u ht_used;
1113 hashtab_T *ht;
1114 hashitem_T *hi;
1115 int todo;
1116} dictiterinfo_T;
1117
1118 static PyObject *
1119DictionaryIterNext(dictiterinfo_T **dii)
1120{
1121 PyObject *r;
1122
1123 if (!(*dii)->todo)
1124 return NULL;
1125
1126 if ((*dii)->ht->ht_array != (*dii)->ht_array ||
1127 (*dii)->ht->ht_used != (*dii)->ht_used)
1128 {
1129 PyErr_SetString(PyExc_RuntimeError,
1130 _("hashtab changed during iteration"));
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001131 return NULL;
1132 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001133
Bram Moolenaara9922d62013-05-30 13:01:18 +02001134 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
1135 ++((*dii)->hi);
1136
1137 --((*dii)->todo);
1138
1139 if (!(r = PyBytes_FromString((char *) (*dii)->hi->hi_key)))
1140 return NULL;
1141
1142 return r;
1143}
1144
1145 static PyObject *
1146DictionaryIter(DictionaryObject *self)
1147{
1148 dictiterinfo_T *dii;
1149 hashtab_T *ht;
1150
1151 if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1152 {
1153 PyErr_NoMemory();
1154 return NULL;
1155 }
1156
1157 ht = &self->dict->dv_hashtab;
1158 dii->ht_array = ht->ht_array;
1159 dii->ht_used = ht->ht_used;
1160 dii->ht = ht;
1161 dii->hi = dii->ht_array;
1162 dii->todo = dii->ht_used;
1163
1164 return IterNew(dii,
1165 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1166 NULL, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02001167}
1168
1169 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001170DictionaryAssItem(DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +02001171{
1172 char_u *key;
1173 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001174 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001175 dictitem_T *di;
1176 DICTKEY_DECL
1177
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001178 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +02001179 {
1180 PyErr_SetVim(_("dict is locked"));
1181 return -1;
1182 }
1183
Bram Moolenaara03e6312013-05-29 22:49:26 +02001184 DICTKEY_GET(-1, 0)
Bram Moolenaardb913952012-06-29 12:54:53 +02001185
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001186 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +02001187
1188 if (valObject == NULL)
1189 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +02001190 hashitem_T *hi;
1191
Bram Moolenaardb913952012-06-29 12:54:53 +02001192 if (di == NULL)
1193 {
Bram Moolenaar696c2112012-09-21 13:43:14 +02001194 DICTKEY_UNREF
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001195 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +02001196 return -1;
1197 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001198 hi = hash_find(&dict->dv_hashtab, di->di_key);
1199 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +02001200 dictitem_free(di);
1201 return 0;
1202 }
1203
1204 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02001205 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02001206
1207 if (di == NULL)
1208 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001209 if (!(di = dictitem_alloc(key)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001210 {
1211 PyErr_NoMemory();
1212 return -1;
1213 }
1214 di->di_tv.v_lock = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001215 di->di_tv.v_type = VAR_UNKNOWN;
Bram Moolenaardb913952012-06-29 12:54:53 +02001216
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001217 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001218 {
Bram Moolenaar696c2112012-09-21 13:43:14 +02001219 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +02001220 vim_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001221 dictitem_free(di);
Bram Moolenaardb913952012-06-29 12:54:53 +02001222 PyErr_SetVim(_("failed to add key to dictionary"));
1223 return -1;
1224 }
1225 }
1226 else
1227 clear_tv(&di->di_tv);
1228
1229 DICTKEY_UNREF
1230
1231 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001232 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001233 return 0;
1234}
1235
Bram Moolenaara9922d62013-05-30 13:01:18 +02001236typedef PyObject *(*hi_to_py)(hashitem_T *);
1237
Bram Moolenaardb913952012-06-29 12:54:53 +02001238 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001239DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
Bram Moolenaardb913952012-06-29 12:54:53 +02001240{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001241 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001242 long_u todo = dict->dv_hashtab.ht_used;
1243 Py_ssize_t i = 0;
1244 PyObject *r;
1245 hashitem_T *hi;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001246 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +02001247
1248 r = PyList_New(todo);
1249 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1250 {
1251 if (!HASHITEM_EMPTY(hi))
1252 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001253 if (!(newObj = hiconvert(hi)))
1254 {
1255 Py_DECREF(r);
1256 return NULL;
1257 }
1258 if (PyList_SetItem(r, i, newObj))
1259 {
1260 Py_DECREF(r);
1261 Py_DECREF(newObj);
1262 return NULL;
1263 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001264 --todo;
1265 ++i;
1266 }
1267 }
1268 return r;
1269}
1270
Bram Moolenaara9922d62013-05-30 13:01:18 +02001271 static PyObject *
1272dict_key(hashitem_T *hi)
1273{
1274 return PyBytes_FromString((char *)(hi->hi_key));
1275}
1276
1277 static PyObject *
1278DictionaryListKeys(DictionaryObject *self)
1279{
1280 return DictionaryListObjects(self, dict_key);
1281}
1282
1283 static PyObject *
1284dict_val(hashitem_T *hi)
1285{
1286 dictitem_T *di;
1287
1288 di = dict_lookup(hi);
1289 return ConvertToPyObject(&di->di_tv);
1290}
1291
1292 static PyObject *
1293DictionaryListValues(DictionaryObject *self)
1294{
1295 return DictionaryListObjects(self, dict_val);
1296}
1297
1298 static PyObject *
1299dict_item(hashitem_T *hi)
1300{
1301 PyObject *keyObject;
1302 PyObject *valObject;
1303 PyObject *r;
1304
1305 if (!(keyObject = dict_key(hi)))
1306 return NULL;
1307
1308 if (!(valObject = dict_val(hi)))
1309 {
1310 Py_DECREF(keyObject);
1311 return NULL;
1312 }
1313
1314 r = Py_BuildValue("(OO)", keyObject, valObject);
1315
1316 Py_DECREF(keyObject);
1317 Py_DECREF(valObject);
1318
1319 return r;
1320}
1321
1322 static PyObject *
1323DictionaryListItems(DictionaryObject *self)
1324{
1325 return DictionaryListObjects(self, dict_item);
1326}
1327
1328 static PyObject *
1329DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
1330{
1331 dict_T *dict = self->dict;
1332
1333 if (dict->dv_lock)
1334 {
1335 PyErr_SetVim(_("dict is locked"));
1336 return NULL;
1337 }
1338
1339 if (kwargs)
1340 {
1341 typval_T tv;
1342
1343 if (ConvertFromPyMapping(kwargs, &tv) == -1)
1344 return NULL;
1345
1346 VimTryStart();
1347 dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force");
1348 clear_tv(&tv);
1349 if (VimTryEnd())
1350 return NULL;
1351 }
1352 else
1353 {
1354 PyObject *object;
1355
1356 if (!PyArg_Parse(args, "(O)", &object))
1357 return NULL;
1358
1359 if (PyObject_HasAttrString(object, "keys"))
1360 return DictionaryUpdate(self, NULL, object);
1361 else
1362 {
1363 PyObject *iterator;
1364 PyObject *item;
1365
1366 if (!(iterator = PyObject_GetIter(object)))
1367 return NULL;
1368
1369 while ((item = PyIter_Next(iterator)))
1370 {
1371 PyObject *fast;
1372 PyObject *keyObject;
1373 PyObject *valObject;
1374 PyObject *todecref;
1375 char_u *key;
1376 dictitem_T *di;
1377
1378 if (!(fast = PySequence_Fast(item, "")))
1379 {
1380 Py_DECREF(iterator);
1381 Py_DECREF(item);
1382 return NULL;
1383 }
1384
1385 Py_DECREF(item);
1386
1387 if (PySequence_Fast_GET_SIZE(fast) != 2)
1388 {
1389 Py_DECREF(iterator);
1390 Py_DECREF(fast);
1391 PyErr_SetString(PyExc_ValueError,
1392 _("expected sequence element of size 2"));
1393 return NULL;
1394 }
1395
1396 keyObject = PySequence_Fast_GET_ITEM(fast, 0);
1397
1398 if (!(key = StringToChars(keyObject, &todecref)))
1399 {
1400 Py_DECREF(iterator);
1401 Py_DECREF(fast);
1402 return NULL;
1403 }
1404
1405 di = dictitem_alloc(key);
1406
1407 Py_XDECREF(todecref);
1408
1409 if (di == NULL)
1410 {
1411 Py_DECREF(fast);
1412 Py_DECREF(iterator);
1413 PyErr_NoMemory();
1414 return NULL;
1415 }
1416 di->di_tv.v_lock = 0;
1417 di->di_tv.v_type = VAR_UNKNOWN;
1418
1419 valObject = PySequence_Fast_GET_ITEM(fast, 1);
1420
1421 if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
1422 {
1423 Py_DECREF(iterator);
1424 Py_DECREF(fast);
1425 dictitem_free(di);
1426 return NULL;
1427 }
1428
1429 Py_DECREF(fast);
1430
1431 if (dict_add(dict, di) == FAIL)
1432 {
1433 Py_DECREF(iterator);
1434 dictitem_free(di);
1435 PyErr_SetVim(_("failed to add key to dictionary"));
1436 return NULL;
1437 }
1438 }
1439
1440 Py_DECREF(iterator);
1441
1442 /* Iterator may have finished due to an exception */
1443 if (PyErr_Occurred())
1444 return NULL;
1445 }
1446 }
1447 Py_INCREF(Py_None);
1448 return Py_None;
1449}
1450
1451 static PyObject *
1452DictionaryGet(DictionaryObject *self, PyObject *args)
1453{
1454 return _DictionaryItem(self, args,
1455 DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
1456}
1457
1458 static PyObject *
1459DictionaryPop(DictionaryObject *self, PyObject *args)
1460{
1461 return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
1462}
1463
1464 static PyObject *
1465DictionaryPopItem(DictionaryObject *self, PyObject *args)
1466{
1467 PyObject *keyObject;
1468
1469 if (!PyArg_ParseTuple(args, "O", &keyObject))
1470 return NULL;
1471
1472 return _DictionaryItem(self, keyObject,
1473 DICT_FLAG_POP|DICT_FLAG_RETURN_PAIR);
1474}
1475
1476 static PyObject *
1477DictionaryHasKey(DictionaryObject *self, PyObject *args)
1478{
1479 PyObject *keyObject;
1480
1481 if (!PyArg_ParseTuple(args, "O", &keyObject))
1482 return NULL;
1483
1484 return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
1485}
1486
1487static PySequenceMethods DictionaryAsSeq = {
1488 0, /* sq_length */
1489 0, /* sq_concat */
1490 0, /* sq_repeat */
1491 0, /* sq_item */
1492 0, /* sq_slice */
1493 0, /* sq_ass_item */
1494 0, /* sq_ass_slice */
1495 (objobjproc) DictionaryContains, /* sq_contains */
1496 0, /* sq_inplace_concat */
1497 0, /* sq_inplace_repeat */
1498};
1499
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001500static PyMappingMethods DictionaryAsMapping = {
1501 (lenfunc) DictionaryLength,
1502 (binaryfunc) DictionaryItem,
1503 (objobjargproc) DictionaryAssItem,
1504};
1505
Bram Moolenaardb913952012-06-29 12:54:53 +02001506static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001507 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaara9922d62013-05-30 13:01:18 +02001508 {"values", (PyCFunction)DictionaryListValues, METH_NOARGS, ""},
1509 {"items", (PyCFunction)DictionaryListItems, METH_NOARGS, ""},
1510 {"update", (PyCFunction)DictionaryUpdate, METH_VARARGS|METH_KEYWORDS, ""},
1511 {"get", (PyCFunction)DictionaryGet, METH_VARARGS, ""},
1512 {"pop", (PyCFunction)DictionaryPop, METH_VARARGS, ""},
1513 {"popitem", (PyCFunction)DictionaryPopItem, METH_VARARGS, ""},
1514 {"has_key", (PyCFunction)DictionaryHasKey, METH_VARARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001515 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
1516 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001517};
1518
1519static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001520static PySequenceMethods ListAsSeq;
1521static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +02001522
1523typedef struct
1524{
1525 PyObject_HEAD
1526 list_T *list;
1527 pylinkedlist_T ref;
1528} ListObject;
1529
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001530#define NEW_LIST(list) ListNew(&ListType, list)
1531
Bram Moolenaardb913952012-06-29 12:54:53 +02001532 static PyObject *
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001533ListNew(PyTypeObject *subtype, list_T *list)
Bram Moolenaardb913952012-06-29 12:54:53 +02001534{
1535 ListObject *self;
1536
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001537 self = (ListObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02001538 if (self == NULL)
1539 return NULL;
1540 self->list = list;
1541 ++list->lv_refcount;
1542
1543 pyll_add((PyObject *)(self), &self->ref, &lastlist);
1544
1545 return (PyObject *)(self);
1546}
1547
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001548 static list_T *
1549py_list_alloc()
1550{
1551 list_T *r;
1552
1553 if (!(r = list_alloc()))
1554 {
1555 PyErr_NoMemory();
1556 return NULL;
1557 }
1558 ++r->lv_refcount;
1559
1560 return r;
1561}
1562
1563 static int
1564list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
1565{
1566 PyObject *iterator;
1567 PyObject *item;
1568 listitem_T *li;
1569
1570 if (!(iterator = PyObject_GetIter(obj)))
1571 return -1;
1572
1573 while ((item = PyIter_Next(iterator)))
1574 {
1575 if (!(li = listitem_alloc()))
1576 {
1577 PyErr_NoMemory();
1578 Py_DECREF(item);
1579 Py_DECREF(iterator);
1580 return -1;
1581 }
1582 li->li_tv.v_lock = 0;
1583 li->li_tv.v_type = VAR_UNKNOWN;
1584
1585 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
1586 {
1587 Py_DECREF(item);
1588 Py_DECREF(iterator);
1589 listitem_free(li);
1590 return -1;
1591 }
1592
1593 Py_DECREF(item);
1594
1595 list_append(l, li);
1596 }
1597
1598 Py_DECREF(iterator);
1599
1600 /* Iterator may have finished due to an exception */
1601 if (PyErr_Occurred())
1602 return -1;
1603
1604 return 0;
1605}
1606
1607 static PyObject *
1608ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1609{
1610 list_T *list;
1611 PyObject *obj = NULL;
1612
1613 if (kwargs)
1614 {
1615 PyErr_SetString(PyExc_TypeError,
1616 _("list constructor does not accept keyword arguments"));
1617 return NULL;
1618 }
1619
1620 if (!PyArg_ParseTuple(args, "|O", &obj))
1621 return NULL;
1622
1623 if (!(list = py_list_alloc()))
1624 return NULL;
1625
1626 if (obj)
1627 {
1628 PyObject *lookup_dict;
1629
1630 if (!(lookup_dict = PyDict_New()))
1631 {
1632 list_unref(list);
1633 return NULL;
1634 }
1635
1636 if (list_py_concat(list, obj, lookup_dict) == -1)
1637 {
1638 Py_DECREF(lookup_dict);
1639 list_unref(list);
1640 return NULL;
1641 }
1642
1643 Py_DECREF(lookup_dict);
1644 }
1645
1646 return ListNew(subtype, list);
1647}
1648
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001649 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001650ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001651{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001652 pyll_remove(&self->ref, &lastlist);
1653 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001654
1655 DESTRUCTOR_FINISH(self);
1656}
1657
Bram Moolenaardb913952012-06-29 12:54:53 +02001658 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001659ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001660{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001661 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02001662}
1663
1664 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001665ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02001666{
1667 listitem_T *li;
1668
Bram Moolenaard6e39182013-05-21 18:30:34 +02001669 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02001670 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001671 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001672 return NULL;
1673 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02001674 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02001675 if (li == NULL)
1676 {
1677 PyErr_SetVim(_("internal error: failed to get vim list item"));
1678 return NULL;
1679 }
1680 return ConvertToPyObject(&li->li_tv);
1681}
1682
1683#define PROC_RANGE \
1684 if (last < 0) {\
1685 if (last < -size) \
1686 last = 0; \
1687 else \
1688 last += size; \
1689 } \
1690 if (first < 0) \
1691 first = 0; \
1692 if (first > size) \
1693 first = size; \
1694 if (last > size) \
1695 last = size;
1696
1697 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001698ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +02001699{
1700 PyInt i;
1701 PyInt size = ListLength(self);
1702 PyInt n;
1703 PyObject *list;
1704 int reversed = 0;
1705
1706 PROC_RANGE
1707 if (first >= last)
1708 first = last;
1709
1710 n = last-first;
1711 list = PyList_New(n);
1712 if (list == NULL)
1713 return NULL;
1714
1715 for (i = 0; i < n; ++i)
1716 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +02001717 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02001718 if (item == NULL)
1719 {
1720 Py_DECREF(list);
1721 return NULL;
1722 }
1723
1724 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
1725 {
1726 Py_DECREF(item);
1727 Py_DECREF(list);
1728 return NULL;
1729 }
1730 }
1731
1732 return list;
1733}
1734
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001735typedef struct
1736{
1737 listwatch_T lw;
1738 list_T *list;
1739} listiterinfo_T;
1740
1741 static void
1742ListIterDestruct(listiterinfo_T *lii)
1743{
1744 list_rem_watch(lii->list, &lii->lw);
1745 PyMem_Free(lii);
1746}
1747
1748 static PyObject *
1749ListIterNext(listiterinfo_T **lii)
1750{
1751 PyObject *r;
1752
1753 if (!((*lii)->lw.lw_item))
1754 return NULL;
1755
1756 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1757 return NULL;
1758
1759 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1760
1761 return r;
1762}
1763
1764 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001765ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001766{
1767 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001768 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001769
1770 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1771 {
1772 PyErr_NoMemory();
1773 return NULL;
1774 }
1775
1776 list_add_watch(l, &lii->lw);
1777 lii->lw.lw_item = l->lv_first;
1778 lii->list = l;
1779
1780 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001781 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
1782 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001783}
1784
Bram Moolenaardb913952012-06-29 12:54:53 +02001785 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001786ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001787{
1788 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001789 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001790 listitem_T *li;
1791 Py_ssize_t length = ListLength(self);
1792
1793 if (l->lv_lock)
1794 {
1795 PyErr_SetVim(_("list is locked"));
1796 return -1;
1797 }
1798 if (index>length || (index==length && obj==NULL))
1799 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001800 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001801 return -1;
1802 }
1803
1804 if (obj == NULL)
1805 {
1806 li = list_find(l, (long) index);
1807 list_remove(l, li, li);
1808 clear_tv(&li->li_tv);
1809 vim_free(li);
1810 return 0;
1811 }
1812
1813 if (ConvertFromPyObject(obj, &tv) == -1)
1814 return -1;
1815
1816 if (index == length)
1817 {
1818 if (list_append_tv(l, &tv) == FAIL)
1819 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001820 clear_tv(&tv);
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001821 PyErr_SetVim(_("failed to add item to list"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001822 return -1;
1823 }
1824 }
1825 else
1826 {
1827 li = list_find(l, (long) index);
1828 clear_tv(&li->li_tv);
1829 copy_tv(&tv, &li->li_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001830 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001831 }
1832 return 0;
1833}
1834
1835 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001836ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001837{
1838 PyInt size = ListLength(self);
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001839 PyObject *iterator;
1840 PyObject *item;
Bram Moolenaardb913952012-06-29 12:54:53 +02001841 listitem_T *li;
1842 listitem_T *next;
1843 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001844 list_T *l = self->list;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001845 PyInt i;
Bram Moolenaardb913952012-06-29 12:54:53 +02001846
1847 if (l->lv_lock)
1848 {
1849 PyErr_SetVim(_("list is locked"));
1850 return -1;
1851 }
1852
1853 PROC_RANGE
1854
1855 if (first == size)
1856 li = NULL;
1857 else
1858 {
1859 li = list_find(l, (long) first);
1860 if (li == NULL)
1861 {
1862 PyErr_SetVim(_("internal error: no vim list item"));
1863 return -1;
1864 }
1865 if (last > first)
1866 {
1867 i = last - first;
1868 while (i-- && li != NULL)
1869 {
1870 next = li->li_next;
1871 listitem_remove(l, li);
1872 li = next;
1873 }
1874 }
1875 }
1876
1877 if (obj == NULL)
1878 return 0;
1879
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001880 if (!(iterator = PyObject_GetIter(obj)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001881 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02001882
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001883 while ((item = PyIter_Next(iterator)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001884 {
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001885 if (ConvertFromPyObject(item, &v) == -1)
1886 {
1887 Py_DECREF(iterator);
1888 Py_DECREF(item);
Bram Moolenaardb913952012-06-29 12:54:53 +02001889 return -1;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001890 }
1891 Py_DECREF(item);
Bram Moolenaardb913952012-06-29 12:54:53 +02001892 if (list_insert_tv(l, &v, li) == FAIL)
1893 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001894 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001895 PyErr_SetVim(_("internal error: failed to add item to list"));
1896 return -1;
1897 }
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001898 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001899 }
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001900 Py_DECREF(iterator);
Bram Moolenaardb913952012-06-29 12:54:53 +02001901 return 0;
1902}
1903
1904 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001905ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001906{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001907 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001908 PyObject *lookup_dict;
1909
1910 if (l->lv_lock)
1911 {
1912 PyErr_SetVim(_("list is locked"));
1913 return NULL;
1914 }
1915
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02001916 if (!(lookup_dict = PyDict_New()))
1917 return NULL;
1918
Bram Moolenaardb913952012-06-29 12:54:53 +02001919 if (list_py_concat(l, obj, lookup_dict) == -1)
1920 {
1921 Py_DECREF(lookup_dict);
1922 return NULL;
1923 }
1924 Py_DECREF(lookup_dict);
1925
1926 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02001927 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02001928}
1929
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001930static char *ListAttrs[] = {
1931 "locked",
1932 NULL
1933};
1934
1935 static PyObject *
1936ListDir(PyObject *self)
1937{
1938 return ObjectDir(self, ListAttrs);
1939}
1940
Bram Moolenaar66b79852012-09-21 14:00:35 +02001941 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001942ListSetattr(ListObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001943{
1944 if (val == NULL)
1945 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001946 PyErr_SetString(PyExc_AttributeError,
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001947 _("cannot delete vim.List attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001948 return -1;
1949 }
1950
1951 if (strcmp(name, "locked") == 0)
1952 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001953 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001954 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001955 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001956 return -1;
1957 }
1958 else
1959 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001960 int istrue = PyObject_IsTrue(val);
1961 if (istrue == -1)
1962 return -1;
1963 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001964 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001965 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001966 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001967 }
1968 return 0;
1969 }
1970 else
1971 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001972 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001973 return -1;
1974 }
1975}
1976
Bram Moolenaardb913952012-06-29 12:54:53 +02001977static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001978 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1979 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
1980 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001981};
1982
1983typedef struct
1984{
1985 PyObject_HEAD
1986 char_u *name;
1987} FunctionObject;
1988
1989static PyTypeObject FunctionType;
1990
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001991#define NEW_FUNCTION(name) FunctionNew(&FunctionType, name)
1992
Bram Moolenaardb913952012-06-29 12:54:53 +02001993 static PyObject *
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001994FunctionNew(PyTypeObject *subtype, char_u *name)
Bram Moolenaardb913952012-06-29 12:54:53 +02001995{
1996 FunctionObject *self;
1997
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02001998 self = (FunctionObject *) subtype->tp_alloc(subtype, 0);
1999
Bram Moolenaardb913952012-06-29 12:54:53 +02002000 if (self == NULL)
2001 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002002
2003 if (isdigit(*name))
Bram Moolenaardb913952012-06-29 12:54:53 +02002004 {
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002005 if (!translated_function_exists(name))
2006 {
2007 PyErr_SetString(PyExc_ValueError,
2008 _("unnamed function does not exist"));
2009 return NULL;
2010 }
2011 self->name = vim_strsave(name);
2012 func_ref(self->name);
2013 }
2014 else
Bram Moolenaar018acca2013-05-30 13:37:28 +02002015 if ((self->name = get_expanded_name(name,
2016 vim_strchr(name, AUTOLOAD_CHAR) == NULL))
2017 == NULL)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002018 {
Bram Moolenaar018acca2013-05-30 13:37:28 +02002019 PyErr_SetString(PyExc_ValueError, _("function does not exist"));
2020 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002021 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002022
2023 return (PyObject *)(self);
2024}
2025
2026 static PyObject *
2027FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2028{
2029 PyObject *self;
2030 char_u *name;
2031
2032 if (kwargs)
2033 {
2034 PyErr_SetString(PyExc_TypeError,
2035 _("function constructor does not accept keyword arguments"));
Bram Moolenaardb913952012-06-29 12:54:53 +02002036 return NULL;
2037 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002038
2039 if (!PyArg_ParseTuple(args, "s", &name))
2040 return NULL;
2041
2042 self = FunctionNew(subtype, name);
2043
2044 return self;
Bram Moolenaardb913952012-06-29 12:54:53 +02002045}
2046
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002047 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002048FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002049{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002050 func_unref(self->name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002051 vim_free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002052
2053 DESTRUCTOR_FINISH(self);
2054}
2055
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002056static char *FunctionAttrs[] = {
2057 "softspace",
2058 NULL
2059};
2060
2061 static PyObject *
2062FunctionDir(PyObject *self)
2063{
2064 return ObjectDir(self, FunctionAttrs);
2065}
2066
Bram Moolenaardb913952012-06-29 12:54:53 +02002067 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002068FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02002069{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002070 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02002071 typval_T args;
2072 typval_T selfdicttv;
2073 typval_T rettv;
2074 dict_T *selfdict = NULL;
2075 PyObject *selfdictObject;
2076 PyObject *result;
2077 int error;
2078
2079 if (ConvertFromPyObject(argsObject, &args) == -1)
2080 return NULL;
2081
2082 if (kwargs != NULL)
2083 {
2084 selfdictObject = PyDict_GetItemString(kwargs, "self");
2085 if (selfdictObject != NULL)
2086 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02002087 if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002088 {
2089 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02002090 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002091 }
Bram Moolenaardb913952012-06-29 12:54:53 +02002092 selfdict = selfdicttv.vval.v_dict;
2093 }
2094 }
2095
Bram Moolenaar71700b82013-05-15 17:49:05 +02002096 Py_BEGIN_ALLOW_THREADS
2097 Python_Lock_Vim();
2098
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002099 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02002100 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02002101
2102 Python_Release_Vim();
2103 Py_END_ALLOW_THREADS
2104
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002105 if (VimTryEnd())
2106 result = NULL;
2107 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02002108 {
2109 result = NULL;
2110 PyErr_SetVim(_("failed to run function"));
2111 }
2112 else
2113 result = ConvertToPyObject(&rettv);
2114
Bram Moolenaardb913952012-06-29 12:54:53 +02002115 clear_tv(&args);
2116 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002117 if (selfdict != NULL)
2118 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002119
2120 return result;
2121}
2122
Bram Moolenaara5b725c2013-05-30 12:43:54 +02002123 static PyObject *
2124FunctionRepr(FunctionObject *self)
2125{
2126 return PyString_FromFormat("<vim.Function '%s'>", self->name);
2127}
2128
Bram Moolenaardb913952012-06-29 12:54:53 +02002129static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002130 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
2131 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002132};
2133
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002134/*
2135 * Options object
2136 */
2137
2138static PyTypeObject OptionsType;
2139
2140typedef int (*checkfun)(void *);
2141
2142typedef struct
2143{
2144 PyObject_HEAD
2145 int opt_type;
2146 void *from;
2147 checkfun Check;
2148 PyObject *fromObj;
2149} OptionsObject;
2150
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002151 static int
2152dummy_check(void *arg UNUSED)
2153{
2154 return 0;
2155}
2156
2157 static PyObject *
2158OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
2159{
2160 OptionsObject *self;
2161
Bram Moolenaar774267b2013-05-21 20:51:59 +02002162 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002163 if (self == NULL)
2164 return NULL;
2165
2166 self->opt_type = opt_type;
2167 self->from = from;
2168 self->Check = Check;
2169 self->fromObj = fromObj;
2170 if (fromObj)
2171 Py_INCREF(fromObj);
2172
2173 return (PyObject *)(self);
2174}
2175
2176 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002177OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002178{
Bram Moolenaar774267b2013-05-21 20:51:59 +02002179 PyObject_GC_UnTrack((void *)(self));
2180 Py_XDECREF(self->fromObj);
2181 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002182}
2183
2184 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002185OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002186{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002187 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002188 return 0;
2189}
2190
2191 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002192OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002193{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002194 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002195 return 0;
2196}
2197
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002198 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002199OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002200{
2201 char_u *key;
2202 int flags;
2203 long numval;
2204 char_u *stringval;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02002205 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002206
Bram Moolenaard6e39182013-05-21 18:30:34 +02002207 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002208 return NULL;
2209
Bram Moolenaara03e6312013-05-29 22:49:26 +02002210 DICTKEY_GET(NULL, 0)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002211
2212 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002213 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002214
2215 DICTKEY_UNREF
2216
2217 if (flags == 0)
2218 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02002219 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002220 return NULL;
2221 }
2222
2223 if (flags & SOPT_UNSET)
2224 {
2225 Py_INCREF(Py_None);
2226 return Py_None;
2227 }
2228 else if (flags & SOPT_BOOL)
2229 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002230 PyObject *r;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002231 r = numval ? Py_True : Py_False;
2232 Py_INCREF(r);
2233 return r;
2234 }
2235 else if (flags & SOPT_NUM)
2236 return PyInt_FromLong(numval);
2237 else if (flags & SOPT_STRING)
2238 {
2239 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002240 {
2241 PyObject *r = PyBytes_FromString((char *) stringval);
2242 vim_free(stringval);
2243 return r;
2244 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002245 else
2246 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002247 PyErr_SetString(PyExc_RuntimeError,
2248 _("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002249 return NULL;
2250 }
2251 }
2252 else
2253 {
2254 PyErr_SetVim("Internal error: unknown option type. Should not happen");
2255 return NULL;
2256 }
2257}
2258
2259 static int
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002260set_option_value_err(key, numval, stringval, opt_flags)
2261 char_u *key;
2262 int numval;
2263 char_u *stringval;
2264 int opt_flags;
2265{
2266 char_u *errmsg;
2267
2268 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
2269 {
2270 if (VimTryEnd())
2271 return FAIL;
2272 PyErr_SetVim((char *)errmsg);
2273 return FAIL;
2274 }
2275 return OK;
2276}
2277
2278 static int
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002279set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
2280 char_u *key;
2281 int numval;
2282 char_u *stringval;
2283 int opt_flags;
2284 int opt_type;
2285 void *from;
2286{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002287 win_T *save_curwin = NULL;
2288 tabpage_T *save_curtab = NULL;
2289 buf_T *save_curbuf = NULL;
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002290 int r = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002291
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002292 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002293 switch (opt_type)
2294 {
2295 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02002296 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
2297 win_find_tabpage((win_T *)from)) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002298 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002299 if (VimTryEnd())
2300 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002301 PyErr_SetVim("Problem while switching windows.");
2302 return -1;
2303 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002304 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002305 restore_win(save_curwin, save_curtab);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002306 if (r == FAIL)
2307 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002308 break;
2309 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02002310 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002311 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002312 restore_buffer(save_curbuf);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002313 if (r == FAIL)
2314 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002315 break;
2316 case SREQ_GLOBAL:
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002317 r = set_option_value_err(key, numval, stringval, opt_flags);
2318 if (r == FAIL)
2319 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002320 break;
2321 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002322 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002323}
2324
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002325 static void *
2326py_memsave(void *p, size_t len)
2327{
2328 void *r;
2329 if (!(r = PyMem_Malloc(len)))
2330 return NULL;
2331 mch_memmove(r, p, len);
2332 return r;
2333}
2334
2335#define PY_STRSAVE(s) ((char_u *) py_memsave(s, STRLEN(s) + 1))
2336
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002337 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002338OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002339{
2340 char_u *key;
2341 int flags;
2342 int opt_flags;
2343 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02002344 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002345
Bram Moolenaard6e39182013-05-21 18:30:34 +02002346 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002347 return -1;
2348
Bram Moolenaara03e6312013-05-29 22:49:26 +02002349 DICTKEY_GET(-1, 0)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002350
2351 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002352 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002353
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002354 if (flags == 0)
2355 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02002356 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002357 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002358 return -1;
2359 }
2360
2361 if (valObject == NULL)
2362 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002363 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002364 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002365 PyErr_SetString(PyExc_ValueError,
2366 _("unable to unset global option"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002367 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002368 return -1;
2369 }
2370 else if (!(flags & SOPT_GLOBAL))
2371 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002372 PyErr_SetString(PyExc_ValueError, _("unable to unset option "
2373 "without global value"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002374 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002375 return -1;
2376 }
2377 else
2378 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002379 unset_global_local_option(key, self->from);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002380 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002381 return 0;
2382 }
2383 }
2384
Bram Moolenaard6e39182013-05-21 18:30:34 +02002385 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002386
2387 if (flags & SOPT_BOOL)
2388 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02002389 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002390
Bram Moolenaarb983f752013-05-15 16:11:50 +02002391 if (istrue == -1)
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002392 r = -1;
2393 else
2394 r = set_option_value_for(key, istrue, NULL,
2395 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002396 }
2397 else if (flags & SOPT_NUM)
2398 {
2399 int val;
2400
2401#if PY_MAJOR_VERSION < 3
2402 if (PyInt_Check(valObject))
2403 val = PyInt_AsLong(valObject);
2404 else
2405#endif
2406 if (PyLong_Check(valObject))
2407 val = PyLong_AsLong(valObject);
2408 else
2409 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002410 PyErr_SetString(PyExc_TypeError, _("object must be integer"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002411 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002412 return -1;
2413 }
2414
2415 r = set_option_value_for(key, val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002416 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002417 }
2418 else
2419 {
2420 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002421 PyObject *todecref;
2422
2423 if ((val = StringToChars(valObject, &todecref)))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002424 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002425 r = set_option_value_for(key, 0, val, opt_flags,
2426 self->opt_type, self->from);
2427 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002428 }
2429 else
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002430 r = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002431 }
2432
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002433 DICTKEY_UNREF
2434
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002435 return r;
2436}
2437
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002438static PyMappingMethods OptionsAsMapping = {
2439 (lenfunc) NULL,
2440 (binaryfunc) OptionsItem,
2441 (objobjargproc) OptionsAssItem,
2442};
2443
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002444/* Tabpage object
2445 */
2446
2447typedef struct
2448{
2449 PyObject_HEAD
2450 tabpage_T *tab;
2451} TabPageObject;
2452
2453static PyObject *WinListNew(TabPageObject *tabObject);
2454
2455static PyTypeObject TabPageType;
2456
2457 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002458CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002459{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002460 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002461 {
2462 PyErr_SetVim(_("attempt to refer to deleted tab page"));
2463 return -1;
2464 }
2465
2466 return 0;
2467}
2468
2469 static PyObject *
2470TabPageNew(tabpage_T *tab)
2471{
2472 TabPageObject *self;
2473
2474 if (TAB_PYTHON_REF(tab))
2475 {
2476 self = TAB_PYTHON_REF(tab);
2477 Py_INCREF(self);
2478 }
2479 else
2480 {
2481 self = PyObject_NEW(TabPageObject, &TabPageType);
2482 if (self == NULL)
2483 return NULL;
2484 self->tab = tab;
2485 TAB_PYTHON_REF(tab) = self;
2486 }
2487
2488 return (PyObject *)(self);
2489}
2490
2491 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002492TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002493{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002494 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
2495 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002496
2497 DESTRUCTOR_FINISH(self);
2498}
2499
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002500static char *TabPageAttrs[] = {
2501 "windows", "number", "vars", "window", "valid",
2502 NULL
2503};
2504
2505 static PyObject *
2506TabPageDir(PyObject *self)
2507{
2508 return ObjectDir(self, TabPageAttrs);
2509}
2510
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002511 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002512TabPageAttrValid(TabPageObject *self, char *name)
2513{
2514 PyObject *r;
2515
2516 if (strcmp(name, "valid") != 0)
2517 return NULL;
2518
2519 r = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
2520 Py_INCREF(r);
2521 return r;
2522}
2523
2524 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002525TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002526{
2527 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002528 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002529 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002530 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002531 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002532 return NEW_DICTIONARY(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002533 else if (strcmp(name, "window") == 0)
2534 {
2535 /* For current tab window.c does not bother to set or update tp_curwin
2536 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002537 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002538 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002539 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02002540 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002541 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002542 else if (strcmp(name, "__members__") == 0)
2543 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002544 return NULL;
2545}
2546
2547 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002548TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002549{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002550 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002551 return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002552 else
2553 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002554 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002555
2556 if (t == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002557 return PyString_FromFormat("<tabpage object (unknown) at %p>",
2558 (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002559 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002560 return PyString_FromFormat("<tabpage %d>", t - 1);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002561 }
2562}
2563
2564static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002565 /* name, function, calling, documentation */
2566 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
2567 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002568};
2569
2570/*
2571 * Window list object
2572 */
2573
2574static PyTypeObject TabListType;
2575static PySequenceMethods TabListAsSeq;
2576
2577typedef struct
2578{
2579 PyObject_HEAD
2580} TabListObject;
2581
2582 static PyInt
2583TabListLength(PyObject *self UNUSED)
2584{
2585 tabpage_T *tp = first_tabpage;
2586 PyInt n = 0;
2587
2588 while (tp != NULL)
2589 {
2590 ++n;
2591 tp = tp->tp_next;
2592 }
2593
2594 return n;
2595}
2596
2597 static PyObject *
2598TabListItem(PyObject *self UNUSED, PyInt n)
2599{
2600 tabpage_T *tp;
2601
2602 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
2603 if (n == 0)
2604 return TabPageNew(tp);
2605
2606 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
2607 return NULL;
2608}
2609
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002610/* Window object
2611 */
2612
2613typedef struct
2614{
2615 PyObject_HEAD
2616 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002617 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002618} WindowObject;
2619
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002620static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002621
2622 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002623CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002624{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002625 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002626 {
2627 PyErr_SetVim(_("attempt to refer to deleted window"));
2628 return -1;
2629 }
2630
2631 return 0;
2632}
2633
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002634 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002635WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02002636{
2637 /* We need to handle deletion of windows underneath us.
2638 * If we add a "w_python*_ref" field to the win_T structure,
2639 * then we can get at it in win_free() in vim. We then
2640 * need to create only ONE Python object per window - if
2641 * we try to create a second, just INCREF the existing one
2642 * and return it. The (single) Python object referring to
2643 * the window is stored in "w_python*_ref".
2644 * On a win_free() we set the Python object's win_T* field
2645 * to an invalid value. We trap all uses of a window
2646 * object, and reject them if the win_T* field is invalid.
2647 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002648 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02002649 * w_python_ref and w_python3_ref fields respectively.
2650 */
2651
2652 WindowObject *self;
2653
2654 if (WIN_PYTHON_REF(win))
2655 {
2656 self = WIN_PYTHON_REF(win);
2657 Py_INCREF(self);
2658 }
2659 else
2660 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02002661 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02002662 if (self == NULL)
2663 return NULL;
2664 self->win = win;
2665 WIN_PYTHON_REF(win) = self;
2666 }
2667
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002668 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
2669
Bram Moolenaar971db462013-05-12 18:44:48 +02002670 return (PyObject *)(self);
2671}
2672
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002673 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002674WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002675{
Bram Moolenaar774267b2013-05-21 20:51:59 +02002676 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02002677 if (self->win && self->win != INVALID_WINDOW_VALUE)
2678 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02002679 Py_XDECREF(((PyObject *)(self->tabObject)));
2680 PyObject_GC_Del((void *)(self));
2681}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002682
Bram Moolenaar774267b2013-05-21 20:51:59 +02002683 static int
2684WindowTraverse(WindowObject *self, visitproc visit, void *arg)
2685{
2686 Py_VISIT(((PyObject *)(self->tabObject)));
2687 return 0;
2688}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002689
Bram Moolenaar774267b2013-05-21 20:51:59 +02002690 static int
2691WindowClear(WindowObject *self)
2692{
2693 Py_CLEAR(self->tabObject);
2694 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002695}
2696
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002697 static win_T *
2698get_firstwin(TabPageObject *tabObject)
2699{
2700 if (tabObject)
2701 {
2702 if (CheckTabPage(tabObject))
2703 return NULL;
2704 /* For current tab window.c does not bother to set or update tp_firstwin
2705 */
2706 else if (tabObject->tab == curtab)
2707 return firstwin;
2708 else
2709 return tabObject->tab->tp_firstwin;
2710 }
2711 else
2712 return firstwin;
2713}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002714static char *WindowAttrs[] = {
2715 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
2716 "tabpage", "valid",
2717 NULL
2718};
2719
2720 static PyObject *
2721WindowDir(PyObject *self)
2722{
2723 return ObjectDir(self, WindowAttrs);
2724}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002725
Bram Moolenaar971db462013-05-12 18:44:48 +02002726 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002727WindowAttrValid(WindowObject *self, char *name)
2728{
2729 PyObject *r;
2730
2731 if (strcmp(name, "valid") != 0)
2732 return NULL;
2733
2734 r = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
2735 Py_INCREF(r);
2736 return r;
2737}
2738
2739 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002740WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002741{
2742 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002743 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002744 else if (strcmp(name, "cursor") == 0)
2745 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002746 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002747
2748 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
2749 }
2750 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002751 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002752#ifdef FEAT_WINDOWS
2753 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002754 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002755#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002756#ifdef FEAT_VERTSPLIT
2757 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002758 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002759 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002760 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002761#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02002762 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002763 return NEW_DICTIONARY(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002764 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002765 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
2766 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02002767 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002768 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002769 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002770 return NULL;
2771 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002772 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002773 }
2774 else if (strcmp(name, "tabpage") == 0)
2775 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002776 Py_INCREF(self->tabObject);
2777 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002778 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002779 else if (strcmp(name, "__members__") == 0)
2780 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002781 else
2782 return NULL;
2783}
2784
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002785 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002786WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002787{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002788 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002789 return -1;
2790
2791 if (strcmp(name, "buffer") == 0)
2792 {
2793 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2794 return -1;
2795 }
2796 else if (strcmp(name, "cursor") == 0)
2797 {
2798 long lnum;
2799 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002800
2801 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2802 return -1;
2803
Bram Moolenaard6e39182013-05-21 18:30:34 +02002804 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002805 {
2806 PyErr_SetVim(_("cursor position outside buffer"));
2807 return -1;
2808 }
2809
2810 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002811 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002812 return -1;
2813
Bram Moolenaard6e39182013-05-21 18:30:34 +02002814 self->win->w_cursor.lnum = lnum;
2815 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002816#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02002817 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002818#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002819 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002820 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002821
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002822 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002823 return 0;
2824 }
2825 else if (strcmp(name, "height") == 0)
2826 {
2827 int height;
2828 win_T *savewin;
2829
2830 if (!PyArg_Parse(val, "i", &height))
2831 return -1;
2832
2833#ifdef FEAT_GUI
2834 need_mouse_correct = TRUE;
2835#endif
2836 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002837 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002838
2839 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002840 win_setheight(height);
2841 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002842 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002843 return -1;
2844
2845 return 0;
2846 }
2847#ifdef FEAT_VERTSPLIT
2848 else if (strcmp(name, "width") == 0)
2849 {
2850 int width;
2851 win_T *savewin;
2852
2853 if (!PyArg_Parse(val, "i", &width))
2854 return -1;
2855
2856#ifdef FEAT_GUI
2857 need_mouse_correct = TRUE;
2858#endif
2859 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002860 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002861
2862 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002863 win_setwidth(width);
2864 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002865 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002866 return -1;
2867
2868 return 0;
2869 }
2870#endif
2871 else
2872 {
2873 PyErr_SetString(PyExc_AttributeError, name);
2874 return -1;
2875 }
2876}
2877
2878 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002879WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002880{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002881 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002882 return PyString_FromFormat("<window object (deleted) at %p>", (self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002883 else
2884 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002885 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002886
Bram Moolenaar6d216452013-05-12 19:00:41 +02002887 if (w == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002888 return PyString_FromFormat("<window object (unknown) at %p>",
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002889 (self));
2890 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002891 return PyString_FromFormat("<window %d>", w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002892 }
2893}
2894
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002895static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002896 /* name, function, calling, documentation */
2897 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
2898 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002899};
2900
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002901/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002902 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002903 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002904
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002905static PyTypeObject WinListType;
2906static PySequenceMethods WinListAsSeq;
2907
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002908typedef struct
2909{
2910 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002911 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002912} WinListObject;
2913
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002914 static PyObject *
2915WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002916{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002917 WinListObject *self;
2918
2919 self = PyObject_NEW(WinListObject, &WinListType);
2920 self->tabObject = tabObject;
2921 Py_INCREF(tabObject);
2922
2923 return (PyObject *)(self);
2924}
2925
2926 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002927WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002928{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002929 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002930
2931 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02002932 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002933 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02002934 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002935
2936 DESTRUCTOR_FINISH(self);
2937}
2938
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002939 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002940WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002941{
2942 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002943 PyInt n = 0;
2944
Bram Moolenaard6e39182013-05-21 18:30:34 +02002945 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002946 return -1;
2947
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002948 while (w != NULL)
2949 {
2950 ++n;
2951 w = W_NEXT(w);
2952 }
2953
2954 return n;
2955}
2956
2957 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002958WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002959{
2960 win_T *w;
2961
Bram Moolenaard6e39182013-05-21 18:30:34 +02002962 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002963 return NULL;
2964
2965 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002966 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002967 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002968
2969 PyErr_SetString(PyExc_IndexError, _("no such window"));
2970 return NULL;
2971}
2972
2973/* Convert a Python string into a Vim line.
2974 *
2975 * The result is in allocated memory. All internal nulls are replaced by
2976 * newline characters. It is an error for the string to contain newline
2977 * characters.
2978 *
2979 * On errors, the Python exception data is set, and NULL is returned.
2980 */
2981 static char *
2982StringToLine(PyObject *obj)
2983{
2984 const char *str;
2985 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002986 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002987 PyInt len;
2988 PyInt i;
2989 char *p;
2990
2991 if (obj == NULL || !PyString_Check(obj))
2992 {
2993 PyErr_BadArgument();
2994 return NULL;
2995 }
2996
Bram Moolenaar19e60942011-06-19 00:27:51 +02002997 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2998 str = PyString_AsString(bytes);
2999 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003000
3001 /*
3002 * Error checking: String must not contain newlines, as we
3003 * are replacing a single line, and we must replace it with
3004 * a single line.
3005 * A trailing newline is removed, so that append(f.readlines()) works.
3006 */
3007 p = memchr(str, '\n', len);
3008 if (p != NULL)
3009 {
3010 if (p == str + len - 1)
3011 --len;
3012 else
3013 {
3014 PyErr_SetVim(_("string cannot contain newlines"));
3015 return NULL;
3016 }
3017 }
3018
3019 /* Create a copy of the string, with internal nulls replaced by
3020 * newline characters, as is the vim convention.
3021 */
3022 save = (char *)alloc((unsigned)(len+1));
3023 if (save == NULL)
3024 {
3025 PyErr_NoMemory();
3026 return NULL;
3027 }
3028
3029 for (i = 0; i < len; ++i)
3030 {
3031 if (str[i] == '\0')
3032 save[i] = '\n';
3033 else
3034 save[i] = str[i];
3035 }
3036
3037 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02003038 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003039
3040 return save;
3041}
3042
3043/* Get a line from the specified buffer. The line number is
3044 * in Vim format (1-based). The line is returned as a Python
3045 * string object.
3046 */
3047 static PyObject *
3048GetBufferLine(buf_T *buf, PyInt n)
3049{
3050 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
3051}
3052
3053
3054/* Get a list of lines from the specified buffer. The line numbers
3055 * are in Vim format (1-based). The range is from lo up to, but not
3056 * including, hi. The list is returned as a Python list of string objects.
3057 */
3058 static PyObject *
3059GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
3060{
3061 PyInt i;
3062 PyInt n = hi - lo;
3063 PyObject *list = PyList_New(n);
3064
3065 if (list == NULL)
3066 return NULL;
3067
3068 for (i = 0; i < n; ++i)
3069 {
3070 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
3071
3072 /* Error check - was the Python string creation OK? */
3073 if (str == NULL)
3074 {
3075 Py_DECREF(list);
3076 return NULL;
3077 }
3078
3079 /* Set the list item */
3080 if (PyList_SetItem(list, i, str))
3081 {
3082 Py_DECREF(str);
3083 Py_DECREF(list);
3084 return NULL;
3085 }
3086 }
3087
3088 /* The ownership of the Python list is passed to the caller (ie,
3089 * the caller should Py_DECREF() the object when it is finished
3090 * with it).
3091 */
3092
3093 return list;
3094}
3095
3096/*
3097 * Check if deleting lines made the cursor position invalid.
3098 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
3099 * deleted).
3100 */
3101 static void
3102py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
3103{
3104 if (curwin->w_cursor.lnum >= lo)
3105 {
3106 /* Adjust the cursor position if it's in/after the changed
3107 * lines. */
3108 if (curwin->w_cursor.lnum >= hi)
3109 {
3110 curwin->w_cursor.lnum += extra;
3111 check_cursor_col();
3112 }
3113 else if (extra < 0)
3114 {
3115 curwin->w_cursor.lnum = lo;
3116 check_cursor();
3117 }
3118 else
3119 check_cursor_col();
3120 changed_cline_bef_curs();
3121 }
3122 invalidate_botline();
3123}
3124
Bram Moolenaar19e60942011-06-19 00:27:51 +02003125/*
3126 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003127 * in Vim format (1-based). The replacement line is given as
3128 * a Python string object. The object is checked for validity
3129 * and correct format. Errors are returned as a value of FAIL.
3130 * The return value is OK on success.
3131 * If OK is returned and len_change is not NULL, *len_change
3132 * is set to the change in the buffer length.
3133 */
3134 static int
3135SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
3136{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003137 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003138 * There are three cases:
3139 * 1. NULL, or None - this is a deletion.
3140 * 2. A string - this is a replacement.
3141 * 3. Anything else - this is an error.
3142 */
3143 if (line == Py_None || line == NULL)
3144 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02003145 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003146
3147 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003148 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003149
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003150 VimTryStart();
3151
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003152 if (u_savedel((linenr_T)n, 1L) == FAIL)
3153 PyErr_SetVim(_("cannot save undo information"));
3154 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
3155 PyErr_SetVim(_("cannot delete line"));
3156 else
3157 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02003158 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003159 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
3160 deleted_lines_mark((linenr_T)n, 1L);
3161 }
3162
Bram Moolenaar105bc352013-05-17 16:03:57 +02003163 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003164
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003165 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003166 return FAIL;
3167
3168 if (len_change)
3169 *len_change = -1;
3170
3171 return OK;
3172 }
3173 else if (PyString_Check(line))
3174 {
3175 char *save = StringToLine(line);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003176 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003177
3178 if (save == NULL)
3179 return FAIL;
3180
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003181 VimTryStart();
3182
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003183 /* We do not need to free "save" if ml_replace() consumes it. */
3184 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003185 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003186
3187 if (u_savesub((linenr_T)n) == FAIL)
3188 {
3189 PyErr_SetVim(_("cannot save undo information"));
3190 vim_free(save);
3191 }
3192 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
3193 {
3194 PyErr_SetVim(_("cannot replace line"));
3195 vim_free(save);
3196 }
3197 else
3198 changed_bytes((linenr_T)n, 0);
3199
Bram Moolenaar105bc352013-05-17 16:03:57 +02003200 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003201
3202 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02003203 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003204 check_cursor_col();
3205
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003206 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003207 return FAIL;
3208
3209 if (len_change)
3210 *len_change = 0;
3211
3212 return OK;
3213 }
3214 else
3215 {
3216 PyErr_BadArgument();
3217 return FAIL;
3218 }
3219}
3220
Bram Moolenaar19e60942011-06-19 00:27:51 +02003221/* Replace a range of lines in the specified buffer. The line numbers are in
3222 * Vim format (1-based). The range is from lo up to, but not including, hi.
3223 * The replacement lines are given as a Python list of string objects. The
3224 * list is checked for validity and correct format. Errors are returned as a
3225 * value of FAIL. The return value is OK on success.
3226 * If OK is returned and len_change is not NULL, *len_change
3227 * is set to the change in the buffer length.
3228 */
3229 static int
3230SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
3231{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003232 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02003233 * There are three cases:
3234 * 1. NULL, or None - this is a deletion.
3235 * 2. A list - this is a replacement.
3236 * 3. Anything else - this is an error.
3237 */
3238 if (list == Py_None || list == NULL)
3239 {
3240 PyInt i;
3241 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003242 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003243
3244 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003245 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003246 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003247
3248 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
3249 PyErr_SetVim(_("cannot save undo information"));
3250 else
3251 {
3252 for (i = 0; i < n; ++i)
3253 {
3254 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3255 {
3256 PyErr_SetVim(_("cannot delete line"));
3257 break;
3258 }
3259 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02003260 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003261 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
3262 deleted_lines_mark((linenr_T)lo, (long)i);
3263 }
3264
Bram Moolenaar105bc352013-05-17 16:03:57 +02003265 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003266
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003267 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02003268 return FAIL;
3269
3270 if (len_change)
3271 *len_change = -n;
3272
3273 return OK;
3274 }
3275 else if (PyList_Check(list))
3276 {
3277 PyInt i;
3278 PyInt new_len = PyList_Size(list);
3279 PyInt old_len = hi - lo;
3280 PyInt extra = 0; /* lines added to text, can be negative */
3281 char **array;
3282 buf_T *savebuf;
3283
3284 if (new_len == 0) /* avoid allocating zero bytes */
3285 array = NULL;
3286 else
3287 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003288 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003289 if (array == NULL)
3290 {
3291 PyErr_NoMemory();
3292 return FAIL;
3293 }
3294 }
3295
3296 for (i = 0; i < new_len; ++i)
3297 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003298 PyObject *line;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003299
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003300 if (!(line = PyList_GetItem(list, i)) ||
3301 !(array[i] = StringToLine(line)))
Bram Moolenaar19e60942011-06-19 00:27:51 +02003302 {
3303 while (i)
3304 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003305 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003306 return FAIL;
3307 }
3308 }
3309
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003310 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02003311 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003312
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003313 /* START of region without "return". Must call restore_buffer()! */
Bram Moolenaar105bc352013-05-17 16:03:57 +02003314 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003315
3316 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
3317 PyErr_SetVim(_("cannot save undo information"));
3318
3319 /* If the size of the range is reducing (ie, new_len < old_len) we
3320 * need to delete some old_len. We do this at the start, by
3321 * repeatedly deleting line "lo".
3322 */
3323 if (!PyErr_Occurred())
3324 {
3325 for (i = 0; i < old_len - new_len; ++i)
3326 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3327 {
3328 PyErr_SetVim(_("cannot delete line"));
3329 break;
3330 }
3331 extra -= i;
3332 }
3333
3334 /* For as long as possible, replace the existing old_len with the
3335 * new old_len. This is a more efficient operation, as it requires
3336 * less memory allocation and freeing.
3337 */
3338 if (!PyErr_Occurred())
3339 {
3340 for (i = 0; i < old_len && i < new_len; ++i)
3341 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
3342 == FAIL)
3343 {
3344 PyErr_SetVim(_("cannot replace line"));
3345 break;
3346 }
3347 }
3348 else
3349 i = 0;
3350
3351 /* Now we may need to insert the remaining new old_len. If we do, we
3352 * must free the strings as we finish with them (we can't pass the
3353 * responsibility to vim in this case).
3354 */
3355 if (!PyErr_Occurred())
3356 {
3357 while (i < new_len)
3358 {
3359 if (ml_append((linenr_T)(lo + i - 1),
3360 (char_u *)array[i], 0, FALSE) == FAIL)
3361 {
3362 PyErr_SetVim(_("cannot insert line"));
3363 break;
3364 }
3365 vim_free(array[i]);
3366 ++i;
3367 ++extra;
3368 }
3369 }
3370
3371 /* Free any left-over old_len, as a result of an error */
3372 while (i < new_len)
3373 {
3374 vim_free(array[i]);
3375 ++i;
3376 }
3377
3378 /* Free the array of old_len. All of its contents have now
3379 * been dealt with (either freed, or the responsibility passed
3380 * to vim.
3381 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003382 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003383
3384 /* Adjust marks. Invalidate any which lie in the
3385 * changed range, and move any in the remainder of the buffer.
3386 */
3387 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
3388 (long)MAXLNUM, (long)extra);
3389 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
3390
Bram Moolenaar105bc352013-05-17 16:03:57 +02003391 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003392 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
3393
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003394 /* END of region without "return". */
Bram Moolenaar105bc352013-05-17 16:03:57 +02003395 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003396
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003397 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02003398 return FAIL;
3399
3400 if (len_change)
3401 *len_change = new_len - old_len;
3402
3403 return OK;
3404 }
3405 else
3406 {
3407 PyErr_BadArgument();
3408 return FAIL;
3409 }
3410}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003411
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003412/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003413 * The line number is in Vim format (1-based). The lines to be inserted are
3414 * given as a Python list of string objects or as a single string. The lines
3415 * to be added are checked for validity and correct format. Errors are
3416 * returned as a value of FAIL. The return value is OK on success.
3417 * If OK is returned and len_change is not NULL, *len_change
3418 * is set to the change in the buffer length.
3419 */
3420 static int
3421InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
3422{
3423 /* First of all, we check the type of the supplied Python object.
3424 * It must be a string or a list, or the call is in error.
3425 */
3426 if (PyString_Check(lines))
3427 {
3428 char *str = StringToLine(lines);
3429 buf_T *savebuf;
3430
3431 if (str == NULL)
3432 return FAIL;
3433
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003434 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003435 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003436 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003437
3438 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
3439 PyErr_SetVim(_("cannot save undo information"));
3440 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
3441 PyErr_SetVim(_("cannot insert line"));
3442 else
3443 appended_lines_mark((linenr_T)n, 1L);
3444
3445 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003446 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003447 update_screen(VALID);
3448
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003449 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003450 return FAIL;
3451
3452 if (len_change)
3453 *len_change = 1;
3454
3455 return OK;
3456 }
3457 else if (PyList_Check(lines))
3458 {
3459 PyInt i;
3460 PyInt size = PyList_Size(lines);
3461 char **array;
3462 buf_T *savebuf;
3463
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003464 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003465 if (array == NULL)
3466 {
3467 PyErr_NoMemory();
3468 return FAIL;
3469 }
3470
3471 for (i = 0; i < size; ++i)
3472 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003473 PyObject *line;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003474
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003475 if (!(line = PyList_GetItem(lines, i)) ||
3476 !(array[i] = StringToLine(line)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003477 {
3478 while (i)
3479 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003480 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003481 return FAIL;
3482 }
3483 }
3484
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003485 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003486 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003487 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003488
3489 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
3490 PyErr_SetVim(_("cannot save undo information"));
3491 else
3492 {
3493 for (i = 0; i < size; ++i)
3494 {
3495 if (ml_append((linenr_T)(n + i),
3496 (char_u *)array[i], 0, FALSE) == FAIL)
3497 {
3498 PyErr_SetVim(_("cannot insert line"));
3499
3500 /* Free the rest of the lines */
3501 while (i < size)
3502 vim_free(array[i++]);
3503
3504 break;
3505 }
3506 vim_free(array[i]);
3507 }
3508 if (i > 0)
3509 appended_lines_mark((linenr_T)n, (long)i);
3510 }
3511
3512 /* Free the array of lines. All of its contents have now
3513 * been freed.
3514 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003515 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003516
Bram Moolenaar105bc352013-05-17 16:03:57 +02003517 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003518 update_screen(VALID);
3519
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003520 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003521 return FAIL;
3522
3523 if (len_change)
3524 *len_change = size;
3525
3526 return OK;
3527 }
3528 else
3529 {
3530 PyErr_BadArgument();
3531 return FAIL;
3532 }
3533}
3534
3535/*
3536 * Common routines for buffers and line ranges
3537 * -------------------------------------------
3538 */
3539
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003540typedef struct
3541{
3542 PyObject_HEAD
3543 buf_T *buf;
3544} BufferObject;
3545
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003546 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003547CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003548{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003549 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003550 {
3551 PyErr_SetVim(_("attempt to refer to deleted buffer"));
3552 return -1;
3553 }
3554
3555 return 0;
3556}
3557
3558 static PyObject *
3559RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
3560{
3561 if (CheckBuffer(self))
3562 return NULL;
3563
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003564 if (end == -1)
3565 end = self->buf->b_ml.ml_line_count;
3566
Bram Moolenaarbd80f352013-05-12 21:16:23 +02003567 if (n < 0)
3568 n += end - start + 1;
3569
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003570 if (n < 0 || n > end - start)
3571 {
3572 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
3573 return NULL;
3574 }
3575
3576 return GetBufferLine(self->buf, n+start);
3577}
3578
3579 static PyObject *
3580RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
3581{
3582 PyInt size;
3583
3584 if (CheckBuffer(self))
3585 return NULL;
3586
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003587 if (end == -1)
3588 end = self->buf->b_ml.ml_line_count;
3589
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003590 size = end - start + 1;
3591
3592 if (lo < 0)
3593 lo = 0;
3594 else if (lo > size)
3595 lo = size;
3596 if (hi < 0)
3597 hi = 0;
3598 if (hi < lo)
3599 hi = lo;
3600 else if (hi > size)
3601 hi = size;
3602
3603 return GetBufferLineList(self->buf, lo+start, hi+start);
3604}
3605
3606 static PyInt
3607RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
3608{
3609 PyInt len_change;
3610
3611 if (CheckBuffer(self))
3612 return -1;
3613
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003614 if (end == -1)
3615 end = self->buf->b_ml.ml_line_count;
3616
Bram Moolenaarbd80f352013-05-12 21:16:23 +02003617 if (n < 0)
3618 n += end - start + 1;
3619
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003620 if (n < 0 || n > end - start)
3621 {
3622 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
3623 return -1;
3624 }
3625
3626 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
3627 return -1;
3628
3629 if (new_end)
3630 *new_end = end + len_change;
3631
3632 return 0;
3633}
3634
Bram Moolenaar19e60942011-06-19 00:27:51 +02003635 static PyInt
3636RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
3637{
3638 PyInt size;
3639 PyInt len_change;
3640
3641 /* Self must be a valid buffer */
3642 if (CheckBuffer(self))
3643 return -1;
3644
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003645 if (end == -1)
3646 end = self->buf->b_ml.ml_line_count;
3647
Bram Moolenaar19e60942011-06-19 00:27:51 +02003648 /* Sort out the slice range */
3649 size = end - start + 1;
3650
3651 if (lo < 0)
3652 lo = 0;
3653 else if (lo > size)
3654 lo = size;
3655 if (hi < 0)
3656 hi = 0;
3657 if (hi < lo)
3658 hi = lo;
3659 else if (hi > size)
3660 hi = size;
3661
3662 if (SetBufferLineList(self->buf, lo + start, hi + start,
3663 val, &len_change) == FAIL)
3664 return -1;
3665
3666 if (new_end)
3667 *new_end = end + len_change;
3668
3669 return 0;
3670}
3671
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003672
3673 static PyObject *
3674RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
3675{
3676 PyObject *lines;
3677 PyInt len_change;
3678 PyInt max;
3679 PyInt n;
3680
3681 if (CheckBuffer(self))
3682 return NULL;
3683
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003684 if (end == -1)
3685 end = self->buf->b_ml.ml_line_count;
3686
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003687 max = n = end - start + 1;
3688
3689 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
3690 return NULL;
3691
3692 if (n < 0 || n > max)
3693 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003694 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003695 return NULL;
3696 }
3697
3698 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
3699 return NULL;
3700
3701 if (new_end)
3702 *new_end = end + len_change;
3703
3704 Py_INCREF(Py_None);
3705 return Py_None;
3706}
3707
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003708/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003709 */
3710
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003711static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003712static PySequenceMethods RangeAsSeq;
3713static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003714
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003715typedef struct
3716{
3717 PyObject_HEAD
3718 BufferObject *buf;
3719 PyInt start;
3720 PyInt end;
3721} RangeObject;
3722
3723 static PyObject *
3724RangeNew(buf_T *buf, PyInt start, PyInt end)
3725{
3726 BufferObject *bufr;
3727 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003728 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003729 if (self == NULL)
3730 return NULL;
3731
3732 bufr = (BufferObject *)BufferNew(buf);
3733 if (bufr == NULL)
3734 {
3735 Py_DECREF(self);
3736 return NULL;
3737 }
3738 Py_INCREF(bufr);
3739
3740 self->buf = bufr;
3741 self->start = start;
3742 self->end = end;
3743
3744 return (PyObject *)(self);
3745}
3746
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003747 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003748RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003749{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003750 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003751 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02003752 PyObject_GC_Del((void *)(self));
3753}
3754
3755 static int
3756RangeTraverse(RangeObject *self, visitproc visit, void *arg)
3757{
3758 Py_VISIT(((PyObject *)(self->buf)));
3759 return 0;
3760}
3761
3762 static int
3763RangeClear(RangeObject *self)
3764{
3765 Py_CLEAR(self->buf);
3766 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003767}
3768
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003769 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003770RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003771{
3772 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003773 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003774 return -1; /* ??? */
3775
Bram Moolenaard6e39182013-05-21 18:30:34 +02003776 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003777}
3778
3779 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003780RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003781{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003782 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003783}
3784
3785 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003786RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003787{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003788 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003789}
3790
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003791static char *RangeAttrs[] = {
3792 "start", "end",
3793 NULL
3794};
3795
3796 static PyObject *
3797RangeDir(PyObject *self)
3798{
3799 return ObjectDir(self, RangeAttrs);
3800}
3801
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003802 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003803RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003804{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003805 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003806}
3807
3808 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003809RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003810{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003811 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003812 return PyString_FromFormat("<range object (for deleted buffer) at %p>",
3813 (self));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003814 else
3815 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003816 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003817
3818 if (name == NULL)
3819 name = "";
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003820
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003821 return PyString_FromFormat("<range %s (%d:%d)>",
3822 name, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003823 }
3824}
3825
3826static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003827 /* name, function, calling, documentation */
3828 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003829 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
3830 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003831};
3832
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003833static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003834static PySequenceMethods BufferAsSeq;
3835static PyMappingMethods BufferAsMapping;
3836
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003837 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02003838BufferNew(buf_T *buf)
3839{
3840 /* We need to handle deletion of buffers underneath us.
3841 * If we add a "b_python*_ref" field to the buf_T structure,
3842 * then we can get at it in buf_freeall() in vim. We then
3843 * need to create only ONE Python object per buffer - if
3844 * we try to create a second, just INCREF the existing one
3845 * and return it. The (single) Python object referring to
3846 * the buffer is stored in "b_python*_ref".
3847 * Question: what to do on a buf_freeall(). We'll probably
3848 * have to either delete the Python object (DECREF it to
3849 * zero - a bad idea, as it leaves dangling refs!) or
3850 * set the buf_T * value to an invalid value (-1?), which
3851 * means we need checks in all access functions... Bah.
3852 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003853 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003854 * b_python_ref and b_python3_ref fields respectively.
3855 */
3856
3857 BufferObject *self;
3858
3859 if (BUF_PYTHON_REF(buf) != NULL)
3860 {
3861 self = BUF_PYTHON_REF(buf);
3862 Py_INCREF(self);
3863 }
3864 else
3865 {
3866 self = PyObject_NEW(BufferObject, &BufferType);
3867 if (self == NULL)
3868 return NULL;
3869 self->buf = buf;
3870 BUF_PYTHON_REF(buf) = self;
3871 }
3872
3873 return (PyObject *)(self);
3874}
3875
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003876 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003877BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003878{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003879 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
3880 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003881
3882 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003883}
3884
Bram Moolenaar971db462013-05-12 18:44:48 +02003885 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003886BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02003887{
3888 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003889 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02003890 return -1; /* ??? */
3891
Bram Moolenaard6e39182013-05-21 18:30:34 +02003892 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02003893}
3894
3895 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003896BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02003897{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003898 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003899}
3900
3901 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003902BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02003903{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003904 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003905}
3906
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003907static char *BufferAttrs[] = {
3908 "name", "number", "vars", "options", "valid",
3909 NULL
3910};
3911
3912 static PyObject *
3913BufferDir(PyObject *self)
3914{
3915 return ObjectDir(self, BufferAttrs);
3916}
3917
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003918 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003919BufferAttrValid(BufferObject *self, char *name)
3920{
3921 PyObject *r;
3922
3923 if (strcmp(name, "valid") != 0)
3924 return NULL;
3925
3926 r = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
3927 Py_INCREF(r);
3928 return r;
3929}
3930
3931 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003932BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003933{
3934 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02003935 return PyString_FromString((self->buf->b_ffname == NULL
3936 ? "" : (char *) self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003937 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003938 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003939 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003940 return NEW_DICTIONARY(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003941 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003942 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
3943 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003944 else if (strcmp(name, "__members__") == 0)
3945 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003946 else
3947 return NULL;
3948}
3949
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003950 static int
3951BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
3952{
3953 if (CheckBuffer(self))
3954 return -1;
3955
3956 if (strcmp(name, "name") == 0)
3957 {
3958 char_u *val;
3959 aco_save_T aco;
3960 int r;
3961 PyObject *todecref;
3962
3963 if (!(val = StringToChars(valObject, &todecref)))
3964 return -1;
3965
3966 VimTryStart();
3967 /* Using aucmd_*: autocommands will be executed by rename_buffer */
3968 aucmd_prepbuf(&aco, self->buf);
3969 r = rename_buffer(val);
3970 aucmd_restbuf(&aco);
3971 Py_XDECREF(todecref);
3972 if (VimTryEnd())
3973 return -1;
3974
3975 if (r == FAIL)
3976 {
3977 PyErr_SetVim(_("failed to rename buffer"));
3978 return -1;
3979 }
3980 return 0;
3981 }
3982 else
3983 {
3984 PyErr_SetString(PyExc_AttributeError, name);
3985 return -1;
3986 }
3987}
3988
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003989 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003990BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003991{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003992 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003993}
3994
3995 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003996BufferMark(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003997{
3998 pos_T *posp;
3999 char *pmark;
4000 char mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02004001 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004002
Bram Moolenaard6e39182013-05-21 18:30:34 +02004003 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004004 return NULL;
4005
4006 if (!PyArg_ParseTuple(args, "s", &pmark))
4007 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004008
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004009 if (STRLEN(pmark) != 1)
4010 {
4011 PyErr_SetString(PyExc_ValueError,
4012 _("mark name must be a single character"));
4013 return NULL;
4014 }
4015
4016 mark = *pmark;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004017 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02004018 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004019 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02004020 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004021 if (VimTryEnd())
4022 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004023
4024 if (posp == NULL)
4025 {
4026 PyErr_SetVim(_("invalid mark name"));
4027 return NULL;
4028 }
4029
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004030 if (posp->lnum <= 0)
4031 {
4032 /* Or raise an error? */
4033 Py_INCREF(Py_None);
4034 return Py_None;
4035 }
4036
4037 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
4038}
4039
4040 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004041BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004042{
4043 PyInt start;
4044 PyInt end;
4045
Bram Moolenaard6e39182013-05-21 18:30:34 +02004046 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004047 return NULL;
4048
4049 if (!PyArg_ParseTuple(args, "nn", &start, &end))
4050 return NULL;
4051
Bram Moolenaard6e39182013-05-21 18:30:34 +02004052 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004053}
4054
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004055 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004056BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004057{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004058 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004059 return PyString_FromFormat("<buffer object (deleted) at %p>", self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004060 else
4061 {
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004062 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004063
4064 if (name == NULL)
4065 name = "";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004066
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004067 return PyString_FromFormat("<buffer %s>", name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004068 }
4069}
4070
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004071static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004072 /* name, function, calling, documentation */
4073 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
4074 {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
4075 {"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 +02004076 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
4077 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004078};
4079
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004080/*
4081 * Buffer list object - Implementation
4082 */
4083
4084static PyTypeObject BufMapType;
4085
4086typedef struct
4087{
4088 PyObject_HEAD
4089} BufMapObject;
4090
4091 static PyInt
4092BufMapLength(PyObject *self UNUSED)
4093{
4094 buf_T *b = firstbuf;
4095 PyInt n = 0;
4096
4097 while (b)
4098 {
4099 ++n;
4100 b = b->b_next;
4101 }
4102
4103 return n;
4104}
4105
4106 static PyObject *
4107BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
4108{
4109 buf_T *b;
4110 int bnr;
4111
4112#if PY_MAJOR_VERSION < 3
4113 if (PyInt_Check(keyObject))
4114 bnr = PyInt_AsLong(keyObject);
4115 else
4116#endif
4117 if (PyLong_Check(keyObject))
4118 bnr = PyLong_AsLong(keyObject);
4119 else
4120 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02004121 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004122 return NULL;
4123 }
4124
4125 b = buflist_findnr(bnr);
4126
4127 if (b)
4128 return BufferNew(b);
4129 else
4130 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02004131 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004132 return NULL;
4133 }
4134}
4135
4136 static void
4137BufMapIterDestruct(PyObject *buffer)
4138{
4139 /* Iteration was stopped before all buffers were processed */
4140 if (buffer)
4141 {
4142 Py_DECREF(buffer);
4143 }
4144}
4145
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004146 static int
4147BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
4148{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004149 if (buffer)
4150 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004151 return 0;
4152}
4153
4154 static int
4155BufMapIterClear(PyObject **buffer)
4156{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004157 if (*buffer)
4158 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004159 return 0;
4160}
4161
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004162 static PyObject *
4163BufMapIterNext(PyObject **buffer)
4164{
4165 PyObject *next;
4166 PyObject *r;
4167
4168 if (!*buffer)
4169 return NULL;
4170
4171 r = *buffer;
4172
4173 if (CheckBuffer((BufferObject *)(r)))
4174 {
4175 *buffer = NULL;
4176 return NULL;
4177 }
4178
4179 if (!((BufferObject *)(r))->buf->b_next)
4180 next = NULL;
4181 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
4182 return NULL;
4183 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02004184 /* Do not increment reference: we no longer hold it (decref), but whoever
4185 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004186 return r;
4187}
4188
4189 static PyObject *
4190BufMapIter(PyObject *self UNUSED)
4191{
4192 PyObject *buffer;
4193
4194 buffer = BufferNew(firstbuf);
4195 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004196 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
4197 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004198}
4199
4200static PyMappingMethods BufMapAsMapping = {
4201 (lenfunc) BufMapLength,
4202 (binaryfunc) BufMapItem,
4203 (objobjargproc) 0,
4204};
4205
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004206/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004207 */
4208
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004209static char *CurrentAttrs[] = {
4210 "buffer", "window", "line", "range", "tabpage",
4211 NULL
4212};
4213
4214 static PyObject *
4215CurrentDir(PyObject *self)
4216{
4217 return ObjectDir(self, CurrentAttrs);
4218}
4219
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004220 static PyObject *
4221CurrentGetattr(PyObject *self UNUSED, char *name)
4222{
4223 if (strcmp(name, "buffer") == 0)
4224 return (PyObject *)BufferNew(curbuf);
4225 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02004226 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004227 else if (strcmp(name, "tabpage") == 0)
4228 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004229 else if (strcmp(name, "line") == 0)
4230 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
4231 else if (strcmp(name, "range") == 0)
4232 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004233 else if (strcmp(name, "__members__") == 0)
4234 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004235 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004236#if PY_MAJOR_VERSION < 3
4237 return Py_FindMethod(WindowMethods, self, name);
4238#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004239 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004240#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004241}
4242
4243 static int
4244CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
4245{
4246 if (strcmp(name, "line") == 0)
4247 {
4248 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
4249 return -1;
4250
4251 return 0;
4252 }
Bram Moolenaare7614592013-05-15 15:51:08 +02004253 else if (strcmp(name, "buffer") == 0)
4254 {
4255 int count;
4256
4257 if (value->ob_type != &BufferType)
4258 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004259 PyErr_SetString(PyExc_TypeError, _("expected vim.Buffer object"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004260 return -1;
4261 }
4262
4263 if (CheckBuffer((BufferObject *)(value)))
4264 return -1;
4265 count = ((BufferObject *)(value))->buf->b_fnum;
4266
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004267 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004268 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
4269 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004270 if (VimTryEnd())
4271 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02004272 PyErr_SetVim(_("failed to switch to given buffer"));
4273 return -1;
4274 }
4275
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004276 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004277 }
4278 else if (strcmp(name, "window") == 0)
4279 {
4280 int count;
4281
4282 if (value->ob_type != &WindowType)
4283 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004284 PyErr_SetString(PyExc_TypeError, _("expected vim.Window object"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004285 return -1;
4286 }
4287
4288 if (CheckWindow((WindowObject *)(value)))
4289 return -1;
4290 count = get_win_number(((WindowObject *)(value))->win, firstwin);
4291
4292 if (!count)
4293 {
4294 PyErr_SetString(PyExc_ValueError,
4295 _("failed to find window in the current tab page"));
4296 return -1;
4297 }
4298
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004299 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004300 win_goto(((WindowObject *)(value))->win);
4301 if (((WindowObject *)(value))->win != curwin)
4302 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004303 if (VimTryEnd())
4304 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02004305 PyErr_SetString(PyExc_RuntimeError,
4306 _("did not switch to the specified window"));
4307 return -1;
4308 }
4309
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004310 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004311 }
4312 else if (strcmp(name, "tabpage") == 0)
4313 {
4314 if (value->ob_type != &TabPageType)
4315 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004316 PyErr_SetString(PyExc_TypeError, _("expected vim.TabPage object"));
Bram Moolenaare7614592013-05-15 15:51:08 +02004317 return -1;
4318 }
4319
4320 if (CheckTabPage((TabPageObject *)(value)))
4321 return -1;
4322
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004323 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004324 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
4325 if (((TabPageObject *)(value))->tab != curtab)
4326 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004327 if (VimTryEnd())
4328 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02004329 PyErr_SetString(PyExc_RuntimeError,
4330 _("did not switch to the specified tab page"));
4331 return -1;
4332 }
4333
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004334 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004335 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004336 else
4337 {
4338 PyErr_SetString(PyExc_AttributeError, name);
4339 return -1;
4340 }
4341}
4342
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004343static struct PyMethodDef CurrentMethods[] = {
4344 /* name, function, calling, documentation */
4345 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
4346 { NULL, NULL, 0, NULL}
4347};
4348
Bram Moolenaardb913952012-06-29 12:54:53 +02004349 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004350init_range_cmd(exarg_T *eap)
4351{
4352 RangeStart = eap->line1;
4353 RangeEnd = eap->line2;
4354}
4355
4356 static void
4357init_range_eval(typval_T *rettv UNUSED)
4358{
4359 RangeStart = (PyInt) curwin->w_cursor.lnum;
4360 RangeEnd = RangeStart;
4361}
4362
4363 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004364run_cmd(const char *cmd, void *arg UNUSED
4365#ifdef PY_CAN_RECURSE
4366 , PyGILState_STATE *pygilstate UNUSED
4367#endif
4368 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004369{
4370 PyRun_SimpleString((char *) cmd);
4371}
4372
4373static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
4374static int code_hdr_len = 30;
4375
4376 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004377run_do(const char *cmd, void *arg UNUSED
4378#ifdef PY_CAN_RECURSE
4379 , PyGILState_STATE *pygilstate
4380#endif
4381 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004382{
4383 PyInt lnum;
4384 size_t len;
4385 char *code;
4386 int status;
4387 PyObject *pyfunc, *pymain;
4388
Bram Moolenaar4ac66762013-05-28 22:31:46 +02004389 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004390 {
4391 EMSG(_("cannot save undo information"));
4392 return;
4393 }
4394
4395 len = code_hdr_len + STRLEN(cmd);
4396 code = PyMem_New(char, len + 1);
4397 memcpy(code, code_hdr, code_hdr_len);
4398 STRCPY(code + code_hdr_len, cmd);
4399 status = PyRun_SimpleString(code);
4400 PyMem_Free(code);
4401
4402 if (status)
4403 {
4404 EMSG(_("failed to run the code"));
4405 return;
4406 }
4407
4408 status = 0;
4409 pymain = PyImport_AddModule("__main__");
4410 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004411#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004412 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004413#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004414
4415 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
4416 {
4417 PyObject *line, *linenr, *ret;
4418
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004419#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004420 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004421#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004422 if (!(line = GetBufferLine(curbuf, lnum)))
4423 goto err;
4424 if (!(linenr = PyInt_FromLong((long) lnum)))
4425 {
4426 Py_DECREF(line);
4427 goto err;
4428 }
4429 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
4430 Py_DECREF(line);
4431 Py_DECREF(linenr);
4432 if (!ret)
4433 goto err;
4434
4435 if (ret != Py_None)
4436 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
4437 goto err;
4438
4439 Py_XDECREF(ret);
4440 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004441#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004442 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004443#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004444 }
4445 goto out;
4446err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004447#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004448 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004449#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004450 PyErr_PrintEx(0);
4451 PythonIO_Flush();
4452 status = 1;
4453out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004454#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004455 if (!status)
4456 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004457#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004458 Py_DECREF(pyfunc);
4459 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
4460 if (status)
4461 return;
4462 check_cursor();
4463 update_curbuf(NOT_VALID);
4464}
4465
4466 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004467run_eval(const char *cmd, typval_T *rettv
4468#ifdef PY_CAN_RECURSE
4469 , PyGILState_STATE *pygilstate UNUSED
4470#endif
4471 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004472{
4473 PyObject *r;
4474
4475 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
4476 if (r == NULL)
4477 {
4478 if (PyErr_Occurred() && !msg_silent)
4479 PyErr_PrintEx(0);
4480 EMSG(_("E858: Eval did not return a valid python object"));
4481 }
4482 else
4483 {
4484 if (ConvertFromPyObject(r, rettv) == -1)
4485 EMSG(_("E859: Failed to convert returned python object to vim value"));
4486 Py_DECREF(r);
4487 }
4488 PyErr_Clear();
4489}
4490
4491 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02004492set_ref_in_py(const int copyID)
4493{
4494 pylinkedlist_T *cur;
4495 dict_T *dd;
4496 list_T *ll;
4497
4498 if (lastdict != NULL)
4499 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
4500 {
4501 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
4502 if (dd->dv_copyID != copyID)
4503 {
4504 dd->dv_copyID = copyID;
4505 set_ref_in_ht(&dd->dv_hashtab, copyID);
4506 }
4507 }
4508
4509 if (lastlist != NULL)
4510 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
4511 {
4512 ll = ((ListObject *) (cur->pll_obj))->list;
4513 if (ll->lv_copyID != copyID)
4514 {
4515 ll->lv_copyID = copyID;
4516 set_ref_in_list(ll, copyID);
4517 }
4518 }
4519}
4520
4521 static int
4522set_string_copy(char_u *str, typval_T *tv)
4523{
4524 tv->vval.v_string = vim_strsave(str);
4525 if (tv->vval.v_string == NULL)
4526 {
4527 PyErr_NoMemory();
4528 return -1;
4529 }
4530 return 0;
4531}
4532
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004533 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004534pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004535{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004536 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004537 char_u *key;
4538 dictitem_T *di;
4539 PyObject *keyObject;
4540 PyObject *valObject;
4541 Py_ssize_t iter = 0;
4542
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004543 if (!(dict = dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004544 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004545
4546 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004547 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004548
4549 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
4550 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004551 PyObject *todecref = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004552
Bram Moolenaara03e6312013-05-29 22:49:26 +02004553 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004554 {
4555 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004556 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004557 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004558
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004559 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004560 {
4561 dict_unref(dict);
4562 return -1;
4563 }
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004564 if (*key == NUL)
4565 {
4566 dict_unref(dict);
4567 Py_XDECREF(todecref);
4568 return -1;
4569 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004570
4571 di = dictitem_alloc(key);
4572
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004573 Py_XDECREF(todecref);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004574
4575 if (di == NULL)
4576 {
4577 PyErr_NoMemory();
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004578 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004579 return -1;
4580 }
4581 di->di_tv.v_lock = 0;
4582
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004583 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004584 {
4585 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004586 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004587 return -1;
4588 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004589
4590 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004591 {
Bram Moolenaara03e6312013-05-29 22:49:26 +02004592 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004593 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004594 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004595 PyErr_SetVim(_("failed to add key to dictionary"));
4596 return -1;
4597 }
4598 }
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004599
4600 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004601 return 0;
4602}
4603
4604 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004605pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004606{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004607 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004608 char_u *key;
4609 dictitem_T *di;
4610 PyObject *list;
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004611 PyObject *iterator;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004612 PyObject *keyObject;
4613 PyObject *valObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004614
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004615 if (!(dict = dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004616 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004617
4618 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004619 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004620
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004621 if (!(list = PyMapping_Keys(obj)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004622 {
4623 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004624 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004625 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004626
4627 if (!(iterator = PyObject_GetIter(list)))
4628 {
4629 dict_unref(dict);
4630 Py_DECREF(list);
4631 return -1;
4632 }
4633 Py_DECREF(list);
4634
4635 while ((keyObject = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004636 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004637 PyObject *todecref;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004638
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004639 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004640 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004641 Py_DECREF(keyObject);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004642 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004643 dict_unref(dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004644 return -1;
4645 }
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004646 if (*key == NUL)
4647 {
4648 Py_DECREF(keyObject);
4649 Py_DECREF(iterator);
4650 Py_XDECREF(todecref);
4651 dict_unref(dict);
4652 return -1;
4653 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004654
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004655 if (!(valObject = PyObject_GetItem(obj, keyObject)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004656 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004657 Py_DECREF(keyObject);
4658 Py_DECREF(iterator);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004659 Py_XDECREF(todecref);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004660 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004661 return -1;
4662 }
4663
4664 di = dictitem_alloc(key);
4665
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004666 Py_DECREF(keyObject);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02004667 Py_XDECREF(todecref);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004668
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004669 if (di == NULL)
4670 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004671 Py_DECREF(iterator);
4672 Py_DECREF(valObject);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004673 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004674 PyErr_NoMemory();
4675 return -1;
4676 }
4677 di->di_tv.v_lock = 0;
4678
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004679 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004680 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004681 Py_DECREF(iterator);
4682 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004683 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004684 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004685 return -1;
4686 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02004687
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004688 Py_DECREF(valObject);
4689
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004690 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004691 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004692 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004693 dictitem_free(di);
4694 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004695 PyErr_SetVim(_("failed to add key to dictionary"));
4696 return -1;
4697 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004698 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004699 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004700 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004701 return 0;
4702}
4703
4704 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004705pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004706{
4707 list_T *l;
4708
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004709 if (!(l = py_list_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004710 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004711
4712 tv->v_type = VAR_LIST;
4713 tv->vval.v_list = l;
4714
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004715 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004716 {
4717 list_unref(l);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004718 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004719 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004720
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004721 --l->lv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004722 return 0;
4723}
4724
Bram Moolenaardb913952012-06-29 12:54:53 +02004725typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
4726
4727 static int
4728convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004729 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02004730{
4731 PyObject *capsule;
4732 char hexBuf[sizeof(void *) * 2 + 3];
4733
4734 sprintf(hexBuf, "%p", obj);
4735
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004736# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004737 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004738# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004739 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004740# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02004741 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02004742 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004743# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004744 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02004745# else
4746 capsule = PyCObject_FromVoidPtr(tv, NULL);
4747# endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02004748 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
4749 {
4750 Py_DECREF(capsule);
4751 tv->v_type = VAR_UNKNOWN;
4752 return -1;
4753 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004754 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02004755 {
4756 tv->v_type = VAR_UNKNOWN;
4757 return -1;
4758 }
4759 /* As we are not using copy_tv which increments reference count we must
4760 * do it ourself. */
4761 switch(tv->v_type)
4762 {
4763 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
4764 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
4765 }
4766 }
4767 else
4768 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004769 typval_T *v;
4770
4771# ifdef PY_USE_CAPSULE
4772 v = PyCapsule_GetPointer(capsule, NULL);
4773# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004774 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004775# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004776 copy_tv(v, tv);
4777 }
4778 return 0;
4779}
4780
4781 static int
Bram Moolenaara9922d62013-05-30 13:01:18 +02004782ConvertFromPyMapping(PyObject *obj, typval_T *tv)
4783{
4784 PyObject *lookup_dict;
4785 int r;
4786
4787 if (!(lookup_dict = PyDict_New()))
4788 return -1;
4789
4790 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
4791 {
4792 tv->v_type = VAR_DICT;
4793 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
4794 ++tv->vval.v_dict->dv_refcount;
4795 r = 0;
4796 }
4797 else if (PyDict_Check(obj))
4798 r = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
4799 else if (PyMapping_Check(obj))
4800 r = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
4801 else
4802 {
4803 PyErr_SetString(PyExc_TypeError,
4804 _("unable to convert object to vim dictionary"));
4805 r = -1;
4806 }
4807 Py_DECREF(lookup_dict);
4808 return r;
4809}
4810
4811 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02004812ConvertFromPyObject(PyObject *obj, typval_T *tv)
4813{
4814 PyObject *lookup_dict;
4815 int r;
4816
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02004817 if (!(lookup_dict = PyDict_New()))
4818 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004819 r = _ConvertFromPyObject(obj, tv, lookup_dict);
4820 Py_DECREF(lookup_dict);
4821 return r;
4822}
4823
4824 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004825_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02004826{
Bram Moolenaara9922d62013-05-30 13:01:18 +02004827 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
Bram Moolenaardb913952012-06-29 12:54:53 +02004828 {
4829 tv->v_type = VAR_DICT;
4830 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
4831 ++tv->vval.v_dict->dv_refcount;
4832 }
4833 else if (obj->ob_type == &ListType)
4834 {
4835 tv->v_type = VAR_LIST;
4836 tv->vval.v_list = (((ListObject *)(obj))->list);
4837 ++tv->vval.v_list->lv_refcount;
4838 }
4839 else if (obj->ob_type == &FunctionType)
4840 {
4841 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
4842 return -1;
4843
4844 tv->v_type = VAR_FUNC;
4845 func_ref(tv->vval.v_string);
4846 }
Bram Moolenaardb913952012-06-29 12:54:53 +02004847 else if (PyBytes_Check(obj))
4848 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004849 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02004850
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004851 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
4852 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004853 if (result == NULL)
4854 return -1;
4855
4856 if (set_string_copy(result, tv) == -1)
4857 return -1;
4858
4859 tv->v_type = VAR_STRING;
4860 }
4861 else if (PyUnicode_Check(obj))
4862 {
4863 PyObject *bytes;
4864 char_u *result;
4865
Bram Moolenaardb913952012-06-29 12:54:53 +02004866 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
4867 if (bytes == NULL)
4868 return -1;
4869
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004870 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
4871 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004872 if (result == NULL)
4873 return -1;
4874
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004875 if (set_string_copy(result, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02004876 {
4877 Py_XDECREF(bytes);
4878 return -1;
4879 }
4880 Py_XDECREF(bytes);
4881
4882 tv->v_type = VAR_STRING;
4883 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02004884#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02004885 else if (PyInt_Check(obj))
4886 {
4887 tv->v_type = VAR_NUMBER;
4888 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
4889 }
4890#endif
4891 else if (PyLong_Check(obj))
4892 {
4893 tv->v_type = VAR_NUMBER;
4894 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
4895 }
4896 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004897 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004898#ifdef FEAT_FLOAT
4899 else if (PyFloat_Check(obj))
4900 {
4901 tv->v_type = VAR_FLOAT;
4902 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
4903 }
4904#endif
Bram Moolenaarbcb40972013-05-30 13:22:13 +02004905 else if (PyObject_HasAttrString(obj, "keys"))
4906 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02004907 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004908 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004909 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004910 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004911 else
4912 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02004913 PyErr_SetString(PyExc_TypeError,
4914 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02004915 return -1;
4916 }
4917 return 0;
4918}
4919
4920 static PyObject *
4921ConvertToPyObject(typval_T *tv)
4922{
4923 if (tv == NULL)
4924 {
4925 PyErr_SetVim(_("NULL reference passed"));
4926 return NULL;
4927 }
4928 switch (tv->v_type)
4929 {
4930 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004931 return PyBytes_FromString(tv->vval.v_string == NULL
4932 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004933 case VAR_NUMBER:
4934 return PyLong_FromLong((long) tv->vval.v_number);
4935#ifdef FEAT_FLOAT
4936 case VAR_FLOAT:
4937 return PyFloat_FromDouble((double) tv->vval.v_float);
4938#endif
4939 case VAR_LIST:
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02004940 return NEW_LIST(tv->vval.v_list);
Bram Moolenaardb913952012-06-29 12:54:53 +02004941 case VAR_DICT:
Bram Moolenaara9922d62013-05-30 13:01:18 +02004942 return NEW_DICTIONARY(tv->vval.v_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004943 case VAR_FUNC:
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02004944 return NEW_FUNCTION(tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004945 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004946 case VAR_UNKNOWN:
4947 Py_INCREF(Py_None);
4948 return Py_None;
4949 default:
4950 PyErr_SetVim(_("internal error: invalid value type"));
4951 return NULL;
4952 }
4953}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004954
4955typedef struct
4956{
4957 PyObject_HEAD
4958} CurrentObject;
4959static PyTypeObject CurrentType;
4960
4961 static void
4962init_structs(void)
4963{
4964 vim_memset(&OutputType, 0, sizeof(OutputType));
4965 OutputType.tp_name = "vim.message";
4966 OutputType.tp_basicsize = sizeof(OutputObject);
4967 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
4968 OutputType.tp_doc = "vim message object";
4969 OutputType.tp_methods = OutputMethods;
4970#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004971 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
4972 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004973 OutputType.tp_alloc = call_PyType_GenericAlloc;
4974 OutputType.tp_new = call_PyType_GenericNew;
4975 OutputType.tp_free = call_PyObject_Free;
4976#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004977 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
4978 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004979#endif
4980
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004981 vim_memset(&IterType, 0, sizeof(IterType));
4982 IterType.tp_name = "vim.iter";
4983 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02004984 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004985 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004986 IterType.tp_iter = (getiterfunc)IterIter;
4987 IterType.tp_iternext = (iternextfunc)IterNext;
4988 IterType.tp_dealloc = (destructor)IterDestructor;
4989 IterType.tp_traverse = (traverseproc)IterTraverse;
4990 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004991
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004992 vim_memset(&BufferType, 0, sizeof(BufferType));
4993 BufferType.tp_name = "vim.buffer";
4994 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004995 BufferType.tp_dealloc = (destructor)BufferDestructor;
4996 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004997 BufferType.tp_as_sequence = &BufferAsSeq;
4998 BufferType.tp_as_mapping = &BufferAsMapping;
4999 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
5000 BufferType.tp_doc = "vim buffer object";
5001 BufferType.tp_methods = BufferMethods;
5002#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005003 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005004 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005005 BufferType.tp_alloc = call_PyType_GenericAlloc;
5006 BufferType.tp_new = call_PyType_GenericNew;
5007 BufferType.tp_free = call_PyObject_Free;
5008#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005009 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005010 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005011#endif
5012
5013 vim_memset(&WindowType, 0, sizeof(WindowType));
5014 WindowType.tp_name = "vim.window";
5015 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005016 WindowType.tp_dealloc = (destructor)WindowDestructor;
5017 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005018 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005019 WindowType.tp_doc = "vim Window object";
5020 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005021 WindowType.tp_traverse = (traverseproc)WindowTraverse;
5022 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005023#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005024 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
5025 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005026 WindowType.tp_alloc = call_PyType_GenericAlloc;
5027 WindowType.tp_new = call_PyType_GenericNew;
5028 WindowType.tp_free = call_PyObject_Free;
5029#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005030 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
5031 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005032#endif
5033
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005034 vim_memset(&TabPageType, 0, sizeof(TabPageType));
5035 TabPageType.tp_name = "vim.tabpage";
5036 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005037 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
5038 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005039 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
5040 TabPageType.tp_doc = "vim tab page object";
5041 TabPageType.tp_methods = TabPageMethods;
5042#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005043 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005044 TabPageType.tp_alloc = call_PyType_GenericAlloc;
5045 TabPageType.tp_new = call_PyType_GenericNew;
5046 TabPageType.tp_free = call_PyObject_Free;
5047#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005048 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005049#endif
5050
Bram Moolenaardfa38d42013-05-15 13:38:47 +02005051 vim_memset(&BufMapType, 0, sizeof(BufMapType));
5052 BufMapType.tp_name = "vim.bufferlist";
5053 BufMapType.tp_basicsize = sizeof(BufMapObject);
5054 BufMapType.tp_as_mapping = &BufMapAsMapping;
5055 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005056 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005057 BufferType.tp_doc = "vim buffer list";
5058
5059 vim_memset(&WinListType, 0, sizeof(WinListType));
5060 WinListType.tp_name = "vim.windowlist";
5061 WinListType.tp_basicsize = sizeof(WinListType);
5062 WinListType.tp_as_sequence = &WinListAsSeq;
5063 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
5064 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005065 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005066
5067 vim_memset(&TabListType, 0, sizeof(TabListType));
5068 TabListType.tp_name = "vim.tabpagelist";
5069 TabListType.tp_basicsize = sizeof(TabListType);
5070 TabListType.tp_as_sequence = &TabListAsSeq;
5071 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
5072 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005073
5074 vim_memset(&RangeType, 0, sizeof(RangeType));
5075 RangeType.tp_name = "vim.range";
5076 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005077 RangeType.tp_dealloc = (destructor)RangeDestructor;
5078 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005079 RangeType.tp_as_sequence = &RangeAsSeq;
5080 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005081 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005082 RangeType.tp_doc = "vim Range object";
5083 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02005084 RangeType.tp_traverse = (traverseproc)RangeTraverse;
5085 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005086#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005087 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005088 RangeType.tp_alloc = call_PyType_GenericAlloc;
5089 RangeType.tp_new = call_PyType_GenericNew;
5090 RangeType.tp_free = call_PyObject_Free;
5091#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005092 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005093#endif
5094
5095 vim_memset(&CurrentType, 0, sizeof(CurrentType));
5096 CurrentType.tp_name = "vim.currentdata";
5097 CurrentType.tp_basicsize = sizeof(CurrentObject);
5098 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
5099 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005100 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005101#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005102 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
5103 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005104#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005105 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
5106 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005107#endif
5108
5109 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
5110 DictionaryType.tp_name = "vim.dictionary";
5111 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005112 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005113 DictionaryType.tp_as_sequence = &DictionaryAsSeq;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005114 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005115 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005116 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
5117 DictionaryType.tp_methods = DictionaryMethods;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005118 DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
5119 DictionaryType.tp_new = (newfunc)DictionaryConstructor;
5120 DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005121#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005122 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
5123 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005124#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005125 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
5126 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005127#endif
5128
5129 vim_memset(&ListType, 0, sizeof(ListType));
5130 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005131 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005132 ListType.tp_basicsize = sizeof(ListObject);
5133 ListType.tp_as_sequence = &ListAsSeq;
5134 ListType.tp_as_mapping = &ListAsMapping;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005135 ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005136 ListType.tp_doc = "list pushing modifications to vim structure";
5137 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005138 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005139 ListType.tp_new = (newfunc)ListConstructor;
5140 ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005141#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005142 ListType.tp_getattro = (getattrofunc)ListGetattro;
5143 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005144#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005145 ListType.tp_getattr = (getattrfunc)ListGetattr;
5146 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005147#endif
5148
5149 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005150 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005151 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005152 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
5153 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005154 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005155 FunctionType.tp_doc = "object that calls vim function";
5156 FunctionType.tp_methods = FunctionMethods;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02005157 FunctionType.tp_repr = (reprfunc)FunctionRepr;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005158 FunctionType.tp_new = (newfunc)FunctionConstructor;
5159 FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005160#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005161 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005162#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005163 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005164#endif
5165
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005166 vim_memset(&OptionsType, 0, sizeof(OptionsType));
5167 OptionsType.tp_name = "vim.options";
5168 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005169 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005170 OptionsType.tp_doc = "object for manipulating options";
5171 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005172 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
5173 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
5174 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005175
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005176#if PY_MAJOR_VERSION >= 3
5177 vim_memset(&vimmodule, 0, sizeof(vimmodule));
5178 vimmodule.m_name = "vim";
5179 vimmodule.m_doc = "Vim Python interface\n";
5180 vimmodule.m_size = -1;
5181 vimmodule.m_methods = VimMethods;
5182#endif
5183}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005184
5185#define PYTYPE_READY(type) \
5186 if (PyType_Ready(&type)) \
5187 return -1;
5188
5189 static int
5190init_types()
5191{
5192 PYTYPE_READY(IterType);
5193 PYTYPE_READY(BufferType);
5194 PYTYPE_READY(RangeType);
5195 PYTYPE_READY(WindowType);
5196 PYTYPE_READY(TabPageType);
5197 PYTYPE_READY(BufMapType);
5198 PYTYPE_READY(WinListType);
5199 PYTYPE_READY(TabListType);
5200 PYTYPE_READY(CurrentType);
5201 PYTYPE_READY(DictionaryType);
5202 PYTYPE_READY(ListType);
5203 PYTYPE_READY(FunctionType);
5204 PYTYPE_READY(OptionsType);
5205 PYTYPE_READY(OutputType);
5206 return 0;
5207}
5208
5209static BufMapObject TheBufferMap =
5210{
5211 PyObject_HEAD_INIT(&BufMapType)
5212};
5213
5214static WinListObject TheWindowList =
5215{
5216 PyObject_HEAD_INIT(&WinListType)
5217 NULL
5218};
5219
5220static CurrentObject TheCurrent =
5221{
5222 PyObject_HEAD_INIT(&CurrentType)
5223};
5224
5225static TabListObject TheTabPageList =
5226{
5227 PyObject_HEAD_INIT(&TabListType)
5228};
5229
5230static struct numeric_constant {
5231 char *name;
5232 int value;
5233} numeric_constants[] = {
5234 {"VAR_LOCKED", VAR_LOCKED},
5235 {"VAR_FIXED", VAR_FIXED},
5236 {"VAR_SCOPE", VAR_SCOPE},
5237 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
5238};
5239
5240static struct object_constant {
5241 char *name;
5242 PyObject *value;
5243} object_constants[] = {
5244 {"buffers", (PyObject *)(void *)&TheBufferMap},
5245 {"windows", (PyObject *)(void *)&TheWindowList},
5246 {"tabpages", (PyObject *)(void *)&TheTabPageList},
5247 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02005248
5249 {"Buffer", (PyObject *)&BufferType},
5250 {"Range", (PyObject *)&RangeType},
5251 {"Window", (PyObject *)&WindowType},
5252 {"TabPage", (PyObject *)&TabPageType},
5253 {"Dictionary", (PyObject *)&DictionaryType},
5254 {"List", (PyObject *)&ListType},
5255 {"Function", (PyObject *)&FunctionType},
5256 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005257};
5258
5259typedef int (*object_adder)(PyObject *, const char *, PyObject *);
5260
5261#define ADD_OBJECT(m, name, obj) \
5262 if (add_object(m, name, obj)) \
5263 return -1;
5264
5265#define ADD_CHECKED_OBJECT(m, name, obj) \
5266 { \
5267 PyObject *value = obj; \
5268 if (!value) \
5269 return -1; \
5270 ADD_OBJECT(m, name, value); \
5271 }
5272
5273 static int
5274populate_module(PyObject *m, object_adder add_object)
5275{
5276 int i;
5277
5278 for (i = 0; i < (int)(sizeof(numeric_constants)
5279 / sizeof(struct numeric_constant));
5280 ++i)
5281 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
5282 PyInt_FromLong(numeric_constants[i].value));
5283
5284 for (i = 0; i < (int)(sizeof(object_constants)
5285 / sizeof(struct object_constant));
5286 ++i)
5287 {
5288 PyObject *value;
5289
5290 value = object_constants[i].value;
5291 Py_INCREF(value);
5292 ADD_OBJECT(m, object_constants[i].name, value);
5293 }
5294
5295 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
5296 return -1;
5297 ADD_OBJECT(m, "error", VimError);
5298
Bram Moolenaara9922d62013-05-30 13:01:18 +02005299 ADD_CHECKED_OBJECT(m, "vars", NEW_DICTIONARY(&globvardict));
5300 ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005301 ADD_CHECKED_OBJECT(m, "options",
5302 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
5303 return 0;
5304}