blob: 339250e99c34dad37b3a12ab05434633df56243f [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/*
10 * Python extensions by Paul Moore, David Leonard, Roland Puntaier.
11 *
12 * Common code for if_python.c and if_python3.c.
13 */
14
Bram Moolenaarc1a995d2012-08-08 16:05:07 +020015#if PY_VERSION_HEX < 0x02050000
16typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
17#endif
18
Bram Moolenaar91805fc2011-06-26 04:01:44 +020019#ifdef FEAT_MBYTE
20# define ENC_OPT p_enc
21#else
22# define ENC_OPT "latin1"
23#endif
24
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020025/*
26 * obtain a lock on the Vim data structures
27 */
28 static void
29Python_Lock_Vim(void)
30{
31}
32
33/*
34 * release a lock on the Vim data structures
35 */
36 static void
37Python_Release_Vim(void)
38{
39}
40
41/* Output object definition
42 */
43
44static PyObject *OutputWrite(PyObject *, PyObject *);
45static PyObject *OutputWritelines(PyObject *, PyObject *);
Bram Moolenaara29a37d2011-03-22 15:47:44 +010046static PyObject *OutputFlush(PyObject *, PyObject *);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020047
Bram Moolenaar2eea1982010-09-21 16:49:37 +020048/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020049typedef void (*writefn)(char_u *);
50static void writer(writefn fn, char_u *str, PyInt n);
51
52typedef struct
53{
54 PyObject_HEAD
55 long softspace;
56 long error;
57} OutputObject;
58
59static struct PyMethodDef OutputMethods[] = {
60 /* name, function, calling, documentation */
Bram Moolenaara29a37d2011-03-22 15:47:44 +010061 {"write", OutputWrite, 1, ""},
62 {"writelines", OutputWritelines, 1, ""},
Bram Moolenaar2afa3232012-06-29 16:28:28 +020063 {"flush", OutputFlush, 1, ""},
Bram Moolenaara29a37d2011-03-22 15:47:44 +010064 { NULL, NULL, 0, NULL}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020065};
66
Bram Moolenaarca8a4df2010-07-31 19:54:14 +020067#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
68
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020069/*************/
70
71/* Output buffer management
72 */
73
Bram Moolenaar77045652012-09-21 13:46:06 +020074 static int
75OutputSetattr(PyObject *self, char *name, PyObject *val)
76{
77 if (val == NULL)
78 {
79 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
80 return -1;
81 }
82
83 if (strcmp(name, "softspace") == 0)
84 {
85 if (!PyInt_Check(val))
86 {
87 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
88 return -1;
89 }
90
91 ((OutputObject *)(self))->softspace = PyInt_AsLong(val);
92 return 0;
93 }
94
95 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
96 return -1;
97}
98
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020099 static PyObject *
100OutputWrite(PyObject *self, PyObject *args)
101{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200102 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200103 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200104 int error = ((OutputObject *)(self))->error;
105
Bram Moolenaar27564802011-09-07 19:30:21 +0200106 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200107 return NULL;
108
109 Py_BEGIN_ALLOW_THREADS
110 Python_Lock_Vim();
111 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
112 Python_Release_Vim();
113 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200114 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200115
116 Py_INCREF(Py_None);
117 return Py_None;
118}
119
120 static PyObject *
121OutputWritelines(PyObject *self, PyObject *args)
122{
123 PyInt n;
124 PyInt i;
125 PyObject *list;
126 int error = ((OutputObject *)(self))->error;
127
128 if (!PyArg_ParseTuple(args, "O", &list))
129 return NULL;
130 Py_INCREF(list);
131
Bram Moolenaardb913952012-06-29 12:54:53 +0200132 if (!PyList_Check(list))
133 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200134 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
135 Py_DECREF(list);
136 return NULL;
137 }
138
139 n = PyList_Size(list);
140
141 for (i = 0; i < n; ++i)
142 {
143 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200144 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200145 PyInt len;
146
Bram Moolenaardb913952012-06-29 12:54:53 +0200147 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
148 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200149 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
150 Py_DECREF(list);
151 return NULL;
152 }
153
154 Py_BEGIN_ALLOW_THREADS
155 Python_Lock_Vim();
156 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
157 Python_Release_Vim();
158 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200159 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200160 }
161
162 Py_DECREF(list);
163 Py_INCREF(Py_None);
164 return Py_None;
165}
166
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100167 static PyObject *
168OutputFlush(PyObject *self UNUSED, PyObject *args UNUSED)
169{
170 /* do nothing */
171 Py_INCREF(Py_None);
172 return Py_None;
173}
174
175
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200176/* Buffer IO, we write one whole line at a time. */
177static garray_T io_ga = {0, 0, 1, 80, NULL};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200178static writefn old_fn = NULL;
179
180 static void
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200181PythonIO_Flush(void)
182{
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200183 if (old_fn != NULL && io_ga.ga_len > 0)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200184 {
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200185 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
186 old_fn((char_u *)io_ga.ga_data);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200187 }
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200188 io_ga.ga_len = 0;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200189}
190
191 static void
192writer(writefn fn, char_u *str, PyInt n)
193{
194 char_u *ptr;
195
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200196 /* Flush when switching output function. */
197 if (fn != old_fn)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200198 PythonIO_Flush();
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200199 old_fn = fn;
200
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200201 /* Write each NL separated line. Text after the last NL is kept for
202 * writing later. */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200203 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
204 {
205 PyInt len = ptr - str;
206
Bram Moolenaar6b5ef062010-10-27 12:18:00 +0200207 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200208 break;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200209
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200210 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
211 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
212 fn((char_u *)io_ga.ga_data);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200213 str = ptr + 1;
214 n -= len + 1;
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200215 io_ga.ga_len = 0;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200216 }
217
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200218 /* Put the remaining text into io_ga for later printing. */
Bram Moolenaar6b5ef062010-10-27 12:18:00 +0200219 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200220 {
221 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
Bram Moolenaar6b5ef062010-10-27 12:18:00 +0200222 io_ga.ga_len += (int)n;
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200223 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200224}
225
226/***************/
227
228static PyTypeObject OutputType;
229
230static OutputObject Output =
231{
232 PyObject_HEAD_INIT(&OutputType)
233 0,
234 0
235};
236
237static OutputObject Error =
238{
239 PyObject_HEAD_INIT(&OutputType)
240 0,
241 1
242};
243
244 static int
245PythonIO_Init_io(void)
246{
247 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
248 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
249
250 if (PyErr_Occurred())
251 {
252 EMSG(_("E264: Python: Error initialising I/O objects"));
253 return -1;
254 }
255
256 return 0;
257}
258
259
260static PyObject *VimError;
261
262/* Check to see whether a Vim error has been reported, or a keyboard
263 * interrupt has been detected.
264 */
265 static int
266VimErrorCheck(void)
267{
268 if (got_int)
269 {
270 PyErr_SetNone(PyExc_KeyboardInterrupt);
271 return 1;
272 }
273 else if (did_emsg && !PyErr_Occurred())
274 {
275 PyErr_SetNone(VimError);
276 return 1;
277 }
278
279 return 0;
280}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200281
282/* Vim module - Implementation
283 */
284 static PyObject *
285VimCommand(PyObject *self UNUSED, PyObject *args)
286{
287 char *cmd;
288 PyObject *result;
289
290 if (!PyArg_ParseTuple(args, "s", &cmd))
291 return NULL;
292
293 PyErr_Clear();
294
295 Py_BEGIN_ALLOW_THREADS
296 Python_Lock_Vim();
297
298 do_cmdline_cmd((char_u *)cmd);
299 update_screen(VALID);
300
301 Python_Release_Vim();
302 Py_END_ALLOW_THREADS
303
304 if (VimErrorCheck())
305 result = NULL;
306 else
307 result = Py_None;
308
309 Py_XINCREF(result);
310 return result;
311}
312
313#ifdef FEAT_EVAL
314/*
315 * Function to translate a typval_T into a PyObject; this will recursively
316 * translate lists/dictionaries into their Python equivalents.
317 *
318 * The depth parameter is to avoid infinite recursion, set it to 1 when
319 * you call VimToPython.
320 */
321 static PyObject *
322VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
323{
324 PyObject *result;
325 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200326 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200327
328 /* Avoid infinite recursion */
329 if (depth > 100)
330 {
331 Py_INCREF(Py_None);
332 result = Py_None;
333 return result;
334 }
335
336 /* Check if we run into a recursive loop. The item must be in lookupDict
337 * then and we can use it again. */
338 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
339 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
340 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200341 sprintf(ptrBuf, "%p",
342 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
343 : (void *)our_tv->vval.v_dict);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200344 result = PyDict_GetItemString(lookupDict, ptrBuf);
345 if (result != NULL)
346 {
347 Py_INCREF(result);
348 return result;
349 }
350 }
351
352 if (our_tv->v_type == VAR_STRING)
353 {
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200354 result = Py_BuildValue("s", our_tv->vval.v_string == NULL
355 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200356 }
357 else if (our_tv->v_type == VAR_NUMBER)
358 {
359 char buf[NUMBUFLEN];
360
361 /* For backwards compatibility numbers are stored as strings. */
362 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
363 result = Py_BuildValue("s", buf);
364 }
365# ifdef FEAT_FLOAT
366 else if (our_tv->v_type == VAR_FLOAT)
367 {
368 char buf[NUMBUFLEN];
369
370 sprintf(buf, "%f", our_tv->vval.v_float);
371 result = Py_BuildValue("s", buf);
372 }
373# endif
374 else if (our_tv->v_type == VAR_LIST)
375 {
376 list_T *list = our_tv->vval.v_list;
377 listitem_T *curr;
378
379 result = PyList_New(0);
380
381 if (list != NULL)
382 {
383 PyDict_SetItemString(lookupDict, ptrBuf, result);
384
385 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
386 {
387 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
388 PyList_Append(result, newObj);
389 Py_DECREF(newObj);
390 }
391 }
392 }
393 else if (our_tv->v_type == VAR_DICT)
394 {
395 result = PyDict_New();
396
397 if (our_tv->vval.v_dict != NULL)
398 {
399 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
400 long_u todo = ht->ht_used;
401 hashitem_T *hi;
402 dictitem_T *di;
403
404 PyDict_SetItemString(lookupDict, ptrBuf, result);
405
406 for (hi = ht->ht_array; todo > 0; ++hi)
407 {
408 if (!HASHITEM_EMPTY(hi))
409 {
410 --todo;
411
412 di = dict_lookup(hi);
413 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
414 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
415 Py_DECREF(newObj);
416 }
417 }
418 }
419 }
420 else
421 {
422 Py_INCREF(Py_None);
423 result = Py_None;
424 }
425
426 return result;
427}
428#endif
429
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{
433#ifdef FEAT_EVAL
434 char *expr;
435 typval_T *our_tv;
436 PyObject *result;
437 PyObject *lookup_dict;
438
439 if (!PyArg_ParseTuple(args, "s", &expr))
440 return NULL;
441
442 Py_BEGIN_ALLOW_THREADS
443 Python_Lock_Vim();
444 our_tv = eval_expr((char_u *)expr, NULL);
445
446 Python_Release_Vim();
447 Py_END_ALLOW_THREADS
448
449 if (our_tv == NULL)
450 {
451 PyErr_SetVim(_("invalid expression"));
452 return NULL;
453 }
454
455 /* Convert the Vim type into a Python type. Create a dictionary that's
456 * used to check for recursive loops. */
457 lookup_dict = PyDict_New();
458 result = VimToPython(our_tv, 1, lookup_dict);
459 Py_DECREF(lookup_dict);
460
461
462 Py_BEGIN_ALLOW_THREADS
463 Python_Lock_Vim();
464 free_tv(our_tv);
465 Python_Release_Vim();
466 Py_END_ALLOW_THREADS
467
468 return result;
469#else
470 PyErr_SetVim(_("expressions disabled at compile time"));
471 return NULL;
472#endif
473}
474
Bram Moolenaardb913952012-06-29 12:54:53 +0200475static PyObject *ConvertToPyObject(typval_T *);
476
477 static PyObject *
478VimEvalPy(PyObject *self UNUSED, PyObject *args UNUSED)
479{
480#ifdef FEAT_EVAL
481 char *expr;
482 typval_T *our_tv;
483 PyObject *result;
484
485 if (!PyArg_ParseTuple(args, "s", &expr))
486 return NULL;
487
488 Py_BEGIN_ALLOW_THREADS
489 Python_Lock_Vim();
490 our_tv = eval_expr((char_u *)expr, NULL);
491
492 Python_Release_Vim();
493 Py_END_ALLOW_THREADS
494
495 if (our_tv == NULL)
496 {
497 PyErr_SetVim(_("invalid expression"));
498 return NULL;
499 }
500
501 result = ConvertToPyObject(our_tv);
502 Py_BEGIN_ALLOW_THREADS
503 Python_Lock_Vim();
504 free_tv(our_tv);
505 Python_Release_Vim();
506 Py_END_ALLOW_THREADS
507
508 return result;
509#else
510 PyErr_SetVim(_("expressions disabled at compile time"));
511 return NULL;
512#endif
513}
514
515 static PyObject *
516VimStrwidth(PyObject *self UNUSED, PyObject *args)
517{
518 char *expr;
519
520 if (!PyArg_ParseTuple(args, "s", &expr))
521 return NULL;
522
Bram Moolenaara54bf402012-12-05 16:30:07 +0100523 return PyLong_FromLong(
524#ifdef FEAT_MBYTE
525 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
526#else
527 STRLEN(expr)
528#endif
529 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200530}
531
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200532/*
533 * Vim module - Definitions
534 */
535
536static struct PyMethodDef VimMethods[] = {
537 /* name, function, calling, documentation */
538 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
539 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar2afa3232012-06-29 16:28:28 +0200540 {"bindeval", VimEvalPy, 1, "Like eval(), but returns objects attached to vim ones"},
541 {"strwidth", VimStrwidth, 1, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200542 { NULL, NULL, 0, NULL }
543};
544
545typedef struct
546{
547 PyObject_HEAD
548 buf_T *buf;
Bram Moolenaardb913952012-06-29 12:54:53 +0200549} BufferObject;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200550
551#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
552
553/*
554 * Buffer list object - Implementation
555 */
556
557 static PyInt
558BufListLength(PyObject *self UNUSED)
559{
560 buf_T *b = firstbuf;
561 PyInt n = 0;
562
563 while (b)
564 {
565 ++n;
566 b = b->b_next;
567 }
568
569 return n;
570}
571
572 static PyObject *
573BufListItem(PyObject *self UNUSED, PyInt n)
574{
575 buf_T *b;
576
577 for (b = firstbuf; b; b = b->b_next, --n)
578 {
579 if (n == 0)
580 return BufferNew(b);
581 }
582
583 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
584 return NULL;
585}
586
587typedef struct
588{
589 PyObject_HEAD
590 win_T *win;
591} WindowObject;
592
Bram Moolenaardb913952012-06-29 12:54:53 +0200593static int ConvertFromPyObject(PyObject *, typval_T *);
594static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
595
596typedef struct pylinkedlist_S {
597 struct pylinkedlist_S *pll_next;
598 struct pylinkedlist_S *pll_prev;
599 PyObject *pll_obj;
600} pylinkedlist_T;
601
602static pylinkedlist_T *lastdict = NULL;
603static pylinkedlist_T *lastlist = NULL;
604
605 static void
606pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
607{
608 if (ref->pll_prev == NULL)
609 {
610 if (ref->pll_next == NULL)
611 {
612 *last = NULL;
613 return;
614 }
615 }
616 else
617 ref->pll_prev->pll_next = ref->pll_next;
618
619 if (ref->pll_next == NULL)
620 *last = ref->pll_prev;
621 else
622 ref->pll_next->pll_prev = ref->pll_prev;
623}
624
625 static void
626pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
627{
628 if (*last == NULL)
629 ref->pll_prev = NULL;
630 else
631 {
632 (*last)->pll_next = ref;
633 ref->pll_prev = *last;
634 }
635 ref->pll_next = NULL;
636 ref->pll_obj = self;
637 *last = ref;
638}
639
640static PyTypeObject DictionaryType;
641
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200642#define DICTKEY_GET_NOTEMPTY(err) \
643 DICTKEY_GET(err) \
644 if (*key == NUL) \
645 { \
646 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
647 return err; \
648 }
649
Bram Moolenaardb913952012-06-29 12:54:53 +0200650typedef struct
651{
652 PyObject_HEAD
653 dict_T *dict;
654 pylinkedlist_T ref;
655} DictionaryObject;
656
657 static PyObject *
658DictionaryNew(dict_T *dict)
659{
660 DictionaryObject *self;
661
662 self = PyObject_NEW(DictionaryObject, &DictionaryType);
663 if (self == NULL)
664 return NULL;
665 self->dict = dict;
666 ++dict->dv_refcount;
667
668 pyll_add((PyObject *)(self), &self->ref, &lastdict);
669
670 return (PyObject *)(self);
671}
672
673 static int
674pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
675{
676 dict_T *d;
677 char_u *key;
678 dictitem_T *di;
679 PyObject *keyObject;
680 PyObject *valObject;
681 Py_ssize_t iter = 0;
682
683 d = dict_alloc();
684 if (d == NULL)
685 {
686 PyErr_NoMemory();
687 return -1;
688 }
689
690 tv->v_type = VAR_DICT;
691 tv->vval.v_dict = d;
692
693 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
694 {
695 DICTKEY_DECL
696
697 if (keyObject == NULL)
698 return -1;
699 if (valObject == NULL)
700 return -1;
701
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200702 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200703
704 di = dictitem_alloc(key);
705
706 DICTKEY_UNREF
707
708 if (di == NULL)
709 {
710 PyErr_NoMemory();
711 return -1;
712 }
713 di->di_tv.v_lock = 0;
714
715 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
716 {
717 vim_free(di);
718 return -1;
719 }
720 if (dict_add(d, di) == FAIL)
721 {
722 vim_free(di);
723 PyErr_SetVim(_("failed to add key to dictionary"));
724 return -1;
725 }
726 }
727 return 0;
728}
729
730 static int
731pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
732{
733 dict_T *d;
734 char_u *key;
735 dictitem_T *di;
736 PyObject *list;
737 PyObject *litem;
738 PyObject *keyObject;
739 PyObject *valObject;
740 Py_ssize_t lsize;
741
742 d = dict_alloc();
743 if (d == NULL)
744 {
745 PyErr_NoMemory();
746 return -1;
747 }
748
749 tv->v_type = VAR_DICT;
750 tv->vval.v_dict = d;
751
752 list = PyMapping_Items(obj);
753 lsize = PyList_Size(list);
754 while (lsize--)
755 {
756 DICTKEY_DECL
757
758 litem = PyList_GetItem(list, lsize);
759 if (litem == NULL)
760 {
761 Py_DECREF(list);
762 return -1;
763 }
764
765 keyObject = PyTuple_GetItem(litem, 0);
766 if (keyObject == NULL)
767 {
768 Py_DECREF(list);
769 Py_DECREF(litem);
770 return -1;
771 }
772
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200773 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200774
775 valObject = PyTuple_GetItem(litem, 1);
776 if (valObject == NULL)
777 {
778 Py_DECREF(list);
779 Py_DECREF(litem);
780 return -1;
781 }
782
783 di = dictitem_alloc(key);
784
785 DICTKEY_UNREF
786
787 if (di == NULL)
788 {
789 Py_DECREF(list);
790 Py_DECREF(litem);
791 PyErr_NoMemory();
792 return -1;
793 }
794 di->di_tv.v_lock = 0;
795
796 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
797 {
798 vim_free(di);
799 Py_DECREF(list);
800 Py_DECREF(litem);
801 return -1;
802 }
803 if (dict_add(d, di) == FAIL)
804 {
805 vim_free(di);
806 Py_DECREF(list);
807 Py_DECREF(litem);
808 PyErr_SetVim(_("failed to add key to dictionary"));
809 return -1;
810 }
811 Py_DECREF(litem);
812 }
813 Py_DECREF(list);
814 return 0;
815}
816
817 static PyInt
Bram Moolenaar66b79852012-09-21 14:00:35 +0200818DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
819{
820 if (val == NULL)
821 {
822 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
823 return -1;
824 }
825
826 if (strcmp(name, "locked") == 0)
827 {
828 if (self->dict->dv_lock == VAR_FIXED)
829 {
830 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
831 return -1;
832 }
833 else
834 {
835 if (!PyBool_Check(val))
836 {
837 PyErr_SetString(PyExc_TypeError, _("Only boolean objects are allowed"));
838 return -1;
839 }
840
841 if (val == Py_True)
842 self->dict->dv_lock = VAR_LOCKED;
843 else
844 self->dict->dv_lock = 0;
845 }
846 return 0;
847 }
848 else
849 {
850 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
851 return -1;
852 }
853}
854
855 static PyInt
Bram Moolenaardb913952012-06-29 12:54:53 +0200856DictionaryLength(PyObject *self)
857{
858 return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used)));
859}
860
861 static PyObject *
862DictionaryItem(PyObject *self, PyObject *keyObject)
863{
864 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200865 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200866 DICTKEY_DECL
867
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200868 DICTKEY_GET_NOTEMPTY(NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +0200869
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200870 di = dict_find(((DictionaryObject *) (self))->dict, key, -1);
871
Bram Moolenaar696c2112012-09-21 13:43:14 +0200872 DICTKEY_UNREF
873
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200874 if (di == NULL)
875 {
876 PyErr_SetString(PyExc_IndexError, _("no such key in dictionary"));
877 return NULL;
878 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200879
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200880 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200881}
882
883 static PyInt
884DictionaryAssItem(PyObject *self, PyObject *keyObject, PyObject *valObject)
885{
886 char_u *key;
887 typval_T tv;
888 dict_T *d = ((DictionaryObject *)(self))->dict;
889 dictitem_T *di;
890 DICTKEY_DECL
891
892 if (d->dv_lock)
893 {
894 PyErr_SetVim(_("dict is locked"));
895 return -1;
896 }
897
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200898 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200899
900 di = dict_find(d, key, -1);
901
902 if (valObject == NULL)
903 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200904 hashitem_T *hi;
905
Bram Moolenaardb913952012-06-29 12:54:53 +0200906 if (di == NULL)
907 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200908 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200909 PyErr_SetString(PyExc_IndexError, _("no such key in dictionary"));
910 return -1;
911 }
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200912 hi = hash_find(&d->dv_hashtab, di->di_key);
Bram Moolenaardb913952012-06-29 12:54:53 +0200913 hash_remove(&d->dv_hashtab, hi);
914 dictitem_free(di);
915 return 0;
916 }
917
918 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200919 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +0200920
921 if (di == NULL)
922 {
923 di = dictitem_alloc(key);
924 if (di == NULL)
925 {
926 PyErr_NoMemory();
927 return -1;
928 }
929 di->di_tv.v_lock = 0;
930
931 if (dict_add(d, di) == FAIL)
932 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200933 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200934 vim_free(di);
935 PyErr_SetVim(_("failed to add key to dictionary"));
936 return -1;
937 }
938 }
939 else
940 clear_tv(&di->di_tv);
941
942 DICTKEY_UNREF
943
944 copy_tv(&tv, &di->di_tv);
945 return 0;
946}
947
948 static PyObject *
949DictionaryListKeys(PyObject *self)
950{
951 dict_T *dict = ((DictionaryObject *)(self))->dict;
952 long_u todo = dict->dv_hashtab.ht_used;
953 Py_ssize_t i = 0;
954 PyObject *r;
955 hashitem_T *hi;
956
957 r = PyList_New(todo);
958 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
959 {
960 if (!HASHITEM_EMPTY(hi))
961 {
962 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
963 --todo;
964 ++i;
965 }
966 }
967 return r;
968}
969
970static struct PyMethodDef DictionaryMethods[] = {
971 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
972 { NULL, NULL, 0, NULL }
973};
974
975static PyTypeObject ListType;
976
977typedef struct
978{
979 PyObject_HEAD
980 list_T *list;
981 pylinkedlist_T ref;
982} ListObject;
983
984 static PyObject *
985ListNew(list_T *list)
986{
987 ListObject *self;
988
989 self = PyObject_NEW(ListObject, &ListType);
990 if (self == NULL)
991 return NULL;
992 self->list = list;
993 ++list->lv_refcount;
994
995 pyll_add((PyObject *)(self), &self->ref, &lastlist);
996
997 return (PyObject *)(self);
998}
999
1000 static int
1001list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict)
1002{
1003 Py_ssize_t i;
1004 Py_ssize_t lsize = PySequence_Size(obj);
1005 PyObject *litem;
1006 listitem_T *li;
1007
1008 for(i=0; i<lsize; i++)
1009 {
1010 li = listitem_alloc();
1011 if (li == NULL)
1012 {
1013 PyErr_NoMemory();
1014 return -1;
1015 }
1016 li->li_tv.v_lock = 0;
1017
1018 litem = PySequence_GetItem(obj, i);
1019 if (litem == NULL)
1020 return -1;
1021 if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1)
1022 return -1;
1023
1024 list_append(l, li);
1025 }
1026 return 0;
1027}
1028
1029 static int
1030pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
1031{
1032 list_T *l;
1033
1034 l = list_alloc();
1035 if (l == NULL)
1036 {
1037 PyErr_NoMemory();
1038 return -1;
1039 }
1040
1041 tv->v_type = VAR_LIST;
1042 tv->vval.v_list = l;
1043
1044 if (list_py_concat(l, obj, lookupDict) == -1)
1045 return -1;
1046
1047 return 0;
1048}
1049
1050 static int
1051pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
1052{
1053 PyObject *iterator = PyObject_GetIter(obj);
1054 PyObject *item;
1055 list_T *l;
1056 listitem_T *li;
1057
1058 l = list_alloc();
1059
1060 if (l == NULL)
1061 {
1062 PyErr_NoMemory();
1063 return -1;
1064 }
1065
1066 tv->vval.v_list = l;
1067 tv->v_type = VAR_LIST;
1068
1069
1070 if (iterator == NULL)
1071 return -1;
1072
1073 while ((item = PyIter_Next(obj)))
1074 {
1075 li = listitem_alloc();
1076 if (li == NULL)
1077 {
1078 PyErr_NoMemory();
1079 return -1;
1080 }
1081 li->li_tv.v_lock = 0;
1082
1083 if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
1084 return -1;
1085
1086 list_append(l, li);
1087
1088 Py_DECREF(item);
1089 }
1090
1091 Py_DECREF(iterator);
1092 return 0;
1093}
1094
1095 static PyInt
1096ListLength(PyObject *self)
1097{
1098 return ((PyInt) (((ListObject *) (self))->list->lv_len));
1099}
1100
1101 static PyObject *
1102ListItem(PyObject *self, Py_ssize_t index)
1103{
1104 listitem_T *li;
1105
1106 if (index>=ListLength(self))
1107 {
1108 PyErr_SetString(PyExc_IndexError, "list index out of range");
1109 return NULL;
1110 }
1111 li = list_find(((ListObject *) (self))->list, (long) index);
1112 if (li == NULL)
1113 {
1114 PyErr_SetVim(_("internal error: failed to get vim list item"));
1115 return NULL;
1116 }
1117 return ConvertToPyObject(&li->li_tv);
1118}
1119
1120#define PROC_RANGE \
1121 if (last < 0) {\
1122 if (last < -size) \
1123 last = 0; \
1124 else \
1125 last += size; \
1126 } \
1127 if (first < 0) \
1128 first = 0; \
1129 if (first > size) \
1130 first = size; \
1131 if (last > size) \
1132 last = size;
1133
1134 static PyObject *
1135ListSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last)
1136{
1137 PyInt i;
1138 PyInt size = ListLength(self);
1139 PyInt n;
1140 PyObject *list;
1141 int reversed = 0;
1142
1143 PROC_RANGE
1144 if (first >= last)
1145 first = last;
1146
1147 n = last-first;
1148 list = PyList_New(n);
1149 if (list == NULL)
1150 return NULL;
1151
1152 for (i = 0; i < n; ++i)
1153 {
1154 PyObject *item = ListItem(self, i);
1155 if (item == NULL)
1156 {
1157 Py_DECREF(list);
1158 return NULL;
1159 }
1160
1161 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
1162 {
1163 Py_DECREF(item);
1164 Py_DECREF(list);
1165 return NULL;
1166 }
1167 }
1168
1169 return list;
1170}
1171
1172 static int
1173ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj)
1174{
1175 typval_T tv;
1176 list_T *l = ((ListObject *) (self))->list;
1177 listitem_T *li;
1178 Py_ssize_t length = ListLength(self);
1179
1180 if (l->lv_lock)
1181 {
1182 PyErr_SetVim(_("list is locked"));
1183 return -1;
1184 }
1185 if (index>length || (index==length && obj==NULL))
1186 {
1187 PyErr_SetString(PyExc_IndexError, "list index out of range");
1188 return -1;
1189 }
1190
1191 if (obj == NULL)
1192 {
1193 li = list_find(l, (long) index);
1194 list_remove(l, li, li);
1195 clear_tv(&li->li_tv);
1196 vim_free(li);
1197 return 0;
1198 }
1199
1200 if (ConvertFromPyObject(obj, &tv) == -1)
1201 return -1;
1202
1203 if (index == length)
1204 {
1205 if (list_append_tv(l, &tv) == FAIL)
1206 {
1207 PyErr_SetVim(_("Failed to add item to list"));
1208 return -1;
1209 }
1210 }
1211 else
1212 {
1213 li = list_find(l, (long) index);
1214 clear_tv(&li->li_tv);
1215 copy_tv(&tv, &li->li_tv);
1216 }
1217 return 0;
1218}
1219
1220 static int
1221ListAssSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
1222{
1223 PyInt size = ListLength(self);
1224 Py_ssize_t i;
1225 Py_ssize_t lsize;
1226 PyObject *litem;
1227 listitem_T *li;
1228 listitem_T *next;
1229 typval_T v;
1230 list_T *l = ((ListObject *) (self))->list;
1231
1232 if (l->lv_lock)
1233 {
1234 PyErr_SetVim(_("list is locked"));
1235 return -1;
1236 }
1237
1238 PROC_RANGE
1239
1240 if (first == size)
1241 li = NULL;
1242 else
1243 {
1244 li = list_find(l, (long) first);
1245 if (li == NULL)
1246 {
1247 PyErr_SetVim(_("internal error: no vim list item"));
1248 return -1;
1249 }
1250 if (last > first)
1251 {
1252 i = last - first;
1253 while (i-- && li != NULL)
1254 {
1255 next = li->li_next;
1256 listitem_remove(l, li);
1257 li = next;
1258 }
1259 }
1260 }
1261
1262 if (obj == NULL)
1263 return 0;
1264
1265 if (!PyList_Check(obj))
1266 {
1267 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1268 return -1;
1269 }
1270
1271 lsize = PyList_Size(obj);
1272
1273 for(i=0; i<lsize; i++)
1274 {
1275 litem = PyList_GetItem(obj, i);
1276 if (litem == NULL)
1277 return -1;
1278 if (ConvertFromPyObject(litem, &v) == -1)
1279 return -1;
1280 if (list_insert_tv(l, &v, li) == FAIL)
1281 {
1282 PyErr_SetVim(_("internal error: failed to add item to list"));
1283 return -1;
1284 }
1285 }
1286 return 0;
1287}
1288
1289 static PyObject *
1290ListConcatInPlace(PyObject *self, PyObject *obj)
1291{
1292 list_T *l = ((ListObject *) (self))->list;
1293 PyObject *lookup_dict;
1294
1295 if (l->lv_lock)
1296 {
1297 PyErr_SetVim(_("list is locked"));
1298 return NULL;
1299 }
1300
1301 if (!PySequence_Check(obj))
1302 {
1303 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1304 return NULL;
1305 }
1306
1307 lookup_dict = PyDict_New();
1308 if (list_py_concat(l, obj, lookup_dict) == -1)
1309 {
1310 Py_DECREF(lookup_dict);
1311 return NULL;
1312 }
1313 Py_DECREF(lookup_dict);
1314
1315 Py_INCREF(self);
1316 return self;
1317}
1318
Bram Moolenaar66b79852012-09-21 14:00:35 +02001319 static int
1320ListSetattr(ListObject *self, char *name, PyObject *val)
1321{
1322 if (val == NULL)
1323 {
1324 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
1325 return -1;
1326 }
1327
1328 if (strcmp(name, "locked") == 0)
1329 {
1330 if (self->list->lv_lock == VAR_FIXED)
1331 {
1332 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed list"));
1333 return -1;
1334 }
1335 else
1336 {
1337 if (!PyBool_Check(val))
1338 {
1339 PyErr_SetString(PyExc_TypeError, _("Only boolean objects are allowed"));
1340 return -1;
1341 }
1342
1343 if (val == Py_True)
1344 self->list->lv_lock = VAR_LOCKED;
1345 else
1346 self->list->lv_lock = 0;
1347 }
1348 return 0;
1349 }
1350 else
1351 {
1352 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
1353 return -1;
1354 }
1355}
1356
Bram Moolenaardb913952012-06-29 12:54:53 +02001357static struct PyMethodDef ListMethods[] = {
1358 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1359 { NULL, NULL, 0, NULL }
1360};
1361
1362typedef struct
1363{
1364 PyObject_HEAD
1365 char_u *name;
1366} FunctionObject;
1367
1368static PyTypeObject FunctionType;
1369
1370 static PyObject *
1371FunctionNew(char_u *name)
1372{
1373 FunctionObject *self;
1374
1375 self = PyObject_NEW(FunctionObject, &FunctionType);
1376 if (self == NULL)
1377 return NULL;
1378 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1379 if (self->name == NULL)
1380 {
1381 PyErr_NoMemory();
1382 return NULL;
1383 }
1384 STRCPY(self->name, name);
1385 func_ref(name);
1386 return (PyObject *)(self);
1387}
1388
1389 static PyObject *
1390FunctionCall(PyObject *self, PyObject *argsObject, PyObject *kwargs)
1391{
1392 FunctionObject *this = (FunctionObject *)(self);
1393 char_u *name = this->name;
1394 typval_T args;
1395 typval_T selfdicttv;
1396 typval_T rettv;
1397 dict_T *selfdict = NULL;
1398 PyObject *selfdictObject;
1399 PyObject *result;
1400 int error;
1401
1402 if (ConvertFromPyObject(argsObject, &args) == -1)
1403 return NULL;
1404
1405 if (kwargs != NULL)
1406 {
1407 selfdictObject = PyDict_GetItemString(kwargs, "self");
1408 if (selfdictObject != NULL)
1409 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001410 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001411 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001412 PyErr_SetString(PyExc_TypeError,
1413 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001414 clear_tv(&args);
1415 return NULL;
1416 }
1417 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
1418 return NULL;
1419 selfdict = selfdicttv.vval.v_dict;
1420 }
1421 }
1422
1423 error = func_call(name, &args, selfdict, &rettv);
1424 if (error != OK)
1425 {
1426 result = NULL;
1427 PyErr_SetVim(_("failed to run function"));
1428 }
1429 else
1430 result = ConvertToPyObject(&rettv);
1431
1432 /* FIXME Check what should really be cleared. */
1433 clear_tv(&args);
1434 clear_tv(&rettv);
1435 /*
1436 * if (selfdict!=NULL)
1437 * clear_tv(selfdicttv);
1438 */
1439
1440 return result;
1441}
1442
1443static struct PyMethodDef FunctionMethods[] = {
1444 {"__call__", (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1445 { NULL, NULL, 0, NULL }
1446};
1447
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001448#define INVALID_WINDOW_VALUE ((win_T *)(-1))
1449
1450 static int
1451CheckWindow(WindowObject *this)
1452{
1453 if (this->win == INVALID_WINDOW_VALUE)
1454 {
1455 PyErr_SetVim(_("attempt to refer to deleted window"));
1456 return -1;
1457 }
1458
1459 return 0;
1460}
1461
1462static int WindowSetattr(PyObject *, char *, PyObject *);
1463static PyObject *WindowRepr(PyObject *);
1464
1465 static int
1466WindowSetattr(PyObject *self, char *name, PyObject *val)
1467{
1468 WindowObject *this = (WindowObject *)(self);
1469
1470 if (CheckWindow(this))
1471 return -1;
1472
1473 if (strcmp(name, "buffer") == 0)
1474 {
1475 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1476 return -1;
1477 }
1478 else if (strcmp(name, "cursor") == 0)
1479 {
1480 long lnum;
1481 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001482
1483 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1484 return -1;
1485
1486 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1487 {
1488 PyErr_SetVim(_("cursor position outside buffer"));
1489 return -1;
1490 }
1491
1492 /* Check for keyboard interrupts */
1493 if (VimErrorCheck())
1494 return -1;
1495
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001496 this->win->w_cursor.lnum = lnum;
1497 this->win->w_cursor.col = col;
1498#ifdef FEAT_VIRTUALEDIT
1499 this->win->w_cursor.coladd = 0;
1500#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001501 /* When column is out of range silently correct it. */
1502 check_cursor_col_win(this->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001503
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001504 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001505 return 0;
1506 }
1507 else if (strcmp(name, "height") == 0)
1508 {
1509 int height;
1510 win_T *savewin;
1511
1512 if (!PyArg_Parse(val, "i", &height))
1513 return -1;
1514
1515#ifdef FEAT_GUI
1516 need_mouse_correct = TRUE;
1517#endif
1518 savewin = curwin;
1519 curwin = this->win;
1520 win_setheight(height);
1521 curwin = savewin;
1522
1523 /* Check for keyboard interrupts */
1524 if (VimErrorCheck())
1525 return -1;
1526
1527 return 0;
1528 }
1529#ifdef FEAT_VERTSPLIT
1530 else if (strcmp(name, "width") == 0)
1531 {
1532 int width;
1533 win_T *savewin;
1534
1535 if (!PyArg_Parse(val, "i", &width))
1536 return -1;
1537
1538#ifdef FEAT_GUI
1539 need_mouse_correct = TRUE;
1540#endif
1541 savewin = curwin;
1542 curwin = this->win;
1543 win_setwidth(width);
1544 curwin = savewin;
1545
1546 /* Check for keyboard interrupts */
1547 if (VimErrorCheck())
1548 return -1;
1549
1550 return 0;
1551 }
1552#endif
1553 else
1554 {
1555 PyErr_SetString(PyExc_AttributeError, name);
1556 return -1;
1557 }
1558}
1559
1560 static PyObject *
1561WindowRepr(PyObject *self)
1562{
1563 static char repr[100];
1564 WindowObject *this = (WindowObject *)(self);
1565
1566 if (this->win == INVALID_WINDOW_VALUE)
1567 {
1568 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
1569 return PyString_FromString(repr);
1570 }
1571 else
1572 {
1573 int i = 0;
1574 win_T *w;
1575
1576 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
1577 ++i;
1578
1579 if (w == NULL)
1580 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
1581 (self));
1582 else
1583 vim_snprintf(repr, 100, _("<window %d>"), i);
1584
1585 return PyString_FromString(repr);
1586 }
1587}
1588
1589/*
1590 * Window list object - Implementation
1591 */
1592 static PyInt
1593WinListLength(PyObject *self UNUSED)
1594{
1595 win_T *w = firstwin;
1596 PyInt n = 0;
1597
1598 while (w != NULL)
1599 {
1600 ++n;
1601 w = W_NEXT(w);
1602 }
1603
1604 return n;
1605}
1606
1607 static PyObject *
1608WinListItem(PyObject *self UNUSED, PyInt n)
1609{
1610 win_T *w;
1611
1612 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
1613 if (n == 0)
1614 return WindowNew(w);
1615
1616 PyErr_SetString(PyExc_IndexError, _("no such window"));
1617 return NULL;
1618}
1619
1620/* Convert a Python string into a Vim line.
1621 *
1622 * The result is in allocated memory. All internal nulls are replaced by
1623 * newline characters. It is an error for the string to contain newline
1624 * characters.
1625 *
1626 * On errors, the Python exception data is set, and NULL is returned.
1627 */
1628 static char *
1629StringToLine(PyObject *obj)
1630{
1631 const char *str;
1632 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02001633 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001634 PyInt len;
1635 PyInt i;
1636 char *p;
1637
1638 if (obj == NULL || !PyString_Check(obj))
1639 {
1640 PyErr_BadArgument();
1641 return NULL;
1642 }
1643
Bram Moolenaar19e60942011-06-19 00:27:51 +02001644 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
1645 str = PyString_AsString(bytes);
1646 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001647
1648 /*
1649 * Error checking: String must not contain newlines, as we
1650 * are replacing a single line, and we must replace it with
1651 * a single line.
1652 * A trailing newline is removed, so that append(f.readlines()) works.
1653 */
1654 p = memchr(str, '\n', len);
1655 if (p != NULL)
1656 {
1657 if (p == str + len - 1)
1658 --len;
1659 else
1660 {
1661 PyErr_SetVim(_("string cannot contain newlines"));
1662 return NULL;
1663 }
1664 }
1665
1666 /* Create a copy of the string, with internal nulls replaced by
1667 * newline characters, as is the vim convention.
1668 */
1669 save = (char *)alloc((unsigned)(len+1));
1670 if (save == NULL)
1671 {
1672 PyErr_NoMemory();
1673 return NULL;
1674 }
1675
1676 for (i = 0; i < len; ++i)
1677 {
1678 if (str[i] == '\0')
1679 save[i] = '\n';
1680 else
1681 save[i] = str[i];
1682 }
1683
1684 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02001685 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001686
1687 return save;
1688}
1689
1690/* Get a line from the specified buffer. The line number is
1691 * in Vim format (1-based). The line is returned as a Python
1692 * string object.
1693 */
1694 static PyObject *
1695GetBufferLine(buf_T *buf, PyInt n)
1696{
1697 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
1698}
1699
1700
1701/* Get a list of lines from the specified buffer. The line numbers
1702 * are in Vim format (1-based). The range is from lo up to, but not
1703 * including, hi. The list is returned as a Python list of string objects.
1704 */
1705 static PyObject *
1706GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
1707{
1708 PyInt i;
1709 PyInt n = hi - lo;
1710 PyObject *list = PyList_New(n);
1711
1712 if (list == NULL)
1713 return NULL;
1714
1715 for (i = 0; i < n; ++i)
1716 {
1717 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
1718
1719 /* Error check - was the Python string creation OK? */
1720 if (str == NULL)
1721 {
1722 Py_DECREF(list);
1723 return NULL;
1724 }
1725
1726 /* Set the list item */
1727 if (PyList_SetItem(list, i, str))
1728 {
1729 Py_DECREF(str);
1730 Py_DECREF(list);
1731 return NULL;
1732 }
1733 }
1734
1735 /* The ownership of the Python list is passed to the caller (ie,
1736 * the caller should Py_DECREF() the object when it is finished
1737 * with it).
1738 */
1739
1740 return list;
1741}
1742
1743/*
1744 * Check if deleting lines made the cursor position invalid.
1745 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
1746 * deleted).
1747 */
1748 static void
1749py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
1750{
1751 if (curwin->w_cursor.lnum >= lo)
1752 {
1753 /* Adjust the cursor position if it's in/after the changed
1754 * lines. */
1755 if (curwin->w_cursor.lnum >= hi)
1756 {
1757 curwin->w_cursor.lnum += extra;
1758 check_cursor_col();
1759 }
1760 else if (extra < 0)
1761 {
1762 curwin->w_cursor.lnum = lo;
1763 check_cursor();
1764 }
1765 else
1766 check_cursor_col();
1767 changed_cline_bef_curs();
1768 }
1769 invalidate_botline();
1770}
1771
Bram Moolenaar19e60942011-06-19 00:27:51 +02001772/*
1773 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001774 * in Vim format (1-based). The replacement line is given as
1775 * a Python string object. The object is checked for validity
1776 * and correct format. Errors are returned as a value of FAIL.
1777 * The return value is OK on success.
1778 * If OK is returned and len_change is not NULL, *len_change
1779 * is set to the change in the buffer length.
1780 */
1781 static int
1782SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
1783{
1784 /* First of all, we check the thpe of the supplied Python object.
1785 * There are three cases:
1786 * 1. NULL, or None - this is a deletion.
1787 * 2. A string - this is a replacement.
1788 * 3. Anything else - this is an error.
1789 */
1790 if (line == Py_None || line == NULL)
1791 {
1792 buf_T *savebuf = curbuf;
1793
1794 PyErr_Clear();
1795 curbuf = buf;
1796
1797 if (u_savedel((linenr_T)n, 1L) == FAIL)
1798 PyErr_SetVim(_("cannot save undo information"));
1799 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
1800 PyErr_SetVim(_("cannot delete line"));
1801 else
1802 {
1803 if (buf == curwin->w_buffer)
1804 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
1805 deleted_lines_mark((linenr_T)n, 1L);
1806 }
1807
1808 curbuf = savebuf;
1809
1810 if (PyErr_Occurred() || VimErrorCheck())
1811 return FAIL;
1812
1813 if (len_change)
1814 *len_change = -1;
1815
1816 return OK;
1817 }
1818 else if (PyString_Check(line))
1819 {
1820 char *save = StringToLine(line);
1821 buf_T *savebuf = curbuf;
1822
1823 if (save == NULL)
1824 return FAIL;
1825
1826 /* We do not need to free "save" if ml_replace() consumes it. */
1827 PyErr_Clear();
1828 curbuf = buf;
1829
1830 if (u_savesub((linenr_T)n) == FAIL)
1831 {
1832 PyErr_SetVim(_("cannot save undo information"));
1833 vim_free(save);
1834 }
1835 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
1836 {
1837 PyErr_SetVim(_("cannot replace line"));
1838 vim_free(save);
1839 }
1840 else
1841 changed_bytes((linenr_T)n, 0);
1842
1843 curbuf = savebuf;
1844
1845 /* Check that the cursor is not beyond the end of the line now. */
1846 if (buf == curwin->w_buffer)
1847 check_cursor_col();
1848
1849 if (PyErr_Occurred() || VimErrorCheck())
1850 return FAIL;
1851
1852 if (len_change)
1853 *len_change = 0;
1854
1855 return OK;
1856 }
1857 else
1858 {
1859 PyErr_BadArgument();
1860 return FAIL;
1861 }
1862}
1863
Bram Moolenaar19e60942011-06-19 00:27:51 +02001864/* Replace a range of lines in the specified buffer. The line numbers are in
1865 * Vim format (1-based). The range is from lo up to, but not including, hi.
1866 * The replacement lines are given as a Python list of string objects. The
1867 * list is checked for validity and correct format. Errors are returned as a
1868 * value of FAIL. The return value is OK on success.
1869 * If OK is returned and len_change is not NULL, *len_change
1870 * is set to the change in the buffer length.
1871 */
1872 static int
1873SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
1874{
1875 /* First of all, we check the thpe of the supplied Python object.
1876 * There are three cases:
1877 * 1. NULL, or None - this is a deletion.
1878 * 2. A list - this is a replacement.
1879 * 3. Anything else - this is an error.
1880 */
1881 if (list == Py_None || list == NULL)
1882 {
1883 PyInt i;
1884 PyInt n = (int)(hi - lo);
1885 buf_T *savebuf = curbuf;
1886
1887 PyErr_Clear();
1888 curbuf = buf;
1889
1890 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
1891 PyErr_SetVim(_("cannot save undo information"));
1892 else
1893 {
1894 for (i = 0; i < n; ++i)
1895 {
1896 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
1897 {
1898 PyErr_SetVim(_("cannot delete line"));
1899 break;
1900 }
1901 }
1902 if (buf == curwin->w_buffer)
1903 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
1904 deleted_lines_mark((linenr_T)lo, (long)i);
1905 }
1906
1907 curbuf = savebuf;
1908
1909 if (PyErr_Occurred() || VimErrorCheck())
1910 return FAIL;
1911
1912 if (len_change)
1913 *len_change = -n;
1914
1915 return OK;
1916 }
1917 else if (PyList_Check(list))
1918 {
1919 PyInt i;
1920 PyInt new_len = PyList_Size(list);
1921 PyInt old_len = hi - lo;
1922 PyInt extra = 0; /* lines added to text, can be negative */
1923 char **array;
1924 buf_T *savebuf;
1925
1926 if (new_len == 0) /* avoid allocating zero bytes */
1927 array = NULL;
1928 else
1929 {
1930 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
1931 if (array == NULL)
1932 {
1933 PyErr_NoMemory();
1934 return FAIL;
1935 }
1936 }
1937
1938 for (i = 0; i < new_len; ++i)
1939 {
1940 PyObject *line = PyList_GetItem(list, i);
1941
1942 array[i] = StringToLine(line);
1943 if (array[i] == NULL)
1944 {
1945 while (i)
1946 vim_free(array[--i]);
1947 vim_free(array);
1948 return FAIL;
1949 }
1950 }
1951
1952 savebuf = curbuf;
1953
1954 PyErr_Clear();
1955 curbuf = buf;
1956
1957 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
1958 PyErr_SetVim(_("cannot save undo information"));
1959
1960 /* If the size of the range is reducing (ie, new_len < old_len) we
1961 * need to delete some old_len. We do this at the start, by
1962 * repeatedly deleting line "lo".
1963 */
1964 if (!PyErr_Occurred())
1965 {
1966 for (i = 0; i < old_len - new_len; ++i)
1967 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
1968 {
1969 PyErr_SetVim(_("cannot delete line"));
1970 break;
1971 }
1972 extra -= i;
1973 }
1974
1975 /* For as long as possible, replace the existing old_len with the
1976 * new old_len. This is a more efficient operation, as it requires
1977 * less memory allocation and freeing.
1978 */
1979 if (!PyErr_Occurred())
1980 {
1981 for (i = 0; i < old_len && i < new_len; ++i)
1982 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
1983 == FAIL)
1984 {
1985 PyErr_SetVim(_("cannot replace line"));
1986 break;
1987 }
1988 }
1989 else
1990 i = 0;
1991
1992 /* Now we may need to insert the remaining new old_len. If we do, we
1993 * must free the strings as we finish with them (we can't pass the
1994 * responsibility to vim in this case).
1995 */
1996 if (!PyErr_Occurred())
1997 {
1998 while (i < new_len)
1999 {
2000 if (ml_append((linenr_T)(lo + i - 1),
2001 (char_u *)array[i], 0, FALSE) == FAIL)
2002 {
2003 PyErr_SetVim(_("cannot insert line"));
2004 break;
2005 }
2006 vim_free(array[i]);
2007 ++i;
2008 ++extra;
2009 }
2010 }
2011
2012 /* Free any left-over old_len, as a result of an error */
2013 while (i < new_len)
2014 {
2015 vim_free(array[i]);
2016 ++i;
2017 }
2018
2019 /* Free the array of old_len. All of its contents have now
2020 * been dealt with (either freed, or the responsibility passed
2021 * to vim.
2022 */
2023 vim_free(array);
2024
2025 /* Adjust marks. Invalidate any which lie in the
2026 * changed range, and move any in the remainder of the buffer.
2027 */
2028 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2029 (long)MAXLNUM, (long)extra);
2030 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2031
2032 if (buf == curwin->w_buffer)
2033 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2034
2035 curbuf = savebuf;
2036
2037 if (PyErr_Occurred() || VimErrorCheck())
2038 return FAIL;
2039
2040 if (len_change)
2041 *len_change = new_len - old_len;
2042
2043 return OK;
2044 }
2045 else
2046 {
2047 PyErr_BadArgument();
2048 return FAIL;
2049 }
2050}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002051
2052/* Insert a number of lines into the specified buffer after the specifed line.
2053 * The line number is in Vim format (1-based). The lines to be inserted are
2054 * given as a Python list of string objects or as a single string. The lines
2055 * to be added are checked for validity and correct format. Errors are
2056 * returned as a value of FAIL. The return value is OK on success.
2057 * If OK is returned and len_change is not NULL, *len_change
2058 * is set to the change in the buffer length.
2059 */
2060 static int
2061InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2062{
2063 /* First of all, we check the type of the supplied Python object.
2064 * It must be a string or a list, or the call is in error.
2065 */
2066 if (PyString_Check(lines))
2067 {
2068 char *str = StringToLine(lines);
2069 buf_T *savebuf;
2070
2071 if (str == NULL)
2072 return FAIL;
2073
2074 savebuf = curbuf;
2075
2076 PyErr_Clear();
2077 curbuf = buf;
2078
2079 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2080 PyErr_SetVim(_("cannot save undo information"));
2081 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2082 PyErr_SetVim(_("cannot insert line"));
2083 else
2084 appended_lines_mark((linenr_T)n, 1L);
2085
2086 vim_free(str);
2087 curbuf = savebuf;
2088 update_screen(VALID);
2089
2090 if (PyErr_Occurred() || VimErrorCheck())
2091 return FAIL;
2092
2093 if (len_change)
2094 *len_change = 1;
2095
2096 return OK;
2097 }
2098 else if (PyList_Check(lines))
2099 {
2100 PyInt i;
2101 PyInt size = PyList_Size(lines);
2102 char **array;
2103 buf_T *savebuf;
2104
2105 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2106 if (array == NULL)
2107 {
2108 PyErr_NoMemory();
2109 return FAIL;
2110 }
2111
2112 for (i = 0; i < size; ++i)
2113 {
2114 PyObject *line = PyList_GetItem(lines, i);
2115 array[i] = StringToLine(line);
2116
2117 if (array[i] == NULL)
2118 {
2119 while (i)
2120 vim_free(array[--i]);
2121 vim_free(array);
2122 return FAIL;
2123 }
2124 }
2125
2126 savebuf = curbuf;
2127
2128 PyErr_Clear();
2129 curbuf = buf;
2130
2131 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2132 PyErr_SetVim(_("cannot save undo information"));
2133 else
2134 {
2135 for (i = 0; i < size; ++i)
2136 {
2137 if (ml_append((linenr_T)(n + i),
2138 (char_u *)array[i], 0, FALSE) == FAIL)
2139 {
2140 PyErr_SetVim(_("cannot insert line"));
2141
2142 /* Free the rest of the lines */
2143 while (i < size)
2144 vim_free(array[i++]);
2145
2146 break;
2147 }
2148 vim_free(array[i]);
2149 }
2150 if (i > 0)
2151 appended_lines_mark((linenr_T)n, (long)i);
2152 }
2153
2154 /* Free the array of lines. All of its contents have now
2155 * been freed.
2156 */
2157 vim_free(array);
2158
2159 curbuf = savebuf;
2160 update_screen(VALID);
2161
2162 if (PyErr_Occurred() || VimErrorCheck())
2163 return FAIL;
2164
2165 if (len_change)
2166 *len_change = size;
2167
2168 return OK;
2169 }
2170 else
2171 {
2172 PyErr_BadArgument();
2173 return FAIL;
2174 }
2175}
2176
2177/*
2178 * Common routines for buffers and line ranges
2179 * -------------------------------------------
2180 */
2181
2182 static int
2183CheckBuffer(BufferObject *this)
2184{
2185 if (this->buf == INVALID_BUFFER_VALUE)
2186 {
2187 PyErr_SetVim(_("attempt to refer to deleted buffer"));
2188 return -1;
2189 }
2190
2191 return 0;
2192}
2193
2194 static PyObject *
2195RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
2196{
2197 if (CheckBuffer(self))
2198 return NULL;
2199
2200 if (n < 0 || n > end - start)
2201 {
2202 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2203 return NULL;
2204 }
2205
2206 return GetBufferLine(self->buf, n+start);
2207}
2208
2209 static PyObject *
2210RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
2211{
2212 PyInt size;
2213
2214 if (CheckBuffer(self))
2215 return NULL;
2216
2217 size = end - start + 1;
2218
2219 if (lo < 0)
2220 lo = 0;
2221 else if (lo > size)
2222 lo = size;
2223 if (hi < 0)
2224 hi = 0;
2225 if (hi < lo)
2226 hi = lo;
2227 else if (hi > size)
2228 hi = size;
2229
2230 return GetBufferLineList(self->buf, lo+start, hi+start);
2231}
2232
2233 static PyInt
2234RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2235{
2236 PyInt len_change;
2237
2238 if (CheckBuffer(self))
2239 return -1;
2240
2241 if (n < 0 || n > end - start)
2242 {
2243 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2244 return -1;
2245 }
2246
2247 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
2248 return -1;
2249
2250 if (new_end)
2251 *new_end = end + len_change;
2252
2253 return 0;
2254}
2255
Bram Moolenaar19e60942011-06-19 00:27:51 +02002256 static PyInt
2257RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2258{
2259 PyInt size;
2260 PyInt len_change;
2261
2262 /* Self must be a valid buffer */
2263 if (CheckBuffer(self))
2264 return -1;
2265
2266 /* Sort out the slice range */
2267 size = end - start + 1;
2268
2269 if (lo < 0)
2270 lo = 0;
2271 else if (lo > size)
2272 lo = size;
2273 if (hi < 0)
2274 hi = 0;
2275 if (hi < lo)
2276 hi = lo;
2277 else if (hi > size)
2278 hi = size;
2279
2280 if (SetBufferLineList(self->buf, lo + start, hi + start,
2281 val, &len_change) == FAIL)
2282 return -1;
2283
2284 if (new_end)
2285 *new_end = end + len_change;
2286
2287 return 0;
2288}
2289
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002290
2291 static PyObject *
2292RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
2293{
2294 PyObject *lines;
2295 PyInt len_change;
2296 PyInt max;
2297 PyInt n;
2298
2299 if (CheckBuffer(self))
2300 return NULL;
2301
2302 max = n = end - start + 1;
2303
2304 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
2305 return NULL;
2306
2307 if (n < 0 || n > max)
2308 {
2309 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
2310 return NULL;
2311 }
2312
2313 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
2314 return NULL;
2315
2316 if (new_end)
2317 *new_end = end + len_change;
2318
2319 Py_INCREF(Py_None);
2320 return Py_None;
2321}
2322
2323
2324/* Buffer object - Definitions
2325 */
2326
2327typedef struct
2328{
2329 PyObject_HEAD
2330 BufferObject *buf;
2331 PyInt start;
2332 PyInt end;
2333} RangeObject;
2334
2335 static PyObject *
2336RangeNew(buf_T *buf, PyInt start, PyInt end)
2337{
2338 BufferObject *bufr;
2339 RangeObject *self;
2340 self = PyObject_NEW(RangeObject, &RangeType);
2341 if (self == NULL)
2342 return NULL;
2343
2344 bufr = (BufferObject *)BufferNew(buf);
2345 if (bufr == NULL)
2346 {
2347 Py_DECREF(self);
2348 return NULL;
2349 }
2350 Py_INCREF(bufr);
2351
2352 self->buf = bufr;
2353 self->start = start;
2354 self->end = end;
2355
2356 return (PyObject *)(self);
2357}
2358
2359 static PyObject *
2360BufferAppend(PyObject *self, PyObject *args)
2361{
2362 return RBAppend((BufferObject *)(self), args, 1,
2363 (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
2364 NULL);
2365}
2366
2367 static PyObject *
2368BufferMark(PyObject *self, PyObject *args)
2369{
2370 pos_T *posp;
2371 char *pmark;
2372 char mark;
2373 buf_T *curbuf_save;
2374
2375 if (CheckBuffer((BufferObject *)(self)))
2376 return NULL;
2377
2378 if (!PyArg_ParseTuple(args, "s", &pmark))
2379 return NULL;
2380 mark = *pmark;
2381
2382 curbuf_save = curbuf;
2383 curbuf = ((BufferObject *)(self))->buf;
2384 posp = getmark(mark, FALSE);
2385 curbuf = curbuf_save;
2386
2387 if (posp == NULL)
2388 {
2389 PyErr_SetVim(_("invalid mark name"));
2390 return NULL;
2391 }
2392
2393 /* Ckeck for keyboard interrupt */
2394 if (VimErrorCheck())
2395 return NULL;
2396
2397 if (posp->lnum <= 0)
2398 {
2399 /* Or raise an error? */
2400 Py_INCREF(Py_None);
2401 return Py_None;
2402 }
2403
2404 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
2405}
2406
2407 static PyObject *
2408BufferRange(PyObject *self, PyObject *args)
2409{
2410 PyInt start;
2411 PyInt end;
2412
2413 if (CheckBuffer((BufferObject *)(self)))
2414 return NULL;
2415
2416 if (!PyArg_ParseTuple(args, "nn", &start, &end))
2417 return NULL;
2418
2419 return RangeNew(((BufferObject *)(self))->buf, start, end);
2420}
2421
2422static struct PyMethodDef BufferMethods[] = {
2423 /* name, function, calling, documentation */
2424 {"append", BufferAppend, 1, "Append data to Vim buffer" },
2425 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
2426 {"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 +01002427#if PY_VERSION_HEX >= 0x03000000
2428 {"__dir__", BufferDir, 4, "List its attributes" },
2429#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002430 { NULL, NULL, 0, NULL }
2431};
2432
2433 static PyObject *
2434RangeAppend(PyObject *self, PyObject *args)
2435{
2436 return RBAppend(((RangeObject *)(self))->buf, args,
2437 ((RangeObject *)(self))->start,
2438 ((RangeObject *)(self))->end,
2439 &((RangeObject *)(self))->end);
2440}
2441
2442 static PyInt
2443RangeLength(PyObject *self)
2444{
2445 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
2446 if (CheckBuffer(((RangeObject *)(self))->buf))
2447 return -1; /* ??? */
2448
2449 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
2450}
2451
2452 static PyObject *
2453RangeItem(PyObject *self, PyInt n)
2454{
2455 return RBItem(((RangeObject *)(self))->buf, n,
2456 ((RangeObject *)(self))->start,
2457 ((RangeObject *)(self))->end);
2458}
2459
2460 static PyObject *
2461RangeRepr(PyObject *self)
2462{
2463 static char repr[100];
2464 RangeObject *this = (RangeObject *)(self);
2465
2466 if (this->buf->buf == INVALID_BUFFER_VALUE)
2467 {
2468 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
2469 (self));
2470 return PyString_FromString(repr);
2471 }
2472 else
2473 {
2474 char *name = (char *)this->buf->buf->b_fname;
2475 int len;
2476
2477 if (name == NULL)
2478 name = "";
2479 len = (int)strlen(name);
2480
2481 if (len > 45)
2482 name = name + (45 - len);
2483
2484 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
2485 len > 45 ? "..." : "", name,
2486 this->start, this->end);
2487
2488 return PyString_FromString(repr);
2489 }
2490}
2491
2492 static PyObject *
2493RangeSlice(PyObject *self, PyInt lo, PyInt hi)
2494{
2495 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
2496 ((RangeObject *)(self))->start,
2497 ((RangeObject *)(self))->end);
2498}
2499
2500/*
2501 * Line range object - Definitions
2502 */
2503
2504static struct PyMethodDef RangeMethods[] = {
2505 /* name, function, calling, documentation */
2506 {"append", RangeAppend, 1, "Append data to the Vim range" },
2507 { NULL, NULL, 0, NULL }
2508};
2509
Bram Moolenaardb913952012-06-29 12:54:53 +02002510 static void
2511set_ref_in_py(const int copyID)
2512{
2513 pylinkedlist_T *cur;
2514 dict_T *dd;
2515 list_T *ll;
2516
2517 if (lastdict != NULL)
2518 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
2519 {
2520 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
2521 if (dd->dv_copyID != copyID)
2522 {
2523 dd->dv_copyID = copyID;
2524 set_ref_in_ht(&dd->dv_hashtab, copyID);
2525 }
2526 }
2527
2528 if (lastlist != NULL)
2529 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
2530 {
2531 ll = ((ListObject *) (cur->pll_obj))->list;
2532 if (ll->lv_copyID != copyID)
2533 {
2534 ll->lv_copyID = copyID;
2535 set_ref_in_list(ll, copyID);
2536 }
2537 }
2538}
2539
2540 static int
2541set_string_copy(char_u *str, typval_T *tv)
2542{
2543 tv->vval.v_string = vim_strsave(str);
2544 if (tv->vval.v_string == NULL)
2545 {
2546 PyErr_NoMemory();
2547 return -1;
2548 }
2549 return 0;
2550}
2551
2552#ifdef FEAT_EVAL
2553typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
2554
2555 static int
2556convert_dl(PyObject *obj, typval_T *tv,
2557 pytotvfunc py_to_tv, PyObject *lookupDict)
2558{
2559 PyObject *capsule;
2560 char hexBuf[sizeof(void *) * 2 + 3];
2561
2562 sprintf(hexBuf, "%p", obj);
2563
Bram Moolenaar2afa3232012-06-29 16:28:28 +02002564# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02002565 capsule = PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02002566# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02002567 capsule = (PyObject *)PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02002568# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02002569 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02002570 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02002571# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02002572 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02002573# else
2574 capsule = PyCObject_FromVoidPtr(tv, NULL);
2575# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02002576 PyDict_SetItemString(lookupDict, hexBuf, capsule);
2577 Py_DECREF(capsule);
2578 if (py_to_tv(obj, tv, lookupDict) == -1)
2579 {
2580 tv->v_type = VAR_UNKNOWN;
2581 return -1;
2582 }
2583 /* As we are not using copy_tv which increments reference count we must
2584 * do it ourself. */
2585 switch(tv->v_type)
2586 {
2587 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
2588 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
2589 }
2590 }
2591 else
2592 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02002593 typval_T *v;
2594
2595# ifdef PY_USE_CAPSULE
2596 v = PyCapsule_GetPointer(capsule, NULL);
2597# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02002598 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02002599# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02002600 copy_tv(v, tv);
2601 }
2602 return 0;
2603}
2604
2605 static int
2606ConvertFromPyObject(PyObject *obj, typval_T *tv)
2607{
2608 PyObject *lookup_dict;
2609 int r;
2610
2611 lookup_dict = PyDict_New();
2612 r = _ConvertFromPyObject(obj, tv, lookup_dict);
2613 Py_DECREF(lookup_dict);
2614 return r;
2615}
2616
2617 static int
2618_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
2619{
2620 if (obj->ob_type == &DictionaryType)
2621 {
2622 tv->v_type = VAR_DICT;
2623 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
2624 ++tv->vval.v_dict->dv_refcount;
2625 }
2626 else if (obj->ob_type == &ListType)
2627 {
2628 tv->v_type = VAR_LIST;
2629 tv->vval.v_list = (((ListObject *)(obj))->list);
2630 ++tv->vval.v_list->lv_refcount;
2631 }
2632 else if (obj->ob_type == &FunctionType)
2633 {
2634 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
2635 return -1;
2636
2637 tv->v_type = VAR_FUNC;
2638 func_ref(tv->vval.v_string);
2639 }
2640#if PY_MAJOR_VERSION >= 3
2641 else if (PyBytes_Check(obj))
2642 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02002643 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02002644
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02002645 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
2646 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02002647 if (result == NULL)
2648 return -1;
2649
2650 if (set_string_copy(result, tv) == -1)
2651 return -1;
2652
2653 tv->v_type = VAR_STRING;
2654 }
2655 else if (PyUnicode_Check(obj))
2656 {
2657 PyObject *bytes;
2658 char_u *result;
2659
2660 bytes = PyString_AsBytes(obj);
2661 if (bytes == NULL)
2662 return -1;
2663
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02002664 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
2665 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02002666 if (result == NULL)
2667 return -1;
2668
2669 if (set_string_copy(result, tv) == -1)
2670 {
2671 Py_XDECREF(bytes);
2672 return -1;
2673 }
2674 Py_XDECREF(bytes);
2675
2676 tv->v_type = VAR_STRING;
2677 }
2678#else
2679 else if (PyUnicode_Check(obj))
2680 {
2681 PyObject *bytes;
2682 char_u *result;
2683
2684 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
2685 if (bytes == NULL)
2686 return -1;
2687
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02002688 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
2689 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02002690 if (result == NULL)
2691 return -1;
2692
2693 if (set_string_copy(result, tv) == -1)
2694 {
2695 Py_XDECREF(bytes);
2696 return -1;
2697 }
2698 Py_XDECREF(bytes);
2699
2700 tv->v_type = VAR_STRING;
2701 }
2702 else if (PyString_Check(obj))
2703 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02002704 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02002705
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02002706 if(PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
2707 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02002708 if (result == NULL)
2709 return -1;
2710
2711 if (set_string_copy(result, tv) == -1)
2712 return -1;
2713
2714 tv->v_type = VAR_STRING;
2715 }
2716 else if (PyInt_Check(obj))
2717 {
2718 tv->v_type = VAR_NUMBER;
2719 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
2720 }
2721#endif
2722 else if (PyLong_Check(obj))
2723 {
2724 tv->v_type = VAR_NUMBER;
2725 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
2726 }
2727 else if (PyDict_Check(obj))
2728 return convert_dl(obj, tv, pydict_to_tv, lookupDict);
2729#ifdef FEAT_FLOAT
2730 else if (PyFloat_Check(obj))
2731 {
2732 tv->v_type = VAR_FLOAT;
2733 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
2734 }
2735#endif
2736 else if (PyIter_Check(obj))
2737 return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
2738 else if (PySequence_Check(obj))
2739 return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
2740 else if (PyMapping_Check(obj))
2741 return convert_dl(obj, tv, pymap_to_tv, lookupDict);
2742 else
2743 {
2744 PyErr_SetString(PyExc_TypeError, _("unable to convert to vim structure"));
2745 return -1;
2746 }
2747 return 0;
2748}
2749
2750 static PyObject *
2751ConvertToPyObject(typval_T *tv)
2752{
2753 if (tv == NULL)
2754 {
2755 PyErr_SetVim(_("NULL reference passed"));
2756 return NULL;
2757 }
2758 switch (tv->v_type)
2759 {
2760 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02002761 return PyBytes_FromString(tv->vval.v_string == NULL
2762 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02002763 case VAR_NUMBER:
2764 return PyLong_FromLong((long) tv->vval.v_number);
2765#ifdef FEAT_FLOAT
2766 case VAR_FLOAT:
2767 return PyFloat_FromDouble((double) tv->vval.v_float);
2768#endif
2769 case VAR_LIST:
2770 return ListNew(tv->vval.v_list);
2771 case VAR_DICT:
2772 return DictionaryNew(tv->vval.v_dict);
2773 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02002774 return FunctionNew(tv->vval.v_string == NULL
2775 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02002776 case VAR_UNKNOWN:
2777 Py_INCREF(Py_None);
2778 return Py_None;
2779 default:
2780 PyErr_SetVim(_("internal error: invalid value type"));
2781 return NULL;
2782 }
2783}
2784#endif