blob: b80a3e24a71f180b83cab89edf15ded57ae7d0b1 [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 {
74 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
75 return -1;
76 }
77
78 if (strcmp(name, "softspace") == 0)
79 {
80 if (!PyInt_Check(val))
81 {
82 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
83 return -1;
84 }
85
86 ((OutputObject *)(self))->softspace = PyInt_AsLong(val);
87 return 0;
88 }
89
90 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
91 return -1;
92}
93
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020094/* Buffer IO, we write one whole line at a time. */
95static garray_T io_ga = {0, 0, 1, 80, NULL};
96static writefn old_fn = NULL;
97
98 static void
99PythonIO_Flush(void)
100{
101 if (old_fn != NULL && io_ga.ga_len > 0)
102 {
103 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
104 old_fn((char_u *)io_ga.ga_data);
105 }
106 io_ga.ga_len = 0;
107}
108
109 static void
110writer(writefn fn, char_u *str, PyInt n)
111{
112 char_u *ptr;
113
114 /* Flush when switching output function. */
115 if (fn != old_fn)
116 PythonIO_Flush();
117 old_fn = fn;
118
119 /* Write each NL separated line. Text after the last NL is kept for
120 * writing later. */
121 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
122 {
123 PyInt len = ptr - str;
124
125 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
126 break;
127
128 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
129 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
130 fn((char_u *)io_ga.ga_data);
131 str = ptr + 1;
132 n -= len + 1;
133 io_ga.ga_len = 0;
134 }
135
136 /* Put the remaining text into io_ga for later printing. */
137 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
138 {
139 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
140 io_ga.ga_len += (int)n;
141 }
142}
143
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200144 static PyObject *
145OutputWrite(PyObject *self, PyObject *args)
146{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200147 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200148 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200149 int error = ((OutputObject *)(self))->error;
150
Bram Moolenaar27564802011-09-07 19:30:21 +0200151 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200152 return NULL;
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 Py_INCREF(Py_None);
162 return Py_None;
163}
164
165 static PyObject *
166OutputWritelines(PyObject *self, PyObject *args)
167{
168 PyInt n;
169 PyInt i;
170 PyObject *list;
171 int error = ((OutputObject *)(self))->error;
172
173 if (!PyArg_ParseTuple(args, "O", &list))
174 return NULL;
175 Py_INCREF(list);
176
Bram Moolenaardb913952012-06-29 12:54:53 +0200177 if (!PyList_Check(list))
178 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200179 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
180 Py_DECREF(list);
181 return NULL;
182 }
183
184 n = PyList_Size(list);
185
186 for (i = 0; i < n; ++i)
187 {
188 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200189 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200190 PyInt len;
191
Bram Moolenaardb913952012-06-29 12:54:53 +0200192 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
193 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200194 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
195 Py_DECREF(list);
196 return NULL;
197 }
198
199 Py_BEGIN_ALLOW_THREADS
200 Python_Lock_Vim();
201 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
202 Python_Release_Vim();
203 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200204 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200205 }
206
207 Py_DECREF(list);
208 Py_INCREF(Py_None);
209 return Py_None;
210}
211
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100212 static PyObject *
213OutputFlush(PyObject *self UNUSED, PyObject *args UNUSED)
214{
215 /* do nothing */
216 Py_INCREF(Py_None);
217 return Py_None;
218}
219
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200220/***************/
221
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200222static struct PyMethodDef OutputMethods[] = {
223 /* name, function, calling, documentation */
224 {"write", OutputWrite, 1, ""},
225 {"writelines", OutputWritelines, 1, ""},
226 {"flush", OutputFlush, 1, ""},
227 { NULL, NULL, 0, NULL}
228};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200229
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 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200284
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200285 static PyObject *
286VimCommand(PyObject *self UNUSED, PyObject *args)
287{
288 char *cmd;
289 PyObject *result;
290
291 if (!PyArg_ParseTuple(args, "s", &cmd))
292 return NULL;
293
294 PyErr_Clear();
295
296 Py_BEGIN_ALLOW_THREADS
297 Python_Lock_Vim();
298
299 do_cmdline_cmd((char_u *)cmd);
300 update_screen(VALID);
301
302 Python_Release_Vim();
303 Py_END_ALLOW_THREADS
304
305 if (VimErrorCheck())
306 result = NULL;
307 else
308 result = Py_None;
309
310 Py_XINCREF(result);
311 return result;
312}
313
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200314/*
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}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200428
429 static PyObject *
Bram Moolenaar09092152010-08-08 16:38:42 +0200430VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200431{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200432 char *expr;
433 typval_T *our_tv;
434 PyObject *result;
435 PyObject *lookup_dict;
436
437 if (!PyArg_ParseTuple(args, "s", &expr))
438 return NULL;
439
440 Py_BEGIN_ALLOW_THREADS
441 Python_Lock_Vim();
442 our_tv = eval_expr((char_u *)expr, NULL);
443
444 Python_Release_Vim();
445 Py_END_ALLOW_THREADS
446
447 if (our_tv == NULL)
448 {
449 PyErr_SetVim(_("invalid expression"));
450 return NULL;
451 }
452
453 /* Convert the Vim type into a Python type. Create a dictionary that's
454 * used to check for recursive loops. */
455 lookup_dict = PyDict_New();
456 result = VimToPython(our_tv, 1, lookup_dict);
457 Py_DECREF(lookup_dict);
458
459
460 Py_BEGIN_ALLOW_THREADS
461 Python_Lock_Vim();
462 free_tv(our_tv);
463 Python_Release_Vim();
464 Py_END_ALLOW_THREADS
465
466 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200467}
468
Bram Moolenaardb913952012-06-29 12:54:53 +0200469static PyObject *ConvertToPyObject(typval_T *);
470
471 static PyObject *
472VimEvalPy(PyObject *self UNUSED, PyObject *args UNUSED)
473{
Bram Moolenaardb913952012-06-29 12:54:53 +0200474 char *expr;
475 typval_T *our_tv;
476 PyObject *result;
477
478 if (!PyArg_ParseTuple(args, "s", &expr))
479 return NULL;
480
481 Py_BEGIN_ALLOW_THREADS
482 Python_Lock_Vim();
483 our_tv = eval_expr((char_u *)expr, NULL);
484
485 Python_Release_Vim();
486 Py_END_ALLOW_THREADS
487
488 if (our_tv == NULL)
489 {
490 PyErr_SetVim(_("invalid expression"));
491 return NULL;
492 }
493
494 result = ConvertToPyObject(our_tv);
495 Py_BEGIN_ALLOW_THREADS
496 Python_Lock_Vim();
497 free_tv(our_tv);
498 Python_Release_Vim();
499 Py_END_ALLOW_THREADS
500
501 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200502}
503
504 static PyObject *
505VimStrwidth(PyObject *self UNUSED, PyObject *args)
506{
507 char *expr;
508
509 if (!PyArg_ParseTuple(args, "s", &expr))
510 return NULL;
511
Bram Moolenaara54bf402012-12-05 16:30:07 +0100512 return PyLong_FromLong(
513#ifdef FEAT_MBYTE
514 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
515#else
516 STRLEN(expr)
517#endif
518 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200519}
520
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200521/*
522 * Vim module - Definitions
523 */
524
525static struct PyMethodDef VimMethods[] = {
526 /* name, function, calling, documentation */
527 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
528 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar2afa3232012-06-29 16:28:28 +0200529 {"bindeval", VimEvalPy, 1, "Like eval(), but returns objects attached to vim ones"},
530 {"strwidth", VimStrwidth, 1, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200531 { NULL, NULL, 0, NULL }
532};
533
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200534/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200535 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200536 */
537
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200538static PyTypeObject IterType;
539
540typedef PyObject *(*nextfun)(void **);
541typedef void (*destructorfun)(void *);
542
543/* Main purpose of this object is removing the need for do python initialization
544 * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects.
545 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200546
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200547typedef struct
548{
549 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200550 void *cur;
551 nextfun next;
552 destructorfun destruct;
553} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200554
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200555 static PyObject *
556IterNew(void *start, destructorfun destruct, nextfun next)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200557{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200558 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200559
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200560 self = PyObject_NEW(IterObject, &IterType);
561 self->cur = start;
562 self->next = next;
563 self->destruct = destruct;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200564
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200565 return (PyObject *)(self);
566}
567
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200568#if 0 /* unused */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200569 static void
570IterDestructor(PyObject *self)
571{
572 IterObject *this = (IterObject *)(self);
573
574 this->destruct(this->cur);
575
576 DESTRUCTOR_FINISH(self);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200577}
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200578#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200579
580 static PyObject *
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200581IterNext(PyObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200582{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200583 IterObject *this = (IterObject *)(self);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200584
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200585 return this->next(&this->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200586}
587
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200588 static PyObject *
589IterIter(PyObject *self)
590{
591 return self;
592}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200593
Bram Moolenaardb913952012-06-29 12:54:53 +0200594typedef struct pylinkedlist_S {
595 struct pylinkedlist_S *pll_next;
596 struct pylinkedlist_S *pll_prev;
597 PyObject *pll_obj;
598} pylinkedlist_T;
599
600static pylinkedlist_T *lastdict = NULL;
601static pylinkedlist_T *lastlist = NULL;
602
603 static void
604pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
605{
606 if (ref->pll_prev == NULL)
607 {
608 if (ref->pll_next == NULL)
609 {
610 *last = NULL;
611 return;
612 }
613 }
614 else
615 ref->pll_prev->pll_next = ref->pll_next;
616
617 if (ref->pll_next == NULL)
618 *last = ref->pll_prev;
619 else
620 ref->pll_next->pll_prev = ref->pll_prev;
621}
622
623 static void
624pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
625{
626 if (*last == NULL)
627 ref->pll_prev = NULL;
628 else
629 {
630 (*last)->pll_next = ref;
631 ref->pll_prev = *last;
632 }
633 ref->pll_next = NULL;
634 ref->pll_obj = self;
635 *last = ref;
636}
637
638static PyTypeObject DictionaryType;
639
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200640#define DICTKEY_GET_NOTEMPTY(err) \
641 DICTKEY_GET(err) \
642 if (*key == NUL) \
643 { \
644 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
645 return err; \
646 }
647
Bram Moolenaardb913952012-06-29 12:54:53 +0200648typedef struct
649{
650 PyObject_HEAD
651 dict_T *dict;
652 pylinkedlist_T ref;
653} DictionaryObject;
654
655 static PyObject *
656DictionaryNew(dict_T *dict)
657{
658 DictionaryObject *self;
659
660 self = PyObject_NEW(DictionaryObject, &DictionaryType);
661 if (self == NULL)
662 return NULL;
663 self->dict = dict;
664 ++dict->dv_refcount;
665
666 pyll_add((PyObject *)(self), &self->ref, &lastdict);
667
668 return (PyObject *)(self);
669}
670
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200671 static void
672DictionaryDestructor(PyObject *self)
673{
674 DictionaryObject *this = ((DictionaryObject *) (self));
675
676 pyll_remove(&this->ref, &lastdict);
677 dict_unref(this->dict);
678
679 DESTRUCTOR_FINISH(self);
680}
681
Bram Moolenaardb913952012-06-29 12:54:53 +0200682 static int
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200683DictionarySetattr(PyObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200684{
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200685 DictionaryObject *this = (DictionaryObject *)(self);
686
Bram Moolenaar66b79852012-09-21 14:00:35 +0200687 if (val == NULL)
688 {
689 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
690 return -1;
691 }
692
693 if (strcmp(name, "locked") == 0)
694 {
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200695 if (this->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200696 {
697 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
698 return -1;
699 }
700 else
701 {
Bram Moolenaar03db85b2013-05-15 14:51:35 +0200702 if (PyObject_IsTrue(val))
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200703 this->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200704 else
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200705 this->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200706 }
707 return 0;
708 }
709 else
710 {
711 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
712 return -1;
713 }
714}
715
716 static PyInt
Bram Moolenaardb913952012-06-29 12:54:53 +0200717DictionaryLength(PyObject *self)
718{
719 return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used)));
720}
721
722 static PyObject *
723DictionaryItem(PyObject *self, PyObject *keyObject)
724{
725 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200726 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200727 DICTKEY_DECL
728
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200729 DICTKEY_GET_NOTEMPTY(NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +0200730
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200731 di = dict_find(((DictionaryObject *) (self))->dict, key, -1);
732
Bram Moolenaar696c2112012-09-21 13:43:14 +0200733 DICTKEY_UNREF
734
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200735 if (di == NULL)
736 {
Bram Moolenaaraf6abb92013-04-24 13:04:26 +0200737 PyErr_SetString(PyExc_KeyError, _("no such key in dictionary"));
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200738 return NULL;
739 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200740
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200741 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200742}
743
744 static PyInt
745DictionaryAssItem(PyObject *self, PyObject *keyObject, PyObject *valObject)
746{
747 char_u *key;
748 typval_T tv;
749 dict_T *d = ((DictionaryObject *)(self))->dict;
750 dictitem_T *di;
751 DICTKEY_DECL
752
753 if (d->dv_lock)
754 {
755 PyErr_SetVim(_("dict is locked"));
756 return -1;
757 }
758
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200759 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200760
761 di = dict_find(d, key, -1);
762
763 if (valObject == NULL)
764 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200765 hashitem_T *hi;
766
Bram Moolenaardb913952012-06-29 12:54:53 +0200767 if (di == NULL)
768 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200769 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200770 PyErr_SetString(PyExc_IndexError, _("no such key in dictionary"));
771 return -1;
772 }
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200773 hi = hash_find(&d->dv_hashtab, di->di_key);
Bram Moolenaardb913952012-06-29 12:54:53 +0200774 hash_remove(&d->dv_hashtab, hi);
775 dictitem_free(di);
776 return 0;
777 }
778
779 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200780 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +0200781
782 if (di == NULL)
783 {
784 di = dictitem_alloc(key);
785 if (di == NULL)
786 {
787 PyErr_NoMemory();
788 return -1;
789 }
790 di->di_tv.v_lock = 0;
791
792 if (dict_add(d, di) == FAIL)
793 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200794 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200795 vim_free(di);
796 PyErr_SetVim(_("failed to add key to dictionary"));
797 return -1;
798 }
799 }
800 else
801 clear_tv(&di->di_tv);
802
803 DICTKEY_UNREF
804
805 copy_tv(&tv, &di->di_tv);
806 return 0;
807}
808
809 static PyObject *
Bram Moolenaarb2c5a5a2013-02-14 22:11:39 +0100810DictionaryListKeys(PyObject *self UNUSED)
Bram Moolenaardb913952012-06-29 12:54:53 +0200811{
812 dict_T *dict = ((DictionaryObject *)(self))->dict;
813 long_u todo = dict->dv_hashtab.ht_used;
814 Py_ssize_t i = 0;
815 PyObject *r;
816 hashitem_T *hi;
817
818 r = PyList_New(todo);
819 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
820 {
821 if (!HASHITEM_EMPTY(hi))
822 {
823 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
824 --todo;
825 ++i;
826 }
827 }
828 return r;
829}
830
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200831static PyMappingMethods DictionaryAsMapping = {
832 (lenfunc) DictionaryLength,
833 (binaryfunc) DictionaryItem,
834 (objobjargproc) DictionaryAssItem,
835};
836
Bram Moolenaardb913952012-06-29 12:54:53 +0200837static struct PyMethodDef DictionaryMethods[] = {
838 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
839 { NULL, NULL, 0, NULL }
840};
841
842static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200843static PySequenceMethods ListAsSeq;
844static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +0200845
846typedef struct
847{
848 PyObject_HEAD
849 list_T *list;
850 pylinkedlist_T ref;
851} ListObject;
852
853 static PyObject *
854ListNew(list_T *list)
855{
856 ListObject *self;
857
858 self = PyObject_NEW(ListObject, &ListType);
859 if (self == NULL)
860 return NULL;
861 self->list = list;
862 ++list->lv_refcount;
863
864 pyll_add((PyObject *)(self), &self->ref, &lastlist);
865
866 return (PyObject *)(self);
867}
868
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200869 static void
870ListDestructor(PyObject *self)
871{
872 ListObject *this = (ListObject *)(self);
873
874 pyll_remove(&this->ref, &lastlist);
875 list_unref(this->list);
876
877 DESTRUCTOR_FINISH(self);
878}
879
Bram Moolenaardb913952012-06-29 12:54:53 +0200880 static int
881list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict)
882{
883 Py_ssize_t i;
884 Py_ssize_t lsize = PySequence_Size(obj);
885 PyObject *litem;
886 listitem_T *li;
887
888 for(i=0; i<lsize; i++)
889 {
890 li = listitem_alloc();
891 if (li == NULL)
892 {
893 PyErr_NoMemory();
894 return -1;
895 }
896 li->li_tv.v_lock = 0;
897
898 litem = PySequence_GetItem(obj, i);
899 if (litem == NULL)
900 return -1;
901 if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1)
902 return -1;
903
904 list_append(l, li);
905 }
906 return 0;
907}
908
Bram Moolenaardb913952012-06-29 12:54:53 +0200909 static PyInt
910ListLength(PyObject *self)
911{
912 return ((PyInt) (((ListObject *) (self))->list->lv_len));
913}
914
915 static PyObject *
916ListItem(PyObject *self, Py_ssize_t index)
917{
918 listitem_T *li;
919
920 if (index>=ListLength(self))
921 {
922 PyErr_SetString(PyExc_IndexError, "list index out of range");
923 return NULL;
924 }
925 li = list_find(((ListObject *) (self))->list, (long) index);
926 if (li == NULL)
927 {
928 PyErr_SetVim(_("internal error: failed to get vim list item"));
929 return NULL;
930 }
931 return ConvertToPyObject(&li->li_tv);
932}
933
934#define PROC_RANGE \
935 if (last < 0) {\
936 if (last < -size) \
937 last = 0; \
938 else \
939 last += size; \
940 } \
941 if (first < 0) \
942 first = 0; \
943 if (first > size) \
944 first = size; \
945 if (last > size) \
946 last = size;
947
948 static PyObject *
949ListSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last)
950{
951 PyInt i;
952 PyInt size = ListLength(self);
953 PyInt n;
954 PyObject *list;
955 int reversed = 0;
956
957 PROC_RANGE
958 if (first >= last)
959 first = last;
960
961 n = last-first;
962 list = PyList_New(n);
963 if (list == NULL)
964 return NULL;
965
966 for (i = 0; i < n; ++i)
967 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +0200968 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +0200969 if (item == NULL)
970 {
971 Py_DECREF(list);
972 return NULL;
973 }
974
975 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
976 {
977 Py_DECREF(item);
978 Py_DECREF(list);
979 return NULL;
980 }
981 }
982
983 return list;
984}
985
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200986typedef struct
987{
988 listwatch_T lw;
989 list_T *list;
990} listiterinfo_T;
991
992 static void
993ListIterDestruct(listiterinfo_T *lii)
994{
995 list_rem_watch(lii->list, &lii->lw);
996 PyMem_Free(lii);
997}
998
999 static PyObject *
1000ListIterNext(listiterinfo_T **lii)
1001{
1002 PyObject *r;
1003
1004 if (!((*lii)->lw.lw_item))
1005 return NULL;
1006
1007 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1008 return NULL;
1009
1010 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1011
1012 return r;
1013}
1014
1015 static PyObject *
1016ListIter(PyObject *self)
1017{
1018 listiterinfo_T *lii;
1019 list_T *l = ((ListObject *) (self))->list;
1020
1021 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1022 {
1023 PyErr_NoMemory();
1024 return NULL;
1025 }
1026
1027 list_add_watch(l, &lii->lw);
1028 lii->lw.lw_item = l->lv_first;
1029 lii->list = l;
1030
1031 return IterNew(lii,
1032 (destructorfun) ListIterDestruct, (nextfun) ListIterNext);
1033}
1034
Bram Moolenaardb913952012-06-29 12:54:53 +02001035 static int
1036ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj)
1037{
1038 typval_T tv;
1039 list_T *l = ((ListObject *) (self))->list;
1040 listitem_T *li;
1041 Py_ssize_t length = ListLength(self);
1042
1043 if (l->lv_lock)
1044 {
1045 PyErr_SetVim(_("list is locked"));
1046 return -1;
1047 }
1048 if (index>length || (index==length && obj==NULL))
1049 {
1050 PyErr_SetString(PyExc_IndexError, "list index out of range");
1051 return -1;
1052 }
1053
1054 if (obj == NULL)
1055 {
1056 li = list_find(l, (long) index);
1057 list_remove(l, li, li);
1058 clear_tv(&li->li_tv);
1059 vim_free(li);
1060 return 0;
1061 }
1062
1063 if (ConvertFromPyObject(obj, &tv) == -1)
1064 return -1;
1065
1066 if (index == length)
1067 {
1068 if (list_append_tv(l, &tv) == FAIL)
1069 {
1070 PyErr_SetVim(_("Failed to add item to list"));
1071 return -1;
1072 }
1073 }
1074 else
1075 {
1076 li = list_find(l, (long) index);
1077 clear_tv(&li->li_tv);
1078 copy_tv(&tv, &li->li_tv);
1079 }
1080 return 0;
1081}
1082
1083 static int
1084ListAssSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
1085{
1086 PyInt size = ListLength(self);
1087 Py_ssize_t i;
1088 Py_ssize_t lsize;
1089 PyObject *litem;
1090 listitem_T *li;
1091 listitem_T *next;
1092 typval_T v;
1093 list_T *l = ((ListObject *) (self))->list;
1094
1095 if (l->lv_lock)
1096 {
1097 PyErr_SetVim(_("list is locked"));
1098 return -1;
1099 }
1100
1101 PROC_RANGE
1102
1103 if (first == size)
1104 li = NULL;
1105 else
1106 {
1107 li = list_find(l, (long) first);
1108 if (li == NULL)
1109 {
1110 PyErr_SetVim(_("internal error: no vim list item"));
1111 return -1;
1112 }
1113 if (last > first)
1114 {
1115 i = last - first;
1116 while (i-- && li != NULL)
1117 {
1118 next = li->li_next;
1119 listitem_remove(l, li);
1120 li = next;
1121 }
1122 }
1123 }
1124
1125 if (obj == NULL)
1126 return 0;
1127
1128 if (!PyList_Check(obj))
1129 {
1130 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1131 return -1;
1132 }
1133
1134 lsize = PyList_Size(obj);
1135
1136 for(i=0; i<lsize; i++)
1137 {
1138 litem = PyList_GetItem(obj, i);
1139 if (litem == NULL)
1140 return -1;
1141 if (ConvertFromPyObject(litem, &v) == -1)
1142 return -1;
1143 if (list_insert_tv(l, &v, li) == FAIL)
1144 {
1145 PyErr_SetVim(_("internal error: failed to add item to list"));
1146 return -1;
1147 }
1148 }
1149 return 0;
1150}
1151
1152 static PyObject *
1153ListConcatInPlace(PyObject *self, PyObject *obj)
1154{
1155 list_T *l = ((ListObject *) (self))->list;
1156 PyObject *lookup_dict;
1157
1158 if (l->lv_lock)
1159 {
1160 PyErr_SetVim(_("list is locked"));
1161 return NULL;
1162 }
1163
1164 if (!PySequence_Check(obj))
1165 {
1166 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1167 return NULL;
1168 }
1169
1170 lookup_dict = PyDict_New();
1171 if (list_py_concat(l, obj, lookup_dict) == -1)
1172 {
1173 Py_DECREF(lookup_dict);
1174 return NULL;
1175 }
1176 Py_DECREF(lookup_dict);
1177
1178 Py_INCREF(self);
1179 return self;
1180}
1181
Bram Moolenaar66b79852012-09-21 14:00:35 +02001182 static int
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001183ListSetattr(PyObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001184{
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001185 ListObject *this = (ListObject *)(self);
1186
Bram Moolenaar66b79852012-09-21 14:00:35 +02001187 if (val == NULL)
1188 {
1189 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
1190 return -1;
1191 }
1192
1193 if (strcmp(name, "locked") == 0)
1194 {
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001195 if (this->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001196 {
1197 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed list"));
1198 return -1;
1199 }
1200 else
1201 {
Bram Moolenaar03db85b2013-05-15 14:51:35 +02001202 if (PyObject_IsTrue(val))
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001203 this->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001204 else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001205 this->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001206 }
1207 return 0;
1208 }
1209 else
1210 {
1211 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
1212 return -1;
1213 }
1214}
1215
Bram Moolenaardb913952012-06-29 12:54:53 +02001216static struct PyMethodDef ListMethods[] = {
1217 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1218 { NULL, NULL, 0, NULL }
1219};
1220
1221typedef struct
1222{
1223 PyObject_HEAD
1224 char_u *name;
1225} FunctionObject;
1226
1227static PyTypeObject FunctionType;
1228
1229 static PyObject *
1230FunctionNew(char_u *name)
1231{
1232 FunctionObject *self;
1233
1234 self = PyObject_NEW(FunctionObject, &FunctionType);
1235 if (self == NULL)
1236 return NULL;
1237 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1238 if (self->name == NULL)
1239 {
1240 PyErr_NoMemory();
1241 return NULL;
1242 }
1243 STRCPY(self->name, name);
1244 func_ref(name);
1245 return (PyObject *)(self);
1246}
1247
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001248 static void
1249FunctionDestructor(PyObject *self)
1250{
1251 FunctionObject *this = (FunctionObject *) (self);
1252
1253 func_unref(this->name);
1254 PyMem_Del(this->name);
1255
1256 DESTRUCTOR_FINISH(self);
1257}
1258
Bram Moolenaardb913952012-06-29 12:54:53 +02001259 static PyObject *
1260FunctionCall(PyObject *self, PyObject *argsObject, PyObject *kwargs)
1261{
1262 FunctionObject *this = (FunctionObject *)(self);
1263 char_u *name = this->name;
1264 typval_T args;
1265 typval_T selfdicttv;
1266 typval_T rettv;
1267 dict_T *selfdict = NULL;
1268 PyObject *selfdictObject;
1269 PyObject *result;
1270 int error;
1271
1272 if (ConvertFromPyObject(argsObject, &args) == -1)
1273 return NULL;
1274
1275 if (kwargs != NULL)
1276 {
1277 selfdictObject = PyDict_GetItemString(kwargs, "self");
1278 if (selfdictObject != NULL)
1279 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001280 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001281 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001282 PyErr_SetString(PyExc_TypeError,
1283 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001284 clear_tv(&args);
1285 return NULL;
1286 }
1287 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
1288 return NULL;
1289 selfdict = selfdicttv.vval.v_dict;
1290 }
1291 }
1292
1293 error = func_call(name, &args, selfdict, &rettv);
1294 if (error != OK)
1295 {
1296 result = NULL;
1297 PyErr_SetVim(_("failed to run function"));
1298 }
1299 else
1300 result = ConvertToPyObject(&rettv);
1301
1302 /* FIXME Check what should really be cleared. */
1303 clear_tv(&args);
1304 clear_tv(&rettv);
1305 /*
1306 * if (selfdict!=NULL)
1307 * clear_tv(selfdicttv);
1308 */
1309
1310 return result;
1311}
1312
1313static struct PyMethodDef FunctionMethods[] = {
1314 {"__call__", (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1315 { NULL, NULL, 0, NULL }
1316};
1317
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001318/*
1319 * Options object
1320 */
1321
1322static PyTypeObject OptionsType;
1323
1324typedef int (*checkfun)(void *);
1325
1326typedef struct
1327{
1328 PyObject_HEAD
1329 int opt_type;
1330 void *from;
1331 checkfun Check;
1332 PyObject *fromObj;
1333} OptionsObject;
1334
1335 static PyObject *
1336OptionsItem(OptionsObject *this, PyObject *keyObject)
1337{
1338 char_u *key;
1339 int flags;
1340 long numval;
1341 char_u *stringval;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001342 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001343
1344 if (this->Check(this->from))
1345 return NULL;
1346
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001347 DICTKEY_GET_NOTEMPTY(NULL)
1348
1349 flags = get_option_value_strict(key, &numval, &stringval,
1350 this->opt_type, this->from);
1351
1352 DICTKEY_UNREF
1353
1354 if (flags == 0)
1355 {
1356 PyErr_SetString(PyExc_KeyError, "Option does not exist in given scope");
1357 return NULL;
1358 }
1359
1360 if (flags & SOPT_UNSET)
1361 {
1362 Py_INCREF(Py_None);
1363 return Py_None;
1364 }
1365 else if (flags & SOPT_BOOL)
1366 {
1367 PyObject *r;
1368 r = numval ? Py_True : Py_False;
1369 Py_INCREF(r);
1370 return r;
1371 }
1372 else if (flags & SOPT_NUM)
1373 return PyInt_FromLong(numval);
1374 else if (flags & SOPT_STRING)
1375 {
1376 if (stringval)
1377 return PyBytes_FromString((char *) stringval);
1378 else
1379 {
1380 PyErr_SetString(PyExc_ValueError, "Unable to get option value");
1381 return NULL;
1382 }
1383 }
1384 else
1385 {
1386 PyErr_SetVim("Internal error: unknown option type. Should not happen");
1387 return NULL;
1388 }
1389}
1390
1391 static int
1392set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
1393 char_u *key;
1394 int numval;
1395 char_u *stringval;
1396 int opt_flags;
1397 int opt_type;
1398 void *from;
1399{
1400 win_T *save_curwin;
1401 tabpage_T *save_curtab;
1402 aco_save_T aco;
1403 int r = 0;
1404
1405 switch (opt_type)
1406 {
1407 case SREQ_WIN:
1408 if (switch_win(&save_curwin, &save_curtab, (win_T *) from, curtab)
1409 == FAIL)
1410 {
1411 PyErr_SetVim("Problem while switching windows.");
1412 return -1;
1413 }
1414 set_option_value(key, numval, stringval, opt_flags);
1415 restore_win(save_curwin, save_curtab);
1416 break;
1417 case SREQ_BUF:
1418 aucmd_prepbuf(&aco, (buf_T *) from);
1419 set_option_value(key, numval, stringval, opt_flags);
1420 aucmd_restbuf(&aco);
1421 break;
1422 case SREQ_GLOBAL:
1423 set_option_value(key, numval, stringval, opt_flags);
1424 break;
1425 }
1426 return r;
1427}
1428
1429 static int
1430OptionsAssItem(OptionsObject *this, PyObject *keyObject, PyObject *valObject)
1431{
1432 char_u *key;
1433 int flags;
1434 int opt_flags;
1435 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001436 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001437
1438 if (this->Check(this->from))
1439 return -1;
1440
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001441 DICTKEY_GET_NOTEMPTY(-1)
1442
1443 flags = get_option_value_strict(key, NULL, NULL,
1444 this->opt_type, this->from);
1445
1446 DICTKEY_UNREF
1447
1448 if (flags == 0)
1449 {
1450 PyErr_SetString(PyExc_KeyError, "Option does not exist in given scope");
1451 return -1;
1452 }
1453
1454 if (valObject == NULL)
1455 {
1456 if (this->opt_type == SREQ_GLOBAL)
1457 {
1458 PyErr_SetString(PyExc_ValueError, "Unable to unset global option");
1459 return -1;
1460 }
1461 else if (!(flags & SOPT_GLOBAL))
1462 {
1463 PyErr_SetString(PyExc_ValueError, "Unable to unset option without "
1464 "global value");
1465 return -1;
1466 }
1467 else
1468 {
1469 unset_global_local_option(key, this->from);
1470 return 0;
1471 }
1472 }
1473
1474 opt_flags = (this->opt_type ? OPT_LOCAL : OPT_GLOBAL);
1475
1476 if (flags & SOPT_BOOL)
1477 {
Bram Moolenaar03db85b2013-05-15 14:51:35 +02001478 r = set_option_value_for(key, PyObject_IsTrue(valObject), NULL,
1479 opt_flags, this->opt_type, this->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001480 }
1481 else if (flags & SOPT_NUM)
1482 {
1483 int val;
1484
1485#if PY_MAJOR_VERSION < 3
1486 if (PyInt_Check(valObject))
1487 val = PyInt_AsLong(valObject);
1488 else
1489#endif
1490 if (PyLong_Check(valObject))
1491 val = PyLong_AsLong(valObject);
1492 else
1493 {
1494 PyErr_SetString(PyExc_ValueError, "Object must be integer");
1495 return -1;
1496 }
1497
1498 r = set_option_value_for(key, val, NULL, opt_flags,
1499 this->opt_type, this->from);
1500 }
1501 else
1502 {
1503 char_u *val;
1504 if (PyBytes_Check(valObject))
1505 {
1506
1507 if (PyString_AsStringAndSize(valObject, (char **) &val, NULL) == -1)
1508 return -1;
1509 if (val == NULL)
1510 return -1;
1511
1512 val = vim_strsave(val);
1513 }
1514 else if (PyUnicode_Check(valObject))
1515 {
1516 PyObject *bytes;
1517
1518 bytes = PyUnicode_AsEncodedString(valObject, (char *)ENC_OPT, NULL);
1519 if (bytes == NULL)
1520 return -1;
1521
1522 if(PyString_AsStringAndSize(bytes, (char **) &val, NULL) == -1)
1523 return -1;
1524 if (val == NULL)
1525 return -1;
1526
1527 val = vim_strsave(val);
1528 Py_XDECREF(bytes);
1529 }
1530 else
1531 {
1532 PyErr_SetString(PyExc_ValueError, "Object must be string");
1533 return -1;
1534 }
1535
1536 r = set_option_value_for(key, 0, val, opt_flags,
1537 this->opt_type, this->from);
1538 vim_free(val);
1539 }
1540
1541 return r;
1542}
1543
1544 static int
1545dummy_check(void *arg UNUSED)
1546{
1547 return 0;
1548}
1549
1550 static PyObject *
1551OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
1552{
1553 OptionsObject *self;
1554
1555 self = PyObject_NEW(OptionsObject, &OptionsType);
1556 if (self == NULL)
1557 return NULL;
1558
1559 self->opt_type = opt_type;
1560 self->from = from;
1561 self->Check = Check;
1562 self->fromObj = fromObj;
1563 if (fromObj)
1564 Py_INCREF(fromObj);
1565
1566 return (PyObject *)(self);
1567}
1568
1569 static void
1570OptionsDestructor(PyObject *self)
1571{
1572 if (((OptionsObject *)(self))->fromObj)
1573 Py_DECREF(((OptionsObject *)(self))->fromObj);
1574 DESTRUCTOR_FINISH(self);
1575}
1576
1577static PyMappingMethods OptionsAsMapping = {
1578 (lenfunc) NULL,
1579 (binaryfunc) OptionsItem,
1580 (objobjargproc) OptionsAssItem,
1581};
1582
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001583/* Tabpage object
1584 */
1585
1586typedef struct
1587{
1588 PyObject_HEAD
1589 tabpage_T *tab;
1590} TabPageObject;
1591
1592static PyObject *WinListNew(TabPageObject *tabObject);
1593
1594static PyTypeObject TabPageType;
1595
1596 static int
1597CheckTabPage(TabPageObject *this)
1598{
1599 if (this->tab == INVALID_TABPAGE_VALUE)
1600 {
1601 PyErr_SetVim(_("attempt to refer to deleted tab page"));
1602 return -1;
1603 }
1604
1605 return 0;
1606}
1607
1608 static PyObject *
1609TabPageNew(tabpage_T *tab)
1610{
1611 TabPageObject *self;
1612
1613 if (TAB_PYTHON_REF(tab))
1614 {
1615 self = TAB_PYTHON_REF(tab);
1616 Py_INCREF(self);
1617 }
1618 else
1619 {
1620 self = PyObject_NEW(TabPageObject, &TabPageType);
1621 if (self == NULL)
1622 return NULL;
1623 self->tab = tab;
1624 TAB_PYTHON_REF(tab) = self;
1625 }
1626
1627 return (PyObject *)(self);
1628}
1629
1630 static void
1631TabPageDestructor(PyObject *self)
1632{
1633 TabPageObject *this = (TabPageObject *)(self);
1634
1635 if (this->tab && this->tab != INVALID_TABPAGE_VALUE)
1636 TAB_PYTHON_REF(this->tab) = NULL;
1637
1638 DESTRUCTOR_FINISH(self);
1639}
1640
1641 static PyObject *
1642TabPageAttr(TabPageObject *this, char *name)
1643{
1644 if (strcmp(name, "windows") == 0)
1645 return WinListNew(this);
1646 else if (strcmp(name, "number") == 0)
1647 return PyLong_FromLong((long) get_tab_number(this->tab));
1648 else if (strcmp(name, "vars") == 0)
1649 return DictionaryNew(this->tab->tp_vars);
1650 else if (strcmp(name, "window") == 0)
1651 {
1652 /* For current tab window.c does not bother to set or update tp_curwin
1653 */
1654 if (this->tab == curtab)
1655 return WindowNew(curwin);
1656 else
1657 return WindowNew(this->tab->tp_curwin);
1658 }
1659 return NULL;
1660}
1661
1662 static PyObject *
1663TabPageRepr(PyObject *self)
1664{
1665 static char repr[100];
1666 TabPageObject *this = (TabPageObject *)(self);
1667
1668 if (this->tab == INVALID_TABPAGE_VALUE)
1669 {
1670 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
1671 return PyString_FromString(repr);
1672 }
1673 else
1674 {
1675 int t = get_tab_number(this->tab);
1676
1677 if (t == 0)
1678 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
1679 (self));
1680 else
1681 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
1682
1683 return PyString_FromString(repr);
1684 }
1685}
1686
1687static struct PyMethodDef TabPageMethods[] = {
1688 /* name, function, calling, documentation */
1689 { NULL, NULL, 0, NULL }
1690};
1691
1692/*
1693 * Window list object
1694 */
1695
1696static PyTypeObject TabListType;
1697static PySequenceMethods TabListAsSeq;
1698
1699typedef struct
1700{
1701 PyObject_HEAD
1702} TabListObject;
1703
1704 static PyInt
1705TabListLength(PyObject *self UNUSED)
1706{
1707 tabpage_T *tp = first_tabpage;
1708 PyInt n = 0;
1709
1710 while (tp != NULL)
1711 {
1712 ++n;
1713 tp = tp->tp_next;
1714 }
1715
1716 return n;
1717}
1718
1719 static PyObject *
1720TabListItem(PyObject *self UNUSED, PyInt n)
1721{
1722 tabpage_T *tp;
1723
1724 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
1725 if (n == 0)
1726 return TabPageNew(tp);
1727
1728 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
1729 return NULL;
1730}
1731
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001732/* Window object
1733 */
1734
1735typedef struct
1736{
1737 PyObject_HEAD
1738 win_T *win;
1739} WindowObject;
1740
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001741static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001742
1743 static int
1744CheckWindow(WindowObject *this)
1745{
1746 if (this->win == INVALID_WINDOW_VALUE)
1747 {
1748 PyErr_SetVim(_("attempt to refer to deleted window"));
1749 return -1;
1750 }
1751
1752 return 0;
1753}
1754
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001755 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02001756WindowNew(win_T *win)
1757{
1758 /* We need to handle deletion of windows underneath us.
1759 * If we add a "w_python*_ref" field to the win_T structure,
1760 * then we can get at it in win_free() in vim. We then
1761 * need to create only ONE Python object per window - if
1762 * we try to create a second, just INCREF the existing one
1763 * and return it. The (single) Python object referring to
1764 * the window is stored in "w_python*_ref".
1765 * On a win_free() we set the Python object's win_T* field
1766 * to an invalid value. We trap all uses of a window
1767 * object, and reject them if the win_T* field is invalid.
1768 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001769 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02001770 * w_python_ref and w_python3_ref fields respectively.
1771 */
1772
1773 WindowObject *self;
1774
1775 if (WIN_PYTHON_REF(win))
1776 {
1777 self = WIN_PYTHON_REF(win);
1778 Py_INCREF(self);
1779 }
1780 else
1781 {
1782 self = PyObject_NEW(WindowObject, &WindowType);
1783 if (self == NULL)
1784 return NULL;
1785 self->win = win;
1786 WIN_PYTHON_REF(win) = self;
1787 }
1788
1789 return (PyObject *)(self);
1790}
1791
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001792 static void
1793WindowDestructor(PyObject *self)
1794{
1795 WindowObject *this = (WindowObject *)(self);
1796
1797 if (this->win && this->win != INVALID_WINDOW_VALUE)
1798 WIN_PYTHON_REF(this->win) = NULL;
1799
1800 DESTRUCTOR_FINISH(self);
1801}
1802
Bram Moolenaar971db462013-05-12 18:44:48 +02001803 static PyObject *
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001804WindowAttr(WindowObject *this, char *name)
1805{
1806 if (strcmp(name, "buffer") == 0)
1807 return (PyObject *)BufferNew(this->win->w_buffer);
1808 else if (strcmp(name, "cursor") == 0)
1809 {
1810 pos_T *pos = &this->win->w_cursor;
1811
1812 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
1813 }
1814 else if (strcmp(name, "height") == 0)
Bram Moolenaar99add412013-05-12 19:09:51 +02001815 return PyLong_FromLong((long)(this->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001816#ifdef FEAT_WINDOWS
1817 else if (strcmp(name, "row") == 0)
1818 return PyLong_FromLong((long)(this->win->w_winrow));
1819#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001820#ifdef FEAT_VERTSPLIT
1821 else if (strcmp(name, "width") == 0)
Bram Moolenaar99add412013-05-12 19:09:51 +02001822 return PyLong_FromLong((long)(W_WIDTH(this->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001823 else if (strcmp(name, "col") == 0)
1824 return PyLong_FromLong((long)(W_WINCOL(this->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001825#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02001826 else if (strcmp(name, "vars") == 0)
1827 return DictionaryNew(this->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001828 else if (strcmp(name, "options") == 0)
1829 return OptionsNew(SREQ_WIN, this->win, (checkfun) CheckWindow,
1830 (PyObject *) this);
Bram Moolenaar6d216452013-05-12 19:00:41 +02001831 else if (strcmp(name, "number") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001832 return PyLong_FromLong((long) get_win_number(this->win, firstwin));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001833 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001834 return Py_BuildValue("[ssssssss]", "buffer", "cursor", "height", "vars",
1835 "options", "number", "row", "col");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001836 else
1837 return NULL;
1838}
1839
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001840 static int
1841WindowSetattr(PyObject *self, char *name, PyObject *val)
1842{
1843 WindowObject *this = (WindowObject *)(self);
1844
1845 if (CheckWindow(this))
1846 return -1;
1847
1848 if (strcmp(name, "buffer") == 0)
1849 {
1850 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1851 return -1;
1852 }
1853 else if (strcmp(name, "cursor") == 0)
1854 {
1855 long lnum;
1856 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001857
1858 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1859 return -1;
1860
1861 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1862 {
1863 PyErr_SetVim(_("cursor position outside buffer"));
1864 return -1;
1865 }
1866
1867 /* Check for keyboard interrupts */
1868 if (VimErrorCheck())
1869 return -1;
1870
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001871 this->win->w_cursor.lnum = lnum;
1872 this->win->w_cursor.col = col;
1873#ifdef FEAT_VIRTUALEDIT
1874 this->win->w_cursor.coladd = 0;
1875#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001876 /* When column is out of range silently correct it. */
1877 check_cursor_col_win(this->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001878
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001879 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001880 return 0;
1881 }
1882 else if (strcmp(name, "height") == 0)
1883 {
1884 int height;
1885 win_T *savewin;
1886
1887 if (!PyArg_Parse(val, "i", &height))
1888 return -1;
1889
1890#ifdef FEAT_GUI
1891 need_mouse_correct = TRUE;
1892#endif
1893 savewin = curwin;
1894 curwin = this->win;
1895 win_setheight(height);
1896 curwin = savewin;
1897
1898 /* Check for keyboard interrupts */
1899 if (VimErrorCheck())
1900 return -1;
1901
1902 return 0;
1903 }
1904#ifdef FEAT_VERTSPLIT
1905 else if (strcmp(name, "width") == 0)
1906 {
1907 int width;
1908 win_T *savewin;
1909
1910 if (!PyArg_Parse(val, "i", &width))
1911 return -1;
1912
1913#ifdef FEAT_GUI
1914 need_mouse_correct = TRUE;
1915#endif
1916 savewin = curwin;
1917 curwin = this->win;
1918 win_setwidth(width);
1919 curwin = savewin;
1920
1921 /* Check for keyboard interrupts */
1922 if (VimErrorCheck())
1923 return -1;
1924
1925 return 0;
1926 }
1927#endif
1928 else
1929 {
1930 PyErr_SetString(PyExc_AttributeError, name);
1931 return -1;
1932 }
1933}
1934
1935 static PyObject *
1936WindowRepr(PyObject *self)
1937{
1938 static char repr[100];
1939 WindowObject *this = (WindowObject *)(self);
1940
1941 if (this->win == INVALID_WINDOW_VALUE)
1942 {
1943 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
1944 return PyString_FromString(repr);
1945 }
1946 else
1947 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001948 int w = get_win_number(this->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001949
Bram Moolenaar6d216452013-05-12 19:00:41 +02001950 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001951 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
1952 (self));
1953 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02001954 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001955
1956 return PyString_FromString(repr);
1957 }
1958}
1959
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001960static struct PyMethodDef WindowMethods[] = {
1961 /* name, function, calling, documentation */
1962 { NULL, NULL, 0, NULL }
1963};
1964
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001965/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001966 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001967 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001968
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001969static PyTypeObject WinListType;
1970static PySequenceMethods WinListAsSeq;
1971
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001972typedef struct
1973{
1974 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001975 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001976} WinListObject;
1977
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001978 static PyObject *
1979WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001980{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001981 WinListObject *self;
1982
1983 self = PyObject_NEW(WinListObject, &WinListType);
1984 self->tabObject = tabObject;
1985 Py_INCREF(tabObject);
1986
1987 return (PyObject *)(self);
1988}
1989
1990 static void
1991WinListDestructor(PyObject *self)
1992{
1993 TabPageObject *tabObject = ((WinListObject *)(self))->tabObject;
1994
1995 if (tabObject)
1996 Py_DECREF((PyObject *)(tabObject));
1997
1998 DESTRUCTOR_FINISH(self);
1999}
2000
2001 static win_T *
2002get_firstwin(WinListObject *this)
2003{
2004 if (this->tabObject)
2005 {
2006 if (CheckTabPage(this->tabObject))
2007 return NULL;
2008 /* For current tab window.c does not bother to set or update tp_firstwin
2009 */
2010 else if (this->tabObject->tab == curtab)
2011 return firstwin;
2012 else
2013 return this->tabObject->tab->tp_firstwin;
2014 }
2015 else
2016 return firstwin;
2017}
2018
2019 static PyInt
2020WinListLength(PyObject *self)
2021{
2022 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002023 PyInt n = 0;
2024
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002025 if (!(w = get_firstwin((WinListObject *)(self))))
2026 return -1;
2027
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002028 while (w != NULL)
2029 {
2030 ++n;
2031 w = W_NEXT(w);
2032 }
2033
2034 return n;
2035}
2036
2037 static PyObject *
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002038WinListItem(PyObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002039{
2040 win_T *w;
2041
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002042 if (!(w = get_firstwin((WinListObject *)(self))))
2043 return NULL;
2044
2045 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002046 if (n == 0)
2047 return WindowNew(w);
2048
2049 PyErr_SetString(PyExc_IndexError, _("no such window"));
2050 return NULL;
2051}
2052
2053/* Convert a Python string into a Vim line.
2054 *
2055 * The result is in allocated memory. All internal nulls are replaced by
2056 * newline characters. It is an error for the string to contain newline
2057 * characters.
2058 *
2059 * On errors, the Python exception data is set, and NULL is returned.
2060 */
2061 static char *
2062StringToLine(PyObject *obj)
2063{
2064 const char *str;
2065 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002066 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002067 PyInt len;
2068 PyInt i;
2069 char *p;
2070
2071 if (obj == NULL || !PyString_Check(obj))
2072 {
2073 PyErr_BadArgument();
2074 return NULL;
2075 }
2076
Bram Moolenaar19e60942011-06-19 00:27:51 +02002077 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2078 str = PyString_AsString(bytes);
2079 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002080
2081 /*
2082 * Error checking: String must not contain newlines, as we
2083 * are replacing a single line, and we must replace it with
2084 * a single line.
2085 * A trailing newline is removed, so that append(f.readlines()) works.
2086 */
2087 p = memchr(str, '\n', len);
2088 if (p != NULL)
2089 {
2090 if (p == str + len - 1)
2091 --len;
2092 else
2093 {
2094 PyErr_SetVim(_("string cannot contain newlines"));
2095 return NULL;
2096 }
2097 }
2098
2099 /* Create a copy of the string, with internal nulls replaced by
2100 * newline characters, as is the vim convention.
2101 */
2102 save = (char *)alloc((unsigned)(len+1));
2103 if (save == NULL)
2104 {
2105 PyErr_NoMemory();
2106 return NULL;
2107 }
2108
2109 for (i = 0; i < len; ++i)
2110 {
2111 if (str[i] == '\0')
2112 save[i] = '\n';
2113 else
2114 save[i] = str[i];
2115 }
2116
2117 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002118 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002119
2120 return save;
2121}
2122
2123/* Get a line from the specified buffer. The line number is
2124 * in Vim format (1-based). The line is returned as a Python
2125 * string object.
2126 */
2127 static PyObject *
2128GetBufferLine(buf_T *buf, PyInt n)
2129{
2130 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2131}
2132
2133
2134/* Get a list of lines from the specified buffer. The line numbers
2135 * are in Vim format (1-based). The range is from lo up to, but not
2136 * including, hi. The list is returned as a Python list of string objects.
2137 */
2138 static PyObject *
2139GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2140{
2141 PyInt i;
2142 PyInt n = hi - lo;
2143 PyObject *list = PyList_New(n);
2144
2145 if (list == NULL)
2146 return NULL;
2147
2148 for (i = 0; i < n; ++i)
2149 {
2150 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2151
2152 /* Error check - was the Python string creation OK? */
2153 if (str == NULL)
2154 {
2155 Py_DECREF(list);
2156 return NULL;
2157 }
2158
2159 /* Set the list item */
2160 if (PyList_SetItem(list, i, str))
2161 {
2162 Py_DECREF(str);
2163 Py_DECREF(list);
2164 return NULL;
2165 }
2166 }
2167
2168 /* The ownership of the Python list is passed to the caller (ie,
2169 * the caller should Py_DECREF() the object when it is finished
2170 * with it).
2171 */
2172
2173 return list;
2174}
2175
2176/*
2177 * Check if deleting lines made the cursor position invalid.
2178 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2179 * deleted).
2180 */
2181 static void
2182py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2183{
2184 if (curwin->w_cursor.lnum >= lo)
2185 {
2186 /* Adjust the cursor position if it's in/after the changed
2187 * lines. */
2188 if (curwin->w_cursor.lnum >= hi)
2189 {
2190 curwin->w_cursor.lnum += extra;
2191 check_cursor_col();
2192 }
2193 else if (extra < 0)
2194 {
2195 curwin->w_cursor.lnum = lo;
2196 check_cursor();
2197 }
2198 else
2199 check_cursor_col();
2200 changed_cline_bef_curs();
2201 }
2202 invalidate_botline();
2203}
2204
Bram Moolenaar19e60942011-06-19 00:27:51 +02002205/*
2206 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002207 * in Vim format (1-based). The replacement line is given as
2208 * a Python string object. The object is checked for validity
2209 * and correct format. Errors are returned as a value of FAIL.
2210 * The return value is OK on success.
2211 * If OK is returned and len_change is not NULL, *len_change
2212 * is set to the change in the buffer length.
2213 */
2214 static int
2215SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2216{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002217 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002218 * There are three cases:
2219 * 1. NULL, or None - this is a deletion.
2220 * 2. A string - this is a replacement.
2221 * 3. Anything else - this is an error.
2222 */
2223 if (line == Py_None || line == NULL)
2224 {
2225 buf_T *savebuf = curbuf;
2226
2227 PyErr_Clear();
2228 curbuf = buf;
2229
2230 if (u_savedel((linenr_T)n, 1L) == FAIL)
2231 PyErr_SetVim(_("cannot save undo information"));
2232 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2233 PyErr_SetVim(_("cannot delete line"));
2234 else
2235 {
2236 if (buf == curwin->w_buffer)
2237 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2238 deleted_lines_mark((linenr_T)n, 1L);
2239 }
2240
2241 curbuf = savebuf;
2242
2243 if (PyErr_Occurred() || VimErrorCheck())
2244 return FAIL;
2245
2246 if (len_change)
2247 *len_change = -1;
2248
2249 return OK;
2250 }
2251 else if (PyString_Check(line))
2252 {
2253 char *save = StringToLine(line);
2254 buf_T *savebuf = curbuf;
2255
2256 if (save == NULL)
2257 return FAIL;
2258
2259 /* We do not need to free "save" if ml_replace() consumes it. */
2260 PyErr_Clear();
2261 curbuf = buf;
2262
2263 if (u_savesub((linenr_T)n) == FAIL)
2264 {
2265 PyErr_SetVim(_("cannot save undo information"));
2266 vim_free(save);
2267 }
2268 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2269 {
2270 PyErr_SetVim(_("cannot replace line"));
2271 vim_free(save);
2272 }
2273 else
2274 changed_bytes((linenr_T)n, 0);
2275
2276 curbuf = savebuf;
2277
2278 /* Check that the cursor is not beyond the end of the line now. */
2279 if (buf == curwin->w_buffer)
2280 check_cursor_col();
2281
2282 if (PyErr_Occurred() || VimErrorCheck())
2283 return FAIL;
2284
2285 if (len_change)
2286 *len_change = 0;
2287
2288 return OK;
2289 }
2290 else
2291 {
2292 PyErr_BadArgument();
2293 return FAIL;
2294 }
2295}
2296
Bram Moolenaar19e60942011-06-19 00:27:51 +02002297/* Replace a range of lines in the specified buffer. The line numbers are in
2298 * Vim format (1-based). The range is from lo up to, but not including, hi.
2299 * The replacement lines are given as a Python list of string objects. The
2300 * list is checked for validity and correct format. Errors are returned as a
2301 * value of FAIL. The return value is OK on success.
2302 * If OK is returned and len_change is not NULL, *len_change
2303 * is set to the change in the buffer length.
2304 */
2305 static int
2306SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2307{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002308 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002309 * There are three cases:
2310 * 1. NULL, or None - this is a deletion.
2311 * 2. A list - this is a replacement.
2312 * 3. Anything else - this is an error.
2313 */
2314 if (list == Py_None || list == NULL)
2315 {
2316 PyInt i;
2317 PyInt n = (int)(hi - lo);
2318 buf_T *savebuf = curbuf;
2319
2320 PyErr_Clear();
2321 curbuf = buf;
2322
2323 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2324 PyErr_SetVim(_("cannot save undo information"));
2325 else
2326 {
2327 for (i = 0; i < n; ++i)
2328 {
2329 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2330 {
2331 PyErr_SetVim(_("cannot delete line"));
2332 break;
2333 }
2334 }
2335 if (buf == curwin->w_buffer)
2336 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2337 deleted_lines_mark((linenr_T)lo, (long)i);
2338 }
2339
2340 curbuf = savebuf;
2341
2342 if (PyErr_Occurred() || VimErrorCheck())
2343 return FAIL;
2344
2345 if (len_change)
2346 *len_change = -n;
2347
2348 return OK;
2349 }
2350 else if (PyList_Check(list))
2351 {
2352 PyInt i;
2353 PyInt new_len = PyList_Size(list);
2354 PyInt old_len = hi - lo;
2355 PyInt extra = 0; /* lines added to text, can be negative */
2356 char **array;
2357 buf_T *savebuf;
2358
2359 if (new_len == 0) /* avoid allocating zero bytes */
2360 array = NULL;
2361 else
2362 {
2363 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
2364 if (array == NULL)
2365 {
2366 PyErr_NoMemory();
2367 return FAIL;
2368 }
2369 }
2370
2371 for (i = 0; i < new_len; ++i)
2372 {
2373 PyObject *line = PyList_GetItem(list, i);
2374
2375 array[i] = StringToLine(line);
2376 if (array[i] == NULL)
2377 {
2378 while (i)
2379 vim_free(array[--i]);
2380 vim_free(array);
2381 return FAIL;
2382 }
2383 }
2384
2385 savebuf = curbuf;
2386
2387 PyErr_Clear();
2388 curbuf = buf;
2389
2390 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2391 PyErr_SetVim(_("cannot save undo information"));
2392
2393 /* If the size of the range is reducing (ie, new_len < old_len) we
2394 * need to delete some old_len. We do this at the start, by
2395 * repeatedly deleting line "lo".
2396 */
2397 if (!PyErr_Occurred())
2398 {
2399 for (i = 0; i < old_len - new_len; ++i)
2400 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2401 {
2402 PyErr_SetVim(_("cannot delete line"));
2403 break;
2404 }
2405 extra -= i;
2406 }
2407
2408 /* For as long as possible, replace the existing old_len with the
2409 * new old_len. This is a more efficient operation, as it requires
2410 * less memory allocation and freeing.
2411 */
2412 if (!PyErr_Occurred())
2413 {
2414 for (i = 0; i < old_len && i < new_len; ++i)
2415 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2416 == FAIL)
2417 {
2418 PyErr_SetVim(_("cannot replace line"));
2419 break;
2420 }
2421 }
2422 else
2423 i = 0;
2424
2425 /* Now we may need to insert the remaining new old_len. If we do, we
2426 * must free the strings as we finish with them (we can't pass the
2427 * responsibility to vim in this case).
2428 */
2429 if (!PyErr_Occurred())
2430 {
2431 while (i < new_len)
2432 {
2433 if (ml_append((linenr_T)(lo + i - 1),
2434 (char_u *)array[i], 0, FALSE) == FAIL)
2435 {
2436 PyErr_SetVim(_("cannot insert line"));
2437 break;
2438 }
2439 vim_free(array[i]);
2440 ++i;
2441 ++extra;
2442 }
2443 }
2444
2445 /* Free any left-over old_len, as a result of an error */
2446 while (i < new_len)
2447 {
2448 vim_free(array[i]);
2449 ++i;
2450 }
2451
2452 /* Free the array of old_len. All of its contents have now
2453 * been dealt with (either freed, or the responsibility passed
2454 * to vim.
2455 */
2456 vim_free(array);
2457
2458 /* Adjust marks. Invalidate any which lie in the
2459 * changed range, and move any in the remainder of the buffer.
2460 */
2461 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2462 (long)MAXLNUM, (long)extra);
2463 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2464
2465 if (buf == curwin->w_buffer)
2466 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2467
2468 curbuf = savebuf;
2469
2470 if (PyErr_Occurred() || VimErrorCheck())
2471 return FAIL;
2472
2473 if (len_change)
2474 *len_change = new_len - old_len;
2475
2476 return OK;
2477 }
2478 else
2479 {
2480 PyErr_BadArgument();
2481 return FAIL;
2482 }
2483}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002484
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002485/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002486 * The line number is in Vim format (1-based). The lines to be inserted are
2487 * given as a Python list of string objects or as a single string. The lines
2488 * to be added are checked for validity and correct format. Errors are
2489 * returned as a value of FAIL. The return value is OK on success.
2490 * If OK is returned and len_change is not NULL, *len_change
2491 * is set to the change in the buffer length.
2492 */
2493 static int
2494InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2495{
2496 /* First of all, we check the type of the supplied Python object.
2497 * It must be a string or a list, or the call is in error.
2498 */
2499 if (PyString_Check(lines))
2500 {
2501 char *str = StringToLine(lines);
2502 buf_T *savebuf;
2503
2504 if (str == NULL)
2505 return FAIL;
2506
2507 savebuf = curbuf;
2508
2509 PyErr_Clear();
2510 curbuf = buf;
2511
2512 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2513 PyErr_SetVim(_("cannot save undo information"));
2514 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2515 PyErr_SetVim(_("cannot insert line"));
2516 else
2517 appended_lines_mark((linenr_T)n, 1L);
2518
2519 vim_free(str);
2520 curbuf = savebuf;
2521 update_screen(VALID);
2522
2523 if (PyErr_Occurred() || VimErrorCheck())
2524 return FAIL;
2525
2526 if (len_change)
2527 *len_change = 1;
2528
2529 return OK;
2530 }
2531 else if (PyList_Check(lines))
2532 {
2533 PyInt i;
2534 PyInt size = PyList_Size(lines);
2535 char **array;
2536 buf_T *savebuf;
2537
2538 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2539 if (array == NULL)
2540 {
2541 PyErr_NoMemory();
2542 return FAIL;
2543 }
2544
2545 for (i = 0; i < size; ++i)
2546 {
2547 PyObject *line = PyList_GetItem(lines, i);
2548 array[i] = StringToLine(line);
2549
2550 if (array[i] == NULL)
2551 {
2552 while (i)
2553 vim_free(array[--i]);
2554 vim_free(array);
2555 return FAIL;
2556 }
2557 }
2558
2559 savebuf = curbuf;
2560
2561 PyErr_Clear();
2562 curbuf = buf;
2563
2564 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2565 PyErr_SetVim(_("cannot save undo information"));
2566 else
2567 {
2568 for (i = 0; i < size; ++i)
2569 {
2570 if (ml_append((linenr_T)(n + i),
2571 (char_u *)array[i], 0, FALSE) == FAIL)
2572 {
2573 PyErr_SetVim(_("cannot insert line"));
2574
2575 /* Free the rest of the lines */
2576 while (i < size)
2577 vim_free(array[i++]);
2578
2579 break;
2580 }
2581 vim_free(array[i]);
2582 }
2583 if (i > 0)
2584 appended_lines_mark((linenr_T)n, (long)i);
2585 }
2586
2587 /* Free the array of lines. All of its contents have now
2588 * been freed.
2589 */
2590 vim_free(array);
2591
2592 curbuf = savebuf;
2593 update_screen(VALID);
2594
2595 if (PyErr_Occurred() || VimErrorCheck())
2596 return FAIL;
2597
2598 if (len_change)
2599 *len_change = size;
2600
2601 return OK;
2602 }
2603 else
2604 {
2605 PyErr_BadArgument();
2606 return FAIL;
2607 }
2608}
2609
2610/*
2611 * Common routines for buffers and line ranges
2612 * -------------------------------------------
2613 */
2614
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002615typedef struct
2616{
2617 PyObject_HEAD
2618 buf_T *buf;
2619} BufferObject;
2620
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002621 static int
2622CheckBuffer(BufferObject *this)
2623{
2624 if (this->buf == INVALID_BUFFER_VALUE)
2625 {
2626 PyErr_SetVim(_("attempt to refer to deleted buffer"));
2627 return -1;
2628 }
2629
2630 return 0;
2631}
2632
2633 static PyObject *
2634RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
2635{
2636 if (CheckBuffer(self))
2637 return NULL;
2638
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002639 if (end == -1)
2640 end = self->buf->b_ml.ml_line_count;
2641
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002642 if (n < 0)
2643 n += end - start + 1;
2644
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002645 if (n < 0 || n > end - start)
2646 {
2647 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2648 return NULL;
2649 }
2650
2651 return GetBufferLine(self->buf, n+start);
2652}
2653
2654 static PyObject *
2655RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
2656{
2657 PyInt size;
2658
2659 if (CheckBuffer(self))
2660 return NULL;
2661
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002662 if (end == -1)
2663 end = self->buf->b_ml.ml_line_count;
2664
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002665 size = end - start + 1;
2666
2667 if (lo < 0)
2668 lo = 0;
2669 else if (lo > size)
2670 lo = size;
2671 if (hi < 0)
2672 hi = 0;
2673 if (hi < lo)
2674 hi = lo;
2675 else if (hi > size)
2676 hi = size;
2677
2678 return GetBufferLineList(self->buf, lo+start, hi+start);
2679}
2680
2681 static PyInt
2682RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2683{
2684 PyInt len_change;
2685
2686 if (CheckBuffer(self))
2687 return -1;
2688
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002689 if (end == -1)
2690 end = self->buf->b_ml.ml_line_count;
2691
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002692 if (n < 0)
2693 n += end - start + 1;
2694
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002695 if (n < 0 || n > end - start)
2696 {
2697 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2698 return -1;
2699 }
2700
2701 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
2702 return -1;
2703
2704 if (new_end)
2705 *new_end = end + len_change;
2706
2707 return 0;
2708}
2709
Bram Moolenaar19e60942011-06-19 00:27:51 +02002710 static PyInt
2711RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2712{
2713 PyInt size;
2714 PyInt len_change;
2715
2716 /* Self must be a valid buffer */
2717 if (CheckBuffer(self))
2718 return -1;
2719
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002720 if (end == -1)
2721 end = self->buf->b_ml.ml_line_count;
2722
Bram Moolenaar19e60942011-06-19 00:27:51 +02002723 /* Sort out the slice range */
2724 size = end - start + 1;
2725
2726 if (lo < 0)
2727 lo = 0;
2728 else if (lo > size)
2729 lo = size;
2730 if (hi < 0)
2731 hi = 0;
2732 if (hi < lo)
2733 hi = lo;
2734 else if (hi > size)
2735 hi = size;
2736
2737 if (SetBufferLineList(self->buf, lo + start, hi + start,
2738 val, &len_change) == FAIL)
2739 return -1;
2740
2741 if (new_end)
2742 *new_end = end + len_change;
2743
2744 return 0;
2745}
2746
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002747
2748 static PyObject *
2749RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
2750{
2751 PyObject *lines;
2752 PyInt len_change;
2753 PyInt max;
2754 PyInt n;
2755
2756 if (CheckBuffer(self))
2757 return NULL;
2758
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002759 if (end == -1)
2760 end = self->buf->b_ml.ml_line_count;
2761
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002762 max = n = end - start + 1;
2763
2764 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
2765 return NULL;
2766
2767 if (n < 0 || n > max)
2768 {
2769 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
2770 return NULL;
2771 }
2772
2773 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
2774 return NULL;
2775
2776 if (new_end)
2777 *new_end = end + len_change;
2778
2779 Py_INCREF(Py_None);
2780 return Py_None;
2781}
2782
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002783/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002784 */
2785
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002786static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002787static PySequenceMethods RangeAsSeq;
2788static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002789
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002790typedef struct
2791{
2792 PyObject_HEAD
2793 BufferObject *buf;
2794 PyInt start;
2795 PyInt end;
2796} RangeObject;
2797
2798 static PyObject *
2799RangeNew(buf_T *buf, PyInt start, PyInt end)
2800{
2801 BufferObject *bufr;
2802 RangeObject *self;
2803 self = PyObject_NEW(RangeObject, &RangeType);
2804 if (self == NULL)
2805 return NULL;
2806
2807 bufr = (BufferObject *)BufferNew(buf);
2808 if (bufr == NULL)
2809 {
2810 Py_DECREF(self);
2811 return NULL;
2812 }
2813 Py_INCREF(bufr);
2814
2815 self->buf = bufr;
2816 self->start = start;
2817 self->end = end;
2818
2819 return (PyObject *)(self);
2820}
2821
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002822 static void
2823RangeDestructor(PyObject *self)
2824{
2825 Py_DECREF(((RangeObject *)(self))->buf);
2826 DESTRUCTOR_FINISH(self);
2827}
2828
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002829 static PyInt
2830RangeLength(PyObject *self)
2831{
2832 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
2833 if (CheckBuffer(((RangeObject *)(self))->buf))
2834 return -1; /* ??? */
2835
2836 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
2837}
2838
2839 static PyObject *
2840RangeItem(PyObject *self, PyInt n)
2841{
2842 return RBItem(((RangeObject *)(self))->buf, n,
2843 ((RangeObject *)(self))->start,
2844 ((RangeObject *)(self))->end);
2845}
2846
2847 static PyObject *
2848RangeSlice(PyObject *self, PyInt lo, PyInt hi)
2849{
2850 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
2851 ((RangeObject *)(self))->start,
2852 ((RangeObject *)(self))->end);
2853}
2854
2855 static PyObject *
2856RangeAppend(PyObject *self, PyObject *args)
2857{
2858 return RBAppend(((RangeObject *)(self))->buf, args,
2859 ((RangeObject *)(self))->start,
2860 ((RangeObject *)(self))->end,
2861 &((RangeObject *)(self))->end);
2862}
2863
2864 static PyObject *
2865RangeRepr(PyObject *self)
2866{
2867 static char repr[100];
2868 RangeObject *this = (RangeObject *)(self);
2869
2870 if (this->buf->buf == INVALID_BUFFER_VALUE)
2871 {
2872 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
2873 (self));
2874 return PyString_FromString(repr);
2875 }
2876 else
2877 {
2878 char *name = (char *)this->buf->buf->b_fname;
2879 int len;
2880
2881 if (name == NULL)
2882 name = "";
2883 len = (int)strlen(name);
2884
2885 if (len > 45)
2886 name = name + (45 - len);
2887
2888 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
2889 len > 45 ? "..." : "", name,
2890 this->start, this->end);
2891
2892 return PyString_FromString(repr);
2893 }
2894}
2895
2896static struct PyMethodDef RangeMethods[] = {
2897 /* name, function, calling, documentation */
2898 {"append", RangeAppend, 1, "Append data to the Vim range" },
2899 { NULL, NULL, 0, NULL }
2900};
2901
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002902static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002903static PySequenceMethods BufferAsSeq;
2904static PyMappingMethods BufferAsMapping;
2905
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002906 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02002907BufferNew(buf_T *buf)
2908{
2909 /* We need to handle deletion of buffers underneath us.
2910 * If we add a "b_python*_ref" field to the buf_T structure,
2911 * then we can get at it in buf_freeall() in vim. We then
2912 * need to create only ONE Python object per buffer - if
2913 * we try to create a second, just INCREF the existing one
2914 * and return it. The (single) Python object referring to
2915 * the buffer is stored in "b_python*_ref".
2916 * Question: what to do on a buf_freeall(). We'll probably
2917 * have to either delete the Python object (DECREF it to
2918 * zero - a bad idea, as it leaves dangling refs!) or
2919 * set the buf_T * value to an invalid value (-1?), which
2920 * means we need checks in all access functions... Bah.
2921 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002922 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02002923 * b_python_ref and b_python3_ref fields respectively.
2924 */
2925
2926 BufferObject *self;
2927
2928 if (BUF_PYTHON_REF(buf) != NULL)
2929 {
2930 self = BUF_PYTHON_REF(buf);
2931 Py_INCREF(self);
2932 }
2933 else
2934 {
2935 self = PyObject_NEW(BufferObject, &BufferType);
2936 if (self == NULL)
2937 return NULL;
2938 self->buf = buf;
2939 BUF_PYTHON_REF(buf) = self;
2940 }
2941
2942 return (PyObject *)(self);
2943}
2944
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002945 static void
2946BufferDestructor(PyObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002947{
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002948 BufferObject *this = (BufferObject *)(self);
2949
2950 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
2951 BUF_PYTHON_REF(this->buf) = NULL;
2952
2953 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002954}
2955
Bram Moolenaar971db462013-05-12 18:44:48 +02002956 static PyInt
2957BufferLength(PyObject *self)
2958{
2959 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
2960 if (CheckBuffer((BufferObject *)(self)))
2961 return -1; /* ??? */
2962
2963 return (PyInt)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
2964}
2965
2966 static PyObject *
2967BufferItem(PyObject *self, PyInt n)
2968{
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002969 return RBItem((BufferObject *)(self), n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02002970}
2971
2972 static PyObject *
2973BufferSlice(PyObject *self, PyInt lo, PyInt hi)
2974{
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002975 return RBSlice((BufferObject *)(self), lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02002976}
2977
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002978 static PyObject *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002979BufferAttr(BufferObject *this, char *name)
2980{
2981 if (strcmp(name, "name") == 0)
2982 return Py_BuildValue("s", this->buf->b_ffname);
2983 else if (strcmp(name, "number") == 0)
2984 return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
2985 else if (strcmp(name, "vars") == 0)
2986 return DictionaryNew(this->buf->b_vars);
2987 else if (strcmp(name, "options") == 0)
2988 return OptionsNew(SREQ_BUF, this->buf, (checkfun) CheckBuffer,
2989 (PyObject *) this);
2990 else if (strcmp(name,"__members__") == 0)
2991 return Py_BuildValue("[ssss]", "name", "number", "vars", "options");
2992 else
2993 return NULL;
2994}
2995
2996 static PyObject *
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002997BufferAppend(PyObject *self, PyObject *args)
2998{
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002999 return RBAppend((BufferObject *)(self), args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003000}
3001
3002 static PyObject *
3003BufferMark(PyObject *self, PyObject *args)
3004{
3005 pos_T *posp;
3006 char *pmark;
3007 char mark;
3008 buf_T *curbuf_save;
3009
3010 if (CheckBuffer((BufferObject *)(self)))
3011 return NULL;
3012
3013 if (!PyArg_ParseTuple(args, "s", &pmark))
3014 return NULL;
3015 mark = *pmark;
3016
3017 curbuf_save = curbuf;
3018 curbuf = ((BufferObject *)(self))->buf;
3019 posp = getmark(mark, FALSE);
3020 curbuf = curbuf_save;
3021
3022 if (posp == NULL)
3023 {
3024 PyErr_SetVim(_("invalid mark name"));
3025 return NULL;
3026 }
3027
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003028 /* Check for keyboard interrupt */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003029 if (VimErrorCheck())
3030 return NULL;
3031
3032 if (posp->lnum <= 0)
3033 {
3034 /* Or raise an error? */
3035 Py_INCREF(Py_None);
3036 return Py_None;
3037 }
3038
3039 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3040}
3041
3042 static PyObject *
3043BufferRange(PyObject *self, PyObject *args)
3044{
3045 PyInt start;
3046 PyInt end;
3047
3048 if (CheckBuffer((BufferObject *)(self)))
3049 return NULL;
3050
3051 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3052 return NULL;
3053
3054 return RangeNew(((BufferObject *)(self))->buf, start, end);
3055}
3056
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003057 static PyObject *
3058BufferRepr(PyObject *self)
3059{
3060 static char repr[100];
3061 BufferObject *this = (BufferObject *)(self);
3062
3063 if (this->buf == INVALID_BUFFER_VALUE)
3064 {
3065 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3066 return PyString_FromString(repr);
3067 }
3068 else
3069 {
3070 char *name = (char *)this->buf->b_fname;
3071 PyInt len;
3072
3073 if (name == NULL)
3074 name = "";
3075 len = strlen(name);
3076
3077 if (len > 35)
3078 name = name + (35 - len);
3079
3080 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3081
3082 return PyString_FromString(repr);
3083 }
3084}
3085
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003086static struct PyMethodDef BufferMethods[] = {
3087 /* name, function, calling, documentation */
3088 {"append", BufferAppend, 1, "Append data to Vim buffer" },
3089 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
3090 {"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 +01003091#if PY_VERSION_HEX >= 0x03000000
3092 {"__dir__", BufferDir, 4, "List its attributes" },
3093#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003094 { NULL, NULL, 0, NULL }
3095};
3096
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003097/*
3098 * Buffer list object - Implementation
3099 */
3100
3101static PyTypeObject BufMapType;
3102
3103typedef struct
3104{
3105 PyObject_HEAD
3106} BufMapObject;
3107
3108 static PyInt
3109BufMapLength(PyObject *self UNUSED)
3110{
3111 buf_T *b = firstbuf;
3112 PyInt n = 0;
3113
3114 while (b)
3115 {
3116 ++n;
3117 b = b->b_next;
3118 }
3119
3120 return n;
3121}
3122
3123 static PyObject *
3124BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3125{
3126 buf_T *b;
3127 int bnr;
3128
3129#if PY_MAJOR_VERSION < 3
3130 if (PyInt_Check(keyObject))
3131 bnr = PyInt_AsLong(keyObject);
3132 else
3133#endif
3134 if (PyLong_Check(keyObject))
3135 bnr = PyLong_AsLong(keyObject);
3136 else
3137 {
3138 PyErr_SetString(PyExc_ValueError, _("key must be integer"));
3139 return NULL;
3140 }
3141
3142 b = buflist_findnr(bnr);
3143
3144 if (b)
3145 return BufferNew(b);
3146 else
3147 {
3148 PyErr_SetString(PyExc_KeyError, _("no such buffer"));
3149 return NULL;
3150 }
3151}
3152
3153 static void
3154BufMapIterDestruct(PyObject *buffer)
3155{
3156 /* Iteration was stopped before all buffers were processed */
3157 if (buffer)
3158 {
3159 Py_DECREF(buffer);
3160 }
3161}
3162
3163 static PyObject *
3164BufMapIterNext(PyObject **buffer)
3165{
3166 PyObject *next;
3167 PyObject *r;
3168
3169 if (!*buffer)
3170 return NULL;
3171
3172 r = *buffer;
3173
3174 if (CheckBuffer((BufferObject *)(r)))
3175 {
3176 *buffer = NULL;
3177 return NULL;
3178 }
3179
3180 if (!((BufferObject *)(r))->buf->b_next)
3181 next = NULL;
3182 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3183 return NULL;
3184 *buffer = next;
3185 /* Do not increment reference: we no longer hold it (decref), but whoever on
3186 * other side will hold (incref). Decref+incref = nothing.
3187 */
3188 return r;
3189}
3190
3191 static PyObject *
3192BufMapIter(PyObject *self UNUSED)
3193{
3194 PyObject *buffer;
3195
3196 buffer = BufferNew(firstbuf);
3197 return IterNew(buffer,
3198 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext);
3199}
3200
3201static PyMappingMethods BufMapAsMapping = {
3202 (lenfunc) BufMapLength,
3203 (binaryfunc) BufMapItem,
3204 (objobjargproc) 0,
3205};
3206
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003207/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003208 */
3209
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003210 static PyObject *
3211CurrentGetattr(PyObject *self UNUSED, char *name)
3212{
3213 if (strcmp(name, "buffer") == 0)
3214 return (PyObject *)BufferNew(curbuf);
3215 else if (strcmp(name, "window") == 0)
3216 return (PyObject *)WindowNew(curwin);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003217 else if (strcmp(name, "tabpage") == 0)
3218 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003219 else if (strcmp(name, "line") == 0)
3220 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3221 else if (strcmp(name, "range") == 0)
3222 return RangeNew(curbuf, RangeStart, RangeEnd);
3223 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003224 return Py_BuildValue("[sssss]", "buffer", "window", "line", "range",
3225 "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003226 else
3227 {
3228 PyErr_SetString(PyExc_AttributeError, name);
3229 return NULL;
3230 }
3231}
3232
3233 static int
3234CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3235{
3236 if (strcmp(name, "line") == 0)
3237 {
3238 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3239 return -1;
3240
3241 return 0;
3242 }
3243 else
3244 {
3245 PyErr_SetString(PyExc_AttributeError, name);
3246 return -1;
3247 }
3248}
3249
Bram Moolenaardb913952012-06-29 12:54:53 +02003250 static void
3251set_ref_in_py(const int copyID)
3252{
3253 pylinkedlist_T *cur;
3254 dict_T *dd;
3255 list_T *ll;
3256
3257 if (lastdict != NULL)
3258 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3259 {
3260 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3261 if (dd->dv_copyID != copyID)
3262 {
3263 dd->dv_copyID = copyID;
3264 set_ref_in_ht(&dd->dv_hashtab, copyID);
3265 }
3266 }
3267
3268 if (lastlist != NULL)
3269 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3270 {
3271 ll = ((ListObject *) (cur->pll_obj))->list;
3272 if (ll->lv_copyID != copyID)
3273 {
3274 ll->lv_copyID = copyID;
3275 set_ref_in_list(ll, copyID);
3276 }
3277 }
3278}
3279
3280 static int
3281set_string_copy(char_u *str, typval_T *tv)
3282{
3283 tv->vval.v_string = vim_strsave(str);
3284 if (tv->vval.v_string == NULL)
3285 {
3286 PyErr_NoMemory();
3287 return -1;
3288 }
3289 return 0;
3290}
3291
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003292 static int
3293pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3294{
3295 dict_T *d;
3296 char_u *key;
3297 dictitem_T *di;
3298 PyObject *keyObject;
3299 PyObject *valObject;
3300 Py_ssize_t iter = 0;
3301
3302 d = dict_alloc();
3303 if (d == NULL)
3304 {
3305 PyErr_NoMemory();
3306 return -1;
3307 }
3308
3309 tv->v_type = VAR_DICT;
3310 tv->vval.v_dict = d;
3311
3312 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
3313 {
3314 DICTKEY_DECL
3315
3316 if (keyObject == NULL)
3317 return -1;
3318 if (valObject == NULL)
3319 return -1;
3320
3321 DICTKEY_GET_NOTEMPTY(-1)
3322
3323 di = dictitem_alloc(key);
3324
3325 DICTKEY_UNREF
3326
3327 if (di == NULL)
3328 {
3329 PyErr_NoMemory();
3330 return -1;
3331 }
3332 di->di_tv.v_lock = 0;
3333
3334 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3335 {
3336 vim_free(di);
3337 return -1;
3338 }
3339 if (dict_add(d, di) == FAIL)
3340 {
3341 vim_free(di);
3342 PyErr_SetVim(_("failed to add key to dictionary"));
3343 return -1;
3344 }
3345 }
3346 return 0;
3347}
3348
3349 static int
3350pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3351{
3352 dict_T *d;
3353 char_u *key;
3354 dictitem_T *di;
3355 PyObject *list;
3356 PyObject *litem;
3357 PyObject *keyObject;
3358 PyObject *valObject;
3359 Py_ssize_t lsize;
3360
3361 d = dict_alloc();
3362 if (d == NULL)
3363 {
3364 PyErr_NoMemory();
3365 return -1;
3366 }
3367
3368 tv->v_type = VAR_DICT;
3369 tv->vval.v_dict = d;
3370
3371 list = PyMapping_Items(obj);
3372 if (list == NULL)
3373 return -1;
3374 lsize = PyList_Size(list);
3375 while (lsize--)
3376 {
3377 DICTKEY_DECL
3378
3379 litem = PyList_GetItem(list, lsize);
3380 if (litem == NULL)
3381 {
3382 Py_DECREF(list);
3383 return -1;
3384 }
3385
3386 keyObject = PyTuple_GetItem(litem, 0);
3387 if (keyObject == NULL)
3388 {
3389 Py_DECREF(list);
3390 Py_DECREF(litem);
3391 return -1;
3392 }
3393
3394 DICTKEY_GET_NOTEMPTY(-1)
3395
3396 valObject = PyTuple_GetItem(litem, 1);
3397 if (valObject == NULL)
3398 {
3399 Py_DECREF(list);
3400 Py_DECREF(litem);
3401 return -1;
3402 }
3403
3404 di = dictitem_alloc(key);
3405
3406 DICTKEY_UNREF
3407
3408 if (di == NULL)
3409 {
3410 Py_DECREF(list);
3411 Py_DECREF(litem);
3412 PyErr_NoMemory();
3413 return -1;
3414 }
3415 di->di_tv.v_lock = 0;
3416
3417 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3418 {
3419 vim_free(di);
3420 Py_DECREF(list);
3421 Py_DECREF(litem);
3422 return -1;
3423 }
3424 if (dict_add(d, di) == FAIL)
3425 {
3426 vim_free(di);
3427 Py_DECREF(list);
3428 Py_DECREF(litem);
3429 PyErr_SetVim(_("failed to add key to dictionary"));
3430 return -1;
3431 }
3432 Py_DECREF(litem);
3433 }
3434 Py_DECREF(list);
3435 return 0;
3436}
3437
3438 static int
3439pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3440{
3441 list_T *l;
3442
3443 l = list_alloc();
3444 if (l == NULL)
3445 {
3446 PyErr_NoMemory();
3447 return -1;
3448 }
3449
3450 tv->v_type = VAR_LIST;
3451 tv->vval.v_list = l;
3452
3453 if (list_py_concat(l, obj, lookupDict) == -1)
3454 return -1;
3455
3456 return 0;
3457}
3458
3459 static int
3460pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3461{
3462 PyObject *iterator = PyObject_GetIter(obj);
3463 PyObject *item;
3464 list_T *l;
3465 listitem_T *li;
3466
3467 l = list_alloc();
3468
3469 if (l == NULL)
3470 {
3471 PyErr_NoMemory();
3472 return -1;
3473 }
3474
3475 tv->vval.v_list = l;
3476 tv->v_type = VAR_LIST;
3477
3478
3479 if (iterator == NULL)
3480 return -1;
3481
3482 while ((item = PyIter_Next(obj)))
3483 {
3484 li = listitem_alloc();
3485 if (li == NULL)
3486 {
3487 PyErr_NoMemory();
3488 return -1;
3489 }
3490 li->li_tv.v_lock = 0;
3491
3492 if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
3493 return -1;
3494
3495 list_append(l, li);
3496
3497 Py_DECREF(item);
3498 }
3499
3500 Py_DECREF(iterator);
3501 return 0;
3502}
3503
Bram Moolenaardb913952012-06-29 12:54:53 +02003504typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
3505
3506 static int
3507convert_dl(PyObject *obj, typval_T *tv,
3508 pytotvfunc py_to_tv, PyObject *lookupDict)
3509{
3510 PyObject *capsule;
3511 char hexBuf[sizeof(void *) * 2 + 3];
3512
3513 sprintf(hexBuf, "%p", obj);
3514
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003515# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02003516 capsule = PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003517# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02003518 capsule = (PyObject *)PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003519# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02003520 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02003521 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003522# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02003523 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02003524# else
3525 capsule = PyCObject_FromVoidPtr(tv, NULL);
3526# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02003527 PyDict_SetItemString(lookupDict, hexBuf, capsule);
3528 Py_DECREF(capsule);
3529 if (py_to_tv(obj, tv, lookupDict) == -1)
3530 {
3531 tv->v_type = VAR_UNKNOWN;
3532 return -1;
3533 }
3534 /* As we are not using copy_tv which increments reference count we must
3535 * do it ourself. */
3536 switch(tv->v_type)
3537 {
3538 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
3539 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
3540 }
3541 }
3542 else
3543 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003544 typval_T *v;
3545
3546# ifdef PY_USE_CAPSULE
3547 v = PyCapsule_GetPointer(capsule, NULL);
3548# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02003549 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003550# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02003551 copy_tv(v, tv);
3552 }
3553 return 0;
3554}
3555
3556 static int
3557ConvertFromPyObject(PyObject *obj, typval_T *tv)
3558{
3559 PyObject *lookup_dict;
3560 int r;
3561
3562 lookup_dict = PyDict_New();
3563 r = _ConvertFromPyObject(obj, tv, lookup_dict);
3564 Py_DECREF(lookup_dict);
3565 return r;
3566}
3567
3568 static int
3569_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3570{
3571 if (obj->ob_type == &DictionaryType)
3572 {
3573 tv->v_type = VAR_DICT;
3574 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
3575 ++tv->vval.v_dict->dv_refcount;
3576 }
3577 else if (obj->ob_type == &ListType)
3578 {
3579 tv->v_type = VAR_LIST;
3580 tv->vval.v_list = (((ListObject *)(obj))->list);
3581 ++tv->vval.v_list->lv_refcount;
3582 }
3583 else if (obj->ob_type == &FunctionType)
3584 {
3585 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
3586 return -1;
3587
3588 tv->v_type = VAR_FUNC;
3589 func_ref(tv->vval.v_string);
3590 }
Bram Moolenaardb913952012-06-29 12:54:53 +02003591 else if (PyBytes_Check(obj))
3592 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003593 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02003594
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003595 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
3596 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02003597 if (result == NULL)
3598 return -1;
3599
3600 if (set_string_copy(result, tv) == -1)
3601 return -1;
3602
3603 tv->v_type = VAR_STRING;
3604 }
3605 else if (PyUnicode_Check(obj))
3606 {
3607 PyObject *bytes;
3608 char_u *result;
3609
Bram Moolenaardb913952012-06-29 12:54:53 +02003610 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
3611 if (bytes == NULL)
3612 return -1;
3613
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003614 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
3615 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02003616 if (result == NULL)
3617 return -1;
3618
3619 if (set_string_copy(result, tv) == -1)
3620 {
3621 Py_XDECREF(bytes);
3622 return -1;
3623 }
3624 Py_XDECREF(bytes);
3625
3626 tv->v_type = VAR_STRING;
3627 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02003628#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02003629 else if (PyInt_Check(obj))
3630 {
3631 tv->v_type = VAR_NUMBER;
3632 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
3633 }
3634#endif
3635 else if (PyLong_Check(obj))
3636 {
3637 tv->v_type = VAR_NUMBER;
3638 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
3639 }
3640 else if (PyDict_Check(obj))
3641 return convert_dl(obj, tv, pydict_to_tv, lookupDict);
3642#ifdef FEAT_FLOAT
3643 else if (PyFloat_Check(obj))
3644 {
3645 tv->v_type = VAR_FLOAT;
3646 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
3647 }
3648#endif
3649 else if (PyIter_Check(obj))
3650 return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
3651 else if (PySequence_Check(obj))
3652 return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
3653 else if (PyMapping_Check(obj))
3654 return convert_dl(obj, tv, pymap_to_tv, lookupDict);
3655 else
3656 {
3657 PyErr_SetString(PyExc_TypeError, _("unable to convert to vim structure"));
3658 return -1;
3659 }
3660 return 0;
3661}
3662
3663 static PyObject *
3664ConvertToPyObject(typval_T *tv)
3665{
3666 if (tv == NULL)
3667 {
3668 PyErr_SetVim(_("NULL reference passed"));
3669 return NULL;
3670 }
3671 switch (tv->v_type)
3672 {
3673 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02003674 return PyBytes_FromString(tv->vval.v_string == NULL
3675 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02003676 case VAR_NUMBER:
3677 return PyLong_FromLong((long) tv->vval.v_number);
3678#ifdef FEAT_FLOAT
3679 case VAR_FLOAT:
3680 return PyFloat_FromDouble((double) tv->vval.v_float);
3681#endif
3682 case VAR_LIST:
3683 return ListNew(tv->vval.v_list);
3684 case VAR_DICT:
3685 return DictionaryNew(tv->vval.v_dict);
3686 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02003687 return FunctionNew(tv->vval.v_string == NULL
3688 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02003689 case VAR_UNKNOWN:
3690 Py_INCREF(Py_None);
3691 return Py_None;
3692 default:
3693 PyErr_SetVim(_("internal error: invalid value type"));
3694 return NULL;
3695 }
3696}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003697
3698typedef struct
3699{
3700 PyObject_HEAD
3701} CurrentObject;
3702static PyTypeObject CurrentType;
3703
3704 static void
3705init_structs(void)
3706{
3707 vim_memset(&OutputType, 0, sizeof(OutputType));
3708 OutputType.tp_name = "vim.message";
3709 OutputType.tp_basicsize = sizeof(OutputObject);
3710 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
3711 OutputType.tp_doc = "vim message object";
3712 OutputType.tp_methods = OutputMethods;
3713#if PY_MAJOR_VERSION >= 3
3714 OutputType.tp_getattro = OutputGetattro;
3715 OutputType.tp_setattro = OutputSetattro;
3716 OutputType.tp_alloc = call_PyType_GenericAlloc;
3717 OutputType.tp_new = call_PyType_GenericNew;
3718 OutputType.tp_free = call_PyObject_Free;
3719#else
3720 OutputType.tp_getattr = OutputGetattr;
3721 OutputType.tp_setattr = OutputSetattr;
3722#endif
3723
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003724 vim_memset(&IterType, 0, sizeof(IterType));
3725 IterType.tp_name = "vim.iter";
3726 IterType.tp_basicsize = sizeof(IterObject);
3727 IterType.tp_flags = Py_TPFLAGS_DEFAULT;
3728 IterType.tp_doc = "generic iterator object";
3729 IterType.tp_iter = IterIter;
3730 IterType.tp_iternext = IterNext;
3731
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003732 vim_memset(&BufferType, 0, sizeof(BufferType));
3733 BufferType.tp_name = "vim.buffer";
3734 BufferType.tp_basicsize = sizeof(BufferType);
3735 BufferType.tp_dealloc = BufferDestructor;
3736 BufferType.tp_repr = BufferRepr;
3737 BufferType.tp_as_sequence = &BufferAsSeq;
3738 BufferType.tp_as_mapping = &BufferAsMapping;
3739 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
3740 BufferType.tp_doc = "vim buffer object";
3741 BufferType.tp_methods = BufferMethods;
3742#if PY_MAJOR_VERSION >= 3
3743 BufferType.tp_getattro = BufferGetattro;
3744 BufferType.tp_alloc = call_PyType_GenericAlloc;
3745 BufferType.tp_new = call_PyType_GenericNew;
3746 BufferType.tp_free = call_PyObject_Free;
3747#else
3748 BufferType.tp_getattr = BufferGetattr;
3749#endif
3750
3751 vim_memset(&WindowType, 0, sizeof(WindowType));
3752 WindowType.tp_name = "vim.window";
3753 WindowType.tp_basicsize = sizeof(WindowObject);
3754 WindowType.tp_dealloc = WindowDestructor;
3755 WindowType.tp_repr = WindowRepr;
3756 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
3757 WindowType.tp_doc = "vim Window object";
3758 WindowType.tp_methods = WindowMethods;
3759#if PY_MAJOR_VERSION >= 3
3760 WindowType.tp_getattro = WindowGetattro;
3761 WindowType.tp_setattro = WindowSetattro;
3762 WindowType.tp_alloc = call_PyType_GenericAlloc;
3763 WindowType.tp_new = call_PyType_GenericNew;
3764 WindowType.tp_free = call_PyObject_Free;
3765#else
3766 WindowType.tp_getattr = WindowGetattr;
3767 WindowType.tp_setattr = WindowSetattr;
3768#endif
3769
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003770 vim_memset(&TabPageType, 0, sizeof(TabPageType));
3771 TabPageType.tp_name = "vim.tabpage";
3772 TabPageType.tp_basicsize = sizeof(TabPageObject);
3773 TabPageType.tp_dealloc = TabPageDestructor;
3774 TabPageType.tp_repr = TabPageRepr;
3775 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
3776 TabPageType.tp_doc = "vim tab page object";
3777 TabPageType.tp_methods = TabPageMethods;
3778#if PY_MAJOR_VERSION >= 3
3779 TabPageType.tp_getattro = TabPageGetattro;
3780 TabPageType.tp_alloc = call_PyType_GenericAlloc;
3781 TabPageType.tp_new = call_PyType_GenericNew;
3782 TabPageType.tp_free = call_PyObject_Free;
3783#else
3784 TabPageType.tp_getattr = TabPageGetattr;
3785#endif
3786
Bram Moolenaardfa38d42013-05-15 13:38:47 +02003787 vim_memset(&BufMapType, 0, sizeof(BufMapType));
3788 BufMapType.tp_name = "vim.bufferlist";
3789 BufMapType.tp_basicsize = sizeof(BufMapObject);
3790 BufMapType.tp_as_mapping = &BufMapAsMapping;
3791 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003792 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003793 BufferType.tp_doc = "vim buffer list";
3794
3795 vim_memset(&WinListType, 0, sizeof(WinListType));
3796 WinListType.tp_name = "vim.windowlist";
3797 WinListType.tp_basicsize = sizeof(WinListType);
3798 WinListType.tp_as_sequence = &WinListAsSeq;
3799 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
3800 WinListType.tp_doc = "vim window list";
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003801 WinListType.tp_dealloc = WinListDestructor;
3802
3803 vim_memset(&TabListType, 0, sizeof(TabListType));
3804 TabListType.tp_name = "vim.tabpagelist";
3805 TabListType.tp_basicsize = sizeof(TabListType);
3806 TabListType.tp_as_sequence = &TabListAsSeq;
3807 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
3808 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003809
3810 vim_memset(&RangeType, 0, sizeof(RangeType));
3811 RangeType.tp_name = "vim.range";
3812 RangeType.tp_basicsize = sizeof(RangeObject);
3813 RangeType.tp_dealloc = RangeDestructor;
3814 RangeType.tp_repr = RangeRepr;
3815 RangeType.tp_as_sequence = &RangeAsSeq;
3816 RangeType.tp_as_mapping = &RangeAsMapping;
3817 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
3818 RangeType.tp_doc = "vim Range object";
3819 RangeType.tp_methods = RangeMethods;
3820#if PY_MAJOR_VERSION >= 3
3821 RangeType.tp_getattro = RangeGetattro;
3822 RangeType.tp_alloc = call_PyType_GenericAlloc;
3823 RangeType.tp_new = call_PyType_GenericNew;
3824 RangeType.tp_free = call_PyObject_Free;
3825#else
3826 RangeType.tp_getattr = RangeGetattr;
3827#endif
3828
3829 vim_memset(&CurrentType, 0, sizeof(CurrentType));
3830 CurrentType.tp_name = "vim.currentdata";
3831 CurrentType.tp_basicsize = sizeof(CurrentObject);
3832 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
3833 CurrentType.tp_doc = "vim current object";
3834#if PY_MAJOR_VERSION >= 3
3835 CurrentType.tp_getattro = CurrentGetattro;
3836 CurrentType.tp_setattro = CurrentSetattro;
3837#else
3838 CurrentType.tp_getattr = CurrentGetattr;
3839 CurrentType.tp_setattr = CurrentSetattr;
3840#endif
3841
3842 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
3843 DictionaryType.tp_name = "vim.dictionary";
3844 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
3845 DictionaryType.tp_dealloc = DictionaryDestructor;
3846 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
3847 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
3848 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
3849 DictionaryType.tp_methods = DictionaryMethods;
3850#if PY_MAJOR_VERSION >= 3
3851 DictionaryType.tp_getattro = DictionaryGetattro;
3852 DictionaryType.tp_setattro = DictionarySetattro;
3853#else
3854 DictionaryType.tp_getattr = DictionaryGetattr;
3855 DictionaryType.tp_setattr = DictionarySetattr;
3856#endif
3857
3858 vim_memset(&ListType, 0, sizeof(ListType));
3859 ListType.tp_name = "vim.list";
3860 ListType.tp_dealloc = ListDestructor;
3861 ListType.tp_basicsize = sizeof(ListObject);
3862 ListType.tp_as_sequence = &ListAsSeq;
3863 ListType.tp_as_mapping = &ListAsMapping;
3864 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
3865 ListType.tp_doc = "list pushing modifications to vim structure";
3866 ListType.tp_methods = ListMethods;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003867 ListType.tp_iter = ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003868#if PY_MAJOR_VERSION >= 3
3869 ListType.tp_getattro = ListGetattro;
3870 ListType.tp_setattro = ListSetattro;
3871#else
3872 ListType.tp_getattr = ListGetattr;
3873 ListType.tp_setattr = ListSetattr;
3874#endif
3875
3876 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003877 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003878 FunctionType.tp_basicsize = sizeof(FunctionObject);
3879 FunctionType.tp_dealloc = FunctionDestructor;
3880 FunctionType.tp_call = FunctionCall;
3881 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
3882 FunctionType.tp_doc = "object that calls vim function";
3883 FunctionType.tp_methods = FunctionMethods;
3884#if PY_MAJOR_VERSION >= 3
3885 FunctionType.tp_getattro = FunctionGetattro;
3886#else
3887 FunctionType.tp_getattr = FunctionGetattr;
3888#endif
3889
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003890 vim_memset(&OptionsType, 0, sizeof(OptionsType));
3891 OptionsType.tp_name = "vim.options";
3892 OptionsType.tp_basicsize = sizeof(OptionsObject);
3893 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT;
3894 OptionsType.tp_doc = "object for manipulating options";
3895 OptionsType.tp_as_mapping = &OptionsAsMapping;
3896 OptionsType.tp_dealloc = OptionsDestructor;
3897
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003898#if PY_MAJOR_VERSION >= 3
3899 vim_memset(&vimmodule, 0, sizeof(vimmodule));
3900 vimmodule.m_name = "vim";
3901 vimmodule.m_doc = "Vim Python interface\n";
3902 vimmodule.m_size = -1;
3903 vimmodule.m_methods = VimMethods;
3904#endif
3905}