blob: e11c62e866f35524f84f4db97cd2b84ad57f8a6e [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
Bram Moolenaar808c2bc2013-06-23 13:11:18 +020021# define ENC_OPT ((char *)p_enc)
Bram Moolenaar91805fc2011-06-26 04:01:44 +020022#else
23# define ENC_OPT "latin1"
24#endif
Bram Moolenaard620aa92013-05-17 16:40:06 +020025#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020026
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020027static const char *vim_special_path = "_vim_path_";
28
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020029#define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020030#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020031#define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
Bram Moolenaarc476e522013-06-23 13:46:40 +020032#define PyErr_FORMAT(exc, str, tail) PyErr_Format(exc, _(str), tail)
33#define PyErr_VIM_FORMAT(str, tail) PyErr_FORMAT(VimError, str, tail)
34
35#define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
36 ? "(NULL)" \
37 : obj->ob_type->tp_name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020038
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +020039#define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
40 "empty keys are not allowed")
Bram Moolenaarc476e522013-06-23 13:46:40 +020041#define RAISE_LOCKED(type) PyErr_SET_VIM(_(type " is locked"))
42#define RAISE_LOCKED_DICTIONARY RAISE_LOCKED("dictionary")
43#define RAISE_LOCKED_LIST RAISE_LOCKED("list")
44#define RAISE_UNDO_FAIL PyErr_SET_VIM("cannot save undo information")
45#define RAISE_LINE_FAIL(act) PyErr_SET_VIM("cannot " act " line")
46#define RAISE_KEY_ADD_FAIL(key) \
47 PyErr_VIM_FORMAT("failed to add key '%s' to dictionary", key)
48#define RAISE_INVALID_INDEX_TYPE(idx) \
49 PyErr_FORMAT(PyExc_TypeError, "index must be int or slice, not %s", \
50 Py_TYPE_NAME(idx));
Bram Moolenaar35eacd72013-05-30 22:06:33 +020051
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020052#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
53#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020054#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020055
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020056typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020057typedef void (*runner)(const char *, void *
58#ifdef PY_CAN_RECURSE
59 , PyGILState_STATE *
60#endif
61 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020062
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020063static int ConvertFromPyObject(PyObject *, typval_T *);
64static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaara9922d62013-05-30 13:01:18 +020065static int ConvertFromPyMapping(PyObject *, typval_T *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020066static PyObject *WindowNew(win_T *, tabpage_T *);
67static PyObject *BufferNew (buf_T *);
68static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020069
70static PyInt RangeStart;
71static PyInt RangeEnd;
72
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020073static PyObject *globals;
74
Bram Moolenaarf4258302013-06-02 18:20:17 +020075static PyObject *py_chdir;
76static PyObject *py_fchdir;
77static PyObject *py_getcwd;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +020078static PyObject *vim_module;
79static PyObject *vim_special_path_object;
Bram Moolenaarf4258302013-06-02 18:20:17 +020080
Bram Moolenaar81c40c52013-06-12 14:41:04 +020081static PyObject *py_find_module;
82static PyObject *py_load_module;
83
84static PyObject *VimError;
85
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020086/*
87 * obtain a lock on the Vim data structures
88 */
89 static void
90Python_Lock_Vim(void)
91{
92}
93
94/*
95 * release a lock on the Vim data structures
96 */
97 static void
98Python_Release_Vim(void)
99{
100}
101
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200102/*
103 * The "todecref" argument holds a pointer to PyObject * that must be
104 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
105 * was needed to generate returned value is object.
106 *
107 * Use Py_XDECREF to decrement reference count.
108 */
109 static char_u *
110StringToChars(PyObject *object, PyObject **todecref)
111{
112 char_u *p;
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200113
114 if (PyBytes_Check(object))
115 {
116
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200117 if (PyBytes_AsStringAndSize(object, (char **) &p, NULL) == -1
118 || p == NULL)
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200119 return NULL;
120
121 *todecref = NULL;
122 }
123 else if (PyUnicode_Check(object))
124 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200125 PyObject *bytes;
126
127 if (!(bytes = PyUnicode_AsEncodedString(object, ENC_OPT, NULL)))
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200128 return NULL;
129
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200130 if(PyBytes_AsStringAndSize(bytes, (char **) &p, NULL) == -1
131 || p == NULL)
132 {
133 Py_DECREF(bytes);
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200134 return NULL;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200135 }
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200136
137 *todecref = bytes;
138 }
139 else
140 {
Bram Moolenaarc476e522013-06-23 13:46:40 +0200141 PyErr_FORMAT(PyExc_TypeError,
142#if PY_MAJOR_VERSION < 3
143 "expected str() or unicode() instance, but got %s"
144#else
145 "expected bytes() or str() instance, but got %s"
146#endif
147 , Py_TYPE_NAME(object));
Bram Moolenaare9ba5162013-05-29 22:02:22 +0200148 return NULL;
149 }
150
151 return (char_u *) p;
152}
153
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200154 static int
155add_string(PyObject *list, char *s)
156{
157 PyObject *string;
158
159 if (!(string = PyString_FromString(s)))
160 return -1;
Bram Moolenaar808c2bc2013-06-23 13:11:18 +0200161
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200162 if (PyList_Append(list, string))
163 {
164 Py_DECREF(string);
165 return -1;
166 }
167
168 Py_DECREF(string);
169 return 0;
170}
171
172 static PyObject *
173ObjectDir(PyObject *self, char **attributes)
174{
175 PyMethodDef *method;
176 char **attr;
177 PyObject *r;
178
179 if (!(r = PyList_New(0)))
180 return NULL;
181
182 if (self)
183 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
184 if (add_string(r, (char *) method->ml_name))
185 {
186 Py_DECREF(r);
187 return NULL;
188 }
189
190 for (attr = attributes ; *attr ; ++attr)
191 if (add_string(r, *attr))
192 {
193 Py_DECREF(r);
194 return NULL;
195 }
196
197#if PY_MAJOR_VERSION < 3
198 if (add_string(r, "__members__"))
199 {
200 Py_DECREF(r);
201 return NULL;
202 }
203#endif
204
205 return r;
206}
207
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200208/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200209 */
210
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200211/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200212typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200213
214static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200215
216typedef struct
217{
218 PyObject_HEAD
219 long softspace;
220 long error;
221} OutputObject;
222
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200223static char *OutputAttrs[] = {
224 "softspace",
225 NULL
226};
227
228 static PyObject *
229OutputDir(PyObject *self)
230{
231 return ObjectDir(self, OutputAttrs);
232}
233
Bram Moolenaar77045652012-09-21 13:46:06 +0200234 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200235OutputSetattr(OutputObject *self, char *name, PyObject *val)
Bram Moolenaar77045652012-09-21 13:46:06 +0200236{
237 if (val == NULL)
238 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200239 PyErr_SET_STRING(PyExc_AttributeError,
240 "can't delete OutputObject attributes");
Bram Moolenaar77045652012-09-21 13:46:06 +0200241 return -1;
242 }
243
244 if (strcmp(name, "softspace") == 0)
245 {
246 if (!PyInt_Check(val))
247 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200248 PyErr_SET_STRING(PyExc_TypeError, "softspace must be an integer");
Bram Moolenaar77045652012-09-21 13:46:06 +0200249 return -1;
250 }
251
Bram Moolenaard6e39182013-05-21 18:30:34 +0200252 self->softspace = PyInt_AsLong(val);
Bram Moolenaar77045652012-09-21 13:46:06 +0200253 return 0;
254 }
255
Bram Moolenaarc476e522013-06-23 13:46:40 +0200256 PyErr_FORMAT(PyExc_AttributeError, "invalid attribute: %s", name);
Bram Moolenaar77045652012-09-21 13:46:06 +0200257 return -1;
258}
259
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200260/* Buffer IO, we write one whole line at a time. */
261static garray_T io_ga = {0, 0, 1, 80, NULL};
262static writefn old_fn = NULL;
263
264 static void
265PythonIO_Flush(void)
266{
267 if (old_fn != NULL && io_ga.ga_len > 0)
268 {
269 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
270 old_fn((char_u *)io_ga.ga_data);
271 }
272 io_ga.ga_len = 0;
273}
274
275 static void
276writer(writefn fn, char_u *str, PyInt n)
277{
278 char_u *ptr;
279
280 /* Flush when switching output function. */
281 if (fn != old_fn)
282 PythonIO_Flush();
283 old_fn = fn;
284
285 /* Write each NL separated line. Text after the last NL is kept for
286 * writing later. */
287 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
288 {
289 PyInt len = ptr - str;
290
291 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
292 break;
293
294 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
295 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
296 fn((char_u *)io_ga.ga_data);
297 str = ptr + 1;
298 n -= len + 1;
299 io_ga.ga_len = 0;
300 }
301
302 /* Put the remaining text into io_ga for later printing. */
303 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
304 {
305 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
306 io_ga.ga_len += (int)n;
307 }
308}
309
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200310 static int
311write_output(OutputObject *self, PyObject *string)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200312{
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200313 Py_ssize_t len = 0;
314 char *str = NULL;
315 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200316
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200317 if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
318 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200319
320 Py_BEGIN_ALLOW_THREADS
321 Python_Lock_Vim();
322 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
323 Python_Release_Vim();
324 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200325 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200326
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200327 return 0;
328}
329
330 static PyObject *
331OutputWrite(OutputObject *self, PyObject *string)
332{
333 if (write_output(self, string))
334 return NULL;
335
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200336 Py_INCREF(Py_None);
337 return Py_None;
338}
339
340 static PyObject *
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200341OutputWritelines(OutputObject *self, PyObject *seq)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200342{
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200343 PyObject *iterator;
344 PyObject *item;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200345
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200346 if (!(iterator = PyObject_GetIter(seq)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200347 return NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200348
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200349 while ((item = PyIter_Next(iterator)))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200350 {
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200351 if (write_output(self, item))
Bram Moolenaardb913952012-06-29 12:54:53 +0200352 {
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200353 Py_DECREF(iterator);
354 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200355 return NULL;
356 }
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200357 Py_DECREF(item);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200358 }
359
Bram Moolenaar01a7a722013-05-30 12:26:58 +0200360 Py_DECREF(iterator);
361
362 /* Iterator may have finished due to an exception */
363 if (PyErr_Occurred())
364 return NULL;
365
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200366 Py_INCREF(Py_None);
367 return Py_None;
368}
369
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100370 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200371OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100372{
373 /* do nothing */
374 Py_INCREF(Py_None);
375 return Py_None;
376}
377
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200378/***************/
379
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200380static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200381 /* name, function, calling, doc */
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +0200382 {"write", (PyCFunction)OutputWrite, METH_O, ""},
383 {"writelines", (PyCFunction)OutputWritelines, METH_O, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200384 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200385 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200386 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200387};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200388
389static OutputObject Output =
390{
391 PyObject_HEAD_INIT(&OutputType)
392 0,
393 0
394};
395
396static OutputObject Error =
397{
398 PyObject_HEAD_INIT(&OutputType)
399 0,
400 1
401};
402
403 static int
404PythonIO_Init_io(void)
405{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +0200406 if (PySys_SetObject("stdout", (PyObject *)(void *)&Output))
407 return -1;
408 if (PySys_SetObject("stderr", (PyObject *)(void *)&Error))
409 return -1;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200410
411 if (PyErr_Occurred())
412 {
413 EMSG(_("E264: Python: Error initialising I/O objects"));
414 return -1;
415 }
416
417 return 0;
418}
419
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200420typedef struct
421{
422 PyObject_HEAD
423 PyObject *module;
424} LoaderObject;
425static PyTypeObject LoaderType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200426
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200427 static void
428LoaderDestructor(LoaderObject *self)
429{
430 Py_DECREF(self->module);
431 DESTRUCTOR_FINISH(self);
432}
433
434 static PyObject *
435LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
436{
437 PyObject *r = self->module;
438
439 Py_INCREF(r);
440 return r;
441}
442
443static struct PyMethodDef LoaderMethods[] = {
444 /* name, function, calling, doc */
445 {"load_module", (PyCFunction)LoaderLoadModule, METH_VARARGS, ""},
446 { NULL, NULL, 0, NULL}
447};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200448
449/* Check to see whether a Vim error has been reported, or a keyboard
450 * interrupt has been detected.
451 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200452
453 static void
454VimTryStart(void)
455{
456 ++trylevel;
457}
458
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200459 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200460VimTryEnd(void)
461{
462 --trylevel;
463 if (got_int)
464 {
465 PyErr_SetNone(PyExc_KeyboardInterrupt);
466 return 1;
467 }
468 else if (!did_throw)
469 return 0;
470 else if (PyErr_Occurred())
471 return 1;
472 else
473 {
474 PyErr_SetVim((char *) current_exception->value);
475 discard_current_exception();
476 return 1;
477 }
478}
479
480 static int
481VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200482{
483 if (got_int)
484 {
485 PyErr_SetNone(PyExc_KeyboardInterrupt);
486 return 1;
487 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200488 return 0;
489}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200490
491/* Vim module - Implementation
492 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200493
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200494 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200495VimCommand(PyObject *self UNUSED, PyObject *string)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200496{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200497 char_u *cmd;
498 PyObject *result;
499 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200500
Bram Moolenaar389a1792013-06-23 13:00:44 +0200501 if (!(cmd = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200502 return NULL;
503
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200504 Py_BEGIN_ALLOW_THREADS
505 Python_Lock_Vim();
506
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200507 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200508 do_cmdline_cmd(cmd);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200509 update_screen(VALID);
510
511 Python_Release_Vim();
512 Py_END_ALLOW_THREADS
513
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200514 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200515 result = NULL;
516 else
517 result = Py_None;
518
519 Py_XINCREF(result);
Bram Moolenaar389a1792013-06-23 13:00:44 +0200520 Py_XDECREF(todecref);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200521 return result;
522}
523
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200524/*
525 * Function to translate a typval_T into a PyObject; this will recursively
526 * translate lists/dictionaries into their Python equivalents.
527 *
528 * The depth parameter is to avoid infinite recursion, set it to 1 when
529 * you call VimToPython.
530 */
531 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200532VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200533{
534 PyObject *result;
535 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200536 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200537
538 /* Avoid infinite recursion */
539 if (depth > 100)
540 {
541 Py_INCREF(Py_None);
542 result = Py_None;
543 return result;
544 }
545
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200546 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200547 * then and we can use it again. */
548 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
549 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
550 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200551 sprintf(ptrBuf, "%p",
552 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
553 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200554
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200555 if ((result = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200556 {
557 Py_INCREF(result);
558 return result;
559 }
560 }
561
562 if (our_tv->v_type == VAR_STRING)
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200563 result = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200564 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200565 else if (our_tv->v_type == VAR_NUMBER)
566 {
567 char buf[NUMBUFLEN];
568
569 /* For backwards compatibility numbers are stored as strings. */
570 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200571 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200572 }
573# ifdef FEAT_FLOAT
574 else if (our_tv->v_type == VAR_FLOAT)
575 {
576 char buf[NUMBUFLEN];
577
578 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200579 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200580 }
581# endif
582 else if (our_tv->v_type == VAR_LIST)
583 {
584 list_T *list = our_tv->vval.v_list;
585 listitem_T *curr;
586
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200587 if (list == NULL)
588 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200589
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200590 if (!(result = PyList_New(0)))
591 return NULL;
592
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200593 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200594 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200595 Py_DECREF(result);
596 return NULL;
597 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200598
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200599 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
600 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200601 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200602 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200603 Py_DECREF(result);
604 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200605 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200606 if (PyList_Append(result, newObj))
607 {
608 Py_DECREF(newObj);
609 Py_DECREF(result);
610 return NULL;
611 }
612 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200613 }
614 }
615 else if (our_tv->v_type == VAR_DICT)
616 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200617
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200618 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
619 long_u todo = ht->ht_used;
620 hashitem_T *hi;
621 dictitem_T *di;
622 if (our_tv->vval.v_dict == NULL)
623 return NULL;
624
625 if (!(result = PyDict_New()))
626 return NULL;
627
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200628 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200629 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200630 Py_DECREF(result);
631 return NULL;
632 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200633
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200634 for (hi = ht->ht_array; todo > 0; ++hi)
635 {
636 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200637 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200638 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200639
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200640 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200641 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200642 {
643 Py_DECREF(result);
644 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200645 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200646 if (PyDict_SetItemString(result, (char *)hi->hi_key, newObj))
647 {
648 Py_DECREF(result);
649 Py_DECREF(newObj);
650 return NULL;
651 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200652 }
653 }
654 }
655 else
656 {
657 Py_INCREF(Py_None);
658 result = Py_None;
659 }
660
661 return result;
662}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200663
664 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200665VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200666{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200667 char_u *expr;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200668 typval_T *our_tv;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200669 PyObject *string;
670 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200671 PyObject *result;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200672 PyObject *lookup_dict;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200673
Bram Moolenaar389a1792013-06-23 13:00:44 +0200674 if (!PyArg_ParseTuple(args, "O", &string))
675 return NULL;
676
677 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200678 return NULL;
679
680 Py_BEGIN_ALLOW_THREADS
681 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200682 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200683 our_tv = eval_expr(expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200684 Python_Release_Vim();
685 Py_END_ALLOW_THREADS
686
Bram Moolenaar389a1792013-06-23 13:00:44 +0200687 Py_XDECREF(todecref);
688
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200689 if (VimTryEnd())
690 return NULL;
691
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200692 if (our_tv == NULL)
693 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200694 PyErr_SET_VIM("invalid expression");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200695 return NULL;
696 }
697
698 /* Convert the Vim type into a Python type. Create a dictionary that's
699 * used to check for recursive loops. */
Bram Moolenaar9bb77d62013-05-30 12:14:49 +0200700 if (!(lookup_dict = PyDict_New()))
701 result = NULL;
702 else
703 {
704 result = VimToPython(our_tv, 1, lookup_dict);
705 Py_DECREF(lookup_dict);
706 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200707
708
709 Py_BEGIN_ALLOW_THREADS
710 Python_Lock_Vim();
711 free_tv(our_tv);
712 Python_Release_Vim();
713 Py_END_ALLOW_THREADS
714
715 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200716}
717
Bram Moolenaardb913952012-06-29 12:54:53 +0200718static PyObject *ConvertToPyObject(typval_T *);
719
720 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200721VimEvalPy(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200722{
Bram Moolenaardb913952012-06-29 12:54:53 +0200723 typval_T *our_tv;
724 PyObject *result;
Bram Moolenaar389a1792013-06-23 13:00:44 +0200725 char_u *expr;
726 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +0200727
Bram Moolenaar389a1792013-06-23 13:00:44 +0200728 if (!(expr = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200729 return NULL;
730
731 Py_BEGIN_ALLOW_THREADS
732 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200733 VimTryStart();
Bram Moolenaar389a1792013-06-23 13:00:44 +0200734 our_tv = eval_expr(expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200735 Python_Release_Vim();
736 Py_END_ALLOW_THREADS
737
Bram Moolenaar389a1792013-06-23 13:00:44 +0200738 Py_XDECREF(todecref);
739
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200740 if (VimTryEnd())
741 return NULL;
742
Bram Moolenaardb913952012-06-29 12:54:53 +0200743 if (our_tv == NULL)
744 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200745 PyErr_SET_VIM("invalid expression");
Bram Moolenaardb913952012-06-29 12:54:53 +0200746 return NULL;
747 }
748
749 result = ConvertToPyObject(our_tv);
750 Py_BEGIN_ALLOW_THREADS
751 Python_Lock_Vim();
752 free_tv(our_tv);
753 Python_Release_Vim();
754 Py_END_ALLOW_THREADS
755
756 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200757}
758
759 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200760VimStrwidth(PyObject *self UNUSED, PyObject *string)
Bram Moolenaardb913952012-06-29 12:54:53 +0200761{
Bram Moolenaar389a1792013-06-23 13:00:44 +0200762 char_u *str;
763 PyObject *todecref;
764 int result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200765
Bram Moolenaar389a1792013-06-23 13:00:44 +0200766 if (!(str = StringToChars(string, &todecref)))
Bram Moolenaardb913952012-06-29 12:54:53 +0200767 return NULL;
768
Bram Moolenaara54bf402012-12-05 16:30:07 +0100769#ifdef FEAT_MBYTE
Bram Moolenaar389a1792013-06-23 13:00:44 +0200770 result = mb_string2cells(str, (int)STRLEN(str));
Bram Moolenaara54bf402012-12-05 16:30:07 +0100771#else
Bram Moolenaar389a1792013-06-23 13:00:44 +0200772 result = STRLEN(str);
Bram Moolenaara54bf402012-12-05 16:30:07 +0100773#endif
Bram Moolenaar389a1792013-06-23 13:00:44 +0200774
775 Py_XDECREF(todecref);
776
777 return PyLong_FromLong(result);
Bram Moolenaardb913952012-06-29 12:54:53 +0200778}
779
Bram Moolenaarf4258302013-06-02 18:20:17 +0200780 static PyObject *
781_VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
782{
783 PyObject *r;
784 PyObject *newwd;
785 PyObject *todecref;
786 char_u *new_dir;
787
Bram Moolenaard4209d22013-06-05 20:34:15 +0200788 if (_chdir == NULL)
789 return NULL;
Bram Moolenaarf4258302013-06-02 18:20:17 +0200790 if (!(r = PyObject_Call(_chdir, args, kwargs)))
791 return NULL;
792
793 if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
794 {
795 Py_DECREF(r);
796 return NULL;
797 }
798
799 if (!(new_dir = StringToChars(newwd, &todecref)))
800 {
801 Py_DECREF(r);
802 Py_DECREF(newwd);
803 return NULL;
804 }
805
806 VimTryStart();
807
808 if (vim_chdir(new_dir))
809 {
810 Py_DECREF(r);
811 Py_DECREF(newwd);
812 Py_XDECREF(todecref);
813
814 if (VimTryEnd())
815 return NULL;
816
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +0200817 PyErr_SET_VIM("failed to change directory");
Bram Moolenaarf4258302013-06-02 18:20:17 +0200818 return NULL;
819 }
820
821 Py_DECREF(newwd);
822 Py_XDECREF(todecref);
823
824 post_chdir(FALSE);
825
826 if (VimTryEnd())
827 {
828 Py_DECREF(r);
829 return NULL;
830 }
831
832 return r;
833}
834
835 static PyObject *
836VimChdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
837{
838 return _VimChdir(py_chdir, args, kwargs);
839}
840
841 static PyObject *
842VimFchdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
843{
844 return _VimChdir(py_fchdir, args, kwargs);
845}
846
Bram Moolenaarc09a6d62013-06-10 21:27:29 +0200847typedef struct {
848 PyObject *callable;
849 PyObject *result;
850} map_rtp_data;
851
852 static void
853map_rtp_callback(char_u *path, void *_data)
854{
855 void **data = (void **) _data;
856 PyObject *pathObject;
857 map_rtp_data *mr_data = *((map_rtp_data **) data);
858
859 if (!(pathObject = PyString_FromString((char *) path)))
860 {
861 *data = NULL;
862 return;
863 }
864
865 mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
866 pathObject, NULL);
867
868 Py_DECREF(pathObject);
869
870 if (!mr_data->result || mr_data->result != Py_None)
871 *data = NULL;
872 else
873 {
874 Py_DECREF(mr_data->result);
875 mr_data->result = NULL;
876 }
877}
878
879 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +0200880VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +0200881{
882 map_rtp_data data;
883
Bram Moolenaar389a1792013-06-23 13:00:44 +0200884 data.callable = callable;
Bram Moolenaarc09a6d62013-06-10 21:27:29 +0200885 data.result = NULL;
886
887 do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
888
889 if (data.result == NULL)
890 {
891 if (PyErr_Occurred())
892 return NULL;
893 else
894 {
895 Py_INCREF(Py_None);
896 return Py_None;
897 }
898 }
899 return data.result;
900}
901
902/*
903 * _vim_runtimepath_ special path implementation.
904 */
905
906 static void
907map_finder_callback(char_u *path, void *_data)
908{
909 void **data = (void **) _data;
910 PyObject *list = *((PyObject **) data);
911 PyObject *pathObject1, *pathObject2;
912 char *pathbuf;
913 size_t pathlen;
914
915 pathlen = STRLEN(path);
916
917#if PY_MAJOR_VERSION < 3
918# define PY_MAIN_DIR_STRING "python2"
919#else
920# define PY_MAIN_DIR_STRING "python3"
921#endif
922#define PY_ALTERNATE_DIR_STRING "pythonx"
923
924#define PYTHONX_STRING_LENGTH 7 /* STRLEN("pythonx") */
925 if (!(pathbuf = PyMem_New(char,
926 pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
927 {
928 PyErr_NoMemory();
929 *data = NULL;
930 return;
931 }
932
933 mch_memmove(pathbuf, path, pathlen + 1);
934 add_pathsep((char_u *) pathbuf);
935
936 pathlen = STRLEN(pathbuf);
937 mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
938 PYTHONX_STRING_LENGTH + 1);
939
940 if (!(pathObject1 = PyString_FromString(pathbuf)))
941 {
942 *data = NULL;
943 PyMem_Free(pathbuf);
944 return;
945 }
946
947 mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
948 PYTHONX_STRING_LENGTH + 1);
949
950 if (!(pathObject2 = PyString_FromString(pathbuf)))
951 {
952 Py_DECREF(pathObject1);
953 PyMem_Free(pathbuf);
954 *data = NULL;
955 return;
956 }
957
958 PyMem_Free(pathbuf);
959
960 if (PyList_Append(list, pathObject1)
961 || PyList_Append(list, pathObject2))
962 *data = NULL;
963
964 Py_DECREF(pathObject1);
965 Py_DECREF(pathObject2);
966}
967
968 static PyObject *
969Vim_GetPaths(PyObject *self UNUSED)
970{
971 PyObject *r;
972
973 if (!(r = PyList_New(0)))
974 return NULL;
975
976 do_in_runtimepath(NULL, FALSE, &map_finder_callback, r);
977
978 if (PyErr_Occurred())
979 {
980 Py_DECREF(r);
981 return NULL;
982 }
983
984 return r;
985}
986
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200987 static PyObject *
988call_load_module(char *name, int len, PyObject *find_module_result)
989{
990 PyObject *fd, *pathname, *description;
991
Bram Moolenaarc476e522013-06-23 13:46:40 +0200992 if (!PyTuple_Check(find_module_result))
Bram Moolenaar81c40c52013-06-12 14:41:04 +0200993 {
Bram Moolenaarc476e522013-06-23 13:46:40 +0200994 PyErr_FORMAT(PyExc_TypeError,
995 "expected 3-tuple as imp.find_module() result, but got %s",
996 Py_TYPE_NAME(find_module_result));
997 return NULL;
998 }
999 if (PyTuple_GET_SIZE(find_module_result) != 3)
1000 {
1001 PyErr_FORMAT(PyExc_TypeError,
1002 "expected 3-tuple as imp.find_module() result, but got "
1003 "tuple of size %d",
1004 (int) PyTuple_GET_SIZE(find_module_result));
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001005 return NULL;
1006 }
1007
1008 if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
1009 || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
1010 || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
1011 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001012 PyErr_SET_STRING(PyExc_RuntimeError,
1013 "internal error: imp.find_module returned tuple with NULL");
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001014 return NULL;
1015 }
1016
1017 return PyObject_CallFunction(py_load_module,
1018 "s#OOO", name, len, fd, pathname, description);
1019}
1020
1021 static PyObject *
1022find_module(char *fullname, char *tail, PyObject *new_path)
1023{
1024 PyObject *find_module_result;
1025 PyObject *module;
1026 char *dot;
1027
1028 if ((dot = (char *) vim_strchr((char_u *) tail, '.')))
1029 {
1030 /*
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001031 * There is a dot in the name: call find_module recursively without the
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001032 * first component
1033 */
1034 PyObject *newest_path;
1035 int partlen = (int) (dot - 1 - tail);
1036
1037 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1038 "s#O", tail, partlen, new_path)))
1039 return NULL;
1040
1041 if (!(module = call_load_module(
1042 fullname,
1043 ((int) (tail - fullname)) + partlen,
1044 find_module_result)))
1045 {
1046 Py_DECREF(find_module_result);
1047 return NULL;
1048 }
1049
1050 Py_DECREF(find_module_result);
1051
1052 if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
1053 {
1054 Py_DECREF(module);
1055 return NULL;
1056 }
1057
1058 Py_DECREF(module);
1059
1060 module = find_module(fullname, dot + 1, newest_path);
1061
1062 Py_DECREF(newest_path);
1063
1064 return module;
1065 }
1066 else
1067 {
1068 if (!(find_module_result = PyObject_CallFunction(py_find_module,
1069 "sO", tail, new_path)))
1070 return NULL;
1071
1072 if (!(module = call_load_module(
1073 fullname,
Bram Moolenaaredb07a22013-06-12 18:13:38 +02001074 (int)STRLEN(fullname),
Bram Moolenaar81c40c52013-06-12 14:41:04 +02001075 find_module_result)))
1076 {
1077 Py_DECREF(find_module_result);
1078 return NULL;
1079 }
1080
1081 Py_DECREF(find_module_result);
1082
1083 return module;
1084 }
1085}
1086
1087 static PyObject *
1088FinderFindModule(PyObject *self, PyObject *args)
1089{
1090 char *fullname;
1091 PyObject *module;
1092 PyObject *new_path;
1093 LoaderObject *loader;
1094
1095 if (!PyArg_ParseTuple(args, "s", &fullname))
1096 return NULL;
1097
1098 if (!(new_path = Vim_GetPaths(self)))
1099 return NULL;
1100
1101 module = find_module(fullname, fullname, new_path);
1102
1103 Py_DECREF(new_path);
1104
1105 if (!module)
1106 {
1107 Py_INCREF(Py_None);
1108 return Py_None;
1109 }
1110
1111 if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
1112 {
1113 Py_DECREF(module);
1114 return NULL;
1115 }
1116
1117 loader->module = module;
1118
1119 return (PyObject *) loader;
1120}
1121
1122 static PyObject *
1123VimPathHook(PyObject *self UNUSED, PyObject *args)
1124{
1125 char *path;
1126
1127 if (PyArg_ParseTuple(args, "s", &path)
1128 && STRCMP(path, vim_special_path) == 0)
1129 {
1130 Py_INCREF(vim_module);
1131 return vim_module;
1132 }
1133
1134 PyErr_Clear();
1135 PyErr_SetNone(PyExc_ImportError);
1136 return NULL;
1137}
1138
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001139/*
1140 * Vim module - Definitions
1141 */
1142
1143static struct PyMethodDef VimMethods[] = {
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001144 /* name, function, calling, documentation */
Bram Moolenaar389a1792013-06-23 13:00:44 +02001145 {"command", VimCommand, METH_O, "Execute a Vim ex-mode command" },
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001146 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02001147 {"bindeval", VimEvalPy, METH_O, "Like eval(), but returns objects attached to vim ones"},
1148 {"strwidth", VimStrwidth, METH_O, "Screen string width, counts <Tab> as having width 1"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001149 {"chdir", (PyCFunction)VimChdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
1150 {"fchdir", (PyCFunction)VimFchdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
Bram Moolenaar389a1792013-06-23 13:00:44 +02001151 {"foreach_rtp", VimForeachRTP, METH_O, "Call given callable for each path in &rtp"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001152 {"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02001153 {"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
1154 {"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
1155 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001156};
1157
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001158/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001159 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001160 */
1161
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001162static PyTypeObject IterType;
1163
1164typedef PyObject *(*nextfun)(void **);
1165typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001166typedef int (*traversefun)(void *, visitproc, void *);
1167typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001168
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001169/* Main purpose of this object is removing the need for do python
1170 * initialization (i.e. PyType_Ready and setting type attributes) for a big
1171 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001172
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001173typedef struct
1174{
1175 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001176 void *cur;
1177 nextfun next;
1178 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001179 traversefun traverse;
1180 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001181} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001182
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001183 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001184IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
1185 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001186{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001187 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001188
Bram Moolenaar774267b2013-05-21 20:51:59 +02001189 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001190 self->cur = start;
1191 self->next = next;
1192 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001193 self->traverse = traverse;
1194 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001195
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001196 return (PyObject *)(self);
1197}
1198
1199 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001200IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001201{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001202 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02001203 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +02001204 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001205}
1206
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001207 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001208IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001209{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001210 if (self->traverse != NULL)
1211 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001212 else
1213 return 0;
1214}
1215
Bram Moolenaar9e74e302013-05-17 21:20:17 +02001216/* Mac OSX defines clear() somewhere. */
1217#ifdef clear
1218# undef clear
1219#endif
1220
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001221 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001222IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001223{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001224 if (self->clear != NULL)
1225 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001226 else
1227 return 0;
1228}
1229
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001230 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001231IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001232{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001233 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001234}
1235
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001236 static PyObject *
1237IterIter(PyObject *self)
1238{
Bram Moolenaar1bcabe12013-05-29 22:52:32 +02001239 Py_INCREF(self);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001240 return self;
1241}
Bram Moolenaardfa38d42013-05-15 13:38:47 +02001242
Bram Moolenaardb913952012-06-29 12:54:53 +02001243typedef struct pylinkedlist_S {
1244 struct pylinkedlist_S *pll_next;
1245 struct pylinkedlist_S *pll_prev;
1246 PyObject *pll_obj;
1247} pylinkedlist_T;
1248
1249static pylinkedlist_T *lastdict = NULL;
1250static pylinkedlist_T *lastlist = NULL;
1251
1252 static void
1253pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
1254{
1255 if (ref->pll_prev == NULL)
1256 {
1257 if (ref->pll_next == NULL)
1258 {
1259 *last = NULL;
1260 return;
1261 }
1262 }
1263 else
1264 ref->pll_prev->pll_next = ref->pll_next;
1265
1266 if (ref->pll_next == NULL)
1267 *last = ref->pll_prev;
1268 else
1269 ref->pll_next->pll_prev = ref->pll_prev;
1270}
1271
1272 static void
1273pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
1274{
1275 if (*last == NULL)
1276 ref->pll_prev = NULL;
1277 else
1278 {
1279 (*last)->pll_next = ref;
1280 ref->pll_prev = *last;
1281 }
1282 ref->pll_next = NULL;
1283 ref->pll_obj = self;
1284 *last = ref;
1285}
1286
1287static PyTypeObject DictionaryType;
1288
1289typedef struct
1290{
1291 PyObject_HEAD
1292 dict_T *dict;
1293 pylinkedlist_T ref;
1294} DictionaryObject;
1295
Bram Moolenaara9922d62013-05-30 13:01:18 +02001296static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
1297
1298#define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
1299
Bram Moolenaardb913952012-06-29 12:54:53 +02001300 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001301DictionaryNew(PyTypeObject *subtype, dict_T *dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02001302{
1303 DictionaryObject *self;
1304
Bram Moolenaara9922d62013-05-30 13:01:18 +02001305 self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02001306 if (self == NULL)
1307 return NULL;
1308 self->dict = dict;
1309 ++dict->dv_refcount;
1310
1311 pyll_add((PyObject *)(self), &self->ref, &lastdict);
1312
1313 return (PyObject *)(self);
1314}
1315
Bram Moolenaara9922d62013-05-30 13:01:18 +02001316 static dict_T *
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001317py_dict_alloc(void)
Bram Moolenaara9922d62013-05-30 13:01:18 +02001318{
1319 dict_T *r;
1320
1321 if (!(r = dict_alloc()))
1322 {
1323 PyErr_NoMemory();
1324 return NULL;
1325 }
1326 ++r->dv_refcount;
1327
1328 return r;
1329}
1330
1331 static PyObject *
1332DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1333{
1334 DictionaryObject *self;
1335 dict_T *dict;
1336
1337 if (!(dict = py_dict_alloc()))
1338 return NULL;
1339
1340 self = (DictionaryObject *) DictionaryNew(subtype, dict);
1341
1342 --dict->dv_refcount;
1343
1344 if (kwargs || PyTuple_Size(args))
1345 {
1346 PyObject *tmp;
1347 if (!(tmp = DictionaryUpdate(self, args, kwargs)))
1348 {
1349 Py_DECREF(self);
1350 return NULL;
1351 }
1352
1353 Py_DECREF(tmp);
1354 }
1355
1356 return (PyObject *)(self);
1357}
1358
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001359 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001360DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001361{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001362 pyll_remove(&self->ref, &lastdict);
1363 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001364
1365 DESTRUCTOR_FINISH(self);
1366}
1367
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001368static char *DictionaryAttrs[] = {
1369 "locked", "scope",
1370 NULL
1371};
1372
1373 static PyObject *
1374DictionaryDir(PyObject *self)
1375{
1376 return ObjectDir(self, DictionaryAttrs);
1377}
1378
Bram Moolenaardb913952012-06-29 12:54:53 +02001379 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001380DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001381{
1382 if (val == NULL)
1383 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001384 PyErr_SET_STRING(PyExc_AttributeError,
1385 "cannot delete vim.Dictionary attributes");
Bram Moolenaar66b79852012-09-21 14:00:35 +02001386 return -1;
1387 }
1388
1389 if (strcmp(name, "locked") == 0)
1390 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001391 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001392 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001393 PyErr_SET_STRING(PyExc_TypeError, "cannot modify fixed dictionary");
Bram Moolenaar66b79852012-09-21 14:00:35 +02001394 return -1;
1395 }
1396 else
1397 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001398 int istrue = PyObject_IsTrue(val);
1399 if (istrue == -1)
1400 return -1;
1401 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001402 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001403 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001404 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001405 }
1406 return 0;
1407 }
1408 else
1409 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001410 PyErr_FORMAT(PyExc_AttributeError, "cannot set attribute %s", name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02001411 return -1;
1412 }
1413}
1414
1415 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001416DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001417{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001418 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +02001419}
1420
Bram Moolenaara9922d62013-05-30 13:01:18 +02001421#define DICT_FLAG_HAS_DEFAULT 0x01
1422#define DICT_FLAG_POP 0x02
1423#define DICT_FLAG_NONE_DEFAULT 0x04
1424#define DICT_FLAG_RETURN_BOOL 0x08 /* Incompatible with DICT_FLAG_POP */
1425#define DICT_FLAG_RETURN_PAIR 0x10
1426
Bram Moolenaardb913952012-06-29 12:54:53 +02001427 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001428_DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
Bram Moolenaardb913952012-06-29 12:54:53 +02001429{
Bram Moolenaara9922d62013-05-30 13:01:18 +02001430 PyObject *keyObject;
1431 PyObject *defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
1432 PyObject *r;
Bram Moolenaardb913952012-06-29 12:54:53 +02001433 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001434 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001435 dict_T *dict = self->dict;
1436 hashitem_T *hi;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001437 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001438
Bram Moolenaara9922d62013-05-30 13:01:18 +02001439 if (flags & DICT_FLAG_HAS_DEFAULT)
1440 {
1441 if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1442 return NULL;
1443 }
1444 else
1445 keyObject = args;
1446
1447 if (flags & DICT_FLAG_RETURN_BOOL)
1448 defObject = Py_False;
1449
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001450 if (!(key = StringToChars(keyObject, &todecref)))
1451 return NULL;
1452
1453 if (*key == NUL)
1454 {
1455 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001456 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001457 return NULL;
1458 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001459
Bram Moolenaara9922d62013-05-30 13:01:18 +02001460 hi = hash_find(&dict->dv_hashtab, key);
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001461
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001462 Py_XDECREF(todecref);
Bram Moolenaar696c2112012-09-21 13:43:14 +02001463
Bram Moolenaara9922d62013-05-30 13:01:18 +02001464 if (HASHITEM_EMPTY(hi))
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001465 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001466 if (defObject)
1467 {
1468 Py_INCREF(defObject);
1469 return defObject;
1470 }
1471 else
1472 {
1473 PyErr_SetObject(PyExc_KeyError, keyObject);
1474 return NULL;
1475 }
1476 }
1477 else if (flags & DICT_FLAG_RETURN_BOOL)
1478 {
1479 Py_INCREF(Py_True);
1480 return Py_True;
1481 }
1482
1483 di = dict_lookup(hi);
1484
1485 if (!(r = ConvertToPyObject(&di->di_tv)))
1486 return NULL;
1487
1488 if (flags & DICT_FLAG_POP)
1489 {
1490 if (dict->dv_lock)
1491 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001492 RAISE_LOCKED_DICTIONARY;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001493 Py_DECREF(r);
1494 return NULL;
1495 }
1496
1497 hash_remove(&dict->dv_hashtab, hi);
1498 dictitem_free(di);
1499 }
1500
Bram Moolenaara9922d62013-05-30 13:01:18 +02001501 return r;
1502}
1503
1504 static PyObject *
1505DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1506{
1507 return _DictionaryItem(self, keyObject, 0);
1508}
1509
1510 static int
1511DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1512{
1513 PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
1514 int r;
1515
1516 r = (rObj == Py_True);
1517
1518 Py_DECREF(Py_True);
1519
1520 return r;
1521}
1522
1523typedef struct
1524{
1525 hashitem_T *ht_array;
1526 long_u ht_used;
1527 hashtab_T *ht;
1528 hashitem_T *hi;
Bram Moolenaar99dc19d2013-05-31 20:49:31 +02001529 long_u todo;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001530} dictiterinfo_T;
1531
1532 static PyObject *
1533DictionaryIterNext(dictiterinfo_T **dii)
1534{
1535 PyObject *r;
1536
1537 if (!(*dii)->todo)
1538 return NULL;
1539
1540 if ((*dii)->ht->ht_array != (*dii)->ht_array ||
1541 (*dii)->ht->ht_used != (*dii)->ht_used)
1542 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02001543 PyErr_SET_STRING(PyExc_RuntimeError,
1544 "hashtab changed during iteration");
Bram Moolenaar231e1a12012-09-05 18:45:28 +02001545 return NULL;
1546 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001547
Bram Moolenaara9922d62013-05-30 13:01:18 +02001548 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi))
1549 ++((*dii)->hi);
1550
1551 --((*dii)->todo);
1552
1553 if (!(r = PyBytes_FromString((char *) (*dii)->hi->hi_key)))
1554 return NULL;
1555
1556 return r;
1557}
1558
1559 static PyObject *
1560DictionaryIter(DictionaryObject *self)
1561{
1562 dictiterinfo_T *dii;
1563 hashtab_T *ht;
1564
1565 if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1566 {
1567 PyErr_NoMemory();
1568 return NULL;
1569 }
1570
1571 ht = &self->dict->dv_hashtab;
1572 dii->ht_array = ht->ht_array;
1573 dii->ht_used = ht->ht_used;
1574 dii->ht = ht;
1575 dii->hi = dii->ht_array;
1576 dii->todo = dii->ht_used;
1577
1578 return IterNew(dii,
1579 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext,
1580 NULL, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02001581}
1582
1583 static PyInt
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02001584DictionaryAssItem(
1585 DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +02001586{
1587 char_u *key;
1588 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001589 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001590 dictitem_T *di;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001591 PyObject *todecref;
Bram Moolenaardb913952012-06-29 12:54:53 +02001592
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001593 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +02001594 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001595 RAISE_LOCKED_DICTIONARY;
Bram Moolenaardb913952012-06-29 12:54:53 +02001596 return -1;
1597 }
1598
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001599 if (!(key = StringToChars(keyObject, &todecref)))
1600 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02001601
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001602 if (*key == NUL)
1603 {
1604 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001605 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001606 return -1;
1607 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001608
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001609 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +02001610
1611 if (valObject == NULL)
1612 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +02001613 hashitem_T *hi;
1614
Bram Moolenaardb913952012-06-29 12:54:53 +02001615 if (di == NULL)
1616 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001617 Py_XDECREF(todecref);
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001618 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +02001619 return -1;
1620 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001621 hi = hash_find(&dict->dv_hashtab, di->di_key);
1622 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +02001623 dictitem_free(di);
Bram Moolenaar78b59572013-06-02 18:54:21 +02001624 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001625 return 0;
1626 }
1627
1628 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaar78b59572013-06-02 18:54:21 +02001629 {
1630 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001631 return -1;
Bram Moolenaar78b59572013-06-02 18:54:21 +02001632 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001633
1634 if (di == NULL)
1635 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001636 if (!(di = dictitem_alloc(key)))
Bram Moolenaardb913952012-06-29 12:54:53 +02001637 {
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001638 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001639 PyErr_NoMemory();
1640 return -1;
1641 }
1642 di->di_tv.v_lock = 0;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001643 di->di_tv.v_type = VAR_UNKNOWN;
Bram Moolenaardb913952012-06-29 12:54:53 +02001644
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001645 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001646 {
1647 vim_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001648 dictitem_free(di);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001649 RAISE_KEY_ADD_FAIL(key);
1650 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001651 return -1;
1652 }
1653 }
1654 else
1655 clear_tv(&di->di_tv);
1656
Bram Moolenaar35eacd72013-05-30 22:06:33 +02001657 Py_XDECREF(todecref);
Bram Moolenaardb913952012-06-29 12:54:53 +02001658
1659 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001660 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001661 return 0;
1662}
1663
Bram Moolenaara9922d62013-05-30 13:01:18 +02001664typedef PyObject *(*hi_to_py)(hashitem_T *);
1665
Bram Moolenaardb913952012-06-29 12:54:53 +02001666 static PyObject *
Bram Moolenaara9922d62013-05-30 13:01:18 +02001667DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
Bram Moolenaardb913952012-06-29 12:54:53 +02001668{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001669 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001670 long_u todo = dict->dv_hashtab.ht_used;
1671 Py_ssize_t i = 0;
1672 PyObject *r;
1673 hashitem_T *hi;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001674 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +02001675
1676 r = PyList_New(todo);
1677 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1678 {
1679 if (!HASHITEM_EMPTY(hi))
1680 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02001681 if (!(newObj = hiconvert(hi)))
1682 {
1683 Py_DECREF(r);
1684 return NULL;
1685 }
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02001686 PyList_SET_ITEM(r, i, newObj);
Bram Moolenaardb913952012-06-29 12:54:53 +02001687 --todo;
1688 ++i;
1689 }
1690 }
1691 return r;
1692}
1693
Bram Moolenaara9922d62013-05-30 13:01:18 +02001694 static PyObject *
1695dict_key(hashitem_T *hi)
1696{
1697 return PyBytes_FromString((char *)(hi->hi_key));
1698}
1699
1700 static PyObject *
1701DictionaryListKeys(DictionaryObject *self)
1702{
1703 return DictionaryListObjects(self, dict_key);
1704}
1705
1706 static PyObject *
1707dict_val(hashitem_T *hi)
1708{
1709 dictitem_T *di;
1710
1711 di = dict_lookup(hi);
1712 return ConvertToPyObject(&di->di_tv);
1713}
1714
1715 static PyObject *
1716DictionaryListValues(DictionaryObject *self)
1717{
1718 return DictionaryListObjects(self, dict_val);
1719}
1720
1721 static PyObject *
1722dict_item(hashitem_T *hi)
1723{
1724 PyObject *keyObject;
1725 PyObject *valObject;
1726 PyObject *r;
1727
1728 if (!(keyObject = dict_key(hi)))
1729 return NULL;
1730
1731 if (!(valObject = dict_val(hi)))
1732 {
1733 Py_DECREF(keyObject);
1734 return NULL;
1735 }
1736
1737 r = Py_BuildValue("(OO)", keyObject, valObject);
1738
1739 Py_DECREF(keyObject);
1740 Py_DECREF(valObject);
1741
1742 return r;
1743}
1744
1745 static PyObject *
1746DictionaryListItems(DictionaryObject *self)
1747{
1748 return DictionaryListObjects(self, dict_item);
1749}
1750
1751 static PyObject *
1752DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
1753{
1754 dict_T *dict = self->dict;
1755
1756 if (dict->dv_lock)
1757 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001758 RAISE_LOCKED_DICTIONARY;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001759 return NULL;
1760 }
1761
1762 if (kwargs)
1763 {
1764 typval_T tv;
1765
1766 if (ConvertFromPyMapping(kwargs, &tv) == -1)
1767 return NULL;
1768
1769 VimTryStart();
1770 dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force");
1771 clear_tv(&tv);
1772 if (VimTryEnd())
1773 return NULL;
1774 }
1775 else
1776 {
1777 PyObject *object;
1778
Bram Moolenaar389a1792013-06-23 13:00:44 +02001779 if (!PyArg_ParseTuple(args, "O", &object))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001780 return NULL;
1781
1782 if (PyObject_HasAttrString(object, "keys"))
1783 return DictionaryUpdate(self, NULL, object);
1784 else
1785 {
1786 PyObject *iterator;
1787 PyObject *item;
1788
1789 if (!(iterator = PyObject_GetIter(object)))
1790 return NULL;
1791
1792 while ((item = PyIter_Next(iterator)))
1793 {
1794 PyObject *fast;
1795 PyObject *keyObject;
1796 PyObject *valObject;
1797 PyObject *todecref;
1798 char_u *key;
1799 dictitem_T *di;
1800
1801 if (!(fast = PySequence_Fast(item, "")))
1802 {
1803 Py_DECREF(iterator);
1804 Py_DECREF(item);
1805 return NULL;
1806 }
1807
1808 Py_DECREF(item);
1809
1810 if (PySequence_Fast_GET_SIZE(fast) != 2)
1811 {
1812 Py_DECREF(iterator);
1813 Py_DECREF(fast);
Bram Moolenaarc476e522013-06-23 13:46:40 +02001814 PyErr_FORMAT(PyExc_ValueError,
1815 "expected sequence element of size 2, "
1816 "but got sequence of size %d",
1817 PySequence_Fast_GET_SIZE(fast));
Bram Moolenaara9922d62013-05-30 13:01:18 +02001818 return NULL;
1819 }
1820
1821 keyObject = PySequence_Fast_GET_ITEM(fast, 0);
1822
1823 if (!(key = StringToChars(keyObject, &todecref)))
1824 {
1825 Py_DECREF(iterator);
1826 Py_DECREF(fast);
1827 return NULL;
1828 }
1829
1830 di = dictitem_alloc(key);
1831
1832 Py_XDECREF(todecref);
1833
1834 if (di == NULL)
1835 {
1836 Py_DECREF(fast);
1837 Py_DECREF(iterator);
1838 PyErr_NoMemory();
1839 return NULL;
1840 }
1841 di->di_tv.v_lock = 0;
1842 di->di_tv.v_type = VAR_UNKNOWN;
1843
1844 valObject = PySequence_Fast_GET_ITEM(fast, 1);
1845
1846 if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
1847 {
1848 Py_DECREF(iterator);
1849 Py_DECREF(fast);
1850 dictitem_free(di);
1851 return NULL;
1852 }
1853
1854 Py_DECREF(fast);
1855
1856 if (dict_add(dict, di) == FAIL)
1857 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02001858 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001859 Py_DECREF(iterator);
1860 dictitem_free(di);
Bram Moolenaara9922d62013-05-30 13:01:18 +02001861 return NULL;
1862 }
1863 }
1864
1865 Py_DECREF(iterator);
1866
1867 /* Iterator may have finished due to an exception */
1868 if (PyErr_Occurred())
1869 return NULL;
1870 }
1871 }
1872 Py_INCREF(Py_None);
1873 return Py_None;
1874}
1875
1876 static PyObject *
1877DictionaryGet(DictionaryObject *self, PyObject *args)
1878{
1879 return _DictionaryItem(self, args,
1880 DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
1881}
1882
1883 static PyObject *
1884DictionaryPop(DictionaryObject *self, PyObject *args)
1885{
1886 return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
1887}
1888
1889 static PyObject *
Bram Moolenaarde71b562013-06-02 17:41:54 +02001890DictionaryPopItem(DictionaryObject *self)
Bram Moolenaara9922d62013-05-30 13:01:18 +02001891{
Bram Moolenaarde71b562013-06-02 17:41:54 +02001892 hashitem_T *hi;
1893 PyObject *r;
1894 PyObject *valObject;
1895 dictitem_T *di;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001896
Bram Moolenaarde71b562013-06-02 17:41:54 +02001897 if (self->dict->dv_hashtab.ht_used == 0)
1898 {
1899 PyErr_SetNone(PyExc_KeyError);
1900 return NULL;
1901 }
1902
1903 hi = self->dict->dv_hashtab.ht_array;
1904 while (HASHITEM_EMPTY(hi))
1905 ++hi;
1906
1907 di = dict_lookup(hi);
1908
1909 if (!(valObject = ConvertToPyObject(&di->di_tv)))
Bram Moolenaara9922d62013-05-30 13:01:18 +02001910 return NULL;
1911
Bram Moolenaarde71b562013-06-02 17:41:54 +02001912 if (!(r = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
1913 {
1914 Py_DECREF(valObject);
1915 return NULL;
1916 }
1917
1918 hash_remove(&self->dict->dv_hashtab, hi);
1919 dictitem_free(di);
1920
1921 return r;
Bram Moolenaara9922d62013-05-30 13:01:18 +02001922}
1923
1924 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02001925DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaara9922d62013-05-30 13:01:18 +02001926{
Bram Moolenaara9922d62013-05-30 13:01:18 +02001927 return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
1928}
1929
1930static PySequenceMethods DictionaryAsSeq = {
1931 0, /* sq_length */
1932 0, /* sq_concat */
1933 0, /* sq_repeat */
1934 0, /* sq_item */
1935 0, /* sq_slice */
1936 0, /* sq_ass_item */
1937 0, /* sq_ass_slice */
1938 (objobjproc) DictionaryContains, /* sq_contains */
1939 0, /* sq_inplace_concat */
1940 0, /* sq_inplace_repeat */
1941};
1942
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001943static PyMappingMethods DictionaryAsMapping = {
1944 (lenfunc) DictionaryLength,
1945 (binaryfunc) DictionaryItem,
1946 (objobjargproc) DictionaryAssItem,
1947};
1948
Bram Moolenaardb913952012-06-29 12:54:53 +02001949static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001950 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaara9922d62013-05-30 13:01:18 +02001951 {"values", (PyCFunction)DictionaryListValues, METH_NOARGS, ""},
1952 {"items", (PyCFunction)DictionaryListItems, METH_NOARGS, ""},
1953 {"update", (PyCFunction)DictionaryUpdate, METH_VARARGS|METH_KEYWORDS, ""},
1954 {"get", (PyCFunction)DictionaryGet, METH_VARARGS, ""},
1955 {"pop", (PyCFunction)DictionaryPop, METH_VARARGS, ""},
Bram Moolenaarde71b562013-06-02 17:41:54 +02001956 {"popitem", (PyCFunction)DictionaryPopItem, METH_NOARGS, ""},
Bram Moolenaar389a1792013-06-23 13:00:44 +02001957 {"has_key", (PyCFunction)DictionaryHasKey, METH_O, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001958 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
1959 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001960};
1961
1962static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001963static PySequenceMethods ListAsSeq;
1964static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +02001965
1966typedef struct
1967{
1968 PyObject_HEAD
1969 list_T *list;
1970 pylinkedlist_T ref;
1971} ListObject;
1972
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001973#define NEW_LIST(list) ListNew(&ListType, list)
1974
Bram Moolenaardb913952012-06-29 12:54:53 +02001975 static PyObject *
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001976ListNew(PyTypeObject *subtype, list_T *list)
Bram Moolenaardb913952012-06-29 12:54:53 +02001977{
1978 ListObject *self;
1979
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001980 self = (ListObject *) subtype->tp_alloc(subtype, 0);
Bram Moolenaardb913952012-06-29 12:54:53 +02001981 if (self == NULL)
1982 return NULL;
1983 self->list = list;
1984 ++list->lv_refcount;
1985
1986 pyll_add((PyObject *)(self), &self->ref, &lastlist);
1987
1988 return (PyObject *)(self);
1989}
1990
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02001991 static list_T *
1992py_list_alloc()
1993{
1994 list_T *r;
1995
1996 if (!(r = list_alloc()))
1997 {
1998 PyErr_NoMemory();
1999 return NULL;
2000 }
2001 ++r->lv_refcount;
2002
2003 return r;
2004}
2005
2006 static int
2007list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
2008{
2009 PyObject *iterator;
2010 PyObject *item;
2011 listitem_T *li;
2012
2013 if (!(iterator = PyObject_GetIter(obj)))
2014 return -1;
2015
2016 while ((item = PyIter_Next(iterator)))
2017 {
2018 if (!(li = listitem_alloc()))
2019 {
2020 PyErr_NoMemory();
2021 Py_DECREF(item);
2022 Py_DECREF(iterator);
2023 return -1;
2024 }
2025 li->li_tv.v_lock = 0;
2026 li->li_tv.v_type = VAR_UNKNOWN;
2027
2028 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
2029 {
2030 Py_DECREF(item);
2031 Py_DECREF(iterator);
2032 listitem_free(li);
2033 return -1;
2034 }
2035
2036 Py_DECREF(item);
2037
2038 list_append(l, li);
2039 }
2040
2041 Py_DECREF(iterator);
2042
2043 /* Iterator may have finished due to an exception */
2044 if (PyErr_Occurred())
2045 return -1;
2046
2047 return 0;
2048}
2049
2050 static PyObject *
2051ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2052{
2053 list_T *list;
2054 PyObject *obj = NULL;
2055
2056 if (kwargs)
2057 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002058 PyErr_SET_STRING(PyExc_TypeError,
2059 "list constructor does not accept keyword arguments");
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002060 return NULL;
2061 }
2062
2063 if (!PyArg_ParseTuple(args, "|O", &obj))
2064 return NULL;
2065
2066 if (!(list = py_list_alloc()))
2067 return NULL;
2068
2069 if (obj)
2070 {
2071 PyObject *lookup_dict;
2072
2073 if (!(lookup_dict = PyDict_New()))
2074 {
2075 list_unref(list);
2076 return NULL;
2077 }
2078
2079 if (list_py_concat(list, obj, lookup_dict) == -1)
2080 {
2081 Py_DECREF(lookup_dict);
2082 list_unref(list);
2083 return NULL;
2084 }
2085
2086 Py_DECREF(lookup_dict);
2087 }
2088
2089 return ListNew(subtype, list);
2090}
2091
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002092 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002093ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002094{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002095 pyll_remove(&self->ref, &lastlist);
2096 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002097
2098 DESTRUCTOR_FINISH(self);
2099}
2100
Bram Moolenaardb913952012-06-29 12:54:53 +02002101 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002102ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02002103{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002104 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02002105}
2106
2107 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002108ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02002109{
2110 listitem_T *li;
2111
Bram Moolenaard6e39182013-05-21 18:30:34 +02002112 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02002113 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002114 PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
Bram Moolenaardb913952012-06-29 12:54:53 +02002115 return NULL;
2116 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02002117 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002118 if (li == NULL)
2119 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002120 /* No more suitable format specifications in python-2.3 */
2121 PyErr_VIM_FORMAT("internal error: failed to get vim list item %d",
2122 (int) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02002123 return NULL;
2124 }
2125 return ConvertToPyObject(&li->li_tv);
2126}
2127
2128#define PROC_RANGE \
2129 if (last < 0) {\
2130 if (last < -size) \
2131 last = 0; \
2132 else \
2133 last += size; \
2134 } \
2135 if (first < 0) \
2136 first = 0; \
2137 if (first > size) \
2138 first = size; \
2139 if (last > size) \
2140 last = size;
2141
2142 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002143ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +02002144{
2145 PyInt i;
2146 PyInt size = ListLength(self);
2147 PyInt n;
2148 PyObject *list;
2149 int reversed = 0;
2150
2151 PROC_RANGE
2152 if (first >= last)
2153 first = last;
2154
2155 n = last-first;
2156 list = PyList_New(n);
2157 if (list == NULL)
2158 return NULL;
2159
2160 for (i = 0; i < n; ++i)
2161 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +02002162 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02002163 if (item == NULL)
2164 {
2165 Py_DECREF(list);
2166 return NULL;
2167 }
2168
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02002169 PyList_SET_ITEM(list, ((reversed)?(n-i-1):(i)), item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002170 }
2171
2172 return list;
2173}
2174
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002175typedef struct
2176{
2177 listwatch_T lw;
2178 list_T *list;
2179} listiterinfo_T;
2180
2181 static void
2182ListIterDestruct(listiterinfo_T *lii)
2183{
2184 list_rem_watch(lii->list, &lii->lw);
2185 PyMem_Free(lii);
2186}
2187
2188 static PyObject *
2189ListIterNext(listiterinfo_T **lii)
2190{
2191 PyObject *r;
2192
2193 if (!((*lii)->lw.lw_item))
2194 return NULL;
2195
2196 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
2197 return NULL;
2198
2199 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
2200
2201 return r;
2202}
2203
2204 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002205ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002206{
2207 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002208 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002209
2210 if (!(lii = PyMem_New(listiterinfo_T, 1)))
2211 {
2212 PyErr_NoMemory();
2213 return NULL;
2214 }
2215
2216 list_add_watch(l, &lii->lw);
2217 lii->lw.lw_item = l->lv_first;
2218 lii->list = l;
2219
2220 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002221 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
2222 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02002223}
2224
Bram Moolenaardb913952012-06-29 12:54:53 +02002225 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002226ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02002227{
2228 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002229 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02002230 listitem_T *li;
2231 Py_ssize_t length = ListLength(self);
2232
2233 if (l->lv_lock)
2234 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002235 RAISE_LOCKED_LIST;
Bram Moolenaardb913952012-06-29 12:54:53 +02002236 return -1;
2237 }
2238 if (index>length || (index==length && obj==NULL))
2239 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002240 PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
Bram Moolenaardb913952012-06-29 12:54:53 +02002241 return -1;
2242 }
2243
2244 if (obj == NULL)
2245 {
2246 li = list_find(l, (long) index);
2247 list_remove(l, li, li);
2248 clear_tv(&li->li_tv);
2249 vim_free(li);
2250 return 0;
2251 }
2252
2253 if (ConvertFromPyObject(obj, &tv) == -1)
2254 return -1;
2255
2256 if (index == length)
2257 {
2258 if (list_append_tv(l, &tv) == FAIL)
2259 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002260 clear_tv(&tv);
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002261 PyErr_SET_VIM("failed to add item to list");
Bram Moolenaardb913952012-06-29 12:54:53 +02002262 return -1;
2263 }
2264 }
2265 else
2266 {
2267 li = list_find(l, (long) index);
2268 clear_tv(&li->li_tv);
2269 copy_tv(&tv, &li->li_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002270 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002271 }
2272 return 0;
2273}
2274
2275 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002276ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02002277{
2278 PyInt size = ListLength(self);
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002279 PyObject *iterator;
2280 PyObject *item;
Bram Moolenaardb913952012-06-29 12:54:53 +02002281 listitem_T *li;
2282 listitem_T *next;
2283 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002284 list_T *l = self->list;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002285 PyInt i;
Bram Moolenaardb913952012-06-29 12:54:53 +02002286
2287 if (l->lv_lock)
2288 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002289 RAISE_LOCKED_LIST;
Bram Moolenaardb913952012-06-29 12:54:53 +02002290 return -1;
2291 }
2292
2293 PROC_RANGE
2294
2295 if (first == size)
2296 li = NULL;
2297 else
2298 {
2299 li = list_find(l, (long) first);
2300 if (li == NULL)
2301 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002302 PyErr_VIM_FORMAT("internal error: no vim list item %d", (int)first);
Bram Moolenaardb913952012-06-29 12:54:53 +02002303 return -1;
2304 }
2305 if (last > first)
2306 {
2307 i = last - first;
2308 while (i-- && li != NULL)
2309 {
2310 next = li->li_next;
2311 listitem_remove(l, li);
2312 li = next;
2313 }
2314 }
2315 }
2316
2317 if (obj == NULL)
2318 return 0;
2319
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002320 if (!(iterator = PyObject_GetIter(obj)))
Bram Moolenaardb913952012-06-29 12:54:53 +02002321 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02002322
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002323 while ((item = PyIter_Next(iterator)))
Bram Moolenaardb913952012-06-29 12:54:53 +02002324 {
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002325 if (ConvertFromPyObject(item, &v) == -1)
2326 {
2327 Py_DECREF(iterator);
2328 Py_DECREF(item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002329 return -1;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002330 }
2331 Py_DECREF(item);
Bram Moolenaardb913952012-06-29 12:54:53 +02002332 if (list_insert_tv(l, &v, li) == FAIL)
2333 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002334 clear_tv(&v);
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002335 PyErr_SET_VIM("internal error: failed to add item to list");
Bram Moolenaardb913952012-06-29 12:54:53 +02002336 return -1;
2337 }
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002338 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02002339 }
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02002340 Py_DECREF(iterator);
Bram Moolenaardb913952012-06-29 12:54:53 +02002341 return 0;
2342}
2343
2344 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002345ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02002346{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002347 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02002348 PyObject *lookup_dict;
2349
2350 if (l->lv_lock)
2351 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002352 RAISE_LOCKED_LIST;
Bram Moolenaardb913952012-06-29 12:54:53 +02002353 return NULL;
2354 }
2355
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02002356 if (!(lookup_dict = PyDict_New()))
2357 return NULL;
2358
Bram Moolenaardb913952012-06-29 12:54:53 +02002359 if (list_py_concat(l, obj, lookup_dict) == -1)
2360 {
2361 Py_DECREF(lookup_dict);
2362 return NULL;
2363 }
2364 Py_DECREF(lookup_dict);
2365
2366 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02002367 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02002368}
2369
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002370static char *ListAttrs[] = {
2371 "locked",
2372 NULL
2373};
2374
2375 static PyObject *
2376ListDir(PyObject *self)
2377{
2378 return ObjectDir(self, ListAttrs);
2379}
2380
Bram Moolenaar66b79852012-09-21 14:00:35 +02002381 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002382ListSetattr(ListObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002383{
2384 if (val == NULL)
2385 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002386 PyErr_SET_STRING(PyExc_AttributeError,
2387 "cannot delete vim.List attributes");
Bram Moolenaar66b79852012-09-21 14:00:35 +02002388 return -1;
2389 }
2390
2391 if (strcmp(name, "locked") == 0)
2392 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002393 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02002394 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002395 PyErr_SET_STRING(PyExc_TypeError, "cannot modify fixed list");
Bram Moolenaar66b79852012-09-21 14:00:35 +02002396 return -1;
2397 }
2398 else
2399 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02002400 int istrue = PyObject_IsTrue(val);
2401 if (istrue == -1)
2402 return -1;
2403 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002404 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002405 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02002406 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02002407 }
2408 return 0;
2409 }
2410 else
2411 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002412 PyErr_FORMAT(PyExc_AttributeError, "cannot set attribute %s", name);
Bram Moolenaar66b79852012-09-21 14:00:35 +02002413 return -1;
2414 }
2415}
2416
Bram Moolenaardb913952012-06-29 12:54:53 +02002417static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002418 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
2419 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
2420 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002421};
2422
2423typedef struct
2424{
2425 PyObject_HEAD
2426 char_u *name;
2427} FunctionObject;
2428
2429static PyTypeObject FunctionType;
2430
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002431#define NEW_FUNCTION(name) FunctionNew(&FunctionType, name)
2432
Bram Moolenaardb913952012-06-29 12:54:53 +02002433 static PyObject *
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002434FunctionNew(PyTypeObject *subtype, char_u *name)
Bram Moolenaardb913952012-06-29 12:54:53 +02002435{
2436 FunctionObject *self;
2437
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002438 self = (FunctionObject *) subtype->tp_alloc(subtype, 0);
2439
Bram Moolenaardb913952012-06-29 12:54:53 +02002440 if (self == NULL)
2441 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002442
2443 if (isdigit(*name))
Bram Moolenaardb913952012-06-29 12:54:53 +02002444 {
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002445 if (!translated_function_exists(name))
2446 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002447 PyErr_FORMAT(PyExc_ValueError,
2448 "unnamed function %s does not exist", name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002449 return NULL;
2450 }
2451 self->name = vim_strsave(name);
2452 func_ref(self->name);
2453 }
2454 else
Bram Moolenaar018acca2013-05-30 13:37:28 +02002455 if ((self->name = get_expanded_name(name,
2456 vim_strchr(name, AUTOLOAD_CHAR) == NULL))
2457 == NULL)
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002458 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002459 PyErr_FORMAT(PyExc_ValueError, "function %s does not exist", name);
Bram Moolenaar018acca2013-05-30 13:37:28 +02002460 return NULL;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002461 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002462
2463 return (PyObject *)(self);
2464}
2465
2466 static PyObject *
2467FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2468{
2469 PyObject *self;
2470 char_u *name;
2471
2472 if (kwargs)
2473 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002474 PyErr_SET_STRING(PyExc_TypeError,
2475 "function constructor does not accept keyword arguments");
Bram Moolenaardb913952012-06-29 12:54:53 +02002476 return NULL;
2477 }
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002478
Bram Moolenaar389a1792013-06-23 13:00:44 +02002479 if (!PyArg_ParseTuple(args, "et", "ascii", &name))
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002480 return NULL;
2481
2482 self = FunctionNew(subtype, name);
2483
Bram Moolenaar389a1792013-06-23 13:00:44 +02002484 PyMem_Free(name);
2485
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002486 return self;
Bram Moolenaardb913952012-06-29 12:54:53 +02002487}
2488
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002489 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002490FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002491{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002492 func_unref(self->name);
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02002493 vim_free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002494
2495 DESTRUCTOR_FINISH(self);
2496}
2497
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002498static char *FunctionAttrs[] = {
2499 "softspace",
2500 NULL
2501};
2502
2503 static PyObject *
2504FunctionDir(PyObject *self)
2505{
2506 return ObjectDir(self, FunctionAttrs);
2507}
2508
Bram Moolenaardb913952012-06-29 12:54:53 +02002509 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002510FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02002511{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002512 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02002513 typval_T args;
2514 typval_T selfdicttv;
2515 typval_T rettv;
2516 dict_T *selfdict = NULL;
2517 PyObject *selfdictObject;
2518 PyObject *result;
2519 int error;
2520
2521 if (ConvertFromPyObject(argsObject, &args) == -1)
2522 return NULL;
2523
2524 if (kwargs != NULL)
2525 {
2526 selfdictObject = PyDict_GetItemString(kwargs, "self");
2527 if (selfdictObject != NULL)
2528 {
Bram Moolenaara9922d62013-05-30 13:01:18 +02002529 if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002530 {
2531 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02002532 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002533 }
Bram Moolenaardb913952012-06-29 12:54:53 +02002534 selfdict = selfdicttv.vval.v_dict;
2535 }
2536 }
2537
Bram Moolenaar71700b82013-05-15 17:49:05 +02002538 Py_BEGIN_ALLOW_THREADS
2539 Python_Lock_Vim();
2540
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002541 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02002542 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02002543
2544 Python_Release_Vim();
2545 Py_END_ALLOW_THREADS
2546
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002547 if (VimTryEnd())
2548 result = NULL;
2549 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02002550 {
2551 result = NULL;
Bram Moolenaarc476e522013-06-23 13:46:40 +02002552 PyErr_VIM_FORMAT("failed to run function %s", (char *)name);
Bram Moolenaardb913952012-06-29 12:54:53 +02002553 }
2554 else
2555 result = ConvertToPyObject(&rettv);
2556
Bram Moolenaardb913952012-06-29 12:54:53 +02002557 clear_tv(&args);
2558 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002559 if (selfdict != NULL)
2560 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02002561
2562 return result;
2563}
2564
Bram Moolenaara5b725c2013-05-30 12:43:54 +02002565 static PyObject *
2566FunctionRepr(FunctionObject *self)
2567{
2568 return PyString_FromFormat("<vim.Function '%s'>", self->name);
2569}
2570
Bram Moolenaardb913952012-06-29 12:54:53 +02002571static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002572 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
2573 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02002574};
2575
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002576/*
2577 * Options object
2578 */
2579
2580static PyTypeObject OptionsType;
2581
2582typedef int (*checkfun)(void *);
2583
2584typedef struct
2585{
2586 PyObject_HEAD
2587 int opt_type;
2588 void *from;
2589 checkfun Check;
2590 PyObject *fromObj;
2591} OptionsObject;
2592
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002593 static int
2594dummy_check(void *arg UNUSED)
2595{
2596 return 0;
2597}
2598
2599 static PyObject *
2600OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
2601{
2602 OptionsObject *self;
2603
Bram Moolenaar774267b2013-05-21 20:51:59 +02002604 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002605 if (self == NULL)
2606 return NULL;
2607
2608 self->opt_type = opt_type;
2609 self->from = from;
2610 self->Check = Check;
2611 self->fromObj = fromObj;
2612 if (fromObj)
2613 Py_INCREF(fromObj);
2614
2615 return (PyObject *)(self);
2616}
2617
2618 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002619OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002620{
Bram Moolenaar774267b2013-05-21 20:51:59 +02002621 PyObject_GC_UnTrack((void *)(self));
2622 Py_XDECREF(self->fromObj);
2623 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002624}
2625
2626 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002627OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002628{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002629 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002630 return 0;
2631}
2632
2633 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002634OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002635{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002636 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02002637 return 0;
2638}
2639
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002640 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002641OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002642{
2643 char_u *key;
2644 int flags;
2645 long numval;
2646 char_u *stringval;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002647 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002648
Bram Moolenaard6e39182013-05-21 18:30:34 +02002649 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002650 return NULL;
2651
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002652 if (!(key = StringToChars(keyObject, &todecref)))
2653 return NULL;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002654
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002655 if (*key == NUL)
2656 {
2657 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002658 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002659 return NULL;
2660 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002661
2662 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002663 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002664
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002665 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002666
2667 if (flags == 0)
2668 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02002669 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002670 return NULL;
2671 }
2672
2673 if (flags & SOPT_UNSET)
2674 {
2675 Py_INCREF(Py_None);
2676 return Py_None;
2677 }
2678 else if (flags & SOPT_BOOL)
2679 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002680 PyObject *r;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002681 r = numval ? Py_True : Py_False;
2682 Py_INCREF(r);
2683 return r;
2684 }
2685 else if (flags & SOPT_NUM)
2686 return PyInt_FromLong(numval);
2687 else if (flags & SOPT_STRING)
2688 {
2689 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002690 {
2691 PyObject *r = PyBytes_FromString((char *) stringval);
2692 vim_free(stringval);
2693 return r;
2694 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002695 else
2696 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002697 PyErr_SET_STRING(PyExc_RuntimeError,
2698 "unable to get option value");
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002699 return NULL;
2700 }
2701 }
2702 else
2703 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002704 PyErr_SET_VIM("internal error: unknown option type");
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002705 return NULL;
2706 }
2707}
2708
2709 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02002710set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002711{
2712 char_u *errmsg;
2713
2714 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
2715 {
2716 if (VimTryEnd())
2717 return FAIL;
2718 PyErr_SetVim((char *)errmsg);
2719 return FAIL;
2720 }
2721 return OK;
2722}
2723
2724 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02002725set_option_value_for(
2726 char_u *key,
2727 int numval,
2728 char_u *stringval,
2729 int opt_flags,
2730 int opt_type,
2731 void *from)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002732{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02002733 win_T *save_curwin = NULL;
2734 tabpage_T *save_curtab = NULL;
2735 buf_T *save_curbuf = NULL;
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002736 int r = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002737
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002738 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002739 switch (opt_type)
2740 {
2741 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02002742 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
Bram Moolenaard6949742013-06-16 14:18:28 +02002743 win_find_tabpage((win_T *)from), FALSE) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002744 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002745 if (VimTryEnd())
2746 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002747 PyErr_SET_VIM("problem while switching windows");
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002748 return -1;
2749 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002750 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaard6949742013-06-16 14:18:28 +02002751 restore_win(save_curwin, save_curtab, FALSE);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002752 if (r == FAIL)
2753 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002754 break;
2755 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02002756 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002757 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002758 restore_buffer(save_curbuf);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002759 if (r == FAIL)
2760 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002761 break;
2762 case SREQ_GLOBAL:
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002763 r = set_option_value_err(key, numval, stringval, opt_flags);
2764 if (r == FAIL)
2765 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002766 break;
2767 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002768 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002769}
2770
2771 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002772OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002773{
2774 char_u *key;
2775 int flags;
2776 int opt_flags;
2777 int r = 0;
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002778 PyObject *todecref;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002779
Bram Moolenaard6e39182013-05-21 18:30:34 +02002780 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002781 return -1;
2782
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002783 if (!(key = StringToChars(keyObject, &todecref)))
2784 return -1;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002785
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002786 if (*key == NUL)
2787 {
2788 RAISE_NO_EMPTY_KEYS;
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02002789 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002790 return -1;
2791 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002792
2793 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002794 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002795
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002796 if (flags == 0)
2797 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02002798 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002799 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002800 return -1;
2801 }
2802
2803 if (valObject == NULL)
2804 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002805 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002806 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002807 PyErr_FORMAT(PyExc_ValueError,
2808 "unable to unset global option %s", key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002809 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002810 return -1;
2811 }
2812 else if (!(flags & SOPT_GLOBAL))
2813 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02002814 PyErr_FORMAT(PyExc_ValueError,
2815 "unable to unset option %s "
2816 "which does not have global value", key);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002817 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002818 return -1;
2819 }
2820 else
2821 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002822 unset_global_local_option(key, self->from);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002823 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002824 return 0;
2825 }
2826 }
2827
Bram Moolenaard6e39182013-05-21 18:30:34 +02002828 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002829
2830 if (flags & SOPT_BOOL)
2831 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02002832 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02002833
Bram Moolenaarb983f752013-05-15 16:11:50 +02002834 if (istrue == -1)
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002835 r = -1;
2836 else
2837 r = set_option_value_for(key, istrue, NULL,
2838 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002839 }
2840 else if (flags & SOPT_NUM)
2841 {
2842 int val;
2843
2844#if PY_MAJOR_VERSION < 3
2845 if (PyInt_Check(valObject))
2846 val = PyInt_AsLong(valObject);
2847 else
2848#endif
2849 if (PyLong_Check(valObject))
2850 val = PyLong_AsLong(valObject);
2851 else
2852 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002853 PyErr_SET_STRING(PyExc_TypeError, "object must be integer");
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002854 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002855 return -1;
2856 }
2857
2858 r = set_option_value_for(key, val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002859 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002860 }
2861 else
2862 {
2863 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002864 PyObject *todecref;
2865
2866 if ((val = StringToChars(valObject, &todecref)))
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002867 r = set_option_value_for(key, 0, val, opt_flags,
2868 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002869 else
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002870 r = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002871 }
2872
Bram Moolenaar35eacd72013-05-30 22:06:33 +02002873 Py_XDECREF(todecref);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02002874
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002875 return r;
2876}
2877
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002878static PyMappingMethods OptionsAsMapping = {
2879 (lenfunc) NULL,
2880 (binaryfunc) OptionsItem,
2881 (objobjargproc) OptionsAssItem,
2882};
2883
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002884/* Tabpage object
2885 */
2886
2887typedef struct
2888{
2889 PyObject_HEAD
2890 tabpage_T *tab;
2891} TabPageObject;
2892
2893static PyObject *WinListNew(TabPageObject *tabObject);
2894
2895static PyTypeObject TabPageType;
2896
2897 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002898CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002899{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002900 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002901 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02002902 PyErr_SET_VIM("attempt to refer to deleted tab page");
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002903 return -1;
2904 }
2905
2906 return 0;
2907}
2908
2909 static PyObject *
2910TabPageNew(tabpage_T *tab)
2911{
2912 TabPageObject *self;
2913
2914 if (TAB_PYTHON_REF(tab))
2915 {
2916 self = TAB_PYTHON_REF(tab);
2917 Py_INCREF(self);
2918 }
2919 else
2920 {
2921 self = PyObject_NEW(TabPageObject, &TabPageType);
2922 if (self == NULL)
2923 return NULL;
2924 self->tab = tab;
2925 TAB_PYTHON_REF(tab) = self;
2926 }
2927
2928 return (PyObject *)(self);
2929}
2930
2931 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002932TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002933{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002934 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
2935 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002936
2937 DESTRUCTOR_FINISH(self);
2938}
2939
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002940static char *TabPageAttrs[] = {
2941 "windows", "number", "vars", "window", "valid",
2942 NULL
2943};
2944
2945 static PyObject *
2946TabPageDir(PyObject *self)
2947{
2948 return ObjectDir(self, TabPageAttrs);
2949}
2950
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002951 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002952TabPageAttrValid(TabPageObject *self, char *name)
2953{
2954 PyObject *r;
2955
2956 if (strcmp(name, "valid") != 0)
2957 return NULL;
2958
2959 r = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
2960 Py_INCREF(r);
2961 return r;
2962}
2963
2964 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002965TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002966{
2967 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002968 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002969 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002970 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002971 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02002972 return NEW_DICTIONARY(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002973 else if (strcmp(name, "window") == 0)
2974 {
2975 /* For current tab window.c does not bother to set or update tp_curwin
2976 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002977 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002978 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002979 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02002980 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002981 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002982 else if (strcmp(name, "__members__") == 0)
2983 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002984 return NULL;
2985}
2986
2987 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002988TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002989{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002990 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002991 return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002992 else
2993 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002994 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002995
2996 if (t == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02002997 return PyString_FromFormat("<tabpage object (unknown) at %p>",
2998 (self));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002999 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003000 return PyString_FromFormat("<tabpage %d>", t - 1);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003001 }
3002}
3003
3004static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003005 /* name, function, calling, documentation */
3006 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
3007 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003008};
3009
3010/*
3011 * Window list object
3012 */
3013
3014static PyTypeObject TabListType;
3015static PySequenceMethods TabListAsSeq;
3016
3017typedef struct
3018{
3019 PyObject_HEAD
3020} TabListObject;
3021
3022 static PyInt
3023TabListLength(PyObject *self UNUSED)
3024{
3025 tabpage_T *tp = first_tabpage;
3026 PyInt n = 0;
3027
3028 while (tp != NULL)
3029 {
3030 ++n;
3031 tp = tp->tp_next;
3032 }
3033
3034 return n;
3035}
3036
3037 static PyObject *
3038TabListItem(PyObject *self UNUSED, PyInt n)
3039{
3040 tabpage_T *tp;
3041
3042 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3043 if (n == 0)
3044 return TabPageNew(tp);
3045
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003046 PyErr_SET_STRING(PyExc_IndexError, "no such tab page");
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003047 return NULL;
3048}
3049
Bram Moolenaar6c85e7f2013-06-23 12:51:32 +02003050/*
3051 * Window object
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003052 */
3053
3054typedef struct
3055{
3056 PyObject_HEAD
3057 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003058 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003059} WindowObject;
3060
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003061static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003062
3063 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003064CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003065{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003066 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003067 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003068 PyErr_SET_VIM("attempt to refer to deleted window");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003069 return -1;
3070 }
3071
3072 return 0;
3073}
3074
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003075 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003076WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02003077{
3078 /* We need to handle deletion of windows underneath us.
3079 * If we add a "w_python*_ref" field to the win_T structure,
3080 * then we can get at it in win_free() in vim. We then
3081 * need to create only ONE Python object per window - if
3082 * we try to create a second, just INCREF the existing one
3083 * and return it. The (single) Python object referring to
3084 * the window is stored in "w_python*_ref".
3085 * On a win_free() we set the Python object's win_T* field
3086 * to an invalid value. We trap all uses of a window
3087 * object, and reject them if the win_T* field is invalid.
3088 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003089 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003090 * w_python_ref and w_python3_ref fields respectively.
3091 */
3092
3093 WindowObject *self;
3094
3095 if (WIN_PYTHON_REF(win))
3096 {
3097 self = WIN_PYTHON_REF(win);
3098 Py_INCREF(self);
3099 }
3100 else
3101 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02003102 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02003103 if (self == NULL)
3104 return NULL;
3105 self->win = win;
3106 WIN_PYTHON_REF(win) = self;
3107 }
3108
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003109 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3110
Bram Moolenaar971db462013-05-12 18:44:48 +02003111 return (PyObject *)(self);
3112}
3113
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003114 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003115WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003116{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003117 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02003118 if (self->win && self->win != INVALID_WINDOW_VALUE)
3119 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003120 Py_XDECREF(((PyObject *)(self->tabObject)));
3121 PyObject_GC_Del((void *)(self));
3122}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003123
Bram Moolenaar774267b2013-05-21 20:51:59 +02003124 static int
3125WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3126{
3127 Py_VISIT(((PyObject *)(self->tabObject)));
3128 return 0;
3129}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003130
Bram Moolenaar774267b2013-05-21 20:51:59 +02003131 static int
3132WindowClear(WindowObject *self)
3133{
3134 Py_CLEAR(self->tabObject);
3135 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003136}
3137
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003138 static win_T *
3139get_firstwin(TabPageObject *tabObject)
3140{
3141 if (tabObject)
3142 {
3143 if (CheckTabPage(tabObject))
3144 return NULL;
3145 /* For current tab window.c does not bother to set or update tp_firstwin
3146 */
3147 else if (tabObject->tab == curtab)
3148 return firstwin;
3149 else
3150 return tabObject->tab->tp_firstwin;
3151 }
3152 else
3153 return firstwin;
3154}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003155static char *WindowAttrs[] = {
3156 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
3157 "tabpage", "valid",
3158 NULL
3159};
3160
3161 static PyObject *
3162WindowDir(PyObject *self)
3163{
3164 return ObjectDir(self, WindowAttrs);
3165}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003166
Bram Moolenaar971db462013-05-12 18:44:48 +02003167 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003168WindowAttrValid(WindowObject *self, char *name)
3169{
3170 PyObject *r;
3171
3172 if (strcmp(name, "valid") != 0)
3173 return NULL;
3174
3175 r = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3176 Py_INCREF(r);
3177 return r;
3178}
3179
3180 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003181WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003182{
3183 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003184 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003185 else if (strcmp(name, "cursor") == 0)
3186 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003187 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003188
3189 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
3190 }
3191 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003192 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003193#ifdef FEAT_WINDOWS
3194 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003195 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003196#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003197#ifdef FEAT_VERTSPLIT
3198 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003199 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02003200 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003201 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003202#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02003203 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02003204 return NEW_DICTIONARY(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02003205 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003206 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
3207 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02003208 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003209 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003210 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003211 return NULL;
3212 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003213 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003214 }
3215 else if (strcmp(name, "tabpage") == 0)
3216 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003217 Py_INCREF(self->tabObject);
3218 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003219 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003220 else if (strcmp(name, "__members__") == 0)
3221 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003222 else
3223 return NULL;
3224}
3225
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003226 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003227WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003228{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003229 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003230 return -1;
3231
3232 if (strcmp(name, "buffer") == 0)
3233 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003234 PyErr_SET_STRING(PyExc_TypeError, "readonly attribute: buffer");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003235 return -1;
3236 }
3237 else if (strcmp(name, "cursor") == 0)
3238 {
3239 long lnum;
3240 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003241
3242 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
3243 return -1;
3244
Bram Moolenaard6e39182013-05-21 18:30:34 +02003245 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003246 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003247 PyErr_SET_VIM("cursor position outside buffer");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003248 return -1;
3249 }
3250
3251 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003252 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003253 return -1;
3254
Bram Moolenaard6e39182013-05-21 18:30:34 +02003255 self->win->w_cursor.lnum = lnum;
3256 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003257#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02003258 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003259#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003260 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003261 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003262
Bram Moolenaar03a807a2011-07-07 15:08:58 +02003263 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003264 return 0;
3265 }
3266 else if (strcmp(name, "height") == 0)
3267 {
3268 int height;
3269 win_T *savewin;
3270
3271 if (!PyArg_Parse(val, "i", &height))
3272 return -1;
3273
3274#ifdef FEAT_GUI
3275 need_mouse_correct = TRUE;
3276#endif
3277 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003278 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003279
3280 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003281 win_setheight(height);
3282 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003283 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003284 return -1;
3285
3286 return 0;
3287 }
3288#ifdef FEAT_VERTSPLIT
3289 else if (strcmp(name, "width") == 0)
3290 {
3291 int width;
3292 win_T *savewin;
3293
3294 if (!PyArg_Parse(val, "i", &width))
3295 return -1;
3296
3297#ifdef FEAT_GUI
3298 need_mouse_correct = TRUE;
3299#endif
3300 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02003301 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003302
3303 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003304 win_setwidth(width);
3305 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003306 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003307 return -1;
3308
3309 return 0;
3310 }
3311#endif
3312 else
3313 {
3314 PyErr_SetString(PyExc_AttributeError, name);
3315 return -1;
3316 }
3317}
3318
3319 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003320WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003321{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003322 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003323 return PyString_FromFormat("<window object (deleted) at %p>", (self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003324 else
3325 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003326 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003327
Bram Moolenaar6d216452013-05-12 19:00:41 +02003328 if (w == 0)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003329 return PyString_FromFormat("<window object (unknown) at %p>",
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003330 (self));
3331 else
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02003332 return PyString_FromFormat("<window %d>", w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003333 }
3334}
3335
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003336static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003337 /* name, function, calling, documentation */
3338 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
3339 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003340};
3341
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003342/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003343 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003344 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003345
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003346static PyTypeObject WinListType;
3347static PySequenceMethods WinListAsSeq;
3348
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003349typedef struct
3350{
3351 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003352 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003353} WinListObject;
3354
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003355 static PyObject *
3356WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003357{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003358 WinListObject *self;
3359
3360 self = PyObject_NEW(WinListObject, &WinListType);
3361 self->tabObject = tabObject;
3362 Py_INCREF(tabObject);
3363
3364 return (PyObject *)(self);
3365}
3366
3367 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003368WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003369{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003370 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003371
3372 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02003373 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003374 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02003375 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003376
3377 DESTRUCTOR_FINISH(self);
3378}
3379
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003380 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003381WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003382{
3383 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003384 PyInt n = 0;
3385
Bram Moolenaard6e39182013-05-21 18:30:34 +02003386 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003387 return -1;
3388
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003389 while (w != NULL)
3390 {
3391 ++n;
3392 w = W_NEXT(w);
3393 }
3394
3395 return n;
3396}
3397
3398 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003399WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003400{
3401 win_T *w;
3402
Bram Moolenaard6e39182013-05-21 18:30:34 +02003403 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003404 return NULL;
3405
3406 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003407 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003408 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003409
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003410 PyErr_SET_STRING(PyExc_IndexError, "no such window");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003411 return NULL;
3412}
3413
3414/* Convert a Python string into a Vim line.
3415 *
3416 * The result is in allocated memory. All internal nulls are replaced by
3417 * newline characters. It is an error for the string to contain newline
3418 * characters.
3419 *
3420 * On errors, the Python exception data is set, and NULL is returned.
3421 */
3422 static char *
3423StringToLine(PyObject *obj)
3424{
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003425 char *str;
3426 char *save;
3427 PyObject *bytes = NULL;
3428 Py_ssize_t len;
3429 PyInt i;
3430 char *p;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003431
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003432 if (PyBytes_Check(obj))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003433 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003434 if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
3435 || str == NULL)
3436 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003437 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003438 else if (PyUnicode_Check(obj))
3439 {
3440 if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
3441 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003442
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003443 if(PyBytes_AsStringAndSize(bytes, &str, &len) == -1
3444 || str == NULL)
3445 {
3446 Py_DECREF(bytes);
3447 return NULL;
3448 }
3449 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003450
3451 /*
3452 * Error checking: String must not contain newlines, as we
3453 * are replacing a single line, and we must replace it with
3454 * a single line.
3455 * A trailing newline is removed, so that append(f.readlines()) works.
3456 */
3457 p = memchr(str, '\n', len);
3458 if (p != NULL)
3459 {
3460 if (p == str + len - 1)
3461 --len;
3462 else
3463 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003464 PyErr_SET_VIM("string cannot contain newlines");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003465 return NULL;
3466 }
3467 }
3468
3469 /* Create a copy of the string, with internal nulls replaced by
3470 * newline characters, as is the vim convention.
3471 */
3472 save = (char *)alloc((unsigned)(len+1));
3473 if (save == NULL)
3474 {
3475 PyErr_NoMemory();
3476 return NULL;
3477 }
3478
3479 for (i = 0; i < len; ++i)
3480 {
3481 if (str[i] == '\0')
3482 save[i] = '\n';
3483 else
3484 save[i] = str[i];
3485 }
3486
3487 save[i] = '\0';
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003488 Py_XDECREF(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003489
3490 return save;
3491}
3492
3493/* Get a line from the specified buffer. The line number is
3494 * in Vim format (1-based). The line is returned as a Python
3495 * string object.
3496 */
3497 static PyObject *
3498GetBufferLine(buf_T *buf, PyInt n)
3499{
3500 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
3501}
3502
3503
3504/* Get a list of lines from the specified buffer. The line numbers
3505 * are in Vim format (1-based). The range is from lo up to, but not
3506 * including, hi. The list is returned as a Python list of string objects.
3507 */
3508 static PyObject *
3509GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
3510{
3511 PyInt i;
3512 PyInt n = hi - lo;
3513 PyObject *list = PyList_New(n);
3514
3515 if (list == NULL)
3516 return NULL;
3517
3518 for (i = 0; i < n; ++i)
3519 {
3520 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
3521
3522 /* Error check - was the Python string creation OK? */
3523 if (str == NULL)
3524 {
3525 Py_DECREF(list);
3526 return NULL;
3527 }
3528
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02003529 PyList_SET_ITEM(list, i, str);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003530 }
3531
3532 /* The ownership of the Python list is passed to the caller (ie,
3533 * the caller should Py_DECREF() the object when it is finished
3534 * with it).
3535 */
3536
3537 return list;
3538}
3539
3540/*
3541 * Check if deleting lines made the cursor position invalid.
3542 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
3543 * deleted).
3544 */
3545 static void
3546py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
3547{
3548 if (curwin->w_cursor.lnum >= lo)
3549 {
3550 /* Adjust the cursor position if it's in/after the changed
3551 * lines. */
3552 if (curwin->w_cursor.lnum >= hi)
3553 {
3554 curwin->w_cursor.lnum += extra;
3555 check_cursor_col();
3556 }
3557 else if (extra < 0)
3558 {
3559 curwin->w_cursor.lnum = lo;
3560 check_cursor();
3561 }
3562 else
3563 check_cursor_col();
3564 changed_cline_bef_curs();
3565 }
3566 invalidate_botline();
3567}
3568
Bram Moolenaar19e60942011-06-19 00:27:51 +02003569/*
3570 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003571 * in Vim format (1-based). The replacement line is given as
3572 * a Python string object. The object is checked for validity
3573 * and correct format. Errors are returned as a value of FAIL.
3574 * The return value is OK on success.
3575 * If OK is returned and len_change is not NULL, *len_change
3576 * is set to the change in the buffer length.
3577 */
3578 static int
3579SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
3580{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003581 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003582 * There are three cases:
3583 * 1. NULL, or None - this is a deletion.
3584 * 2. A string - this is a replacement.
3585 * 3. Anything else - this is an error.
3586 */
3587 if (line == Py_None || line == NULL)
3588 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02003589 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003590
3591 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003592 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003593
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003594 VimTryStart();
3595
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003596 if (u_savedel((linenr_T)n, 1L) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003597 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003598 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003599 RAISE_LINE_FAIL("delete");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003600 else
3601 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02003602 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003603 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
3604 deleted_lines_mark((linenr_T)n, 1L);
3605 }
3606
Bram Moolenaar105bc352013-05-17 16:03:57 +02003607 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003608
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003609 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003610 return FAIL;
3611
3612 if (len_change)
3613 *len_change = -1;
3614
3615 return OK;
3616 }
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003617 else if (PyBytes_Check(line) || PyUnicode_Check(line))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003618 {
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003619 char *save = StringToLine(line);
3620 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003621
3622 if (save == NULL)
3623 return FAIL;
3624
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003625 VimTryStart();
3626
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003627 /* We do not need to free "save" if ml_replace() consumes it. */
3628 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003629 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003630
3631 if (u_savesub((linenr_T)n) == FAIL)
3632 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003633 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003634 vim_free(save);
3635 }
3636 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
3637 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003638 RAISE_LINE_FAIL("replace");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003639 vim_free(save);
3640 }
3641 else
3642 changed_bytes((linenr_T)n, 0);
3643
Bram Moolenaar105bc352013-05-17 16:03:57 +02003644 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003645
3646 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02003647 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003648 check_cursor_col();
3649
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003650 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003651 return FAIL;
3652
3653 if (len_change)
3654 *len_change = 0;
3655
3656 return OK;
3657 }
3658 else
3659 {
3660 PyErr_BadArgument();
3661 return FAIL;
3662 }
3663}
3664
Bram Moolenaar19e60942011-06-19 00:27:51 +02003665/* Replace a range of lines in the specified buffer. The line numbers are in
3666 * Vim format (1-based). The range is from lo up to, but not including, hi.
3667 * The replacement lines are given as a Python list of string objects. The
3668 * list is checked for validity and correct format. Errors are returned as a
3669 * value of FAIL. The return value is OK on success.
3670 * If OK is returned and len_change is not NULL, *len_change
3671 * is set to the change in the buffer length.
3672 */
3673 static int
3674SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
3675{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003676 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02003677 * There are three cases:
3678 * 1. NULL, or None - this is a deletion.
3679 * 2. A list - this is a replacement.
3680 * 3. Anything else - this is an error.
3681 */
3682 if (list == Py_None || list == NULL)
3683 {
3684 PyInt i;
3685 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003686 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003687
3688 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003689 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003690 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003691
3692 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003693 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003694 else
3695 {
3696 for (i = 0; i < n; ++i)
3697 {
3698 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3699 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003700 RAISE_LINE_FAIL("delete");
Bram Moolenaar19e60942011-06-19 00:27:51 +02003701 break;
3702 }
3703 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02003704 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003705 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
3706 deleted_lines_mark((linenr_T)lo, (long)i);
3707 }
3708
Bram Moolenaar105bc352013-05-17 16:03:57 +02003709 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003710
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003711 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02003712 return FAIL;
3713
3714 if (len_change)
3715 *len_change = -n;
3716
3717 return OK;
3718 }
3719 else if (PyList_Check(list))
3720 {
3721 PyInt i;
3722 PyInt new_len = PyList_Size(list);
3723 PyInt old_len = hi - lo;
3724 PyInt extra = 0; /* lines added to text, can be negative */
3725 char **array;
3726 buf_T *savebuf;
3727
3728 if (new_len == 0) /* avoid allocating zero bytes */
3729 array = NULL;
3730 else
3731 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003732 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003733 if (array == NULL)
3734 {
3735 PyErr_NoMemory();
3736 return FAIL;
3737 }
3738 }
3739
3740 for (i = 0; i < new_len; ++i)
3741 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003742 PyObject *line;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003743
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003744 if (!(line = PyList_GetItem(list, i)) ||
3745 !(array[i] = StringToLine(line)))
Bram Moolenaar19e60942011-06-19 00:27:51 +02003746 {
3747 while (i)
3748 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003749 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003750 return FAIL;
3751 }
3752 }
3753
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003754 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02003755 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003756
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003757 /* START of region without "return". Must call restore_buffer()! */
Bram Moolenaar105bc352013-05-17 16:03:57 +02003758 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003759
3760 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003761 RAISE_UNDO_FAIL;
Bram Moolenaar19e60942011-06-19 00:27:51 +02003762
3763 /* If the size of the range is reducing (ie, new_len < old_len) we
3764 * need to delete some old_len. We do this at the start, by
3765 * repeatedly deleting line "lo".
3766 */
3767 if (!PyErr_Occurred())
3768 {
3769 for (i = 0; i < old_len - new_len; ++i)
3770 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
3771 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003772 RAISE_LINE_FAIL("delete");
Bram Moolenaar19e60942011-06-19 00:27:51 +02003773 break;
3774 }
3775 extra -= i;
3776 }
3777
3778 /* For as long as possible, replace the existing old_len with the
3779 * new old_len. This is a more efficient operation, as it requires
3780 * less memory allocation and freeing.
3781 */
3782 if (!PyErr_Occurred())
3783 {
3784 for (i = 0; i < old_len && i < new_len; ++i)
3785 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
3786 == FAIL)
3787 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003788 RAISE_LINE_FAIL("replace");
Bram Moolenaar19e60942011-06-19 00:27:51 +02003789 break;
3790 }
3791 }
3792 else
3793 i = 0;
3794
3795 /* Now we may need to insert the remaining new old_len. If we do, we
3796 * must free the strings as we finish with them (we can't pass the
3797 * responsibility to vim in this case).
3798 */
3799 if (!PyErr_Occurred())
3800 {
3801 while (i < new_len)
3802 {
3803 if (ml_append((linenr_T)(lo + i - 1),
3804 (char_u *)array[i], 0, FALSE) == FAIL)
3805 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003806 RAISE_LINE_FAIL("insert");
Bram Moolenaar19e60942011-06-19 00:27:51 +02003807 break;
3808 }
3809 vim_free(array[i]);
3810 ++i;
3811 ++extra;
3812 }
3813 }
3814
3815 /* Free any left-over old_len, as a result of an error */
3816 while (i < new_len)
3817 {
3818 vim_free(array[i]);
3819 ++i;
3820 }
3821
3822 /* Free the array of old_len. All of its contents have now
3823 * been dealt with (either freed, or the responsibility passed
3824 * to vim.
3825 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003826 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003827
3828 /* Adjust marks. Invalidate any which lie in the
3829 * changed range, and move any in the remainder of the buffer.
3830 */
3831 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
3832 (long)MAXLNUM, (long)extra);
3833 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
3834
Bram Moolenaar105bc352013-05-17 16:03:57 +02003835 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02003836 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
3837
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003838 /* END of region without "return". */
Bram Moolenaar105bc352013-05-17 16:03:57 +02003839 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02003840
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003841 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02003842 return FAIL;
3843
3844 if (len_change)
3845 *len_change = new_len - old_len;
3846
3847 return OK;
3848 }
3849 else
3850 {
3851 PyErr_BadArgument();
3852 return FAIL;
3853 }
3854}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003855
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003856/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003857 * The line number is in Vim format (1-based). The lines to be inserted are
3858 * given as a Python list of string objects or as a single string. The lines
3859 * to be added are checked for validity and correct format. Errors are
3860 * returned as a value of FAIL. The return value is OK on success.
3861 * If OK is returned and len_change is not NULL, *len_change
3862 * is set to the change in the buffer length.
3863 */
3864 static int
3865InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
3866{
3867 /* First of all, we check the type of the supplied Python object.
3868 * It must be a string or a list, or the call is in error.
3869 */
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02003870 if (PyBytes_Check(lines) || PyUnicode_Check(lines))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003871 {
3872 char *str = StringToLine(lines);
3873 buf_T *savebuf;
3874
3875 if (str == NULL)
3876 return FAIL;
3877
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003878 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003879 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003880 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003881
3882 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003883 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003884 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003885 RAISE_LINE_FAIL("insert");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003886 else
3887 appended_lines_mark((linenr_T)n, 1L);
3888
3889 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003890 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003891 update_screen(VALID);
3892
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003893 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003894 return FAIL;
3895
3896 if (len_change)
3897 *len_change = 1;
3898
3899 return OK;
3900 }
3901 else if (PyList_Check(lines))
3902 {
3903 PyInt i;
3904 PyInt size = PyList_Size(lines);
3905 char **array;
3906 buf_T *savebuf;
3907
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003908 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003909 if (array == NULL)
3910 {
3911 PyErr_NoMemory();
3912 return FAIL;
3913 }
3914
3915 for (i = 0; i < size; ++i)
3916 {
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003917 PyObject *line;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003918
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02003919 if (!(line = PyList_GetItem(lines, i)) ||
3920 !(array[i] = StringToLine(line)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003921 {
3922 while (i)
3923 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003924 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003925 return FAIL;
3926 }
3927 }
3928
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003929 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003930 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02003931 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003932
3933 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
Bram Moolenaarc476e522013-06-23 13:46:40 +02003934 RAISE_UNDO_FAIL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003935 else
3936 {
3937 for (i = 0; i < size; ++i)
3938 {
3939 if (ml_append((linenr_T)(n + i),
3940 (char_u *)array[i], 0, FALSE) == FAIL)
3941 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02003942 RAISE_LINE_FAIL("insert");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003943
3944 /* Free the rest of the lines */
3945 while (i < size)
3946 vim_free(array[i++]);
3947
3948 break;
3949 }
3950 vim_free(array[i]);
3951 }
3952 if (i > 0)
3953 appended_lines_mark((linenr_T)n, (long)i);
3954 }
3955
3956 /* Free the array of lines. All of its contents have now
3957 * been freed.
3958 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003959 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003960
Bram Moolenaar105bc352013-05-17 16:03:57 +02003961 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003962 update_screen(VALID);
3963
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003964 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003965 return FAIL;
3966
3967 if (len_change)
3968 *len_change = size;
3969
3970 return OK;
3971 }
3972 else
3973 {
3974 PyErr_BadArgument();
3975 return FAIL;
3976 }
3977}
3978
3979/*
3980 * Common routines for buffers and line ranges
3981 * -------------------------------------------
3982 */
3983
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003984typedef struct
3985{
3986 PyObject_HEAD
3987 buf_T *buf;
3988} BufferObject;
3989
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003990 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003991CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003992{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003993 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003994 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02003995 PyErr_SET_VIM("attempt to refer to deleted buffer");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003996 return -1;
3997 }
3998
3999 return 0;
4000}
4001
4002 static PyObject *
4003RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4004{
4005 if (CheckBuffer(self))
4006 return NULL;
4007
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004008 if (end == -1)
4009 end = self->buf->b_ml.ml_line_count;
4010
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004011 if (n < 0)
4012 n += end - start + 1;
4013
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004014 if (n < 0 || n > end - start)
4015 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004016 PyErr_SET_STRING(PyExc_IndexError, "line number out of range");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004017 return NULL;
4018 }
4019
4020 return GetBufferLine(self->buf, n+start);
4021}
4022
4023 static PyObject *
4024RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4025{
4026 PyInt size;
4027
4028 if (CheckBuffer(self))
4029 return NULL;
4030
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004031 if (end == -1)
4032 end = self->buf->b_ml.ml_line_count;
4033
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004034 size = end - start + 1;
4035
4036 if (lo < 0)
4037 lo = 0;
4038 else if (lo > size)
4039 lo = size;
4040 if (hi < 0)
4041 hi = 0;
4042 if (hi < lo)
4043 hi = lo;
4044 else if (hi > size)
4045 hi = size;
4046
4047 return GetBufferLineList(self->buf, lo+start, hi+start);
4048}
4049
4050 static PyInt
4051RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
4052{
4053 PyInt len_change;
4054
4055 if (CheckBuffer(self))
4056 return -1;
4057
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004058 if (end == -1)
4059 end = self->buf->b_ml.ml_line_count;
4060
Bram Moolenaarbd80f352013-05-12 21:16:23 +02004061 if (n < 0)
4062 n += end - start + 1;
4063
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004064 if (n < 0 || n > end - start)
4065 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004066 PyErr_SET_STRING(PyExc_IndexError, "line number out of range");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004067 return -1;
4068 }
4069
4070 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
4071 return -1;
4072
4073 if (new_end)
4074 *new_end = end + len_change;
4075
4076 return 0;
4077}
4078
Bram Moolenaar19e60942011-06-19 00:27:51 +02004079 static PyInt
4080RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
4081{
4082 PyInt size;
4083 PyInt len_change;
4084
4085 /* Self must be a valid buffer */
4086 if (CheckBuffer(self))
4087 return -1;
4088
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004089 if (end == -1)
4090 end = self->buf->b_ml.ml_line_count;
4091
Bram Moolenaar19e60942011-06-19 00:27:51 +02004092 /* Sort out the slice range */
4093 size = end - start + 1;
4094
4095 if (lo < 0)
4096 lo = 0;
4097 else if (lo > size)
4098 lo = size;
4099 if (hi < 0)
4100 hi = 0;
4101 if (hi < lo)
4102 hi = lo;
4103 else if (hi > size)
4104 hi = size;
4105
4106 if (SetBufferLineList(self->buf, lo + start, hi + start,
4107 val, &len_change) == FAIL)
4108 return -1;
4109
4110 if (new_end)
4111 *new_end = end + len_change;
4112
4113 return 0;
4114}
4115
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004116
4117 static PyObject *
4118RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
4119{
4120 PyObject *lines;
4121 PyInt len_change;
4122 PyInt max;
4123 PyInt n;
4124
4125 if (CheckBuffer(self))
4126 return NULL;
4127
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02004128 if (end == -1)
4129 end = self->buf->b_ml.ml_line_count;
4130
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004131 max = n = end - start + 1;
4132
4133 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
4134 return NULL;
4135
4136 if (n < 0 || n > max)
4137 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004138 PyErr_SET_STRING(PyExc_IndexError, "line number out of range");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004139 return NULL;
4140 }
4141
4142 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
4143 return NULL;
4144
4145 if (new_end)
4146 *new_end = end + len_change;
4147
4148 Py_INCREF(Py_None);
4149 return Py_None;
4150}
4151
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004152/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004153 */
4154
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004155static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004156static PySequenceMethods RangeAsSeq;
4157static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004158
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004159typedef struct
4160{
4161 PyObject_HEAD
4162 BufferObject *buf;
4163 PyInt start;
4164 PyInt end;
4165} RangeObject;
4166
4167 static PyObject *
4168RangeNew(buf_T *buf, PyInt start, PyInt end)
4169{
4170 BufferObject *bufr;
4171 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004172 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004173 if (self == NULL)
4174 return NULL;
4175
4176 bufr = (BufferObject *)BufferNew(buf);
4177 if (bufr == NULL)
4178 {
4179 Py_DECREF(self);
4180 return NULL;
4181 }
4182 Py_INCREF(bufr);
4183
4184 self->buf = bufr;
4185 self->start = start;
4186 self->end = end;
4187
4188 return (PyObject *)(self);
4189}
4190
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004191 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004192RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004193{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004194 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004195 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02004196 PyObject_GC_Del((void *)(self));
4197}
4198
4199 static int
4200RangeTraverse(RangeObject *self, visitproc visit, void *arg)
4201{
4202 Py_VISIT(((PyObject *)(self->buf)));
4203 return 0;
4204}
4205
4206 static int
4207RangeClear(RangeObject *self)
4208{
4209 Py_CLEAR(self->buf);
4210 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004211}
4212
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004213 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004214RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004215{
4216 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004217 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004218 return -1; /* ??? */
4219
Bram Moolenaard6e39182013-05-21 18:30:34 +02004220 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004221}
4222
4223 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004224RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004225{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004226 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004227}
4228
4229 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004230RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004231{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004232 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004233}
4234
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004235static char *RangeAttrs[] = {
4236 "start", "end",
4237 NULL
4238};
4239
4240 static PyObject *
4241RangeDir(PyObject *self)
4242{
4243 return ObjectDir(self, RangeAttrs);
4244}
4245
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004246 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004247RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004248{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004249 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004250}
4251
4252 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004253RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004254{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004255 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004256 return PyString_FromFormat("<range object (for deleted buffer) at %p>",
4257 (self));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004258 else
4259 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02004260 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004261
4262 if (name == NULL)
4263 name = "";
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004264
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004265 return PyString_FromFormat("<range %s (%d:%d)>",
Bram Moolenaarf62d9422013-05-30 19:01:24 +02004266 name, (int)self->start, (int)self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004267 }
4268}
4269
4270static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004271 /* name, function, calling, documentation */
4272 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004273 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
4274 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004275};
4276
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004277static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004278static PySequenceMethods BufferAsSeq;
4279static PyMappingMethods BufferAsMapping;
4280
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004281 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02004282BufferNew(buf_T *buf)
4283{
4284 /* We need to handle deletion of buffers underneath us.
4285 * If we add a "b_python*_ref" field to the buf_T structure,
4286 * then we can get at it in buf_freeall() in vim. We then
4287 * need to create only ONE Python object per buffer - if
4288 * we try to create a second, just INCREF the existing one
4289 * and return it. The (single) Python object referring to
4290 * the buffer is stored in "b_python*_ref".
4291 * Question: what to do on a buf_freeall(). We'll probably
4292 * have to either delete the Python object (DECREF it to
4293 * zero - a bad idea, as it leaves dangling refs!) or
4294 * set the buf_T * value to an invalid value (-1?), which
4295 * means we need checks in all access functions... Bah.
4296 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004297 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02004298 * b_python_ref and b_python3_ref fields respectively.
4299 */
4300
4301 BufferObject *self;
4302
4303 if (BUF_PYTHON_REF(buf) != NULL)
4304 {
4305 self = BUF_PYTHON_REF(buf);
4306 Py_INCREF(self);
4307 }
4308 else
4309 {
4310 self = PyObject_NEW(BufferObject, &BufferType);
4311 if (self == NULL)
4312 return NULL;
4313 self->buf = buf;
4314 BUF_PYTHON_REF(buf) = self;
4315 }
4316
4317 return (PyObject *)(self);
4318}
4319
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004320 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02004321BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004322{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004323 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
4324 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004325
4326 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004327}
4328
Bram Moolenaar971db462013-05-12 18:44:48 +02004329 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02004330BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02004331{
4332 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02004333 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02004334 return -1; /* ??? */
4335
Bram Moolenaard6e39182013-05-21 18:30:34 +02004336 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02004337}
4338
4339 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004340BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02004341{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004342 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004343}
4344
4345 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004346BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02004347{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004348 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02004349}
4350
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004351static char *BufferAttrs[] = {
4352 "name", "number", "vars", "options", "valid",
4353 NULL
4354};
4355
4356 static PyObject *
4357BufferDir(PyObject *self)
4358{
4359 return ObjectDir(self, BufferAttrs);
4360}
4361
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004362 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02004363BufferAttrValid(BufferObject *self, char *name)
4364{
4365 PyObject *r;
4366
4367 if (strcmp(name, "valid") != 0)
4368 return NULL;
4369
4370 r = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
4371 Py_INCREF(r);
4372 return r;
4373}
4374
4375 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004376BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004377{
4378 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02004379 return PyString_FromString((self->buf->b_ffname == NULL
4380 ? "" : (char *) self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004381 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004382 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004383 else if (strcmp(name, "vars") == 0)
Bram Moolenaara9922d62013-05-30 13:01:18 +02004384 return NEW_DICTIONARY(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004385 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02004386 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
4387 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004388 else if (strcmp(name, "__members__") == 0)
4389 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004390 else
4391 return NULL;
4392}
4393
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004394 static int
4395BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
4396{
4397 if (CheckBuffer(self))
4398 return -1;
4399
4400 if (strcmp(name, "name") == 0)
4401 {
4402 char_u *val;
4403 aco_save_T aco;
4404 int r;
4405 PyObject *todecref;
4406
4407 if (!(val = StringToChars(valObject, &todecref)))
4408 return -1;
4409
4410 VimTryStart();
4411 /* Using aucmd_*: autocommands will be executed by rename_buffer */
4412 aucmd_prepbuf(&aco, self->buf);
4413 r = rename_buffer(val);
4414 aucmd_restbuf(&aco);
4415 Py_XDECREF(todecref);
4416 if (VimTryEnd())
4417 return -1;
4418
4419 if (r == FAIL)
4420 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004421 PyErr_SET_VIM("failed to rename buffer");
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004422 return -1;
4423 }
4424 return 0;
4425 }
4426 else
4427 {
4428 PyErr_SetString(PyExc_AttributeError, name);
4429 return -1;
4430 }
4431}
4432
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004433 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004434BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004435{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004436 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004437}
4438
4439 static PyObject *
Bram Moolenaar389a1792013-06-23 13:00:44 +02004440BufferMark(BufferObject *self, PyObject *pmarkObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004441{
4442 pos_T *posp;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004443 char_u *pmark;
4444 char_u mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02004445 buf_T *savebuf;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004446 PyObject *todecref;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004447
Bram Moolenaard6e39182013-05-21 18:30:34 +02004448 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004449 return NULL;
4450
Bram Moolenaar389a1792013-06-23 13:00:44 +02004451 if (!(pmark = StringToChars(pmarkObject, &todecref)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004452 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004453
Bram Moolenaar389a1792013-06-23 13:00:44 +02004454 if (pmark[0] == '\0' || pmark[1] != '\0')
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004455 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004456 PyErr_SET_STRING(PyExc_ValueError,
4457 "mark name must be a single character");
Bram Moolenaar494ff7e2013-05-30 13:17:17 +02004458 return NULL;
4459 }
4460
4461 mark = *pmark;
Bram Moolenaar389a1792013-06-23 13:00:44 +02004462
4463 Py_XDECREF(todecref);
4464
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004465 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02004466 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004467 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02004468 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004469 if (VimTryEnd())
4470 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004471
4472 if (posp == NULL)
4473 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004474 PyErr_SET_VIM("invalid mark name");
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004475 return NULL;
4476 }
4477
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004478 if (posp->lnum <= 0)
4479 {
4480 /* Or raise an error? */
4481 Py_INCREF(Py_None);
4482 return Py_None;
4483 }
4484
4485 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
4486}
4487
4488 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004489BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004490{
4491 PyInt start;
4492 PyInt end;
4493
Bram Moolenaard6e39182013-05-21 18:30:34 +02004494 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004495 return NULL;
4496
4497 if (!PyArg_ParseTuple(args, "nn", &start, &end))
4498 return NULL;
4499
Bram Moolenaard6e39182013-05-21 18:30:34 +02004500 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004501}
4502
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004503 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02004504BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004505{
Bram Moolenaard6e39182013-05-21 18:30:34 +02004506 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004507 return PyString_FromFormat("<buffer object (deleted) at %p>", self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004508 else
4509 {
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004510 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004511
4512 if (name == NULL)
4513 name = "";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004514
Bram Moolenaar1a3b5692013-05-30 12:40:39 +02004515 return PyString_FromFormat("<buffer %s>", name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004516 }
4517}
4518
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004519static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004520 /* name, function, calling, documentation */
4521 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
Bram Moolenaar389a1792013-06-23 13:00:44 +02004522 {"mark", (PyCFunction)BufferMark, METH_O, "Return (row,col) representing position of named mark" },
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02004523 {"range", (PyCFunction)BufferRange, METH_VARARGS, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004524 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
4525 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004526};
4527
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004528/*
4529 * Buffer list object - Implementation
4530 */
4531
4532static PyTypeObject BufMapType;
4533
4534typedef struct
4535{
4536 PyObject_HEAD
4537} BufMapObject;
4538
4539 static PyInt
4540BufMapLength(PyObject *self UNUSED)
4541{
4542 buf_T *b = firstbuf;
4543 PyInt n = 0;
4544
4545 while (b)
4546 {
4547 ++n;
4548 b = b->b_next;
4549 }
4550
4551 return n;
4552}
4553
4554 static PyObject *
4555BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
4556{
4557 buf_T *b;
4558 int bnr;
4559
4560#if PY_MAJOR_VERSION < 3
4561 if (PyInt_Check(keyObject))
4562 bnr = PyInt_AsLong(keyObject);
4563 else
4564#endif
4565 if (PyLong_Check(keyObject))
4566 bnr = PyLong_AsLong(keyObject);
4567 else
4568 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004569 PyErr_SET_STRING(PyExc_TypeError, "key must be integer");
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004570 return NULL;
4571 }
4572
4573 b = buflist_findnr(bnr);
4574
4575 if (b)
4576 return BufferNew(b);
4577 else
4578 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02004579 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004580 return NULL;
4581 }
4582}
4583
4584 static void
4585BufMapIterDestruct(PyObject *buffer)
4586{
4587 /* Iteration was stopped before all buffers were processed */
4588 if (buffer)
4589 {
4590 Py_DECREF(buffer);
4591 }
4592}
4593
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004594 static int
4595BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
4596{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004597 if (buffer)
4598 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004599 return 0;
4600}
4601
4602 static int
4603BufMapIterClear(PyObject **buffer)
4604{
Bram Moolenaar774267b2013-05-21 20:51:59 +02004605 if (*buffer)
4606 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004607 return 0;
4608}
4609
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004610 static PyObject *
4611BufMapIterNext(PyObject **buffer)
4612{
4613 PyObject *next;
4614 PyObject *r;
4615
4616 if (!*buffer)
4617 return NULL;
4618
4619 r = *buffer;
4620
4621 if (CheckBuffer((BufferObject *)(r)))
4622 {
4623 *buffer = NULL;
4624 return NULL;
4625 }
4626
4627 if (!((BufferObject *)(r))->buf->b_next)
4628 next = NULL;
4629 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
4630 return NULL;
4631 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02004632 /* Do not increment reference: we no longer hold it (decref), but whoever
4633 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004634 return r;
4635}
4636
4637 static PyObject *
4638BufMapIter(PyObject *self UNUSED)
4639{
4640 PyObject *buffer;
4641
4642 buffer = BufferNew(firstbuf);
4643 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02004644 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
4645 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004646}
4647
4648static PyMappingMethods BufMapAsMapping = {
4649 (lenfunc) BufMapLength,
4650 (binaryfunc) BufMapItem,
4651 (objobjargproc) 0,
4652};
4653
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004654/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02004655 */
4656
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004657static char *CurrentAttrs[] = {
4658 "buffer", "window", "line", "range", "tabpage",
4659 NULL
4660};
4661
4662 static PyObject *
4663CurrentDir(PyObject *self)
4664{
4665 return ObjectDir(self, CurrentAttrs);
4666}
4667
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004668 static PyObject *
4669CurrentGetattr(PyObject *self UNUSED, char *name)
4670{
4671 if (strcmp(name, "buffer") == 0)
4672 return (PyObject *)BufferNew(curbuf);
4673 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02004674 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004675 else if (strcmp(name, "tabpage") == 0)
4676 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004677 else if (strcmp(name, "line") == 0)
4678 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
4679 else if (strcmp(name, "range") == 0)
4680 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004681 else if (strcmp(name, "__members__") == 0)
4682 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004683 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004684#if PY_MAJOR_VERSION < 3
4685 return Py_FindMethod(WindowMethods, self, name);
4686#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004687 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004688#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004689}
4690
4691 static int
4692CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
4693{
4694 if (strcmp(name, "line") == 0)
4695 {
4696 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
4697 return -1;
4698
4699 return 0;
4700 }
Bram Moolenaare7614592013-05-15 15:51:08 +02004701 else if (strcmp(name, "buffer") == 0)
4702 {
4703 int count;
4704
4705 if (value->ob_type != &BufferType)
4706 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004707 PyErr_FORMAT(PyExc_TypeError,
4708 "expected vim.Buffer object, but got %s",
4709 Py_TYPE_NAME(value));
Bram Moolenaare7614592013-05-15 15:51:08 +02004710 return -1;
4711 }
4712
4713 if (CheckBuffer((BufferObject *)(value)))
4714 return -1;
4715 count = ((BufferObject *)(value))->buf->b_fnum;
4716
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004717 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004718 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
4719 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004720 if (VimTryEnd())
4721 return -1;
Bram Moolenaarc476e522013-06-23 13:46:40 +02004722 PyErr_VIM_FORMAT("failed to switch to buffer %d", count);
Bram Moolenaare7614592013-05-15 15:51:08 +02004723 return -1;
4724 }
4725
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004726 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004727 }
4728 else if (strcmp(name, "window") == 0)
4729 {
4730 int count;
4731
4732 if (value->ob_type != &WindowType)
4733 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004734 PyErr_FORMAT(PyExc_TypeError,
4735 "expected vim.Window object, but got %s",
4736 Py_TYPE_NAME(value));
Bram Moolenaare7614592013-05-15 15:51:08 +02004737 return -1;
4738 }
4739
4740 if (CheckWindow((WindowObject *)(value)))
4741 return -1;
4742 count = get_win_number(((WindowObject *)(value))->win, firstwin);
4743
4744 if (!count)
4745 {
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004746 PyErr_SET_STRING(PyExc_ValueError,
4747 "failed to find window in the current tab page");
Bram Moolenaare7614592013-05-15 15:51:08 +02004748 return -1;
4749 }
4750
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004751 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004752 win_goto(((WindowObject *)(value))->win);
4753 if (((WindowObject *)(value))->win != curwin)
4754 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004755 if (VimTryEnd())
4756 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004757 PyErr_SET_STRING(PyExc_RuntimeError,
4758 "did not switch to the specified window");
Bram Moolenaare7614592013-05-15 15:51:08 +02004759 return -1;
4760 }
4761
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004762 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004763 }
4764 else if (strcmp(name, "tabpage") == 0)
4765 {
4766 if (value->ob_type != &TabPageType)
4767 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02004768 PyErr_FORMAT(PyExc_TypeError,
4769 "expected vim.TabPage object, but got %s",
4770 Py_TYPE_NAME(value));
Bram Moolenaare7614592013-05-15 15:51:08 +02004771 return -1;
4772 }
4773
4774 if (CheckTabPage((TabPageObject *)(value)))
4775 return -1;
4776
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004777 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02004778 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
4779 if (((TabPageObject *)(value))->tab != curtab)
4780 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004781 if (VimTryEnd())
4782 return -1;
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02004783 PyErr_SET_STRING(PyExc_RuntimeError,
4784 "did not switch to the specified tab page");
Bram Moolenaare7614592013-05-15 15:51:08 +02004785 return -1;
4786 }
4787
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02004788 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02004789 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004790 else
4791 {
4792 PyErr_SetString(PyExc_AttributeError, name);
4793 return -1;
4794 }
4795}
4796
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004797static struct PyMethodDef CurrentMethods[] = {
4798 /* name, function, calling, documentation */
4799 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
4800 { NULL, NULL, 0, NULL}
4801};
4802
Bram Moolenaardb913952012-06-29 12:54:53 +02004803 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004804init_range_cmd(exarg_T *eap)
4805{
4806 RangeStart = eap->line1;
4807 RangeEnd = eap->line2;
4808}
4809
4810 static void
4811init_range_eval(typval_T *rettv UNUSED)
4812{
4813 RangeStart = (PyInt) curwin->w_cursor.lnum;
4814 RangeEnd = RangeStart;
4815}
4816
4817 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004818run_cmd(const char *cmd, void *arg UNUSED
4819#ifdef PY_CAN_RECURSE
4820 , PyGILState_STATE *pygilstate UNUSED
4821#endif
4822 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004823{
4824 PyRun_SimpleString((char *) cmd);
4825}
4826
4827static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
4828static int code_hdr_len = 30;
4829
4830 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004831run_do(const char *cmd, void *arg UNUSED
4832#ifdef PY_CAN_RECURSE
4833 , PyGILState_STATE *pygilstate
4834#endif
4835 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004836{
4837 PyInt lnum;
4838 size_t len;
4839 char *code;
4840 int status;
4841 PyObject *pyfunc, *pymain;
4842
Bram Moolenaar4ac66762013-05-28 22:31:46 +02004843 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004844 {
4845 EMSG(_("cannot save undo information"));
4846 return;
4847 }
4848
4849 len = code_hdr_len + STRLEN(cmd);
4850 code = PyMem_New(char, len + 1);
4851 memcpy(code, code_hdr, code_hdr_len);
4852 STRCPY(code + code_hdr_len, cmd);
4853 status = PyRun_SimpleString(code);
4854 PyMem_Free(code);
4855
4856 if (status)
4857 {
4858 EMSG(_("failed to run the code"));
4859 return;
4860 }
4861
4862 status = 0;
4863 pymain = PyImport_AddModule("__main__");
4864 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004865#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004866 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004867#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004868
4869 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
4870 {
4871 PyObject *line, *linenr, *ret;
4872
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004873#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004874 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004875#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004876 if (!(line = GetBufferLine(curbuf, lnum)))
4877 goto err;
4878 if (!(linenr = PyInt_FromLong((long) lnum)))
4879 {
4880 Py_DECREF(line);
4881 goto err;
4882 }
4883 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
4884 Py_DECREF(line);
4885 Py_DECREF(linenr);
4886 if (!ret)
4887 goto err;
4888
4889 if (ret != Py_None)
4890 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
4891 goto err;
4892
4893 Py_XDECREF(ret);
4894 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004895#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004896 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004897#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004898 }
4899 goto out;
4900err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004901#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004902 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004903#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004904 PyErr_PrintEx(0);
4905 PythonIO_Flush();
4906 status = 1;
4907out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004908#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004909 if (!status)
4910 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004911#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004912 Py_DECREF(pyfunc);
4913 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
4914 if (status)
4915 return;
4916 check_cursor();
4917 update_curbuf(NOT_VALID);
4918}
4919
4920 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02004921run_eval(const char *cmd, typval_T *rettv
4922#ifdef PY_CAN_RECURSE
4923 , PyGILState_STATE *pygilstate UNUSED
4924#endif
4925 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02004926{
4927 PyObject *r;
4928
4929 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
4930 if (r == NULL)
4931 {
4932 if (PyErr_Occurred() && !msg_silent)
4933 PyErr_PrintEx(0);
4934 EMSG(_("E858: Eval did not return a valid python object"));
4935 }
4936 else
4937 {
4938 if (ConvertFromPyObject(r, rettv) == -1)
4939 EMSG(_("E859: Failed to convert returned python object to vim value"));
4940 Py_DECREF(r);
4941 }
4942 PyErr_Clear();
4943}
4944
4945 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02004946set_ref_in_py(const int copyID)
4947{
4948 pylinkedlist_T *cur;
4949 dict_T *dd;
4950 list_T *ll;
4951
4952 if (lastdict != NULL)
4953 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
4954 {
4955 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
4956 if (dd->dv_copyID != copyID)
4957 {
4958 dd->dv_copyID = copyID;
4959 set_ref_in_ht(&dd->dv_hashtab, copyID);
4960 }
4961 }
4962
4963 if (lastlist != NULL)
4964 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
4965 {
4966 ll = ((ListObject *) (cur->pll_obj))->list;
4967 if (ll->lv_copyID != copyID)
4968 {
4969 ll->lv_copyID = copyID;
4970 set_ref_in_list(ll, copyID);
4971 }
4972 }
4973}
4974
4975 static int
4976set_string_copy(char_u *str, typval_T *tv)
4977{
4978 tv->vval.v_string = vim_strsave(str);
4979 if (tv->vval.v_string == NULL)
4980 {
4981 PyErr_NoMemory();
4982 return -1;
4983 }
4984 return 0;
4985}
4986
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004987 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004988pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004989{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004990 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004991 char_u *key;
4992 dictitem_T *di;
4993 PyObject *keyObject;
4994 PyObject *valObject;
4995 Py_ssize_t iter = 0;
4996
Bram Moolenaar35eacd72013-05-30 22:06:33 +02004997 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004998 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004999
5000 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005001 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005002
5003 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5004 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005005 PyObject *todecref = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005006
Bram Moolenaara03e6312013-05-29 22:49:26 +02005007 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005008 {
5009 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005010 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005011 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005012
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005013 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005014 {
5015 dict_unref(dict);
5016 return -1;
5017 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005018
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005019 if (*key == NUL)
5020 {
5021 dict_unref(dict);
5022 Py_XDECREF(todecref);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005023 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005024 return -1;
5025 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005026
5027 di = dictitem_alloc(key);
5028
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005029 Py_XDECREF(todecref);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005030
5031 if (di == NULL)
5032 {
5033 PyErr_NoMemory();
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005034 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005035 return -1;
5036 }
5037 di->di_tv.v_lock = 0;
5038
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005039 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005040 {
5041 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005042 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005043 return -1;
5044 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005045
5046 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005047 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005048 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaara03e6312013-05-29 22:49:26 +02005049 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005050 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005051 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005052 return -1;
5053 }
5054 }
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005055
5056 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005057 return 0;
5058}
5059
5060 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005061pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005062{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005063 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005064 char_u *key;
5065 dictitem_T *di;
5066 PyObject *list;
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005067 PyObject *iterator;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005068 PyObject *keyObject;
5069 PyObject *valObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005070
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005071 if (!(dict = py_dict_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005072 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005073
5074 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005075 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005076
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005077 if (!(list = PyMapping_Keys(obj)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005078 {
5079 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005080 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005081 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005082
5083 if (!(iterator = PyObject_GetIter(list)))
5084 {
5085 dict_unref(dict);
5086 Py_DECREF(list);
5087 return -1;
5088 }
5089 Py_DECREF(list);
5090
5091 while ((keyObject = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005092 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005093 PyObject *todecref;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005094
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005095 if (!(key = StringToChars(keyObject, &todecref)))
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005096 {
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005097 Py_DECREF(keyObject);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005098 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005099 dict_unref(dict);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005100 return -1;
5101 }
Bram Moolenaar4f2109d2013-06-02 18:07:37 +02005102
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005103 if (*key == NUL)
5104 {
5105 Py_DECREF(keyObject);
5106 Py_DECREF(iterator);
5107 Py_XDECREF(todecref);
5108 dict_unref(dict);
Bram Moolenaar35eacd72013-05-30 22:06:33 +02005109 RAISE_NO_EMPTY_KEYS;
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005110 return -1;
5111 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005112
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005113 if (!(valObject = PyObject_GetItem(obj, keyObject)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005114 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005115 Py_DECREF(keyObject);
5116 Py_DECREF(iterator);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005117 Py_XDECREF(todecref);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005118 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005119 return -1;
5120 }
5121
5122 di = dictitem_alloc(key);
5123
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005124 Py_DECREF(keyObject);
Bram Moolenaarfc714b32013-05-30 14:52:37 +02005125 Py_XDECREF(todecref);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005126
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005127 if (di == NULL)
5128 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005129 Py_DECREF(iterator);
5130 Py_DECREF(valObject);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005131 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005132 PyErr_NoMemory();
5133 return -1;
5134 }
5135 di->di_tv.v_lock = 0;
5136
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005137 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005138 {
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005139 Py_DECREF(iterator);
5140 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005141 vim_free(di);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005142 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005143 return -1;
5144 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02005145
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005146 Py_DECREF(valObject);
5147
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005148 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005149 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005150 RAISE_KEY_ADD_FAIL(di->di_key);
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005151 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005152 dictitem_free(di);
5153 dict_unref(dict);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005154 return -1;
5155 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005156 }
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005157 Py_DECREF(iterator);
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005158 --dict->dv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005159 return 0;
5160}
5161
5162 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005163pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005164{
5165 list_T *l;
5166
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005167 if (!(l = py_list_alloc()))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005168 return -1;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005169
5170 tv->v_type = VAR_LIST;
5171 tv->vval.v_list = l;
5172
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005173 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005174 {
5175 list_unref(l);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005176 return -1;
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005177 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005178
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005179 --l->lv_refcount;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02005180 return 0;
5181}
5182
Bram Moolenaardb913952012-06-29 12:54:53 +02005183typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
5184
5185 static int
5186convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005187 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005188{
5189 PyObject *capsule;
5190 char hexBuf[sizeof(void *) * 2 + 3];
5191
5192 sprintf(hexBuf, "%p", obj);
5193
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005194# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005195 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005196# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005197 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005198# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02005199 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02005200 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005201# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02005202 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02005203# else
5204 capsule = PyCObject_FromVoidPtr(tv, NULL);
5205# endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02005206 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
5207 {
5208 Py_DECREF(capsule);
5209 tv->v_type = VAR_UNKNOWN;
5210 return -1;
5211 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005212 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02005213 {
5214 tv->v_type = VAR_UNKNOWN;
5215 return -1;
5216 }
5217 /* As we are not using copy_tv which increments reference count we must
5218 * do it ourself. */
5219 switch(tv->v_type)
5220 {
5221 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
5222 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
5223 }
5224 }
5225 else
5226 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005227 typval_T *v;
5228
5229# ifdef PY_USE_CAPSULE
5230 v = PyCapsule_GetPointer(capsule, NULL);
5231# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02005232 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02005233# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02005234 copy_tv(v, tv);
5235 }
5236 return 0;
5237}
5238
5239 static int
Bram Moolenaara9922d62013-05-30 13:01:18 +02005240ConvertFromPyMapping(PyObject *obj, typval_T *tv)
5241{
5242 PyObject *lookup_dict;
5243 int r;
5244
5245 if (!(lookup_dict = PyDict_New()))
5246 return -1;
5247
5248 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
5249 {
5250 tv->v_type = VAR_DICT;
5251 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5252 ++tv->vval.v_dict->dv_refcount;
5253 r = 0;
5254 }
5255 else if (PyDict_Check(obj))
5256 r = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
5257 else if (PyMapping_Check(obj))
5258 r = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
5259 else
5260 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005261 PyErr_FORMAT(PyExc_TypeError,
5262 "unable to convert %s to vim dictionary",
5263 Py_TYPE_NAME(obj));
Bram Moolenaara9922d62013-05-30 13:01:18 +02005264 r = -1;
5265 }
5266 Py_DECREF(lookup_dict);
5267 return r;
5268}
5269
5270 static int
Bram Moolenaardb913952012-06-29 12:54:53 +02005271ConvertFromPyObject(PyObject *obj, typval_T *tv)
5272{
5273 PyObject *lookup_dict;
5274 int r;
5275
Bram Moolenaar9bb77d62013-05-30 12:14:49 +02005276 if (!(lookup_dict = PyDict_New()))
5277 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005278 r = _ConvertFromPyObject(obj, tv, lookup_dict);
5279 Py_DECREF(lookup_dict);
5280 return r;
5281}
5282
5283 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005284_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02005285{
Bram Moolenaara9922d62013-05-30 13:01:18 +02005286 if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
Bram Moolenaardb913952012-06-29 12:54:53 +02005287 {
5288 tv->v_type = VAR_DICT;
5289 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
5290 ++tv->vval.v_dict->dv_refcount;
5291 }
5292 else if (obj->ob_type == &ListType)
5293 {
5294 tv->v_type = VAR_LIST;
5295 tv->vval.v_list = (((ListObject *)(obj))->list);
5296 ++tv->vval.v_list->lv_refcount;
5297 }
5298 else if (obj->ob_type == &FunctionType)
5299 {
5300 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
5301 return -1;
5302
5303 tv->v_type = VAR_FUNC;
5304 func_ref(tv->vval.v_string);
5305 }
Bram Moolenaardb913952012-06-29 12:54:53 +02005306 else if (PyBytes_Check(obj))
5307 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005308 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02005309
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02005310 if (PyBytes_AsStringAndSize(obj, (char **) &result, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005311 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005312 if (result == NULL)
5313 return -1;
5314
5315 if (set_string_copy(result, tv) == -1)
5316 return -1;
5317
5318 tv->v_type = VAR_STRING;
5319 }
5320 else if (PyUnicode_Check(obj))
5321 {
5322 PyObject *bytes;
5323 char_u *result;
5324
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02005325 bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +02005326 if (bytes == NULL)
5327 return -1;
5328
Bram Moolenaar808c2bc2013-06-23 13:11:18 +02005329 if(PyBytes_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02005330 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02005331 if (result == NULL)
5332 return -1;
5333
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005334 if (set_string_copy(result, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02005335 {
5336 Py_XDECREF(bytes);
5337 return -1;
5338 }
5339 Py_XDECREF(bytes);
5340
5341 tv->v_type = VAR_STRING;
5342 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02005343#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02005344 else if (PyInt_Check(obj))
5345 {
5346 tv->v_type = VAR_NUMBER;
5347 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
5348 }
5349#endif
5350 else if (PyLong_Check(obj))
5351 {
5352 tv->v_type = VAR_NUMBER;
5353 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
5354 }
5355 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005356 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005357#ifdef FEAT_FLOAT
5358 else if (PyFloat_Check(obj))
5359 {
5360 tv->v_type = VAR_FLOAT;
5361 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
5362 }
5363#endif
Bram Moolenaarbcb40972013-05-30 13:22:13 +02005364 else if (PyObject_HasAttrString(obj, "keys"))
5365 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005366 else if (PyIter_Check(obj) || PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005367 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005368 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02005369 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005370 else
5371 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005372 PyErr_FORMAT(PyExc_TypeError,
5373 "unable to convert %s to vim structure",
5374 Py_TYPE_NAME(obj));
Bram Moolenaardb913952012-06-29 12:54:53 +02005375 return -1;
5376 }
5377 return 0;
5378}
5379
5380 static PyObject *
5381ConvertToPyObject(typval_T *tv)
5382{
5383 if (tv == NULL)
5384 {
Bram Moolenaarc476e522013-06-23 13:46:40 +02005385 PyErr_SET_VIM("internal error: NULL reference passed");
Bram Moolenaardb913952012-06-29 12:54:53 +02005386 return NULL;
5387 }
5388 switch (tv->v_type)
5389 {
5390 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02005391 return PyBytes_FromString(tv->vval.v_string == NULL
5392 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02005393 case VAR_NUMBER:
5394 return PyLong_FromLong((long) tv->vval.v_number);
5395#ifdef FEAT_FLOAT
5396 case VAR_FLOAT:
5397 return PyFloat_FromDouble((double) tv->vval.v_float);
5398#endif
5399 case VAR_LIST:
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005400 return NEW_LIST(tv->vval.v_list);
Bram Moolenaardb913952012-06-29 12:54:53 +02005401 case VAR_DICT:
Bram Moolenaara9922d62013-05-30 13:01:18 +02005402 return NEW_DICTIONARY(tv->vval.v_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02005403 case VAR_FUNC:
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005404 return NEW_FUNCTION(tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02005405 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02005406 case VAR_UNKNOWN:
5407 Py_INCREF(Py_None);
5408 return Py_None;
5409 default:
Bram Moolenaar0bd80cc2013-06-23 13:28:17 +02005410 PyErr_SET_VIM("internal error: invalid value type");
Bram Moolenaardb913952012-06-29 12:54:53 +02005411 return NULL;
5412 }
5413}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005414
5415typedef struct
5416{
5417 PyObject_HEAD
5418} CurrentObject;
5419static PyTypeObject CurrentType;
5420
5421 static void
5422init_structs(void)
5423{
5424 vim_memset(&OutputType, 0, sizeof(OutputType));
5425 OutputType.tp_name = "vim.message";
5426 OutputType.tp_basicsize = sizeof(OutputObject);
5427 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
5428 OutputType.tp_doc = "vim message object";
5429 OutputType.tp_methods = OutputMethods;
5430#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005431 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
5432 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005433 OutputType.tp_alloc = call_PyType_GenericAlloc;
5434 OutputType.tp_new = call_PyType_GenericNew;
5435 OutputType.tp_free = call_PyObject_Free;
5436#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005437 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
5438 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005439#endif
5440
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005441 vim_memset(&IterType, 0, sizeof(IterType));
5442 IterType.tp_name = "vim.iter";
5443 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005444 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005445 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005446 IterType.tp_iter = (getiterfunc)IterIter;
5447 IterType.tp_iternext = (iternextfunc)IterNext;
5448 IterType.tp_dealloc = (destructor)IterDestructor;
5449 IterType.tp_traverse = (traverseproc)IterTraverse;
5450 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005451
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005452 vim_memset(&BufferType, 0, sizeof(BufferType));
5453 BufferType.tp_name = "vim.buffer";
5454 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005455 BufferType.tp_dealloc = (destructor)BufferDestructor;
5456 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005457 BufferType.tp_as_sequence = &BufferAsSeq;
5458 BufferType.tp_as_mapping = &BufferAsMapping;
5459 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
5460 BufferType.tp_doc = "vim buffer object";
5461 BufferType.tp_methods = BufferMethods;
5462#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005463 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005464 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005465 BufferType.tp_alloc = call_PyType_GenericAlloc;
5466 BufferType.tp_new = call_PyType_GenericNew;
5467 BufferType.tp_free = call_PyObject_Free;
5468#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005469 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02005470 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005471#endif
5472
5473 vim_memset(&WindowType, 0, sizeof(WindowType));
5474 WindowType.tp_name = "vim.window";
5475 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005476 WindowType.tp_dealloc = (destructor)WindowDestructor;
5477 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005478 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005479 WindowType.tp_doc = "vim Window object";
5480 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005481 WindowType.tp_traverse = (traverseproc)WindowTraverse;
5482 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005483#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005484 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
5485 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005486 WindowType.tp_alloc = call_PyType_GenericAlloc;
5487 WindowType.tp_new = call_PyType_GenericNew;
5488 WindowType.tp_free = call_PyObject_Free;
5489#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005490 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
5491 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005492#endif
5493
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005494 vim_memset(&TabPageType, 0, sizeof(TabPageType));
5495 TabPageType.tp_name = "vim.tabpage";
5496 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005497 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
5498 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005499 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
5500 TabPageType.tp_doc = "vim tab page object";
5501 TabPageType.tp_methods = TabPageMethods;
5502#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005503 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005504 TabPageType.tp_alloc = call_PyType_GenericAlloc;
5505 TabPageType.tp_new = call_PyType_GenericNew;
5506 TabPageType.tp_free = call_PyObject_Free;
5507#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005508 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005509#endif
5510
Bram Moolenaardfa38d42013-05-15 13:38:47 +02005511 vim_memset(&BufMapType, 0, sizeof(BufMapType));
5512 BufMapType.tp_name = "vim.bufferlist";
5513 BufMapType.tp_basicsize = sizeof(BufMapObject);
5514 BufMapType.tp_as_mapping = &BufMapAsMapping;
5515 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005516 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005517 BufferType.tp_doc = "vim buffer list";
5518
5519 vim_memset(&WinListType, 0, sizeof(WinListType));
5520 WinListType.tp_name = "vim.windowlist";
5521 WinListType.tp_basicsize = sizeof(WinListType);
5522 WinListType.tp_as_sequence = &WinListAsSeq;
5523 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
5524 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005525 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02005526
5527 vim_memset(&TabListType, 0, sizeof(TabListType));
5528 TabListType.tp_name = "vim.tabpagelist";
5529 TabListType.tp_basicsize = sizeof(TabListType);
5530 TabListType.tp_as_sequence = &TabListAsSeq;
5531 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
5532 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005533
5534 vim_memset(&RangeType, 0, sizeof(RangeType));
5535 RangeType.tp_name = "vim.range";
5536 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005537 RangeType.tp_dealloc = (destructor)RangeDestructor;
5538 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005539 RangeType.tp_as_sequence = &RangeAsSeq;
5540 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02005541 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005542 RangeType.tp_doc = "vim Range object";
5543 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02005544 RangeType.tp_traverse = (traverseproc)RangeTraverse;
5545 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005546#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005547 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005548 RangeType.tp_alloc = call_PyType_GenericAlloc;
5549 RangeType.tp_new = call_PyType_GenericNew;
5550 RangeType.tp_free = call_PyObject_Free;
5551#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005552 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005553#endif
5554
5555 vim_memset(&CurrentType, 0, sizeof(CurrentType));
5556 CurrentType.tp_name = "vim.currentdata";
5557 CurrentType.tp_basicsize = sizeof(CurrentObject);
5558 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
5559 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02005560 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005561#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005562 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
5563 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005564#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005565 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
5566 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005567#endif
5568
5569 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
5570 DictionaryType.tp_name = "vim.dictionary";
5571 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005572 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005573 DictionaryType.tp_as_sequence = &DictionaryAsSeq;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005574 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005575 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005576 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
5577 DictionaryType.tp_methods = DictionaryMethods;
Bram Moolenaara9922d62013-05-30 13:01:18 +02005578 DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
5579 DictionaryType.tp_new = (newfunc)DictionaryConstructor;
5580 DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005581#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005582 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
5583 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005584#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005585 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
5586 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005587#endif
5588
5589 vim_memset(&ListType, 0, sizeof(ListType));
5590 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02005591 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005592 ListType.tp_basicsize = sizeof(ListObject);
5593 ListType.tp_as_sequence = &ListAsSeq;
5594 ListType.tp_as_mapping = &ListAsMapping;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005595 ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005596 ListType.tp_doc = "list pushing modifications to vim structure";
5597 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005598 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar78cddbe2013-05-30 13:05:58 +02005599 ListType.tp_new = (newfunc)ListConstructor;
5600 ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005601#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005602 ListType.tp_getattro = (getattrofunc)ListGetattro;
5603 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005604#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005605 ListType.tp_getattr = (getattrfunc)ListGetattr;
5606 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005607#endif
5608
5609 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02005610 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005611 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02005612 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
5613 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005614 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005615 FunctionType.tp_doc = "object that calls vim function";
5616 FunctionType.tp_methods = FunctionMethods;
Bram Moolenaara5b725c2013-05-30 12:43:54 +02005617 FunctionType.tp_repr = (reprfunc)FunctionRepr;
Bram Moolenaar355fd9b2013-05-30 13:14:13 +02005618 FunctionType.tp_new = (newfunc)FunctionConstructor;
5619 FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005620#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02005621 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005622#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02005623 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005624#endif
5625
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005626 vim_memset(&OptionsType, 0, sizeof(OptionsType));
5627 OptionsType.tp_name = "vim.options";
5628 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02005629 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005630 OptionsType.tp_doc = "object for manipulating options";
5631 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02005632 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
5633 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
5634 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02005635
Bram Moolenaar81c40c52013-06-12 14:41:04 +02005636 vim_memset(&LoaderType, 0, sizeof(LoaderType));
5637 LoaderType.tp_name = "vim.Loader";
5638 LoaderType.tp_basicsize = sizeof(LoaderObject);
5639 LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
5640 LoaderType.tp_doc = "vim message object";
5641 LoaderType.tp_methods = LoaderMethods;
5642 LoaderType.tp_dealloc = (destructor)LoaderDestructor;
5643
Bram Moolenaar4d1da492013-04-24 13:39:15 +02005644#if PY_MAJOR_VERSION >= 3
5645 vim_memset(&vimmodule, 0, sizeof(vimmodule));
5646 vimmodule.m_name = "vim";
5647 vimmodule.m_doc = "Vim Python interface\n";
5648 vimmodule.m_size = -1;
5649 vimmodule.m_methods = VimMethods;
5650#endif
5651}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005652
5653#define PYTYPE_READY(type) \
5654 if (PyType_Ready(&type)) \
5655 return -1;
5656
5657 static int
5658init_types()
5659{
5660 PYTYPE_READY(IterType);
5661 PYTYPE_READY(BufferType);
5662 PYTYPE_READY(RangeType);
5663 PYTYPE_READY(WindowType);
5664 PYTYPE_READY(TabPageType);
5665 PYTYPE_READY(BufMapType);
5666 PYTYPE_READY(WinListType);
5667 PYTYPE_READY(TabListType);
5668 PYTYPE_READY(CurrentType);
5669 PYTYPE_READY(DictionaryType);
5670 PYTYPE_READY(ListType);
5671 PYTYPE_READY(FunctionType);
5672 PYTYPE_READY(OptionsType);
5673 PYTYPE_READY(OutputType);
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02005674 PYTYPE_READY(LoaderType);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005675 return 0;
5676}
5677
5678 static int
Bram Moolenaar5ab9d982013-06-16 14:25:57 +02005679init_sys_path(void)
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005680{
5681 PyObject *path;
5682 PyObject *path_hook;
5683 PyObject *path_hooks;
5684
5685 if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
5686 return -1;
5687
5688 if (!(path_hooks = PySys_GetObject("path_hooks")))
5689 {
5690 PyErr_Clear();
5691 path_hooks = PyList_New(1);
5692 PyList_SET_ITEM(path_hooks, 0, path_hook);
5693 if (PySys_SetObject("path_hooks", path_hooks))
5694 {
5695 Py_DECREF(path_hooks);
5696 return -1;
5697 }
5698 Py_DECREF(path_hooks);
5699 }
5700 else if (PyList_Check(path_hooks))
5701 {
5702 if (PyList_Append(path_hooks, path_hook))
5703 {
5704 Py_DECREF(path_hook);
5705 return -1;
5706 }
5707 Py_DECREF(path_hook);
5708 }
5709 else
5710 {
5711 VimTryStart();
5712 EMSG(_("Failed to set path hook: sys.path_hooks is not a list\n"
5713 "You should now do the following:\n"
5714 "- append vim.path_hook to sys.path_hooks\n"
5715 "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
5716 VimTryEnd(); /* Discard the error */
5717 Py_DECREF(path_hook);
5718 return 0;
5719 }
5720
5721 if (!(path = PySys_GetObject("path")))
5722 {
5723 PyErr_Clear();
5724 path = PyList_New(1);
5725 Py_INCREF(vim_special_path_object);
5726 PyList_SET_ITEM(path, 0, vim_special_path_object);
5727 if (PySys_SetObject("path", path))
5728 {
5729 Py_DECREF(path);
5730 return -1;
5731 }
5732 Py_DECREF(path);
5733 }
5734 else if (PyList_Check(path))
5735 {
5736 if (PyList_Append(path, vim_special_path_object))
5737 return -1;
5738 }
5739 else
5740 {
5741 VimTryStart();
5742 EMSG(_("Failed to set path: sys.path is not a list\n"
5743 "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
5744 VimTryEnd(); /* Discard the error */
5745 }
5746
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005747 return 0;
5748}
5749
5750static BufMapObject TheBufferMap =
5751{
5752 PyObject_HEAD_INIT(&BufMapType)
5753};
5754
5755static WinListObject TheWindowList =
5756{
5757 PyObject_HEAD_INIT(&WinListType)
5758 NULL
5759};
5760
5761static CurrentObject TheCurrent =
5762{
5763 PyObject_HEAD_INIT(&CurrentType)
5764};
5765
5766static TabListObject TheTabPageList =
5767{
5768 PyObject_HEAD_INIT(&TabListType)
5769};
5770
5771static struct numeric_constant {
5772 char *name;
5773 int value;
5774} numeric_constants[] = {
5775 {"VAR_LOCKED", VAR_LOCKED},
5776 {"VAR_FIXED", VAR_FIXED},
5777 {"VAR_SCOPE", VAR_SCOPE},
5778 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
5779};
5780
5781static struct object_constant {
5782 char *name;
5783 PyObject *value;
5784} object_constants[] = {
5785 {"buffers", (PyObject *)(void *)&TheBufferMap},
5786 {"windows", (PyObject *)(void *)&TheWindowList},
5787 {"tabpages", (PyObject *)(void *)&TheTabPageList},
5788 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02005789
5790 {"Buffer", (PyObject *)&BufferType},
5791 {"Range", (PyObject *)&RangeType},
5792 {"Window", (PyObject *)&WindowType},
5793 {"TabPage", (PyObject *)&TabPageType},
5794 {"Dictionary", (PyObject *)&DictionaryType},
5795 {"List", (PyObject *)&ListType},
5796 {"Function", (PyObject *)&FunctionType},
5797 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar81c40c52013-06-12 14:41:04 +02005798 {"_Loader", (PyObject *)&LoaderType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005799};
5800
5801typedef int (*object_adder)(PyObject *, const char *, PyObject *);
Bram Moolenaarf4258302013-06-02 18:20:17 +02005802typedef PyObject *(*attr_getter)(PyObject *, const char *);
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005803
5804#define ADD_OBJECT(m, name, obj) \
5805 if (add_object(m, name, obj)) \
5806 return -1;
5807
5808#define ADD_CHECKED_OBJECT(m, name, obj) \
5809 { \
5810 PyObject *value = obj; \
5811 if (!value) \
5812 return -1; \
5813 ADD_OBJECT(m, name, value); \
5814 }
5815
5816 static int
Bram Moolenaarf4258302013-06-02 18:20:17 +02005817populate_module(PyObject *m, object_adder add_object, attr_getter get_attr)
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005818{
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02005819 int i;
5820 PyObject *other_module;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02005821 PyObject *attr;
Bram Moolenaar81c40c52013-06-12 14:41:04 +02005822 PyObject *imp;
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005823
5824 for (i = 0; i < (int)(sizeof(numeric_constants)
5825 / sizeof(struct numeric_constant));
5826 ++i)
5827 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
5828 PyInt_FromLong(numeric_constants[i].value));
5829
5830 for (i = 0; i < (int)(sizeof(object_constants)
5831 / sizeof(struct object_constant));
5832 ++i)
5833 {
5834 PyObject *value;
5835
5836 value = object_constants[i].value;
5837 Py_INCREF(value);
5838 ADD_OBJECT(m, object_constants[i].name, value);
5839 }
5840
5841 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
5842 return -1;
5843 ADD_OBJECT(m, "error", VimError);
5844
Bram Moolenaara9922d62013-05-30 13:01:18 +02005845 ADD_CHECKED_OBJECT(m, "vars", NEW_DICTIONARY(&globvardict));
5846 ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(&vimvardict));
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005847 ADD_CHECKED_OBJECT(m, "options",
5848 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
Bram Moolenaarf4258302013-06-02 18:20:17 +02005849
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02005850 if (!(other_module = PyImport_ImportModule("os")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02005851 return -1;
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02005852 ADD_OBJECT(m, "os", other_module);
Bram Moolenaarf4258302013-06-02 18:20:17 +02005853
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02005854 if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02005855 return -1;
5856 ADD_OBJECT(m, "_getcwd", py_getcwd)
5857
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02005858 if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02005859 return -1;
5860 ADD_OBJECT(m, "_chdir", py_chdir);
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02005861 if (!(attr = get_attr(m, "chdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02005862 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02005863 if (PyObject_SetAttrString(other_module, "chdir", attr))
5864 {
5865 Py_DECREF(attr);
5866 return -1;
5867 }
5868 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02005869
Bram Moolenaarc1ba10c2013-06-10 20:39:03 +02005870 if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02005871 {
5872 ADD_OBJECT(m, "_fchdir", py_fchdir);
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02005873 if (!(attr = get_attr(m, "fchdir")))
Bram Moolenaarf4258302013-06-02 18:20:17 +02005874 return -1;
Bram Moolenaarf9c9b322013-06-10 20:47:36 +02005875 if (PyObject_SetAttrString(other_module, "fchdir", attr))
5876 {
5877 Py_DECREF(attr);
5878 return -1;
5879 }
5880 Py_DECREF(attr);
Bram Moolenaarf4258302013-06-02 18:20:17 +02005881 }
Bram Moolenaare9056b12013-06-03 20:04:48 +02005882 else
5883 PyErr_Clear();
Bram Moolenaarf4258302013-06-02 18:20:17 +02005884
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005885 if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
5886 return -1;
5887
5888 ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
5889
Bram Moolenaar81c40c52013-06-12 14:41:04 +02005890 if (!(imp = PyImport_ImportModule("imp")))
5891 return -1;
5892
5893 if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
5894 {
5895 Py_DECREF(imp);
5896 return -1;
5897 }
5898
5899 if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
5900 {
5901 Py_DECREF(py_find_module);
5902 Py_DECREF(imp);
5903 return -1;
5904 }
5905
5906 Py_DECREF(imp);
5907
Bram Moolenaar9f3685a2013-06-12 14:20:36 +02005908 ADD_OBJECT(m, "_find_module", py_find_module);
5909 ADD_OBJECT(m, "_load_module", py_load_module);
Bram Moolenaarc09a6d62013-06-10 21:27:29 +02005910
Bram Moolenaar1dc28782013-05-21 19:11:01 +02005911 return 0;
5912}