blob: 4905bed68d0493f5abdd889c4102933d8d762d38 [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
25
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020026#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
27
28#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
29#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020030#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020031
32static int ConvertFromPyObject(PyObject *, typval_T *);
33static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
34
35static PyInt RangeStart;
36static PyInt RangeEnd;
37
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020038/*
39 * obtain a lock on the Vim data structures
40 */
41 static void
42Python_Lock_Vim(void)
43{
44}
45
46/*
47 * release a lock on the Vim data structures
48 */
49 static void
50Python_Release_Vim(void)
51{
52}
53
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020054/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020055 */
56
Bram Moolenaar2eea1982010-09-21 16:49:37 +020057/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020058typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020059
60static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020061
62typedef struct
63{
64 PyObject_HEAD
65 long softspace;
66 long error;
67} OutputObject;
68
Bram Moolenaar77045652012-09-21 13:46:06 +020069 static int
70OutputSetattr(PyObject *self, char *name, PyObject *val)
71{
72 if (val == NULL)
73 {
Bram Moolenaar8661b172013-05-15 15:44:28 +020074 PyErr_SetString(PyExc_AttributeError,
75 _("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +020076 return -1;
77 }
78
79 if (strcmp(name, "softspace") == 0)
80 {
81 if (!PyInt_Check(val))
82 {
83 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
84 return -1;
85 }
86
87 ((OutputObject *)(self))->softspace = PyInt_AsLong(val);
88 return 0;
89 }
90
91 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
92 return -1;
93}
94
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020095/* Buffer IO, we write one whole line at a time. */
96static garray_T io_ga = {0, 0, 1, 80, NULL};
97static writefn old_fn = NULL;
98
99 static void
100PythonIO_Flush(void)
101{
102 if (old_fn != NULL && io_ga.ga_len > 0)
103 {
104 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
105 old_fn((char_u *)io_ga.ga_data);
106 }
107 io_ga.ga_len = 0;
108}
109
110 static void
111writer(writefn fn, char_u *str, PyInt n)
112{
113 char_u *ptr;
114
115 /* Flush when switching output function. */
116 if (fn != old_fn)
117 PythonIO_Flush();
118 old_fn = fn;
119
120 /* Write each NL separated line. Text after the last NL is kept for
121 * writing later. */
122 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
123 {
124 PyInt len = ptr - str;
125
126 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
127 break;
128
129 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
130 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
131 fn((char_u *)io_ga.ga_data);
132 str = ptr + 1;
133 n -= len + 1;
134 io_ga.ga_len = 0;
135 }
136
137 /* Put the remaining text into io_ga for later printing. */
138 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
139 {
140 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
141 io_ga.ga_len += (int)n;
142 }
143}
144
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200145 static PyObject *
146OutputWrite(PyObject *self, PyObject *args)
147{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200148 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200149 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200150 int error = ((OutputObject *)(self))->error;
151
Bram Moolenaar27564802011-09-07 19:30:21 +0200152 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200153 return NULL;
154
155 Py_BEGIN_ALLOW_THREADS
156 Python_Lock_Vim();
157 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
158 Python_Release_Vim();
159 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200160 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200161
162 Py_INCREF(Py_None);
163 return Py_None;
164}
165
166 static PyObject *
167OutputWritelines(PyObject *self, PyObject *args)
168{
169 PyInt n;
170 PyInt i;
171 PyObject *list;
172 int error = ((OutputObject *)(self))->error;
173
174 if (!PyArg_ParseTuple(args, "O", &list))
175 return NULL;
176 Py_INCREF(list);
177
Bram Moolenaardb913952012-06-29 12:54:53 +0200178 if (!PyList_Check(list))
179 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200180 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
181 Py_DECREF(list);
182 return NULL;
183 }
184
185 n = PyList_Size(list);
186
187 for (i = 0; i < n; ++i)
188 {
189 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200190 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200191 PyInt len;
192
Bram Moolenaardb913952012-06-29 12:54:53 +0200193 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
194 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200195 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
196 Py_DECREF(list);
197 return NULL;
198 }
199
200 Py_BEGIN_ALLOW_THREADS
201 Python_Lock_Vim();
202 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
203 Python_Release_Vim();
204 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200205 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200206 }
207
208 Py_DECREF(list);
209 Py_INCREF(Py_None);
210 return Py_None;
211}
212
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100213 static PyObject *
214OutputFlush(PyObject *self UNUSED, PyObject *args UNUSED)
215{
216 /* do nothing */
217 Py_INCREF(Py_None);
218 return Py_None;
219}
220
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200221/***************/
222
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200223static struct PyMethodDef OutputMethods[] = {
224 /* name, function, calling, documentation */
225 {"write", OutputWrite, 1, ""},
226 {"writelines", OutputWritelines, 1, ""},
227 {"flush", OutputFlush, 1, ""},
228 { NULL, NULL, 0, NULL}
229};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200230
231static OutputObject Output =
232{
233 PyObject_HEAD_INIT(&OutputType)
234 0,
235 0
236};
237
238static OutputObject Error =
239{
240 PyObject_HEAD_INIT(&OutputType)
241 0,
242 1
243};
244
245 static int
246PythonIO_Init_io(void)
247{
248 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
249 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
250
251 if (PyErr_Occurred())
252 {
253 EMSG(_("E264: Python: Error initialising I/O objects"));
254 return -1;
255 }
256
257 return 0;
258}
259
260
261static PyObject *VimError;
262
263/* Check to see whether a Vim error has been reported, or a keyboard
264 * interrupt has been detected.
265 */
266 static int
267VimErrorCheck(void)
268{
269 if (got_int)
270 {
271 PyErr_SetNone(PyExc_KeyboardInterrupt);
272 return 1;
273 }
274 else if (did_emsg && !PyErr_Occurred())
275 {
276 PyErr_SetNone(VimError);
277 return 1;
278 }
279
280 return 0;
281}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200282
283/* Vim module - Implementation
284 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200285
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200286 static PyObject *
287VimCommand(PyObject *self UNUSED, PyObject *args)
288{
289 char *cmd;
290 PyObject *result;
291
292 if (!PyArg_ParseTuple(args, "s", &cmd))
293 return NULL;
294
295 PyErr_Clear();
296
297 Py_BEGIN_ALLOW_THREADS
298 Python_Lock_Vim();
299
300 do_cmdline_cmd((char_u *)cmd);
301 update_screen(VALID);
302
303 Python_Release_Vim();
304 Py_END_ALLOW_THREADS
305
306 if (VimErrorCheck())
307 result = NULL;
308 else
309 result = Py_None;
310
311 Py_XINCREF(result);
312 return result;
313}
314
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200315/*
316 * Function to translate a typval_T into a PyObject; this will recursively
317 * translate lists/dictionaries into their Python equivalents.
318 *
319 * The depth parameter is to avoid infinite recursion, set it to 1 when
320 * you call VimToPython.
321 */
322 static PyObject *
323VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
324{
325 PyObject *result;
326 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200327 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200328
329 /* Avoid infinite recursion */
330 if (depth > 100)
331 {
332 Py_INCREF(Py_None);
333 result = Py_None;
334 return result;
335 }
336
337 /* Check if we run into a recursive loop. The item must be in lookupDict
338 * then and we can use it again. */
339 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
340 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
341 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200342 sprintf(ptrBuf, "%p",
343 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
344 : (void *)our_tv->vval.v_dict);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200345 result = PyDict_GetItemString(lookupDict, ptrBuf);
346 if (result != NULL)
347 {
348 Py_INCREF(result);
349 return result;
350 }
351 }
352
353 if (our_tv->v_type == VAR_STRING)
354 {
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200355 result = Py_BuildValue("s", our_tv->vval.v_string == NULL
356 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200357 }
358 else if (our_tv->v_type == VAR_NUMBER)
359 {
360 char buf[NUMBUFLEN];
361
362 /* For backwards compatibility numbers are stored as strings. */
363 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
364 result = Py_BuildValue("s", buf);
365 }
366# ifdef FEAT_FLOAT
367 else if (our_tv->v_type == VAR_FLOAT)
368 {
369 char buf[NUMBUFLEN];
370
371 sprintf(buf, "%f", our_tv->vval.v_float);
372 result = Py_BuildValue("s", buf);
373 }
374# endif
375 else if (our_tv->v_type == VAR_LIST)
376 {
377 list_T *list = our_tv->vval.v_list;
378 listitem_T *curr;
379
380 result = PyList_New(0);
381
382 if (list != NULL)
383 {
384 PyDict_SetItemString(lookupDict, ptrBuf, result);
385
386 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
387 {
388 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
389 PyList_Append(result, newObj);
390 Py_DECREF(newObj);
391 }
392 }
393 }
394 else if (our_tv->v_type == VAR_DICT)
395 {
396 result = PyDict_New();
397
398 if (our_tv->vval.v_dict != NULL)
399 {
400 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
401 long_u todo = ht->ht_used;
402 hashitem_T *hi;
403 dictitem_T *di;
404
405 PyDict_SetItemString(lookupDict, ptrBuf, result);
406
407 for (hi = ht->ht_array; todo > 0; ++hi)
408 {
409 if (!HASHITEM_EMPTY(hi))
410 {
411 --todo;
412
413 di = dict_lookup(hi);
414 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
415 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
416 Py_DECREF(newObj);
417 }
418 }
419 }
420 }
421 else
422 {
423 Py_INCREF(Py_None);
424 result = Py_None;
425 }
426
427 return result;
428}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200429
430 static PyObject *
Bram Moolenaar09092152010-08-08 16:38:42 +0200431VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200432{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200433 char *expr;
434 typval_T *our_tv;
435 PyObject *result;
436 PyObject *lookup_dict;
437
438 if (!PyArg_ParseTuple(args, "s", &expr))
439 return NULL;
440
441 Py_BEGIN_ALLOW_THREADS
442 Python_Lock_Vim();
443 our_tv = eval_expr((char_u *)expr, NULL);
444
445 Python_Release_Vim();
446 Py_END_ALLOW_THREADS
447
448 if (our_tv == NULL)
449 {
450 PyErr_SetVim(_("invalid expression"));
451 return NULL;
452 }
453
454 /* Convert the Vim type into a Python type. Create a dictionary that's
455 * used to check for recursive loops. */
456 lookup_dict = PyDict_New();
457 result = VimToPython(our_tv, 1, lookup_dict);
458 Py_DECREF(lookup_dict);
459
460
461 Py_BEGIN_ALLOW_THREADS
462 Python_Lock_Vim();
463 free_tv(our_tv);
464 Python_Release_Vim();
465 Py_END_ALLOW_THREADS
466
467 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200468}
469
Bram Moolenaardb913952012-06-29 12:54:53 +0200470static PyObject *ConvertToPyObject(typval_T *);
471
472 static PyObject *
473VimEvalPy(PyObject *self UNUSED, PyObject *args UNUSED)
474{
Bram Moolenaardb913952012-06-29 12:54:53 +0200475 char *expr;
476 typval_T *our_tv;
477 PyObject *result;
478
479 if (!PyArg_ParseTuple(args, "s", &expr))
480 return NULL;
481
482 Py_BEGIN_ALLOW_THREADS
483 Python_Lock_Vim();
484 our_tv = eval_expr((char_u *)expr, NULL);
485
486 Python_Release_Vim();
487 Py_END_ALLOW_THREADS
488
489 if (our_tv == NULL)
490 {
491 PyErr_SetVim(_("invalid expression"));
492 return NULL;
493 }
494
495 result = ConvertToPyObject(our_tv);
496 Py_BEGIN_ALLOW_THREADS
497 Python_Lock_Vim();
498 free_tv(our_tv);
499 Python_Release_Vim();
500 Py_END_ALLOW_THREADS
501
502 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200503}
504
505 static PyObject *
506VimStrwidth(PyObject *self UNUSED, PyObject *args)
507{
508 char *expr;
509
510 if (!PyArg_ParseTuple(args, "s", &expr))
511 return NULL;
512
Bram Moolenaara54bf402012-12-05 16:30:07 +0100513 return PyLong_FromLong(
514#ifdef FEAT_MBYTE
515 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
516#else
517 STRLEN(expr)
518#endif
519 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200520}
521
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200522/*
523 * Vim module - Definitions
524 */
525
526static struct PyMethodDef VimMethods[] = {
527 /* name, function, calling, documentation */
528 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
529 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar2afa3232012-06-29 16:28:28 +0200530 {"bindeval", VimEvalPy, 1, "Like eval(), but returns objects attached to vim ones"},
531 {"strwidth", VimStrwidth, 1, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200532 { NULL, NULL, 0, NULL }
533};
534
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200535/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200536 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200537 */
538
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200539static PyTypeObject IterType;
540
541typedef PyObject *(*nextfun)(void **);
542typedef void (*destructorfun)(void *);
543
544/* Main purpose of this object is removing the need for do python initialization
545 * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects.
546 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200547
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200548typedef struct
549{
550 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200551 void *cur;
552 nextfun next;
553 destructorfun destruct;
554} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200555
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200556 static PyObject *
557IterNew(void *start, destructorfun destruct, nextfun next)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200558{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200559 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200560
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200561 self = PyObject_NEW(IterObject, &IterType);
562 self->cur = start;
563 self->next = next;
564 self->destruct = destruct;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200565
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200566 return (PyObject *)(self);
567}
568
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200569#if 0 /* unused */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200570 static void
571IterDestructor(PyObject *self)
572{
573 IterObject *this = (IterObject *)(self);
574
575 this->destruct(this->cur);
576
577 DESTRUCTOR_FINISH(self);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200578}
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200579#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200580
581 static PyObject *
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200582IterNext(PyObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200583{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200584 IterObject *this = (IterObject *)(self);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200585
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200586 return this->next(&this->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200587}
588
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200589 static PyObject *
590IterIter(PyObject *self)
591{
592 return self;
593}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200594
Bram Moolenaardb913952012-06-29 12:54:53 +0200595typedef struct pylinkedlist_S {
596 struct pylinkedlist_S *pll_next;
597 struct pylinkedlist_S *pll_prev;
598 PyObject *pll_obj;
599} pylinkedlist_T;
600
601static pylinkedlist_T *lastdict = NULL;
602static pylinkedlist_T *lastlist = NULL;
603
604 static void
605pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
606{
607 if (ref->pll_prev == NULL)
608 {
609 if (ref->pll_next == NULL)
610 {
611 *last = NULL;
612 return;
613 }
614 }
615 else
616 ref->pll_prev->pll_next = ref->pll_next;
617
618 if (ref->pll_next == NULL)
619 *last = ref->pll_prev;
620 else
621 ref->pll_next->pll_prev = ref->pll_prev;
622}
623
624 static void
625pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
626{
627 if (*last == NULL)
628 ref->pll_prev = NULL;
629 else
630 {
631 (*last)->pll_next = ref;
632 ref->pll_prev = *last;
633 }
634 ref->pll_next = NULL;
635 ref->pll_obj = self;
636 *last = ref;
637}
638
639static PyTypeObject DictionaryType;
640
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200641#define DICTKEY_GET_NOTEMPTY(err) \
642 DICTKEY_GET(err) \
643 if (*key == NUL) \
644 { \
645 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
646 return err; \
647 }
648
Bram Moolenaardb913952012-06-29 12:54:53 +0200649typedef struct
650{
651 PyObject_HEAD
652 dict_T *dict;
653 pylinkedlist_T ref;
654} DictionaryObject;
655
656 static PyObject *
657DictionaryNew(dict_T *dict)
658{
659 DictionaryObject *self;
660
661 self = PyObject_NEW(DictionaryObject, &DictionaryType);
662 if (self == NULL)
663 return NULL;
664 self->dict = dict;
665 ++dict->dv_refcount;
666
667 pyll_add((PyObject *)(self), &self->ref, &lastdict);
668
669 return (PyObject *)(self);
670}
671
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200672 static void
673DictionaryDestructor(PyObject *self)
674{
675 DictionaryObject *this = ((DictionaryObject *) (self));
676
677 pyll_remove(&this->ref, &lastdict);
678 dict_unref(this->dict);
679
680 DESTRUCTOR_FINISH(self);
681}
682
Bram Moolenaardb913952012-06-29 12:54:53 +0200683 static int
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200684DictionarySetattr(PyObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200685{
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200686 DictionaryObject *this = (DictionaryObject *)(self);
687
Bram Moolenaar66b79852012-09-21 14:00:35 +0200688 if (val == NULL)
689 {
690 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
691 return -1;
692 }
693
694 if (strcmp(name, "locked") == 0)
695 {
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200696 if (this->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200697 {
698 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
699 return -1;
700 }
701 else
702 {
Bram Moolenaarb983f752013-05-15 16:11:50 +0200703 int istrue = PyObject_IsTrue(val);
704 if (istrue == -1)
705 return -1;
706 else if (istrue)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200707 this->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200708 else
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200709 this->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200710 }
711 return 0;
712 }
713 else
714 {
715 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
716 return -1;
717 }
718}
719
720 static PyInt
Bram Moolenaardb913952012-06-29 12:54:53 +0200721DictionaryLength(PyObject *self)
722{
723 return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used)));
724}
725
726 static PyObject *
727DictionaryItem(PyObject *self, PyObject *keyObject)
728{
729 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200730 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200731 DICTKEY_DECL
732
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200733 DICTKEY_GET_NOTEMPTY(NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +0200734
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200735 di = dict_find(((DictionaryObject *) (self))->dict, key, -1);
736
Bram Moolenaar696c2112012-09-21 13:43:14 +0200737 DICTKEY_UNREF
738
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200739 if (di == NULL)
740 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200741 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200742 return NULL;
743 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200744
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200745 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200746}
747
748 static PyInt
749DictionaryAssItem(PyObject *self, PyObject *keyObject, PyObject *valObject)
750{
751 char_u *key;
752 typval_T tv;
753 dict_T *d = ((DictionaryObject *)(self))->dict;
754 dictitem_T *di;
755 DICTKEY_DECL
756
757 if (d->dv_lock)
758 {
759 PyErr_SetVim(_("dict is locked"));
760 return -1;
761 }
762
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200763 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200764
765 di = dict_find(d, key, -1);
766
767 if (valObject == NULL)
768 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200769 hashitem_T *hi;
770
Bram Moolenaardb913952012-06-29 12:54:53 +0200771 if (di == NULL)
772 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200773 DICTKEY_UNREF
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200774 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +0200775 return -1;
776 }
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200777 hi = hash_find(&d->dv_hashtab, di->di_key);
Bram Moolenaardb913952012-06-29 12:54:53 +0200778 hash_remove(&d->dv_hashtab, hi);
779 dictitem_free(di);
780 return 0;
781 }
782
783 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200784 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +0200785
786 if (di == NULL)
787 {
788 di = dictitem_alloc(key);
789 if (di == NULL)
790 {
791 PyErr_NoMemory();
792 return -1;
793 }
794 di->di_tv.v_lock = 0;
795
796 if (dict_add(d, di) == FAIL)
797 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200798 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200799 vim_free(di);
800 PyErr_SetVim(_("failed to add key to dictionary"));
801 return -1;
802 }
803 }
804 else
805 clear_tv(&di->di_tv);
806
807 DICTKEY_UNREF
808
809 copy_tv(&tv, &di->di_tv);
810 return 0;
811}
812
813 static PyObject *
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +0100814DictionaryListKeys(PyObject *self UNUSED)
Bram Moolenaardb913952012-06-29 12:54:53 +0200815{
816 dict_T *dict = ((DictionaryObject *)(self))->dict;
817 long_u todo = dict->dv_hashtab.ht_used;
818 Py_ssize_t i = 0;
819 PyObject *r;
820 hashitem_T *hi;
821
822 r = PyList_New(todo);
823 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
824 {
825 if (!HASHITEM_EMPTY(hi))
826 {
827 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
828 --todo;
829 ++i;
830 }
831 }
832 return r;
833}
834
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200835static PyMappingMethods DictionaryAsMapping = {
836 (lenfunc) DictionaryLength,
837 (binaryfunc) DictionaryItem,
838 (objobjargproc) DictionaryAssItem,
839};
840
Bram Moolenaardb913952012-06-29 12:54:53 +0200841static struct PyMethodDef DictionaryMethods[] = {
842 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
843 { NULL, NULL, 0, NULL }
844};
845
846static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200847static PySequenceMethods ListAsSeq;
848static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +0200849
850typedef struct
851{
852 PyObject_HEAD
853 list_T *list;
854 pylinkedlist_T ref;
855} ListObject;
856
857 static PyObject *
858ListNew(list_T *list)
859{
860 ListObject *self;
861
862 self = PyObject_NEW(ListObject, &ListType);
863 if (self == NULL)
864 return NULL;
865 self->list = list;
866 ++list->lv_refcount;
867
868 pyll_add((PyObject *)(self), &self->ref, &lastlist);
869
870 return (PyObject *)(self);
871}
872
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200873 static void
874ListDestructor(PyObject *self)
875{
876 ListObject *this = (ListObject *)(self);
877
878 pyll_remove(&this->ref, &lastlist);
879 list_unref(this->list);
880
881 DESTRUCTOR_FINISH(self);
882}
883
Bram Moolenaardb913952012-06-29 12:54:53 +0200884 static int
885list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict)
886{
887 Py_ssize_t i;
888 Py_ssize_t lsize = PySequence_Size(obj);
889 PyObject *litem;
890 listitem_T *li;
891
892 for(i=0; i<lsize; i++)
893 {
894 li = listitem_alloc();
895 if (li == NULL)
896 {
897 PyErr_NoMemory();
898 return -1;
899 }
900 li->li_tv.v_lock = 0;
901
902 litem = PySequence_GetItem(obj, i);
903 if (litem == NULL)
904 return -1;
905 if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1)
906 return -1;
907
908 list_append(l, li);
909 }
910 return 0;
911}
912
Bram Moolenaardb913952012-06-29 12:54:53 +0200913 static PyInt
914ListLength(PyObject *self)
915{
916 return ((PyInt) (((ListObject *) (self))->list->lv_len));
917}
918
919 static PyObject *
920ListItem(PyObject *self, Py_ssize_t index)
921{
922 listitem_T *li;
923
924 if (index>=ListLength(self))
925 {
Bram Moolenaar8661b172013-05-15 15:44:28 +0200926 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +0200927 return NULL;
928 }
929 li = list_find(((ListObject *) (self))->list, (long) index);
930 if (li == NULL)
931 {
932 PyErr_SetVim(_("internal error: failed to get vim list item"));
933 return NULL;
934 }
935 return ConvertToPyObject(&li->li_tv);
936}
937
938#define PROC_RANGE \
939 if (last < 0) {\
940 if (last < -size) \
941 last = 0; \
942 else \
943 last += size; \
944 } \
945 if (first < 0) \
946 first = 0; \
947 if (first > size) \
948 first = size; \
949 if (last > size) \
950 last = size;
951
952 static PyObject *
953ListSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last)
954{
955 PyInt i;
956 PyInt size = ListLength(self);
957 PyInt n;
958 PyObject *list;
959 int reversed = 0;
960
961 PROC_RANGE
962 if (first >= last)
963 first = last;
964
965 n = last-first;
966 list = PyList_New(n);
967 if (list == NULL)
968 return NULL;
969
970 for (i = 0; i < n; ++i)
971 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +0200972 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +0200973 if (item == NULL)
974 {
975 Py_DECREF(list);
976 return NULL;
977 }
978
979 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
980 {
981 Py_DECREF(item);
982 Py_DECREF(list);
983 return NULL;
984 }
985 }
986
987 return list;
988}
989
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200990typedef struct
991{
992 listwatch_T lw;
993 list_T *list;
994} listiterinfo_T;
995
996 static void
997ListIterDestruct(listiterinfo_T *lii)
998{
999 list_rem_watch(lii->list, &lii->lw);
1000 PyMem_Free(lii);
1001}
1002
1003 static PyObject *
1004ListIterNext(listiterinfo_T **lii)
1005{
1006 PyObject *r;
1007
1008 if (!((*lii)->lw.lw_item))
1009 return NULL;
1010
1011 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1012 return NULL;
1013
1014 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1015
1016 return r;
1017}
1018
1019 static PyObject *
1020ListIter(PyObject *self)
1021{
1022 listiterinfo_T *lii;
1023 list_T *l = ((ListObject *) (self))->list;
1024
1025 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1026 {
1027 PyErr_NoMemory();
1028 return NULL;
1029 }
1030
1031 list_add_watch(l, &lii->lw);
1032 lii->lw.lw_item = l->lv_first;
1033 lii->list = l;
1034
1035 return IterNew(lii,
1036 (destructorfun) ListIterDestruct, (nextfun) ListIterNext);
1037}
1038
Bram Moolenaardb913952012-06-29 12:54:53 +02001039 static int
1040ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj)
1041{
1042 typval_T tv;
1043 list_T *l = ((ListObject *) (self))->list;
1044 listitem_T *li;
1045 Py_ssize_t length = ListLength(self);
1046
1047 if (l->lv_lock)
1048 {
1049 PyErr_SetVim(_("list is locked"));
1050 return -1;
1051 }
1052 if (index>length || (index==length && obj==NULL))
1053 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001054 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001055 return -1;
1056 }
1057
1058 if (obj == NULL)
1059 {
1060 li = list_find(l, (long) index);
1061 list_remove(l, li, li);
1062 clear_tv(&li->li_tv);
1063 vim_free(li);
1064 return 0;
1065 }
1066
1067 if (ConvertFromPyObject(obj, &tv) == -1)
1068 return -1;
1069
1070 if (index == length)
1071 {
1072 if (list_append_tv(l, &tv) == FAIL)
1073 {
1074 PyErr_SetVim(_("Failed to add item to list"));
1075 return -1;
1076 }
1077 }
1078 else
1079 {
1080 li = list_find(l, (long) index);
1081 clear_tv(&li->li_tv);
1082 copy_tv(&tv, &li->li_tv);
1083 }
1084 return 0;
1085}
1086
1087 static int
1088ListAssSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
1089{
1090 PyInt size = ListLength(self);
1091 Py_ssize_t i;
1092 Py_ssize_t lsize;
1093 PyObject *litem;
1094 listitem_T *li;
1095 listitem_T *next;
1096 typval_T v;
1097 list_T *l = ((ListObject *) (self))->list;
1098
1099 if (l->lv_lock)
1100 {
1101 PyErr_SetVim(_("list is locked"));
1102 return -1;
1103 }
1104
1105 PROC_RANGE
1106
1107 if (first == size)
1108 li = NULL;
1109 else
1110 {
1111 li = list_find(l, (long) first);
1112 if (li == NULL)
1113 {
1114 PyErr_SetVim(_("internal error: no vim list item"));
1115 return -1;
1116 }
1117 if (last > first)
1118 {
1119 i = last - first;
1120 while (i-- && li != NULL)
1121 {
1122 next = li->li_next;
1123 listitem_remove(l, li);
1124 li = next;
1125 }
1126 }
1127 }
1128
1129 if (obj == NULL)
1130 return 0;
1131
1132 if (!PyList_Check(obj))
1133 {
1134 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1135 return -1;
1136 }
1137
1138 lsize = PyList_Size(obj);
1139
1140 for(i=0; i<lsize; i++)
1141 {
1142 litem = PyList_GetItem(obj, i);
1143 if (litem == NULL)
1144 return -1;
1145 if (ConvertFromPyObject(litem, &v) == -1)
1146 return -1;
1147 if (list_insert_tv(l, &v, li) == FAIL)
1148 {
1149 PyErr_SetVim(_("internal error: failed to add item to list"));
1150 return -1;
1151 }
1152 }
1153 return 0;
1154}
1155
1156 static PyObject *
1157ListConcatInPlace(PyObject *self, PyObject *obj)
1158{
1159 list_T *l = ((ListObject *) (self))->list;
1160 PyObject *lookup_dict;
1161
1162 if (l->lv_lock)
1163 {
1164 PyErr_SetVim(_("list is locked"));
1165 return NULL;
1166 }
1167
1168 if (!PySequence_Check(obj))
1169 {
1170 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1171 return NULL;
1172 }
1173
1174 lookup_dict = PyDict_New();
1175 if (list_py_concat(l, obj, lookup_dict) == -1)
1176 {
1177 Py_DECREF(lookup_dict);
1178 return NULL;
1179 }
1180 Py_DECREF(lookup_dict);
1181
1182 Py_INCREF(self);
1183 return self;
1184}
1185
Bram Moolenaar66b79852012-09-21 14:00:35 +02001186 static int
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001187ListSetattr(PyObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001188{
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001189 ListObject *this = (ListObject *)(self);
1190
Bram Moolenaar66b79852012-09-21 14:00:35 +02001191 if (val == NULL)
1192 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001193 PyErr_SetString(PyExc_AttributeError,
1194 _("cannot delete vim.dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001195 return -1;
1196 }
1197
1198 if (strcmp(name, "locked") == 0)
1199 {
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001200 if (this->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001201 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001202 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001203 return -1;
1204 }
1205 else
1206 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001207 int istrue = PyObject_IsTrue(val);
1208 if (istrue == -1)
1209 return -1;
1210 else if (istrue)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001211 this->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001212 else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001213 this->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001214 }
1215 return 0;
1216 }
1217 else
1218 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001219 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001220 return -1;
1221 }
1222}
1223
Bram Moolenaardb913952012-06-29 12:54:53 +02001224static struct PyMethodDef ListMethods[] = {
1225 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1226 { NULL, NULL, 0, NULL }
1227};
1228
1229typedef struct
1230{
1231 PyObject_HEAD
1232 char_u *name;
1233} FunctionObject;
1234
1235static PyTypeObject FunctionType;
1236
1237 static PyObject *
1238FunctionNew(char_u *name)
1239{
1240 FunctionObject *self;
1241
1242 self = PyObject_NEW(FunctionObject, &FunctionType);
1243 if (self == NULL)
1244 return NULL;
1245 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1246 if (self->name == NULL)
1247 {
1248 PyErr_NoMemory();
1249 return NULL;
1250 }
1251 STRCPY(self->name, name);
1252 func_ref(name);
1253 return (PyObject *)(self);
1254}
1255
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001256 static void
1257FunctionDestructor(PyObject *self)
1258{
1259 FunctionObject *this = (FunctionObject *) (self);
1260
1261 func_unref(this->name);
1262 PyMem_Del(this->name);
1263
1264 DESTRUCTOR_FINISH(self);
1265}
1266
Bram Moolenaardb913952012-06-29 12:54:53 +02001267 static PyObject *
1268FunctionCall(PyObject *self, PyObject *argsObject, PyObject *kwargs)
1269{
1270 FunctionObject *this = (FunctionObject *)(self);
1271 char_u *name = this->name;
1272 typval_T args;
1273 typval_T selfdicttv;
1274 typval_T rettv;
1275 dict_T *selfdict = NULL;
1276 PyObject *selfdictObject;
1277 PyObject *result;
1278 int error;
1279
1280 if (ConvertFromPyObject(argsObject, &args) == -1)
1281 return NULL;
1282
1283 if (kwargs != NULL)
1284 {
1285 selfdictObject = PyDict_GetItemString(kwargs, "self");
1286 if (selfdictObject != NULL)
1287 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001288 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001289 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001290 PyErr_SetString(PyExc_TypeError,
1291 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001292 clear_tv(&args);
1293 return NULL;
1294 }
1295 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
1296 return NULL;
1297 selfdict = selfdicttv.vval.v_dict;
1298 }
1299 }
1300
1301 error = func_call(name, &args, selfdict, &rettv);
1302 if (error != OK)
1303 {
1304 result = NULL;
1305 PyErr_SetVim(_("failed to run function"));
1306 }
1307 else
1308 result = ConvertToPyObject(&rettv);
1309
1310 /* FIXME Check what should really be cleared. */
1311 clear_tv(&args);
1312 clear_tv(&rettv);
1313 /*
1314 * if (selfdict!=NULL)
1315 * clear_tv(selfdicttv);
1316 */
1317
1318 return result;
1319}
1320
1321static struct PyMethodDef FunctionMethods[] = {
1322 {"__call__", (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1323 { NULL, NULL, 0, NULL }
1324};
1325
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001326/*
1327 * Options object
1328 */
1329
1330static PyTypeObject OptionsType;
1331
1332typedef int (*checkfun)(void *);
1333
1334typedef struct
1335{
1336 PyObject_HEAD
1337 int opt_type;
1338 void *from;
1339 checkfun Check;
1340 PyObject *fromObj;
1341} OptionsObject;
1342
1343 static PyObject *
1344OptionsItem(OptionsObject *this, PyObject *keyObject)
1345{
1346 char_u *key;
1347 int flags;
1348 long numval;
1349 char_u *stringval;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001350 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001351
1352 if (this->Check(this->from))
1353 return NULL;
1354
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001355 DICTKEY_GET_NOTEMPTY(NULL)
1356
1357 flags = get_option_value_strict(key, &numval, &stringval,
1358 this->opt_type, this->from);
1359
1360 DICTKEY_UNREF
1361
1362 if (flags == 0)
1363 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001364 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001365 return NULL;
1366 }
1367
1368 if (flags & SOPT_UNSET)
1369 {
1370 Py_INCREF(Py_None);
1371 return Py_None;
1372 }
1373 else if (flags & SOPT_BOOL)
1374 {
1375 PyObject *r;
1376 r = numval ? Py_True : Py_False;
1377 Py_INCREF(r);
1378 return r;
1379 }
1380 else if (flags & SOPT_NUM)
1381 return PyInt_FromLong(numval);
1382 else if (flags & SOPT_STRING)
1383 {
1384 if (stringval)
1385 return PyBytes_FromString((char *) stringval);
1386 else
1387 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001388 PyErr_SetString(PyExc_RuntimeError,
1389 _("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001390 return NULL;
1391 }
1392 }
1393 else
1394 {
1395 PyErr_SetVim("Internal error: unknown option type. Should not happen");
1396 return NULL;
1397 }
1398}
1399
1400 static int
1401set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
1402 char_u *key;
1403 int numval;
1404 char_u *stringval;
1405 int opt_flags;
1406 int opt_type;
1407 void *from;
1408{
1409 win_T *save_curwin;
1410 tabpage_T *save_curtab;
1411 aco_save_T aco;
1412 int r = 0;
1413
1414 switch (opt_type)
1415 {
1416 case SREQ_WIN:
1417 if (switch_win(&save_curwin, &save_curtab, (win_T *) from, curtab)
1418 == FAIL)
1419 {
1420 PyErr_SetVim("Problem while switching windows.");
1421 return -1;
1422 }
1423 set_option_value(key, numval, stringval, opt_flags);
1424 restore_win(save_curwin, save_curtab);
1425 break;
1426 case SREQ_BUF:
1427 aucmd_prepbuf(&aco, (buf_T *) from);
1428 set_option_value(key, numval, stringval, opt_flags);
1429 aucmd_restbuf(&aco);
1430 break;
1431 case SREQ_GLOBAL:
1432 set_option_value(key, numval, stringval, opt_flags);
1433 break;
1434 }
1435 return r;
1436}
1437
1438 static int
1439OptionsAssItem(OptionsObject *this, PyObject *keyObject, PyObject *valObject)
1440{
1441 char_u *key;
1442 int flags;
1443 int opt_flags;
1444 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001445 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001446
1447 if (this->Check(this->from))
1448 return -1;
1449
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001450 DICTKEY_GET_NOTEMPTY(-1)
1451
1452 flags = get_option_value_strict(key, NULL, NULL,
1453 this->opt_type, this->from);
1454
1455 DICTKEY_UNREF
1456
1457 if (flags == 0)
1458 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001459 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001460 return -1;
1461 }
1462
1463 if (valObject == NULL)
1464 {
1465 if (this->opt_type == SREQ_GLOBAL)
1466 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001467 PyErr_SetString(PyExc_ValueError,
1468 _("unable to unset global option"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001469 return -1;
1470 }
1471 else if (!(flags & SOPT_GLOBAL))
1472 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001473 PyErr_SetString(PyExc_ValueError, _("unable to unset option "
1474 "without global value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001475 return -1;
1476 }
1477 else
1478 {
1479 unset_global_local_option(key, this->from);
1480 return 0;
1481 }
1482 }
1483
1484 opt_flags = (this->opt_type ? OPT_LOCAL : OPT_GLOBAL);
1485
1486 if (flags & SOPT_BOOL)
1487 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001488 int istrue = PyObject_IsTrue(valObject);
1489 if (istrue == -1)
1490 return -1;
1491 r = set_option_value_for(key, istrue, NULL,
Bram Moolenaar03db85b2013-05-15 14:51:35 +02001492 opt_flags, this->opt_type, this->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001493 }
1494 else if (flags & SOPT_NUM)
1495 {
1496 int val;
1497
1498#if PY_MAJOR_VERSION < 3
1499 if (PyInt_Check(valObject))
1500 val = PyInt_AsLong(valObject);
1501 else
1502#endif
1503 if (PyLong_Check(valObject))
1504 val = PyLong_AsLong(valObject);
1505 else
1506 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001507 PyErr_SetString(PyExc_TypeError, _("object must be integer"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001508 return -1;
1509 }
1510
1511 r = set_option_value_for(key, val, NULL, opt_flags,
1512 this->opt_type, this->from);
1513 }
1514 else
1515 {
1516 char_u *val;
1517 if (PyBytes_Check(valObject))
1518 {
1519
1520 if (PyString_AsStringAndSize(valObject, (char **) &val, NULL) == -1)
1521 return -1;
1522 if (val == NULL)
1523 return -1;
1524
1525 val = vim_strsave(val);
1526 }
1527 else if (PyUnicode_Check(valObject))
1528 {
1529 PyObject *bytes;
1530
1531 bytes = PyUnicode_AsEncodedString(valObject, (char *)ENC_OPT, NULL);
1532 if (bytes == NULL)
1533 return -1;
1534
1535 if(PyString_AsStringAndSize(bytes, (char **) &val, NULL) == -1)
1536 return -1;
1537 if (val == NULL)
1538 return -1;
1539
1540 val = vim_strsave(val);
1541 Py_XDECREF(bytes);
1542 }
1543 else
1544 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001545 PyErr_SetString(PyExc_TypeError, _("object must be string"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001546 return -1;
1547 }
1548
1549 r = set_option_value_for(key, 0, val, opt_flags,
1550 this->opt_type, this->from);
1551 vim_free(val);
1552 }
1553
1554 return r;
1555}
1556
1557 static int
1558dummy_check(void *arg UNUSED)
1559{
1560 return 0;
1561}
1562
1563 static PyObject *
1564OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
1565{
1566 OptionsObject *self;
1567
1568 self = PyObject_NEW(OptionsObject, &OptionsType);
1569 if (self == NULL)
1570 return NULL;
1571
1572 self->opt_type = opt_type;
1573 self->from = from;
1574 self->Check = Check;
1575 self->fromObj = fromObj;
1576 if (fromObj)
1577 Py_INCREF(fromObj);
1578
1579 return (PyObject *)(self);
1580}
1581
1582 static void
1583OptionsDestructor(PyObject *self)
1584{
1585 if (((OptionsObject *)(self))->fromObj)
1586 Py_DECREF(((OptionsObject *)(self))->fromObj);
1587 DESTRUCTOR_FINISH(self);
1588}
1589
1590static PyMappingMethods OptionsAsMapping = {
1591 (lenfunc) NULL,
1592 (binaryfunc) OptionsItem,
1593 (objobjargproc) OptionsAssItem,
1594};
1595
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001596/* Tabpage object
1597 */
1598
1599typedef struct
1600{
1601 PyObject_HEAD
1602 tabpage_T *tab;
1603} TabPageObject;
1604
1605static PyObject *WinListNew(TabPageObject *tabObject);
1606
1607static PyTypeObject TabPageType;
1608
1609 static int
1610CheckTabPage(TabPageObject *this)
1611{
1612 if (this->tab == INVALID_TABPAGE_VALUE)
1613 {
1614 PyErr_SetVim(_("attempt to refer to deleted tab page"));
1615 return -1;
1616 }
1617
1618 return 0;
1619}
1620
1621 static PyObject *
1622TabPageNew(tabpage_T *tab)
1623{
1624 TabPageObject *self;
1625
1626 if (TAB_PYTHON_REF(tab))
1627 {
1628 self = TAB_PYTHON_REF(tab);
1629 Py_INCREF(self);
1630 }
1631 else
1632 {
1633 self = PyObject_NEW(TabPageObject, &TabPageType);
1634 if (self == NULL)
1635 return NULL;
1636 self->tab = tab;
1637 TAB_PYTHON_REF(tab) = self;
1638 }
1639
1640 return (PyObject *)(self);
1641}
1642
1643 static void
1644TabPageDestructor(PyObject *self)
1645{
1646 TabPageObject *this = (TabPageObject *)(self);
1647
1648 if (this->tab && this->tab != INVALID_TABPAGE_VALUE)
1649 TAB_PYTHON_REF(this->tab) = NULL;
1650
1651 DESTRUCTOR_FINISH(self);
1652}
1653
1654 static PyObject *
1655TabPageAttr(TabPageObject *this, char *name)
1656{
1657 if (strcmp(name, "windows") == 0)
1658 return WinListNew(this);
1659 else if (strcmp(name, "number") == 0)
1660 return PyLong_FromLong((long) get_tab_number(this->tab));
1661 else if (strcmp(name, "vars") == 0)
1662 return DictionaryNew(this->tab->tp_vars);
1663 else if (strcmp(name, "window") == 0)
1664 {
1665 /* For current tab window.c does not bother to set or update tp_curwin
1666 */
1667 if (this->tab == curtab)
1668 return WindowNew(curwin);
1669 else
1670 return WindowNew(this->tab->tp_curwin);
1671 }
1672 return NULL;
1673}
1674
1675 static PyObject *
1676TabPageRepr(PyObject *self)
1677{
1678 static char repr[100];
1679 TabPageObject *this = (TabPageObject *)(self);
1680
1681 if (this->tab == INVALID_TABPAGE_VALUE)
1682 {
1683 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
1684 return PyString_FromString(repr);
1685 }
1686 else
1687 {
1688 int t = get_tab_number(this->tab);
1689
1690 if (t == 0)
1691 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
1692 (self));
1693 else
1694 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
1695
1696 return PyString_FromString(repr);
1697 }
1698}
1699
1700static struct PyMethodDef TabPageMethods[] = {
1701 /* name, function, calling, documentation */
1702 { NULL, NULL, 0, NULL }
1703};
1704
1705/*
1706 * Window list object
1707 */
1708
1709static PyTypeObject TabListType;
1710static PySequenceMethods TabListAsSeq;
1711
1712typedef struct
1713{
1714 PyObject_HEAD
1715} TabListObject;
1716
1717 static PyInt
1718TabListLength(PyObject *self UNUSED)
1719{
1720 tabpage_T *tp = first_tabpage;
1721 PyInt n = 0;
1722
1723 while (tp != NULL)
1724 {
1725 ++n;
1726 tp = tp->tp_next;
1727 }
1728
1729 return n;
1730}
1731
1732 static PyObject *
1733TabListItem(PyObject *self UNUSED, PyInt n)
1734{
1735 tabpage_T *tp;
1736
1737 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
1738 if (n == 0)
1739 return TabPageNew(tp);
1740
1741 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
1742 return NULL;
1743}
1744
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001745/* Window object
1746 */
1747
1748typedef struct
1749{
1750 PyObject_HEAD
1751 win_T *win;
1752} WindowObject;
1753
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001754static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001755
1756 static int
1757CheckWindow(WindowObject *this)
1758{
1759 if (this->win == INVALID_WINDOW_VALUE)
1760 {
1761 PyErr_SetVim(_("attempt to refer to deleted window"));
1762 return -1;
1763 }
1764
1765 return 0;
1766}
1767
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001768 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02001769WindowNew(win_T *win)
1770{
1771 /* We need to handle deletion of windows underneath us.
1772 * If we add a "w_python*_ref" field to the win_T structure,
1773 * then we can get at it in win_free() in vim. We then
1774 * need to create only ONE Python object per window - if
1775 * we try to create a second, just INCREF the existing one
1776 * and return it. The (single) Python object referring to
1777 * the window is stored in "w_python*_ref".
1778 * On a win_free() we set the Python object's win_T* field
1779 * to an invalid value. We trap all uses of a window
1780 * object, and reject them if the win_T* field is invalid.
1781 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001782 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02001783 * w_python_ref and w_python3_ref fields respectively.
1784 */
1785
1786 WindowObject *self;
1787
1788 if (WIN_PYTHON_REF(win))
1789 {
1790 self = WIN_PYTHON_REF(win);
1791 Py_INCREF(self);
1792 }
1793 else
1794 {
1795 self = PyObject_NEW(WindowObject, &WindowType);
1796 if (self == NULL)
1797 return NULL;
1798 self->win = win;
1799 WIN_PYTHON_REF(win) = self;
1800 }
1801
1802 return (PyObject *)(self);
1803}
1804
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001805 static void
1806WindowDestructor(PyObject *self)
1807{
1808 WindowObject *this = (WindowObject *)(self);
1809
1810 if (this->win && this->win != INVALID_WINDOW_VALUE)
1811 WIN_PYTHON_REF(this->win) = NULL;
1812
1813 DESTRUCTOR_FINISH(self);
1814}
1815
Bram Moolenaar971db462013-05-12 18:44:48 +02001816 static PyObject *
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001817WindowAttr(WindowObject *this, char *name)
1818{
1819 if (strcmp(name, "buffer") == 0)
1820 return (PyObject *)BufferNew(this->win->w_buffer);
1821 else if (strcmp(name, "cursor") == 0)
1822 {
1823 pos_T *pos = &this->win->w_cursor;
1824
1825 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
1826 }
1827 else if (strcmp(name, "height") == 0)
Bram Moolenaar99add412013-05-12 19:09:51 +02001828 return PyLong_FromLong((long)(this->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001829#ifdef FEAT_WINDOWS
1830 else if (strcmp(name, "row") == 0)
1831 return PyLong_FromLong((long)(this->win->w_winrow));
1832#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001833#ifdef FEAT_VERTSPLIT
1834 else if (strcmp(name, "width") == 0)
Bram Moolenaar99add412013-05-12 19:09:51 +02001835 return PyLong_FromLong((long)(W_WIDTH(this->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001836 else if (strcmp(name, "col") == 0)
1837 return PyLong_FromLong((long)(W_WINCOL(this->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001838#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02001839 else if (strcmp(name, "vars") == 0)
1840 return DictionaryNew(this->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001841 else if (strcmp(name, "options") == 0)
1842 return OptionsNew(SREQ_WIN, this->win, (checkfun) CheckWindow,
1843 (PyObject *) this);
Bram Moolenaar6d216452013-05-12 19:00:41 +02001844 else if (strcmp(name, "number") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001845 return PyLong_FromLong((long) get_win_number(this->win, firstwin));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001846 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001847 return Py_BuildValue("[ssssssss]", "buffer", "cursor", "height", "vars",
1848 "options", "number", "row", "col");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001849 else
1850 return NULL;
1851}
1852
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001853 static int
1854WindowSetattr(PyObject *self, char *name, PyObject *val)
1855{
1856 WindowObject *this = (WindowObject *)(self);
1857
1858 if (CheckWindow(this))
1859 return -1;
1860
1861 if (strcmp(name, "buffer") == 0)
1862 {
1863 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1864 return -1;
1865 }
1866 else if (strcmp(name, "cursor") == 0)
1867 {
1868 long lnum;
1869 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001870
1871 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1872 return -1;
1873
1874 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1875 {
1876 PyErr_SetVim(_("cursor position outside buffer"));
1877 return -1;
1878 }
1879
1880 /* Check for keyboard interrupts */
1881 if (VimErrorCheck())
1882 return -1;
1883
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001884 this->win->w_cursor.lnum = lnum;
1885 this->win->w_cursor.col = col;
1886#ifdef FEAT_VIRTUALEDIT
1887 this->win->w_cursor.coladd = 0;
1888#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001889 /* When column is out of range silently correct it. */
1890 check_cursor_col_win(this->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001891
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001892 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001893 return 0;
1894 }
1895 else if (strcmp(name, "height") == 0)
1896 {
1897 int height;
1898 win_T *savewin;
1899
1900 if (!PyArg_Parse(val, "i", &height))
1901 return -1;
1902
1903#ifdef FEAT_GUI
1904 need_mouse_correct = TRUE;
1905#endif
1906 savewin = curwin;
1907 curwin = this->win;
1908 win_setheight(height);
1909 curwin = savewin;
1910
1911 /* Check for keyboard interrupts */
1912 if (VimErrorCheck())
1913 return -1;
1914
1915 return 0;
1916 }
1917#ifdef FEAT_VERTSPLIT
1918 else if (strcmp(name, "width") == 0)
1919 {
1920 int width;
1921 win_T *savewin;
1922
1923 if (!PyArg_Parse(val, "i", &width))
1924 return -1;
1925
1926#ifdef FEAT_GUI
1927 need_mouse_correct = TRUE;
1928#endif
1929 savewin = curwin;
1930 curwin = this->win;
1931 win_setwidth(width);
1932 curwin = savewin;
1933
1934 /* Check for keyboard interrupts */
1935 if (VimErrorCheck())
1936 return -1;
1937
1938 return 0;
1939 }
1940#endif
1941 else
1942 {
1943 PyErr_SetString(PyExc_AttributeError, name);
1944 return -1;
1945 }
1946}
1947
1948 static PyObject *
1949WindowRepr(PyObject *self)
1950{
1951 static char repr[100];
1952 WindowObject *this = (WindowObject *)(self);
1953
1954 if (this->win == INVALID_WINDOW_VALUE)
1955 {
1956 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
1957 return PyString_FromString(repr);
1958 }
1959 else
1960 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001961 int w = get_win_number(this->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001962
Bram Moolenaar6d216452013-05-12 19:00:41 +02001963 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001964 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
1965 (self));
1966 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02001967 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001968
1969 return PyString_FromString(repr);
1970 }
1971}
1972
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001973static struct PyMethodDef WindowMethods[] = {
1974 /* name, function, calling, documentation */
1975 { NULL, NULL, 0, NULL }
1976};
1977
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001978/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001979 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001980 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001981
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001982static PyTypeObject WinListType;
1983static PySequenceMethods WinListAsSeq;
1984
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001985typedef struct
1986{
1987 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001988 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001989} WinListObject;
1990
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001991 static PyObject *
1992WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001993{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001994 WinListObject *self;
1995
1996 self = PyObject_NEW(WinListObject, &WinListType);
1997 self->tabObject = tabObject;
1998 Py_INCREF(tabObject);
1999
2000 return (PyObject *)(self);
2001}
2002
2003 static void
2004WinListDestructor(PyObject *self)
2005{
2006 TabPageObject *tabObject = ((WinListObject *)(self))->tabObject;
2007
2008 if (tabObject)
2009 Py_DECREF((PyObject *)(tabObject));
2010
2011 DESTRUCTOR_FINISH(self);
2012}
2013
2014 static win_T *
2015get_firstwin(WinListObject *this)
2016{
2017 if (this->tabObject)
2018 {
2019 if (CheckTabPage(this->tabObject))
2020 return NULL;
2021 /* For current tab window.c does not bother to set or update tp_firstwin
2022 */
2023 else if (this->tabObject->tab == curtab)
2024 return firstwin;
2025 else
2026 return this->tabObject->tab->tp_firstwin;
2027 }
2028 else
2029 return firstwin;
2030}
2031
2032 static PyInt
2033WinListLength(PyObject *self)
2034{
2035 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002036 PyInt n = 0;
2037
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002038 if (!(w = get_firstwin((WinListObject *)(self))))
2039 return -1;
2040
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002041 while (w != NULL)
2042 {
2043 ++n;
2044 w = W_NEXT(w);
2045 }
2046
2047 return n;
2048}
2049
2050 static PyObject *
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002051WinListItem(PyObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002052{
2053 win_T *w;
2054
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002055 if (!(w = get_firstwin((WinListObject *)(self))))
2056 return NULL;
2057
2058 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002059 if (n == 0)
2060 return WindowNew(w);
2061
2062 PyErr_SetString(PyExc_IndexError, _("no such window"));
2063 return NULL;
2064}
2065
2066/* Convert a Python string into a Vim line.
2067 *
2068 * The result is in allocated memory. All internal nulls are replaced by
2069 * newline characters. It is an error for the string to contain newline
2070 * characters.
2071 *
2072 * On errors, the Python exception data is set, and NULL is returned.
2073 */
2074 static char *
2075StringToLine(PyObject *obj)
2076{
2077 const char *str;
2078 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002079 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002080 PyInt len;
2081 PyInt i;
2082 char *p;
2083
2084 if (obj == NULL || !PyString_Check(obj))
2085 {
2086 PyErr_BadArgument();
2087 return NULL;
2088 }
2089
Bram Moolenaar19e60942011-06-19 00:27:51 +02002090 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2091 str = PyString_AsString(bytes);
2092 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002093
2094 /*
2095 * Error checking: String must not contain newlines, as we
2096 * are replacing a single line, and we must replace it with
2097 * a single line.
2098 * A trailing newline is removed, so that append(f.readlines()) works.
2099 */
2100 p = memchr(str, '\n', len);
2101 if (p != NULL)
2102 {
2103 if (p == str + len - 1)
2104 --len;
2105 else
2106 {
2107 PyErr_SetVim(_("string cannot contain newlines"));
2108 return NULL;
2109 }
2110 }
2111
2112 /* Create a copy of the string, with internal nulls replaced by
2113 * newline characters, as is the vim convention.
2114 */
2115 save = (char *)alloc((unsigned)(len+1));
2116 if (save == NULL)
2117 {
2118 PyErr_NoMemory();
2119 return NULL;
2120 }
2121
2122 for (i = 0; i < len; ++i)
2123 {
2124 if (str[i] == '\0')
2125 save[i] = '\n';
2126 else
2127 save[i] = str[i];
2128 }
2129
2130 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002131 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002132
2133 return save;
2134}
2135
2136/* Get a line from the specified buffer. The line number is
2137 * in Vim format (1-based). The line is returned as a Python
2138 * string object.
2139 */
2140 static PyObject *
2141GetBufferLine(buf_T *buf, PyInt n)
2142{
2143 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2144}
2145
2146
2147/* Get a list of lines from the specified buffer. The line numbers
2148 * are in Vim format (1-based). The range is from lo up to, but not
2149 * including, hi. The list is returned as a Python list of string objects.
2150 */
2151 static PyObject *
2152GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2153{
2154 PyInt i;
2155 PyInt n = hi - lo;
2156 PyObject *list = PyList_New(n);
2157
2158 if (list == NULL)
2159 return NULL;
2160
2161 for (i = 0; i < n; ++i)
2162 {
2163 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2164
2165 /* Error check - was the Python string creation OK? */
2166 if (str == NULL)
2167 {
2168 Py_DECREF(list);
2169 return NULL;
2170 }
2171
2172 /* Set the list item */
2173 if (PyList_SetItem(list, i, str))
2174 {
2175 Py_DECREF(str);
2176 Py_DECREF(list);
2177 return NULL;
2178 }
2179 }
2180
2181 /* The ownership of the Python list is passed to the caller (ie,
2182 * the caller should Py_DECREF() the object when it is finished
2183 * with it).
2184 */
2185
2186 return list;
2187}
2188
2189/*
2190 * Check if deleting lines made the cursor position invalid.
2191 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2192 * deleted).
2193 */
2194 static void
2195py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2196{
2197 if (curwin->w_cursor.lnum >= lo)
2198 {
2199 /* Adjust the cursor position if it's in/after the changed
2200 * lines. */
2201 if (curwin->w_cursor.lnum >= hi)
2202 {
2203 curwin->w_cursor.lnum += extra;
2204 check_cursor_col();
2205 }
2206 else if (extra < 0)
2207 {
2208 curwin->w_cursor.lnum = lo;
2209 check_cursor();
2210 }
2211 else
2212 check_cursor_col();
2213 changed_cline_bef_curs();
2214 }
2215 invalidate_botline();
2216}
2217
Bram Moolenaar19e60942011-06-19 00:27:51 +02002218/*
2219 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002220 * in Vim format (1-based). The replacement line is given as
2221 * a Python string object. The object is checked for validity
2222 * and correct format. Errors are returned as a value of FAIL.
2223 * The return value is OK on success.
2224 * If OK is returned and len_change is not NULL, *len_change
2225 * is set to the change in the buffer length.
2226 */
2227 static int
2228SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2229{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002230 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002231 * There are three cases:
2232 * 1. NULL, or None - this is a deletion.
2233 * 2. A string - this is a replacement.
2234 * 3. Anything else - this is an error.
2235 */
2236 if (line == Py_None || line == NULL)
2237 {
2238 buf_T *savebuf = curbuf;
2239
2240 PyErr_Clear();
2241 curbuf = buf;
2242
2243 if (u_savedel((linenr_T)n, 1L) == FAIL)
2244 PyErr_SetVim(_("cannot save undo information"));
2245 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2246 PyErr_SetVim(_("cannot delete line"));
2247 else
2248 {
2249 if (buf == curwin->w_buffer)
2250 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2251 deleted_lines_mark((linenr_T)n, 1L);
2252 }
2253
2254 curbuf = savebuf;
2255
2256 if (PyErr_Occurred() || VimErrorCheck())
2257 return FAIL;
2258
2259 if (len_change)
2260 *len_change = -1;
2261
2262 return OK;
2263 }
2264 else if (PyString_Check(line))
2265 {
2266 char *save = StringToLine(line);
2267 buf_T *savebuf = curbuf;
2268
2269 if (save == NULL)
2270 return FAIL;
2271
2272 /* We do not need to free "save" if ml_replace() consumes it. */
2273 PyErr_Clear();
2274 curbuf = buf;
2275
2276 if (u_savesub((linenr_T)n) == FAIL)
2277 {
2278 PyErr_SetVim(_("cannot save undo information"));
2279 vim_free(save);
2280 }
2281 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2282 {
2283 PyErr_SetVim(_("cannot replace line"));
2284 vim_free(save);
2285 }
2286 else
2287 changed_bytes((linenr_T)n, 0);
2288
2289 curbuf = savebuf;
2290
2291 /* Check that the cursor is not beyond the end of the line now. */
2292 if (buf == curwin->w_buffer)
2293 check_cursor_col();
2294
2295 if (PyErr_Occurred() || VimErrorCheck())
2296 return FAIL;
2297
2298 if (len_change)
2299 *len_change = 0;
2300
2301 return OK;
2302 }
2303 else
2304 {
2305 PyErr_BadArgument();
2306 return FAIL;
2307 }
2308}
2309
Bram Moolenaar19e60942011-06-19 00:27:51 +02002310/* Replace a range of lines in the specified buffer. The line numbers are in
2311 * Vim format (1-based). The range is from lo up to, but not including, hi.
2312 * The replacement lines are given as a Python list of string objects. The
2313 * list is checked for validity and correct format. Errors are returned as a
2314 * value of FAIL. The return value is OK on success.
2315 * If OK is returned and len_change is not NULL, *len_change
2316 * is set to the change in the buffer length.
2317 */
2318 static int
2319SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2320{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002321 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002322 * There are three cases:
2323 * 1. NULL, or None - this is a deletion.
2324 * 2. A list - this is a replacement.
2325 * 3. Anything else - this is an error.
2326 */
2327 if (list == Py_None || list == NULL)
2328 {
2329 PyInt i;
2330 PyInt n = (int)(hi - lo);
2331 buf_T *savebuf = curbuf;
2332
2333 PyErr_Clear();
2334 curbuf = buf;
2335
2336 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2337 PyErr_SetVim(_("cannot save undo information"));
2338 else
2339 {
2340 for (i = 0; i < n; ++i)
2341 {
2342 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2343 {
2344 PyErr_SetVim(_("cannot delete line"));
2345 break;
2346 }
2347 }
2348 if (buf == curwin->w_buffer)
2349 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2350 deleted_lines_mark((linenr_T)lo, (long)i);
2351 }
2352
2353 curbuf = savebuf;
2354
2355 if (PyErr_Occurred() || VimErrorCheck())
2356 return FAIL;
2357
2358 if (len_change)
2359 *len_change = -n;
2360
2361 return OK;
2362 }
2363 else if (PyList_Check(list))
2364 {
2365 PyInt i;
2366 PyInt new_len = PyList_Size(list);
2367 PyInt old_len = hi - lo;
2368 PyInt extra = 0; /* lines added to text, can be negative */
2369 char **array;
2370 buf_T *savebuf;
2371
2372 if (new_len == 0) /* avoid allocating zero bytes */
2373 array = NULL;
2374 else
2375 {
2376 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
2377 if (array == NULL)
2378 {
2379 PyErr_NoMemory();
2380 return FAIL;
2381 }
2382 }
2383
2384 for (i = 0; i < new_len; ++i)
2385 {
2386 PyObject *line = PyList_GetItem(list, i);
2387
2388 array[i] = StringToLine(line);
2389 if (array[i] == NULL)
2390 {
2391 while (i)
2392 vim_free(array[--i]);
2393 vim_free(array);
2394 return FAIL;
2395 }
2396 }
2397
2398 savebuf = curbuf;
2399
2400 PyErr_Clear();
2401 curbuf = buf;
2402
2403 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2404 PyErr_SetVim(_("cannot save undo information"));
2405
2406 /* If the size of the range is reducing (ie, new_len < old_len) we
2407 * need to delete some old_len. We do this at the start, by
2408 * repeatedly deleting line "lo".
2409 */
2410 if (!PyErr_Occurred())
2411 {
2412 for (i = 0; i < old_len - new_len; ++i)
2413 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2414 {
2415 PyErr_SetVim(_("cannot delete line"));
2416 break;
2417 }
2418 extra -= i;
2419 }
2420
2421 /* For as long as possible, replace the existing old_len with the
2422 * new old_len. This is a more efficient operation, as it requires
2423 * less memory allocation and freeing.
2424 */
2425 if (!PyErr_Occurred())
2426 {
2427 for (i = 0; i < old_len && i < new_len; ++i)
2428 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2429 == FAIL)
2430 {
2431 PyErr_SetVim(_("cannot replace line"));
2432 break;
2433 }
2434 }
2435 else
2436 i = 0;
2437
2438 /* Now we may need to insert the remaining new old_len. If we do, we
2439 * must free the strings as we finish with them (we can't pass the
2440 * responsibility to vim in this case).
2441 */
2442 if (!PyErr_Occurred())
2443 {
2444 while (i < new_len)
2445 {
2446 if (ml_append((linenr_T)(lo + i - 1),
2447 (char_u *)array[i], 0, FALSE) == FAIL)
2448 {
2449 PyErr_SetVim(_("cannot insert line"));
2450 break;
2451 }
2452 vim_free(array[i]);
2453 ++i;
2454 ++extra;
2455 }
2456 }
2457
2458 /* Free any left-over old_len, as a result of an error */
2459 while (i < new_len)
2460 {
2461 vim_free(array[i]);
2462 ++i;
2463 }
2464
2465 /* Free the array of old_len. All of its contents have now
2466 * been dealt with (either freed, or the responsibility passed
2467 * to vim.
2468 */
2469 vim_free(array);
2470
2471 /* Adjust marks. Invalidate any which lie in the
2472 * changed range, and move any in the remainder of the buffer.
2473 */
2474 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2475 (long)MAXLNUM, (long)extra);
2476 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2477
2478 if (buf == curwin->w_buffer)
2479 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2480
2481 curbuf = savebuf;
2482
2483 if (PyErr_Occurred() || VimErrorCheck())
2484 return FAIL;
2485
2486 if (len_change)
2487 *len_change = new_len - old_len;
2488
2489 return OK;
2490 }
2491 else
2492 {
2493 PyErr_BadArgument();
2494 return FAIL;
2495 }
2496}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002497
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002498/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002499 * The line number is in Vim format (1-based). The lines to be inserted are
2500 * given as a Python list of string objects or as a single string. The lines
2501 * to be added are checked for validity and correct format. Errors are
2502 * returned as a value of FAIL. The return value is OK on success.
2503 * If OK is returned and len_change is not NULL, *len_change
2504 * is set to the change in the buffer length.
2505 */
2506 static int
2507InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2508{
2509 /* First of all, we check the type of the supplied Python object.
2510 * It must be a string or a list, or the call is in error.
2511 */
2512 if (PyString_Check(lines))
2513 {
2514 char *str = StringToLine(lines);
2515 buf_T *savebuf;
2516
2517 if (str == NULL)
2518 return FAIL;
2519
2520 savebuf = curbuf;
2521
2522 PyErr_Clear();
2523 curbuf = buf;
2524
2525 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2526 PyErr_SetVim(_("cannot save undo information"));
2527 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2528 PyErr_SetVim(_("cannot insert line"));
2529 else
2530 appended_lines_mark((linenr_T)n, 1L);
2531
2532 vim_free(str);
2533 curbuf = savebuf;
2534 update_screen(VALID);
2535
2536 if (PyErr_Occurred() || VimErrorCheck())
2537 return FAIL;
2538
2539 if (len_change)
2540 *len_change = 1;
2541
2542 return OK;
2543 }
2544 else if (PyList_Check(lines))
2545 {
2546 PyInt i;
2547 PyInt size = PyList_Size(lines);
2548 char **array;
2549 buf_T *savebuf;
2550
2551 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2552 if (array == NULL)
2553 {
2554 PyErr_NoMemory();
2555 return FAIL;
2556 }
2557
2558 for (i = 0; i < size; ++i)
2559 {
2560 PyObject *line = PyList_GetItem(lines, i);
2561 array[i] = StringToLine(line);
2562
2563 if (array[i] == NULL)
2564 {
2565 while (i)
2566 vim_free(array[--i]);
2567 vim_free(array);
2568 return FAIL;
2569 }
2570 }
2571
2572 savebuf = curbuf;
2573
2574 PyErr_Clear();
2575 curbuf = buf;
2576
2577 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2578 PyErr_SetVim(_("cannot save undo information"));
2579 else
2580 {
2581 for (i = 0; i < size; ++i)
2582 {
2583 if (ml_append((linenr_T)(n + i),
2584 (char_u *)array[i], 0, FALSE) == FAIL)
2585 {
2586 PyErr_SetVim(_("cannot insert line"));
2587
2588 /* Free the rest of the lines */
2589 while (i < size)
2590 vim_free(array[i++]);
2591
2592 break;
2593 }
2594 vim_free(array[i]);
2595 }
2596 if (i > 0)
2597 appended_lines_mark((linenr_T)n, (long)i);
2598 }
2599
2600 /* Free the array of lines. All of its contents have now
2601 * been freed.
2602 */
2603 vim_free(array);
2604
2605 curbuf = savebuf;
2606 update_screen(VALID);
2607
2608 if (PyErr_Occurred() || VimErrorCheck())
2609 return FAIL;
2610
2611 if (len_change)
2612 *len_change = size;
2613
2614 return OK;
2615 }
2616 else
2617 {
2618 PyErr_BadArgument();
2619 return FAIL;
2620 }
2621}
2622
2623/*
2624 * Common routines for buffers and line ranges
2625 * -------------------------------------------
2626 */
2627
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002628typedef struct
2629{
2630 PyObject_HEAD
2631 buf_T *buf;
2632} BufferObject;
2633
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002634 static int
2635CheckBuffer(BufferObject *this)
2636{
2637 if (this->buf == INVALID_BUFFER_VALUE)
2638 {
2639 PyErr_SetVim(_("attempt to refer to deleted buffer"));
2640 return -1;
2641 }
2642
2643 return 0;
2644}
2645
2646 static PyObject *
2647RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
2648{
2649 if (CheckBuffer(self))
2650 return NULL;
2651
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002652 if (end == -1)
2653 end = self->buf->b_ml.ml_line_count;
2654
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002655 if (n < 0)
2656 n += end - start + 1;
2657
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002658 if (n < 0 || n > end - start)
2659 {
2660 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2661 return NULL;
2662 }
2663
2664 return GetBufferLine(self->buf, n+start);
2665}
2666
2667 static PyObject *
2668RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
2669{
2670 PyInt size;
2671
2672 if (CheckBuffer(self))
2673 return NULL;
2674
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002675 if (end == -1)
2676 end = self->buf->b_ml.ml_line_count;
2677
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002678 size = end - start + 1;
2679
2680 if (lo < 0)
2681 lo = 0;
2682 else if (lo > size)
2683 lo = size;
2684 if (hi < 0)
2685 hi = 0;
2686 if (hi < lo)
2687 hi = lo;
2688 else if (hi > size)
2689 hi = size;
2690
2691 return GetBufferLineList(self->buf, lo+start, hi+start);
2692}
2693
2694 static PyInt
2695RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2696{
2697 PyInt len_change;
2698
2699 if (CheckBuffer(self))
2700 return -1;
2701
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002702 if (end == -1)
2703 end = self->buf->b_ml.ml_line_count;
2704
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002705 if (n < 0)
2706 n += end - start + 1;
2707
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002708 if (n < 0 || n > end - start)
2709 {
2710 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2711 return -1;
2712 }
2713
2714 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
2715 return -1;
2716
2717 if (new_end)
2718 *new_end = end + len_change;
2719
2720 return 0;
2721}
2722
Bram Moolenaar19e60942011-06-19 00:27:51 +02002723 static PyInt
2724RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2725{
2726 PyInt size;
2727 PyInt len_change;
2728
2729 /* Self must be a valid buffer */
2730 if (CheckBuffer(self))
2731 return -1;
2732
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002733 if (end == -1)
2734 end = self->buf->b_ml.ml_line_count;
2735
Bram Moolenaar19e60942011-06-19 00:27:51 +02002736 /* Sort out the slice range */
2737 size = end - start + 1;
2738
2739 if (lo < 0)
2740 lo = 0;
2741 else if (lo > size)
2742 lo = size;
2743 if (hi < 0)
2744 hi = 0;
2745 if (hi < lo)
2746 hi = lo;
2747 else if (hi > size)
2748 hi = size;
2749
2750 if (SetBufferLineList(self->buf, lo + start, hi + start,
2751 val, &len_change) == FAIL)
2752 return -1;
2753
2754 if (new_end)
2755 *new_end = end + len_change;
2756
2757 return 0;
2758}
2759
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002760
2761 static PyObject *
2762RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
2763{
2764 PyObject *lines;
2765 PyInt len_change;
2766 PyInt max;
2767 PyInt n;
2768
2769 if (CheckBuffer(self))
2770 return NULL;
2771
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002772 if (end == -1)
2773 end = self->buf->b_ml.ml_line_count;
2774
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002775 max = n = end - start + 1;
2776
2777 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
2778 return NULL;
2779
2780 if (n < 0 || n > max)
2781 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002782 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002783 return NULL;
2784 }
2785
2786 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
2787 return NULL;
2788
2789 if (new_end)
2790 *new_end = end + len_change;
2791
2792 Py_INCREF(Py_None);
2793 return Py_None;
2794}
2795
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002796/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002797 */
2798
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002799static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002800static PySequenceMethods RangeAsSeq;
2801static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002802
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002803typedef struct
2804{
2805 PyObject_HEAD
2806 BufferObject *buf;
2807 PyInt start;
2808 PyInt end;
2809} RangeObject;
2810
2811 static PyObject *
2812RangeNew(buf_T *buf, PyInt start, PyInt end)
2813{
2814 BufferObject *bufr;
2815 RangeObject *self;
2816 self = PyObject_NEW(RangeObject, &RangeType);
2817 if (self == NULL)
2818 return NULL;
2819
2820 bufr = (BufferObject *)BufferNew(buf);
2821 if (bufr == NULL)
2822 {
2823 Py_DECREF(self);
2824 return NULL;
2825 }
2826 Py_INCREF(bufr);
2827
2828 self->buf = bufr;
2829 self->start = start;
2830 self->end = end;
2831
2832 return (PyObject *)(self);
2833}
2834
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002835 static void
2836RangeDestructor(PyObject *self)
2837{
2838 Py_DECREF(((RangeObject *)(self))->buf);
2839 DESTRUCTOR_FINISH(self);
2840}
2841
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002842 static PyInt
2843RangeLength(PyObject *self)
2844{
2845 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
2846 if (CheckBuffer(((RangeObject *)(self))->buf))
2847 return -1; /* ??? */
2848
2849 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
2850}
2851
2852 static PyObject *
2853RangeItem(PyObject *self, PyInt n)
2854{
2855 return RBItem(((RangeObject *)(self))->buf, n,
2856 ((RangeObject *)(self))->start,
2857 ((RangeObject *)(self))->end);
2858}
2859
2860 static PyObject *
2861RangeSlice(PyObject *self, PyInt lo, PyInt hi)
2862{
2863 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
2864 ((RangeObject *)(self))->start,
2865 ((RangeObject *)(self))->end);
2866}
2867
2868 static PyObject *
2869RangeAppend(PyObject *self, PyObject *args)
2870{
2871 return RBAppend(((RangeObject *)(self))->buf, args,
2872 ((RangeObject *)(self))->start,
2873 ((RangeObject *)(self))->end,
2874 &((RangeObject *)(self))->end);
2875}
2876
2877 static PyObject *
2878RangeRepr(PyObject *self)
2879{
2880 static char repr[100];
2881 RangeObject *this = (RangeObject *)(self);
2882
2883 if (this->buf->buf == INVALID_BUFFER_VALUE)
2884 {
2885 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
2886 (self));
2887 return PyString_FromString(repr);
2888 }
2889 else
2890 {
2891 char *name = (char *)this->buf->buf->b_fname;
2892 int len;
2893
2894 if (name == NULL)
2895 name = "";
2896 len = (int)strlen(name);
2897
2898 if (len > 45)
2899 name = name + (45 - len);
2900
2901 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
2902 len > 45 ? "..." : "", name,
2903 this->start, this->end);
2904
2905 return PyString_FromString(repr);
2906 }
2907}
2908
2909static struct PyMethodDef RangeMethods[] = {
2910 /* name, function, calling, documentation */
2911 {"append", RangeAppend, 1, "Append data to the Vim range" },
2912 { NULL, NULL, 0, NULL }
2913};
2914
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002915static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002916static PySequenceMethods BufferAsSeq;
2917static PyMappingMethods BufferAsMapping;
2918
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002919 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02002920BufferNew(buf_T *buf)
2921{
2922 /* We need to handle deletion of buffers underneath us.
2923 * If we add a "b_python*_ref" field to the buf_T structure,
2924 * then we can get at it in buf_freeall() in vim. We then
2925 * need to create only ONE Python object per buffer - if
2926 * we try to create a second, just INCREF the existing one
2927 * and return it. The (single) Python object referring to
2928 * the buffer is stored in "b_python*_ref".
2929 * Question: what to do on a buf_freeall(). We'll probably
2930 * have to either delete the Python object (DECREF it to
2931 * zero - a bad idea, as it leaves dangling refs!) or
2932 * set the buf_T * value to an invalid value (-1?), which
2933 * means we need checks in all access functions... Bah.
2934 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002935 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02002936 * b_python_ref and b_python3_ref fields respectively.
2937 */
2938
2939 BufferObject *self;
2940
2941 if (BUF_PYTHON_REF(buf) != NULL)
2942 {
2943 self = BUF_PYTHON_REF(buf);
2944 Py_INCREF(self);
2945 }
2946 else
2947 {
2948 self = PyObject_NEW(BufferObject, &BufferType);
2949 if (self == NULL)
2950 return NULL;
2951 self->buf = buf;
2952 BUF_PYTHON_REF(buf) = self;
2953 }
2954
2955 return (PyObject *)(self);
2956}
2957
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002958 static void
2959BufferDestructor(PyObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002960{
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002961 BufferObject *this = (BufferObject *)(self);
2962
2963 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
2964 BUF_PYTHON_REF(this->buf) = NULL;
2965
2966 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002967}
2968
Bram Moolenaar971db462013-05-12 18:44:48 +02002969 static PyInt
2970BufferLength(PyObject *self)
2971{
2972 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
2973 if (CheckBuffer((BufferObject *)(self)))
2974 return -1; /* ??? */
2975
2976 return (PyInt)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
2977}
2978
2979 static PyObject *
2980BufferItem(PyObject *self, PyInt n)
2981{
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002982 return RBItem((BufferObject *)(self), n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02002983}
2984
2985 static PyObject *
2986BufferSlice(PyObject *self, PyInt lo, PyInt hi)
2987{
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002988 return RBSlice((BufferObject *)(self), lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02002989}
2990
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002991 static PyObject *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002992BufferAttr(BufferObject *this, char *name)
2993{
2994 if (strcmp(name, "name") == 0)
2995 return Py_BuildValue("s", this->buf->b_ffname);
2996 else if (strcmp(name, "number") == 0)
2997 return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
2998 else if (strcmp(name, "vars") == 0)
2999 return DictionaryNew(this->buf->b_vars);
3000 else if (strcmp(name, "options") == 0)
3001 return OptionsNew(SREQ_BUF, this->buf, (checkfun) CheckBuffer,
3002 (PyObject *) this);
3003 else if (strcmp(name,"__members__") == 0)
3004 return Py_BuildValue("[ssss]", "name", "number", "vars", "options");
3005 else
3006 return NULL;
3007}
3008
3009 static PyObject *
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003010BufferAppend(PyObject *self, PyObject *args)
3011{
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003012 return RBAppend((BufferObject *)(self), args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003013}
3014
3015 static PyObject *
3016BufferMark(PyObject *self, PyObject *args)
3017{
3018 pos_T *posp;
3019 char *pmark;
3020 char mark;
3021 buf_T *curbuf_save;
3022
3023 if (CheckBuffer((BufferObject *)(self)))
3024 return NULL;
3025
3026 if (!PyArg_ParseTuple(args, "s", &pmark))
3027 return NULL;
3028 mark = *pmark;
3029
3030 curbuf_save = curbuf;
3031 curbuf = ((BufferObject *)(self))->buf;
3032 posp = getmark(mark, FALSE);
3033 curbuf = curbuf_save;
3034
3035 if (posp == NULL)
3036 {
3037 PyErr_SetVim(_("invalid mark name"));
3038 return NULL;
3039 }
3040
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003041 /* Check for keyboard interrupt */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003042 if (VimErrorCheck())
3043 return NULL;
3044
3045 if (posp->lnum <= 0)
3046 {
3047 /* Or raise an error? */
3048 Py_INCREF(Py_None);
3049 return Py_None;
3050 }
3051
3052 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3053}
3054
3055 static PyObject *
3056BufferRange(PyObject *self, PyObject *args)
3057{
3058 PyInt start;
3059 PyInt end;
3060
3061 if (CheckBuffer((BufferObject *)(self)))
3062 return NULL;
3063
3064 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3065 return NULL;
3066
3067 return RangeNew(((BufferObject *)(self))->buf, start, end);
3068}
3069
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003070 static PyObject *
3071BufferRepr(PyObject *self)
3072{
3073 static char repr[100];
3074 BufferObject *this = (BufferObject *)(self);
3075
3076 if (this->buf == INVALID_BUFFER_VALUE)
3077 {
3078 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3079 return PyString_FromString(repr);
3080 }
3081 else
3082 {
3083 char *name = (char *)this->buf->b_fname;
3084 PyInt len;
3085
3086 if (name == NULL)
3087 name = "";
3088 len = strlen(name);
3089
3090 if (len > 35)
3091 name = name + (35 - len);
3092
3093 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3094
3095 return PyString_FromString(repr);
3096 }
3097}
3098
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003099static struct PyMethodDef BufferMethods[] = {
3100 /* name, function, calling, documentation */
3101 {"append", BufferAppend, 1, "Append data to Vim buffer" },
3102 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
3103 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaar7f85d292012-02-04 20:17:26 +01003104#if PY_VERSION_HEX >= 0x03000000
3105 {"__dir__", BufferDir, 4, "List its attributes" },
3106#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003107 { NULL, NULL, 0, NULL }
3108};
3109
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003110/*
3111 * Buffer list object - Implementation
3112 */
3113
3114static PyTypeObject BufMapType;
3115
3116typedef struct
3117{
3118 PyObject_HEAD
3119} BufMapObject;
3120
3121 static PyInt
3122BufMapLength(PyObject *self UNUSED)
3123{
3124 buf_T *b = firstbuf;
3125 PyInt n = 0;
3126
3127 while (b)
3128 {
3129 ++n;
3130 b = b->b_next;
3131 }
3132
3133 return n;
3134}
3135
3136 static PyObject *
3137BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3138{
3139 buf_T *b;
3140 int bnr;
3141
3142#if PY_MAJOR_VERSION < 3
3143 if (PyInt_Check(keyObject))
3144 bnr = PyInt_AsLong(keyObject);
3145 else
3146#endif
3147 if (PyLong_Check(keyObject))
3148 bnr = PyLong_AsLong(keyObject);
3149 else
3150 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003151 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003152 return NULL;
3153 }
3154
3155 b = buflist_findnr(bnr);
3156
3157 if (b)
3158 return BufferNew(b);
3159 else
3160 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003161 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003162 return NULL;
3163 }
3164}
3165
3166 static void
3167BufMapIterDestruct(PyObject *buffer)
3168{
3169 /* Iteration was stopped before all buffers were processed */
3170 if (buffer)
3171 {
3172 Py_DECREF(buffer);
3173 }
3174}
3175
3176 static PyObject *
3177BufMapIterNext(PyObject **buffer)
3178{
3179 PyObject *next;
3180 PyObject *r;
3181
3182 if (!*buffer)
3183 return NULL;
3184
3185 r = *buffer;
3186
3187 if (CheckBuffer((BufferObject *)(r)))
3188 {
3189 *buffer = NULL;
3190 return NULL;
3191 }
3192
3193 if (!((BufferObject *)(r))->buf->b_next)
3194 next = NULL;
3195 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3196 return NULL;
3197 *buffer = next;
3198 /* Do not increment reference: we no longer hold it (decref), but whoever on
3199 * other side will hold (incref). Decref+incref = nothing.
3200 */
3201 return r;
3202}
3203
3204 static PyObject *
3205BufMapIter(PyObject *self UNUSED)
3206{
3207 PyObject *buffer;
3208
3209 buffer = BufferNew(firstbuf);
3210 return IterNew(buffer,
3211 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext);
3212}
3213
3214static PyMappingMethods BufMapAsMapping = {
3215 (lenfunc) BufMapLength,
3216 (binaryfunc) BufMapItem,
3217 (objobjargproc) 0,
3218};
3219
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003220/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003221 */
3222
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003223 static PyObject *
3224CurrentGetattr(PyObject *self UNUSED, char *name)
3225{
3226 if (strcmp(name, "buffer") == 0)
3227 return (PyObject *)BufferNew(curbuf);
3228 else if (strcmp(name, "window") == 0)
3229 return (PyObject *)WindowNew(curwin);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003230 else if (strcmp(name, "tabpage") == 0)
3231 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003232 else if (strcmp(name, "line") == 0)
3233 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3234 else if (strcmp(name, "range") == 0)
3235 return RangeNew(curbuf, RangeStart, RangeEnd);
3236 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003237 return Py_BuildValue("[sssss]", "buffer", "window", "line", "range",
3238 "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003239 else
3240 {
3241 PyErr_SetString(PyExc_AttributeError, name);
3242 return NULL;
3243 }
3244}
3245
3246 static int
3247CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3248{
3249 if (strcmp(name, "line") == 0)
3250 {
3251 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3252 return -1;
3253
3254 return 0;
3255 }
Bram Moolenaare7614592013-05-15 15:51:08 +02003256 else if (strcmp(name, "buffer") == 0)
3257 {
3258 int count;
3259
3260 if (value->ob_type != &BufferType)
3261 {
3262 PyErr_SetString(PyExc_TypeError, _("expected vim.buffer object"));
3263 return -1;
3264 }
3265
3266 if (CheckBuffer((BufferObject *)(value)))
3267 return -1;
3268 count = ((BufferObject *)(value))->buf->b_fnum;
3269
3270 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
3271 {
3272 PyErr_SetVim(_("failed to switch to given buffer"));
3273 return -1;
3274 }
3275
3276 return 0;
3277 }
3278 else if (strcmp(name, "window") == 0)
3279 {
3280 int count;
3281
3282 if (value->ob_type != &WindowType)
3283 {
3284 PyErr_SetString(PyExc_TypeError, _("expected vim.window object"));
3285 return -1;
3286 }
3287
3288 if (CheckWindow((WindowObject *)(value)))
3289 return -1;
3290 count = get_win_number(((WindowObject *)(value))->win, firstwin);
3291
3292 if (!count)
3293 {
3294 PyErr_SetString(PyExc_ValueError,
3295 _("failed to find window in the current tab page"));
3296 return -1;
3297 }
3298
3299 win_goto(((WindowObject *)(value))->win);
3300 if (((WindowObject *)(value))->win != curwin)
3301 {
3302 PyErr_SetString(PyExc_RuntimeError,
3303 _("did not switch to the specified window"));
3304 return -1;
3305 }
3306
3307 return 0;
3308 }
3309 else if (strcmp(name, "tabpage") == 0)
3310 {
3311 if (value->ob_type != &TabPageType)
3312 {
3313 PyErr_SetString(PyExc_TypeError, _("expected vim.tabpage object"));
3314 return -1;
3315 }
3316
3317 if (CheckTabPage((TabPageObject *)(value)))
3318 return -1;
3319
3320 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
3321 if (((TabPageObject *)(value))->tab != curtab)
3322 {
3323 PyErr_SetString(PyExc_RuntimeError,
3324 _("did not switch to the specified tab page"));
3325 return -1;
3326 }
3327
3328 return 0;
3329 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003330 else
3331 {
3332 PyErr_SetString(PyExc_AttributeError, name);
3333 return -1;
3334 }
3335}
3336
Bram Moolenaardb913952012-06-29 12:54:53 +02003337 static void
3338set_ref_in_py(const int copyID)
3339{
3340 pylinkedlist_T *cur;
3341 dict_T *dd;
3342 list_T *ll;
3343
3344 if (lastdict != NULL)
3345 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3346 {
3347 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3348 if (dd->dv_copyID != copyID)
3349 {
3350 dd->dv_copyID = copyID;
3351 set_ref_in_ht(&dd->dv_hashtab, copyID);
3352 }
3353 }
3354
3355 if (lastlist != NULL)
3356 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3357 {
3358 ll = ((ListObject *) (cur->pll_obj))->list;
3359 if (ll->lv_copyID != copyID)
3360 {
3361 ll->lv_copyID = copyID;
3362 set_ref_in_list(ll, copyID);
3363 }
3364 }
3365}
3366
3367 static int
3368set_string_copy(char_u *str, typval_T *tv)
3369{
3370 tv->vval.v_string = vim_strsave(str);
3371 if (tv->vval.v_string == NULL)
3372 {
3373 PyErr_NoMemory();
3374 return -1;
3375 }
3376 return 0;
3377}
3378
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003379 static int
3380pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3381{
3382 dict_T *d;
3383 char_u *key;
3384 dictitem_T *di;
3385 PyObject *keyObject;
3386 PyObject *valObject;
3387 Py_ssize_t iter = 0;
3388
3389 d = dict_alloc();
3390 if (d == NULL)
3391 {
3392 PyErr_NoMemory();
3393 return -1;
3394 }
3395
3396 tv->v_type = VAR_DICT;
3397 tv->vval.v_dict = d;
3398
3399 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
3400 {
3401 DICTKEY_DECL
3402
3403 if (keyObject == NULL)
3404 return -1;
3405 if (valObject == NULL)
3406 return -1;
3407
3408 DICTKEY_GET_NOTEMPTY(-1)
3409
3410 di = dictitem_alloc(key);
3411
3412 DICTKEY_UNREF
3413
3414 if (di == NULL)
3415 {
3416 PyErr_NoMemory();
3417 return -1;
3418 }
3419 di->di_tv.v_lock = 0;
3420
3421 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3422 {
3423 vim_free(di);
3424 return -1;
3425 }
3426 if (dict_add(d, di) == FAIL)
3427 {
3428 vim_free(di);
3429 PyErr_SetVim(_("failed to add key to dictionary"));
3430 return -1;
3431 }
3432 }
3433 return 0;
3434}
3435
3436 static int
3437pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3438{
3439 dict_T *d;
3440 char_u *key;
3441 dictitem_T *di;
3442 PyObject *list;
3443 PyObject *litem;
3444 PyObject *keyObject;
3445 PyObject *valObject;
3446 Py_ssize_t lsize;
3447
3448 d = dict_alloc();
3449 if (d == NULL)
3450 {
3451 PyErr_NoMemory();
3452 return -1;
3453 }
3454
3455 tv->v_type = VAR_DICT;
3456 tv->vval.v_dict = d;
3457
3458 list = PyMapping_Items(obj);
3459 if (list == NULL)
3460 return -1;
3461 lsize = PyList_Size(list);
3462 while (lsize--)
3463 {
3464 DICTKEY_DECL
3465
3466 litem = PyList_GetItem(list, lsize);
3467 if (litem == NULL)
3468 {
3469 Py_DECREF(list);
3470 return -1;
3471 }
3472
3473 keyObject = PyTuple_GetItem(litem, 0);
3474 if (keyObject == NULL)
3475 {
3476 Py_DECREF(list);
3477 Py_DECREF(litem);
3478 return -1;
3479 }
3480
3481 DICTKEY_GET_NOTEMPTY(-1)
3482
3483 valObject = PyTuple_GetItem(litem, 1);
3484 if (valObject == NULL)
3485 {
3486 Py_DECREF(list);
3487 Py_DECREF(litem);
3488 return -1;
3489 }
3490
3491 di = dictitem_alloc(key);
3492
3493 DICTKEY_UNREF
3494
3495 if (di == NULL)
3496 {
3497 Py_DECREF(list);
3498 Py_DECREF(litem);
3499 PyErr_NoMemory();
3500 return -1;
3501 }
3502 di->di_tv.v_lock = 0;
3503
3504 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3505 {
3506 vim_free(di);
3507 Py_DECREF(list);
3508 Py_DECREF(litem);
3509 return -1;
3510 }
3511 if (dict_add(d, di) == FAIL)
3512 {
3513 vim_free(di);
3514 Py_DECREF(list);
3515 Py_DECREF(litem);
3516 PyErr_SetVim(_("failed to add key to dictionary"));
3517 return -1;
3518 }
3519 Py_DECREF(litem);
3520 }
3521 Py_DECREF(list);
3522 return 0;
3523}
3524
3525 static int
3526pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3527{
3528 list_T *l;
3529
3530 l = list_alloc();
3531 if (l == NULL)
3532 {
3533 PyErr_NoMemory();
3534 return -1;
3535 }
3536
3537 tv->v_type = VAR_LIST;
3538 tv->vval.v_list = l;
3539
3540 if (list_py_concat(l, obj, lookupDict) == -1)
3541 return -1;
3542
3543 return 0;
3544}
3545
3546 static int
3547pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3548{
3549 PyObject *iterator = PyObject_GetIter(obj);
3550 PyObject *item;
3551 list_T *l;
3552 listitem_T *li;
3553
3554 l = list_alloc();
3555
3556 if (l == NULL)
3557 {
3558 PyErr_NoMemory();
3559 return -1;
3560 }
3561
3562 tv->vval.v_list = l;
3563 tv->v_type = VAR_LIST;
3564
3565
3566 if (iterator == NULL)
3567 return -1;
3568
3569 while ((item = PyIter_Next(obj)))
3570 {
3571 li = listitem_alloc();
3572 if (li == NULL)
3573 {
3574 PyErr_NoMemory();
3575 return -1;
3576 }
3577 li->li_tv.v_lock = 0;
3578
3579 if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
3580 return -1;
3581
3582 list_append(l, li);
3583
3584 Py_DECREF(item);
3585 }
3586
3587 Py_DECREF(iterator);
3588 return 0;
3589}
3590
Bram Moolenaardb913952012-06-29 12:54:53 +02003591typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
3592
3593 static int
3594convert_dl(PyObject *obj, typval_T *tv,
3595 pytotvfunc py_to_tv, PyObject *lookupDict)
3596{
3597 PyObject *capsule;
3598 char hexBuf[sizeof(void *) * 2 + 3];
3599
3600 sprintf(hexBuf, "%p", obj);
3601
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003602# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02003603 capsule = PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003604# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02003605 capsule = (PyObject *)PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003606# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02003607 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02003608 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003609# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02003610 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02003611# else
3612 capsule = PyCObject_FromVoidPtr(tv, NULL);
3613# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02003614 PyDict_SetItemString(lookupDict, hexBuf, capsule);
3615 Py_DECREF(capsule);
3616 if (py_to_tv(obj, tv, lookupDict) == -1)
3617 {
3618 tv->v_type = VAR_UNKNOWN;
3619 return -1;
3620 }
3621 /* As we are not using copy_tv which increments reference count we must
3622 * do it ourself. */
3623 switch(tv->v_type)
3624 {
3625 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
3626 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
3627 }
3628 }
3629 else
3630 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003631 typval_T *v;
3632
3633# ifdef PY_USE_CAPSULE
3634 v = PyCapsule_GetPointer(capsule, NULL);
3635# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02003636 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003637# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02003638 copy_tv(v, tv);
3639 }
3640 return 0;
3641}
3642
3643 static int
3644ConvertFromPyObject(PyObject *obj, typval_T *tv)
3645{
3646 PyObject *lookup_dict;
3647 int r;
3648
3649 lookup_dict = PyDict_New();
3650 r = _ConvertFromPyObject(obj, tv, lookup_dict);
3651 Py_DECREF(lookup_dict);
3652 return r;
3653}
3654
3655 static int
3656_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3657{
3658 if (obj->ob_type == &DictionaryType)
3659 {
3660 tv->v_type = VAR_DICT;
3661 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
3662 ++tv->vval.v_dict->dv_refcount;
3663 }
3664 else if (obj->ob_type == &ListType)
3665 {
3666 tv->v_type = VAR_LIST;
3667 tv->vval.v_list = (((ListObject *)(obj))->list);
3668 ++tv->vval.v_list->lv_refcount;
3669 }
3670 else if (obj->ob_type == &FunctionType)
3671 {
3672 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
3673 return -1;
3674
3675 tv->v_type = VAR_FUNC;
3676 func_ref(tv->vval.v_string);
3677 }
Bram Moolenaardb913952012-06-29 12:54:53 +02003678 else if (PyBytes_Check(obj))
3679 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003680 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02003681
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003682 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
3683 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02003684 if (result == NULL)
3685 return -1;
3686
3687 if (set_string_copy(result, tv) == -1)
3688 return -1;
3689
3690 tv->v_type = VAR_STRING;
3691 }
3692 else if (PyUnicode_Check(obj))
3693 {
3694 PyObject *bytes;
3695 char_u *result;
3696
Bram Moolenaardb913952012-06-29 12:54:53 +02003697 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
3698 if (bytes == NULL)
3699 return -1;
3700
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003701 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
3702 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02003703 if (result == NULL)
3704 return -1;
3705
3706 if (set_string_copy(result, tv) == -1)
3707 {
3708 Py_XDECREF(bytes);
3709 return -1;
3710 }
3711 Py_XDECREF(bytes);
3712
3713 tv->v_type = VAR_STRING;
3714 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02003715#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02003716 else if (PyInt_Check(obj))
3717 {
3718 tv->v_type = VAR_NUMBER;
3719 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
3720 }
3721#endif
3722 else if (PyLong_Check(obj))
3723 {
3724 tv->v_type = VAR_NUMBER;
3725 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
3726 }
3727 else if (PyDict_Check(obj))
3728 return convert_dl(obj, tv, pydict_to_tv, lookupDict);
3729#ifdef FEAT_FLOAT
3730 else if (PyFloat_Check(obj))
3731 {
3732 tv->v_type = VAR_FLOAT;
3733 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
3734 }
3735#endif
3736 else if (PyIter_Check(obj))
3737 return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
3738 else if (PySequence_Check(obj))
3739 return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
3740 else if (PyMapping_Check(obj))
3741 return convert_dl(obj, tv, pymap_to_tv, lookupDict);
3742 else
3743 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003744 PyErr_SetString(PyExc_TypeError,
3745 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02003746 return -1;
3747 }
3748 return 0;
3749}
3750
3751 static PyObject *
3752ConvertToPyObject(typval_T *tv)
3753{
3754 if (tv == NULL)
3755 {
3756 PyErr_SetVim(_("NULL reference passed"));
3757 return NULL;
3758 }
3759 switch (tv->v_type)
3760 {
3761 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02003762 return PyBytes_FromString(tv->vval.v_string == NULL
3763 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02003764 case VAR_NUMBER:
3765 return PyLong_FromLong((long) tv->vval.v_number);
3766#ifdef FEAT_FLOAT
3767 case VAR_FLOAT:
3768 return PyFloat_FromDouble((double) tv->vval.v_float);
3769#endif
3770 case VAR_LIST:
3771 return ListNew(tv->vval.v_list);
3772 case VAR_DICT:
3773 return DictionaryNew(tv->vval.v_dict);
3774 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02003775 return FunctionNew(tv->vval.v_string == NULL
3776 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02003777 case VAR_UNKNOWN:
3778 Py_INCREF(Py_None);
3779 return Py_None;
3780 default:
3781 PyErr_SetVim(_("internal error: invalid value type"));
3782 return NULL;
3783 }
3784}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003785
3786typedef struct
3787{
3788 PyObject_HEAD
3789} CurrentObject;
3790static PyTypeObject CurrentType;
3791
3792 static void
3793init_structs(void)
3794{
3795 vim_memset(&OutputType, 0, sizeof(OutputType));
3796 OutputType.tp_name = "vim.message";
3797 OutputType.tp_basicsize = sizeof(OutputObject);
3798 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
3799 OutputType.tp_doc = "vim message object";
3800 OutputType.tp_methods = OutputMethods;
3801#if PY_MAJOR_VERSION >= 3
3802 OutputType.tp_getattro = OutputGetattro;
3803 OutputType.tp_setattro = OutputSetattro;
3804 OutputType.tp_alloc = call_PyType_GenericAlloc;
3805 OutputType.tp_new = call_PyType_GenericNew;
3806 OutputType.tp_free = call_PyObject_Free;
3807#else
3808 OutputType.tp_getattr = OutputGetattr;
3809 OutputType.tp_setattr = OutputSetattr;
3810#endif
3811
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003812 vim_memset(&IterType, 0, sizeof(IterType));
3813 IterType.tp_name = "vim.iter";
3814 IterType.tp_basicsize = sizeof(IterObject);
3815 IterType.tp_flags = Py_TPFLAGS_DEFAULT;
3816 IterType.tp_doc = "generic iterator object";
3817 IterType.tp_iter = IterIter;
3818 IterType.tp_iternext = IterNext;
3819
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003820 vim_memset(&BufferType, 0, sizeof(BufferType));
3821 BufferType.tp_name = "vim.buffer";
3822 BufferType.tp_basicsize = sizeof(BufferType);
3823 BufferType.tp_dealloc = BufferDestructor;
3824 BufferType.tp_repr = BufferRepr;
3825 BufferType.tp_as_sequence = &BufferAsSeq;
3826 BufferType.tp_as_mapping = &BufferAsMapping;
3827 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
3828 BufferType.tp_doc = "vim buffer object";
3829 BufferType.tp_methods = BufferMethods;
3830#if PY_MAJOR_VERSION >= 3
3831 BufferType.tp_getattro = BufferGetattro;
3832 BufferType.tp_alloc = call_PyType_GenericAlloc;
3833 BufferType.tp_new = call_PyType_GenericNew;
3834 BufferType.tp_free = call_PyObject_Free;
3835#else
3836 BufferType.tp_getattr = BufferGetattr;
3837#endif
3838
3839 vim_memset(&WindowType, 0, sizeof(WindowType));
3840 WindowType.tp_name = "vim.window";
3841 WindowType.tp_basicsize = sizeof(WindowObject);
3842 WindowType.tp_dealloc = WindowDestructor;
3843 WindowType.tp_repr = WindowRepr;
3844 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
3845 WindowType.tp_doc = "vim Window object";
3846 WindowType.tp_methods = WindowMethods;
3847#if PY_MAJOR_VERSION >= 3
3848 WindowType.tp_getattro = WindowGetattro;
3849 WindowType.tp_setattro = WindowSetattro;
3850 WindowType.tp_alloc = call_PyType_GenericAlloc;
3851 WindowType.tp_new = call_PyType_GenericNew;
3852 WindowType.tp_free = call_PyObject_Free;
3853#else
3854 WindowType.tp_getattr = WindowGetattr;
3855 WindowType.tp_setattr = WindowSetattr;
3856#endif
3857
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003858 vim_memset(&TabPageType, 0, sizeof(TabPageType));
3859 TabPageType.tp_name = "vim.tabpage";
3860 TabPageType.tp_basicsize = sizeof(TabPageObject);
3861 TabPageType.tp_dealloc = TabPageDestructor;
3862 TabPageType.tp_repr = TabPageRepr;
3863 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
3864 TabPageType.tp_doc = "vim tab page object";
3865 TabPageType.tp_methods = TabPageMethods;
3866#if PY_MAJOR_VERSION >= 3
3867 TabPageType.tp_getattro = TabPageGetattro;
3868 TabPageType.tp_alloc = call_PyType_GenericAlloc;
3869 TabPageType.tp_new = call_PyType_GenericNew;
3870 TabPageType.tp_free = call_PyObject_Free;
3871#else
3872 TabPageType.tp_getattr = TabPageGetattr;
3873#endif
3874
Bram Moolenaardfa38d42013-05-15 13:38:47 +02003875 vim_memset(&BufMapType, 0, sizeof(BufMapType));
3876 BufMapType.tp_name = "vim.bufferlist";
3877 BufMapType.tp_basicsize = sizeof(BufMapObject);
3878 BufMapType.tp_as_mapping = &BufMapAsMapping;
3879 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003880 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003881 BufferType.tp_doc = "vim buffer list";
3882
3883 vim_memset(&WinListType, 0, sizeof(WinListType));
3884 WinListType.tp_name = "vim.windowlist";
3885 WinListType.tp_basicsize = sizeof(WinListType);
3886 WinListType.tp_as_sequence = &WinListAsSeq;
3887 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
3888 WinListType.tp_doc = "vim window list";
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003889 WinListType.tp_dealloc = WinListDestructor;
3890
3891 vim_memset(&TabListType, 0, sizeof(TabListType));
3892 TabListType.tp_name = "vim.tabpagelist";
3893 TabListType.tp_basicsize = sizeof(TabListType);
3894 TabListType.tp_as_sequence = &TabListAsSeq;
3895 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
3896 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003897
3898 vim_memset(&RangeType, 0, sizeof(RangeType));
3899 RangeType.tp_name = "vim.range";
3900 RangeType.tp_basicsize = sizeof(RangeObject);
3901 RangeType.tp_dealloc = RangeDestructor;
3902 RangeType.tp_repr = RangeRepr;
3903 RangeType.tp_as_sequence = &RangeAsSeq;
3904 RangeType.tp_as_mapping = &RangeAsMapping;
3905 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
3906 RangeType.tp_doc = "vim Range object";
3907 RangeType.tp_methods = RangeMethods;
3908#if PY_MAJOR_VERSION >= 3
3909 RangeType.tp_getattro = RangeGetattro;
3910 RangeType.tp_alloc = call_PyType_GenericAlloc;
3911 RangeType.tp_new = call_PyType_GenericNew;
3912 RangeType.tp_free = call_PyObject_Free;
3913#else
3914 RangeType.tp_getattr = RangeGetattr;
3915#endif
3916
3917 vim_memset(&CurrentType, 0, sizeof(CurrentType));
3918 CurrentType.tp_name = "vim.currentdata";
3919 CurrentType.tp_basicsize = sizeof(CurrentObject);
3920 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
3921 CurrentType.tp_doc = "vim current object";
3922#if PY_MAJOR_VERSION >= 3
3923 CurrentType.tp_getattro = CurrentGetattro;
3924 CurrentType.tp_setattro = CurrentSetattro;
3925#else
3926 CurrentType.tp_getattr = CurrentGetattr;
3927 CurrentType.tp_setattr = CurrentSetattr;
3928#endif
3929
3930 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
3931 DictionaryType.tp_name = "vim.dictionary";
3932 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
3933 DictionaryType.tp_dealloc = DictionaryDestructor;
3934 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
3935 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
3936 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
3937 DictionaryType.tp_methods = DictionaryMethods;
3938#if PY_MAJOR_VERSION >= 3
3939 DictionaryType.tp_getattro = DictionaryGetattro;
3940 DictionaryType.tp_setattro = DictionarySetattro;
3941#else
3942 DictionaryType.tp_getattr = DictionaryGetattr;
3943 DictionaryType.tp_setattr = DictionarySetattr;
3944#endif
3945
3946 vim_memset(&ListType, 0, sizeof(ListType));
3947 ListType.tp_name = "vim.list";
3948 ListType.tp_dealloc = ListDestructor;
3949 ListType.tp_basicsize = sizeof(ListObject);
3950 ListType.tp_as_sequence = &ListAsSeq;
3951 ListType.tp_as_mapping = &ListAsMapping;
3952 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
3953 ListType.tp_doc = "list pushing modifications to vim structure";
3954 ListType.tp_methods = ListMethods;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003955 ListType.tp_iter = ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003956#if PY_MAJOR_VERSION >= 3
3957 ListType.tp_getattro = ListGetattro;
3958 ListType.tp_setattro = ListSetattro;
3959#else
3960 ListType.tp_getattr = ListGetattr;
3961 ListType.tp_setattr = ListSetattr;
3962#endif
3963
3964 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003965 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003966 FunctionType.tp_basicsize = sizeof(FunctionObject);
3967 FunctionType.tp_dealloc = FunctionDestructor;
3968 FunctionType.tp_call = FunctionCall;
3969 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
3970 FunctionType.tp_doc = "object that calls vim function";
3971 FunctionType.tp_methods = FunctionMethods;
3972#if PY_MAJOR_VERSION >= 3
3973 FunctionType.tp_getattro = FunctionGetattro;
3974#else
3975 FunctionType.tp_getattr = FunctionGetattr;
3976#endif
3977
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003978 vim_memset(&OptionsType, 0, sizeof(OptionsType));
3979 OptionsType.tp_name = "vim.options";
3980 OptionsType.tp_basicsize = sizeof(OptionsObject);
3981 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT;
3982 OptionsType.tp_doc = "object for manipulating options";
3983 OptionsType.tp_as_mapping = &OptionsAsMapping;
3984 OptionsType.tp_dealloc = OptionsDestructor;
3985
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003986#if PY_MAJOR_VERSION >= 3
3987 vim_memset(&vimmodule, 0, sizeof(vimmodule));
3988 vimmodule.m_name = "vim";
3989 vimmodule.m_doc = "Vim Python interface\n";
3990 vimmodule.m_size = -1;
3991 vimmodule.m_methods = VimMethods;
3992#endif
3993}