xref: /vim-8.2.3635/src/if_py_both.h (revision 7a3fe3e1)
1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 /*
10  * Python extensions by Paul Moore, David Leonard, Roland Puntaier, Nikolay
11  * Pavlov.
12  *
13  * Common code for if_python.c and if_python3.c.
14  */
15 
16 static char_u e_py_systemexit[]	= "E880: Can't handle SystemExit of %s exception in vim";
17 
18 #if PY_VERSION_HEX < 0x02050000
19 typedef int Py_ssize_t;  // Python 2.4 and earlier don't have this type.
20 #endif
21 
22 // Use values that are known to work, others may make Vim crash.
23 #define ENC_OPT (enc_utf8 ? "utf-8" : enc_dbcs ? "euc-jp" : (char *)p_enc)
24 #define DOPY_FUNC "_vim_pydo"
25 
26 static const char *vim_special_path = "_vim_path_";
27 
28 #define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
29 #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
30 #define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
31 #define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg)
32 #define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2)
33 #define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg)
34 
35 #define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
36 	? "(NULL)" \
37 	: obj->ob_type->tp_name)
38 
39 #define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
40 					    N_("empty keys are not allowed"))
41 #define RAISE_LOCKED_DICTIONARY PyErr_SET_VIM(N_("dictionary is locked"))
42 #define RAISE_LOCKED_LIST PyErr_SET_VIM(N_("list is locked"))
43 #define RAISE_UNDO_FAIL PyErr_SET_VIM(N_("cannot save undo information"))
44 #define RAISE_DELETE_LINE_FAIL PyErr_SET_VIM(N_("cannot delete line"))
45 #define RAISE_INSERT_LINE_FAIL PyErr_SET_VIM(N_("cannot insert line"))
46 #define RAISE_REPLACE_LINE_FAIL PyErr_SET_VIM(N_("cannot replace line"))
47 #define RAISE_KEY_ADD_FAIL(key) \
48     PyErr_VIM_FORMAT(N_("failed to add key '%s' to dictionary"), key)
49 #define RAISE_INVALID_INDEX_TYPE(idx) \
50     PyErr_FORMAT(PyExc_TypeError, N_("index must be int or slice, not %s"), \
51 	    Py_TYPE_NAME(idx));
52 
53 #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
54 #define INVALID_WINDOW_VALUE ((win_T *)(-1))
55 #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
56 
57 typedef void (*rangeinitializer)(void *);
58 typedef void (*runner)(const char *, void *
59 #ifdef PY_CAN_RECURSE
60 	, PyGILState_STATE *
61 #endif
62 	);
63 
64 static int ConvertFromPyObject(PyObject *, typval_T *);
65 static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
66 static int ConvertFromPyMapping(PyObject *, typval_T *);
67 static int ConvertFromPySequence(PyObject *, typval_T *);
68 static PyObject *WindowNew(win_T *, tabpage_T *);
69 static PyObject *BufferNew (buf_T *);
70 static PyObject *LineToString(const char *);
71 
72 static PyInt RangeStart;
73 static PyInt RangeEnd;
74 
75 static PyObject *globals;
76 
77 static PyObject *py_chdir;
78 static PyObject *py_fchdir;
79 static PyObject *py_getcwd;
80 static PyObject *vim_module;
81 static PyObject *vim_special_path_object;
82 
83 #if PY_VERSION_HEX >= 0x030700f0
84 static PyObject *py_find_spec;
85 #else
86 static PyObject *py_load_module;
87 #endif
88 static PyObject *py_find_module;
89 
90 static PyObject *VimError;
91 
92 /*
93  * obtain a lock on the Vim data structures
94  */
95     static void
Python_Lock_Vim(void)96 Python_Lock_Vim(void)
97 {
98 }
99 
100 /*
101  * release a lock on the Vim data structures
102  */
103     static void
Python_Release_Vim(void)104 Python_Release_Vim(void)
105 {
106 }
107 
108 /*
109  * The "todecref" argument holds a pointer to PyObject * that must be
110  * DECREF'ed after returned char_u * is no longer needed or NULL if all what
111  * was needed to generate returned value is object.
112  *
113  * Use Py_XDECREF to decrement reference count.
114  */
115     static char_u *
StringToChars(PyObject * obj,PyObject ** todecref)116 StringToChars(PyObject *obj, PyObject **todecref)
117 {
118     char_u	*str;
119 
120     if (PyBytes_Check(obj))
121     {
122 
123 	if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1
124 		|| str == NULL)
125 	    return NULL;
126 
127 	*todecref = NULL;
128     }
129     else if (PyUnicode_Check(obj))
130     {
131 	PyObject	*bytes;
132 
133 	if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT,
134 							   ERRORS_ENCODE_ARG)))
135 	    return NULL;
136 
137 	if (PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1
138 		|| str == NULL)
139 	{
140 	    Py_DECREF(bytes);
141 	    return NULL;
142 	}
143 
144 	*todecref = bytes;
145     }
146     else
147     {
148 #if PY_MAJOR_VERSION < 3
149 	PyErr_FORMAT(PyExc_TypeError,
150 		N_("expected str() or unicode() instance, but got %s"),
151 		Py_TYPE_NAME(obj));
152 #else
153 	PyErr_FORMAT(PyExc_TypeError,
154 		N_("expected bytes() or str() instance, but got %s"),
155 		Py_TYPE_NAME(obj));
156 #endif
157 	return NULL;
158     }
159 
160     return (char_u *) str;
161 }
162 
163 #define NUMBER_LONG     1
164 #define NUMBER_INT      2
165 #define NUMBER_NATURAL  4
166 #define NUMBER_UNSIGNED 8
167 
168     static int
NumberToLong(PyObject * obj,long * result,int flags)169 NumberToLong(PyObject *obj, long *result, int flags)
170 {
171 #if PY_MAJOR_VERSION < 3
172     if (PyInt_Check(obj))
173     {
174 	*result = PyInt_AsLong(obj);
175 	if (PyErr_Occurred())
176 	    return -1;
177     }
178     else
179 #endif
180     if (PyLong_Check(obj))
181     {
182 	*result = PyLong_AsLong(obj);
183 	if (PyErr_Occurred())
184 	    return -1;
185     }
186     else if (PyNumber_Check(obj))
187     {
188 	PyObject	*num;
189 
190 	if (!(num = PyNumber_Long(obj)))
191 	    return -1;
192 
193 	*result = PyLong_AsLong(num);
194 
195 	Py_DECREF(num);
196 
197 	if (PyErr_Occurred())
198 	    return -1;
199     }
200     else
201     {
202 #if PY_MAJOR_VERSION < 3
203 	PyErr_FORMAT(PyExc_TypeError,
204 		N_("expected int(), long() or something supporting "
205 		   "coercing to long(), but got %s"),
206 		Py_TYPE_NAME(obj));
207 #else
208 	PyErr_FORMAT(PyExc_TypeError,
209 		N_("expected int() or something supporting coercing to int(), "
210 		   "but got %s"),
211 		Py_TYPE_NAME(obj));
212 #endif
213 	return -1;
214     }
215 
216     if (flags & NUMBER_INT)
217     {
218 	if (*result > INT_MAX)
219 	{
220 	    PyErr_SET_STRING(PyExc_OverflowError,
221 		    N_("value is too large to fit into C int type"));
222 	    return -1;
223 	}
224 	else if (*result < INT_MIN)
225 	{
226 	    PyErr_SET_STRING(PyExc_OverflowError,
227 		    N_("value is too small to fit into C int type"));
228 	    return -1;
229 	}
230     }
231 
232     if (flags & NUMBER_NATURAL)
233     {
234 	if (*result <= 0)
235 	{
236 	    PyErr_SET_STRING(PyExc_ValueError,
237 		    N_("number must be greater than zero"));
238 	    return -1;
239 	}
240     }
241     else if (flags & NUMBER_UNSIGNED)
242     {
243 	if (*result < 0)
244 	{
245 	    PyErr_SET_STRING(PyExc_ValueError,
246 		    N_("number must be greater or equal to zero"));
247 	    return -1;
248 	}
249     }
250 
251     return 0;
252 }
253 
254     static int
add_string(PyObject * list,char * s)255 add_string(PyObject *list, char *s)
256 {
257     PyObject	*string;
258 
259     if (!(string = PyString_FromString(s)))
260 	return -1;
261 
262     if (PyList_Append(list, string))
263     {
264 	Py_DECREF(string);
265 	return -1;
266     }
267 
268     Py_DECREF(string);
269     return 0;
270 }
271 
272     static PyObject *
ObjectDir(PyObject * self,char ** attributes)273 ObjectDir(PyObject *self, char **attributes)
274 {
275     PyMethodDef	*method;
276     char	**attr;
277     PyObject	*ret;
278 
279     if (!(ret = PyList_New(0)))
280 	return NULL;
281 
282     if (self)
283 	for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
284 	    if (add_string(ret, (char *)method->ml_name))
285 	    {
286 		Py_DECREF(ret);
287 		return NULL;
288 	    }
289 
290     for (attr = attributes ; *attr ; ++attr)
291 	if (add_string(ret, *attr))
292 	{
293 	    Py_DECREF(ret);
294 	    return NULL;
295 	}
296 
297 #if PY_MAJOR_VERSION < 3
298     if (add_string(ret, "__members__"))
299     {
300 	Py_DECREF(ret);
301 	return NULL;
302     }
303 #endif
304 
305     return ret;
306 }
307 
308 // Output buffer management
309 
310 // Function to write a line, points to either msg() or emsg().
311 typedef int (*writefn)(char *);
312 
313 static PyTypeObject OutputType;
314 
315 typedef struct
316 {
317     PyObject_HEAD
318     long softspace;
319     long error;
320 } OutputObject;
321 
322 static char *OutputAttrs[] = {
323     "softspace",
324     NULL
325 };
326 
327     static PyObject *
OutputDir(PyObject * self,PyObject * args UNUSED)328 OutputDir(PyObject *self, PyObject *args UNUSED)
329 {
330     return ObjectDir(self, OutputAttrs);
331 }
332 
333     static int
OutputSetattr(OutputObject * self,char * name,PyObject * valObject)334 OutputSetattr(OutputObject *self, char *name, PyObject *valObject)
335 {
336     if (valObject == NULL)
337     {
338 	PyErr_SET_STRING(PyExc_AttributeError,
339 		N_("can't delete OutputObject attributes"));
340 	return -1;
341     }
342 
343     if (strcmp(name, "softspace") == 0)
344     {
345 	if (NumberToLong(valObject, &(self->softspace), NUMBER_UNSIGNED))
346 	    return -1;
347 	return 0;
348     }
349 
350     PyErr_FORMAT(PyExc_AttributeError, N_("invalid attribute: %s"), name);
351     return -1;
352 }
353 
354 // Buffer IO, we write one whole line at a time.
355 static garray_T io_ga = {0, 0, 1, 80, NULL};
356 static writefn old_fn = NULL;
357 
358     static void
PythonIO_Flush(void)359 PythonIO_Flush(void)
360 {
361     if (old_fn != NULL && io_ga.ga_len > 0)
362     {
363 	((char *)io_ga.ga_data)[io_ga.ga_len] = NUL;
364 	old_fn((char *)io_ga.ga_data);
365     }
366     io_ga.ga_len = 0;
367 }
368 
369     static void
writer(writefn fn,char_u * str,PyInt n)370 writer(writefn fn, char_u *str, PyInt n)
371 {
372     char_u *ptr;
373 
374     // Flush when switching output function.
375     if (fn != old_fn)
376 	PythonIO_Flush();
377     old_fn = fn;
378 
379     // Write each NL separated line.  Text after the last NL is kept for
380     // writing later.
381     // For normal messages: Do not output when "got_int" was set.  This avoids
382     // a loop gone crazy flooding the terminal with messages.  Also for when
383     // "q" is pressed at the more-prompt.
384     while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL
385 					  && (fn == (writefn)emsg || !got_int))
386     {
387 	PyInt len = ptr - str;
388 
389 	if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
390 	    break;
391 
392 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
393 	((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
394 	fn((char *)io_ga.ga_data);
395 	str = ptr + 1;
396 	n -= len + 1;
397 	io_ga.ga_len = 0;
398     }
399 
400     // Put the remaining text into io_ga for later printing.
401     if (n > 0 && (fn == (writefn)emsg || !got_int)
402 					&& ga_grow(&io_ga, (int)(n + 1)) == OK)
403     {
404 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
405 	io_ga.ga_len += (int)n;
406     }
407 }
408 
409     static int
write_output(OutputObject * self,PyObject * string)410 write_output(OutputObject *self, PyObject *string)
411 {
412     Py_ssize_t	len = 0;
413     char	*str = NULL;
414     int		error = self->error;
415 
416     if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
417 	return -1;
418 
419     Py_BEGIN_ALLOW_THREADS
420     Python_Lock_Vim();
421     if (error)
422 	emsg_severe = TRUE;
423     writer((writefn)(error ? emsg : msg), (char_u *)str, len);
424     Python_Release_Vim();
425     Py_END_ALLOW_THREADS
426     PyMem_Free(str);
427 
428     return 0;
429 }
430 
431     static PyObject *
OutputWrite(OutputObject * self,PyObject * string)432 OutputWrite(OutputObject *self, PyObject *string)
433 {
434     if (write_output(self, string))
435 	return NULL;
436 
437     Py_INCREF(Py_None);
438     return Py_None;
439 }
440 
441     static PyObject *
OutputWritelines(OutputObject * self,PyObject * seq)442 OutputWritelines(OutputObject *self, PyObject *seq)
443 {
444     PyObject	*iterator;
445     PyObject	*item;
446 
447     if (!(iterator = PyObject_GetIter(seq)))
448 	return NULL;
449 
450     while ((item = PyIter_Next(iterator)))
451     {
452 	if (write_output(self, item))
453 	{
454 	    Py_DECREF(iterator);
455 	    Py_DECREF(item);
456 	    return NULL;
457 	}
458 	Py_DECREF(item);
459     }
460 
461     Py_DECREF(iterator);
462 
463     // Iterator may have finished due to an exception
464     if (PyErr_Occurred())
465 	return NULL;
466 
467     Py_INCREF(Py_None);
468     return Py_None;
469 }
470 
471     static PyObject *
AlwaysNone(PyObject * self UNUSED,PyObject * args UNUSED)472 AlwaysNone(PyObject *self UNUSED, PyObject *args UNUSED)
473 {
474     // do nothing
475     Py_INCREF(Py_None);
476     return Py_None;
477 }
478 #define ALWAYS_NONE AlwaysNone(NULL, NULL)
479 
480     static PyObject *
AlwaysFalse(PyObject * self UNUSED,PyObject * args UNUSED)481 AlwaysFalse(PyObject *self UNUSED, PyObject *args UNUSED)
482 {
483     // do nothing
484     PyObject	*ret = Py_False;
485     Py_INCREF(ret);
486     return ret;
487 }
488 #define ALWAYS_FALSE AlwaysFalse(NULL, NULL)
489 
490     static PyObject *
AlwaysTrue(PyObject * self UNUSED,PyObject * args UNUSED)491 AlwaysTrue(PyObject *self UNUSED, PyObject *args UNUSED)
492 {
493     // do nothing
494     PyObject	*ret = Py_True;
495     Py_INCREF(ret);
496     return ret;
497 }
498 #define ALWAYS_TRUE AlwaysTrue(NULL, NULL)
499 
500 /***************/
501 
502 static struct PyMethodDef OutputMethods[] = {
503     // name,	    function,				calling,	doc
504     {"write",	    (PyCFunction)OutputWrite,		METH_O,		""},
505     {"writelines",  (PyCFunction)OutputWritelines,	METH_O,		""},
506     {"flush",	    (PyCFunction)AlwaysNone,		METH_NOARGS,	""},
507     {"close",	    (PyCFunction)AlwaysNone,		METH_NOARGS,	""},
508     {"isatty",	    (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
509     {"readable",    (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
510     {"seekable",    (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
511     {"writable",    (PyCFunction)AlwaysTrue,		METH_NOARGS,	""},
512     {"closed",      (PyCFunction)AlwaysFalse,		METH_NOARGS,	""},
513     {"__dir__",	    (PyCFunction)OutputDir,		METH_NOARGS,	""},
514     { NULL,	    NULL,				0,		NULL}
515 };
516 
517 static OutputObject Output =
518 {
519     PyObject_HEAD_INIT(&OutputType)
520     0,
521     0
522 };
523 
524 static OutputObject Error =
525 {
526     PyObject_HEAD_INIT(&OutputType)
527     0,
528     1
529 };
530 
531     static int
PythonIO_Init_io(void)532 PythonIO_Init_io(void)
533 {
534     if (PySys_SetObject("stdout", (PyObject *)(void *)&Output))
535 	return -1;
536     if (PySys_SetObject("stderr", (PyObject *)(void *)&Error))
537 	return -1;
538 
539     if (PyErr_Occurred())
540     {
541 	emsg(_("E264: Python: Error initialising I/O objects"));
542 	return -1;
543     }
544 
545     return 0;
546 }
547 
548 #if PY_VERSION_HEX < 0x030700f0
549 static PyObject *call_load_module(char *name, int len, PyObject *find_module_result);
550 
551 typedef struct
552 {
553     PyObject_HEAD
554     char	*fullname;
555     PyObject	*result;
556 } LoaderObject;
557 static PyTypeObject LoaderType;
558 
559     static void
LoaderDestructor(LoaderObject * self)560 LoaderDestructor(LoaderObject *self)
561 {
562     vim_free(self->fullname);
563     Py_XDECREF(self->result);
564     DESTRUCTOR_FINISH(self);
565 }
566 
567     static PyObject *
LoaderLoadModule(LoaderObject * self,PyObject * args UNUSED)568 LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
569 {
570     char	*fullname = self->fullname;
571     PyObject	*result = self->result;
572     PyObject	*module;
573 
574     if (!fullname)
575     {
576 	module = result ? result : Py_None;
577 	Py_INCREF(module);
578 	return module;
579     }
580 
581     module = call_load_module(fullname, (int)STRLEN(fullname), result);
582 
583     self->fullname = NULL;
584     self->result = module;
585 
586     vim_free(fullname);
587     Py_DECREF(result);
588 
589     if (!module)
590     {
591 	if (PyErr_Occurred())
592 	    return NULL;
593 
594 	Py_INCREF(Py_None);
595 	return Py_None;
596     }
597 
598     Py_INCREF(module);
599     return module;
600 }
601 
602 static struct PyMethodDef LoaderMethods[] = {
603     // name,	    function,				calling,	doc
604     {"load_module", (PyCFunction)LoaderLoadModule,	METH_VARARGS,	""},
605     { NULL,	    NULL,				0,		NULL}
606 };
607 #endif
608 
609 /*
610  * Check to see whether a Vim error has been reported, or a keyboard
611  * interrupt has been detected.
612  */
613     static void
VimTryStart(void)614 VimTryStart(void)
615 {
616     ++trylevel;
617 }
618 
619     static int
VimTryEnd(void)620 VimTryEnd(void)
621 {
622     --trylevel;
623     // Without this it stops processing all subsequent Vim script commands and
624     // generates strange error messages if I e.g. try calling Test() in a cycle
625     did_emsg = FALSE;
626     // Keyboard interrupt should be preferred over anything else
627     if (got_int)
628     {
629 	if (did_throw)
630 	    discard_current_exception();
631 	got_int = FALSE;
632 	PyErr_SetNone(PyExc_KeyboardInterrupt);
633 	return -1;
634     }
635     else if (msg_list != NULL && *msg_list != NULL)
636     {
637 	int	should_free;
638 	char	*msg;
639 
640 	msg = get_exception_string(*msg_list, ET_ERROR, NULL, &should_free);
641 
642 	if (msg == NULL)
643 	{
644 	    PyErr_NoMemory();
645 	    return -1;
646 	}
647 
648 	PyErr_SetVim(msg);
649 
650 	free_global_msglist();
651 
652 	if (should_free)
653 	    vim_free(msg);
654 
655 	return -1;
656     }
657     else if (!did_throw)
658 	return (PyErr_Occurred() ? -1 : 0);
659     // Python exception is preferred over Vim one; unlikely to occur though
660     else if (PyErr_Occurred())
661     {
662 	discard_current_exception();
663 	return -1;
664     }
665     // Finally transform Vim script exception to python one
666     else
667     {
668 	PyErr_SetVim((char *)current_exception->value);
669 	discard_current_exception();
670 	return -1;
671     }
672 }
673 
674     static int
VimCheckInterrupt(void)675 VimCheckInterrupt(void)
676 {
677     if (got_int)
678     {
679 	PyErr_SetNone(PyExc_KeyboardInterrupt);
680 	return 1;
681     }
682     return 0;
683 }
684 
685 // Vim module - Implementation
686 
687     static PyObject *
VimCommand(PyObject * self UNUSED,PyObject * string)688 VimCommand(PyObject *self UNUSED, PyObject *string)
689 {
690     char_u	*cmd;
691     PyObject	*ret;
692     PyObject	*todecref;
693 
694     if (!(cmd = StringToChars(string, &todecref)))
695 	return NULL;
696 
697     Py_BEGIN_ALLOW_THREADS
698     Python_Lock_Vim();
699 
700     VimTryStart();
701     do_cmdline_cmd(cmd);
702     update_screen(VALID);
703 
704     Python_Release_Vim();
705     Py_END_ALLOW_THREADS
706 
707     if (VimTryEnd())
708 	ret = NULL;
709     else
710 	ret = Py_None;
711 
712     Py_XINCREF(ret);
713     Py_XDECREF(todecref);
714     return ret;
715 }
716 
717 /*
718  * Function to translate a typval_T into a PyObject; this will recursively
719  * translate lists/dictionaries into their Python equivalents.
720  *
721  * The depth parameter is to avoid infinite recursion, set it to 1 when
722  * you call VimToPython.
723  */
724     static PyObject *
VimToPython(typval_T * our_tv,int depth,PyObject * lookup_dict)725 VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
726 {
727     PyObject	*ret;
728     PyObject	*newObj;
729     char	ptrBuf[sizeof(void *) * 2 + 3];
730 
731     // Avoid infinite recursion
732     if (depth > 100)
733     {
734 	Py_INCREF(Py_None);
735 	ret = Py_None;
736 	return ret;
737     }
738 
739     // Check if we run into a recursive loop.  The item must be in lookup_dict
740     // then and we can use it again.
741     if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
742 	    || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
743     {
744 	sprintf(ptrBuf, "%p",
745 		our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
746 					   : (void *)our_tv->vval.v_dict);
747 
748 	if ((ret = PyDict_GetItemString(lookup_dict, ptrBuf)))
749 	{
750 	    Py_INCREF(ret);
751 	    return ret;
752 	}
753     }
754 
755     if (our_tv->v_type == VAR_STRING)
756 	ret = PyString_FromString(our_tv->vval.v_string == NULL
757 					? "" : (char *)our_tv->vval.v_string);
758     else if (our_tv->v_type == VAR_NUMBER)
759     {
760 	char buf[NUMBUFLEN];
761 
762 	// For backwards compatibility numbers are stored as strings.
763 	sprintf(buf, "%ld", (long)our_tv->vval.v_number);
764 	ret = PyString_FromString((char *)buf);
765     }
766 #ifdef FEAT_FLOAT
767     else if (our_tv->v_type == VAR_FLOAT)
768     {
769 	char buf[NUMBUFLEN];
770 
771 	sprintf(buf, "%f", our_tv->vval.v_float);
772 	ret = PyString_FromString((char *)buf);
773     }
774 #endif
775     else if (our_tv->v_type == VAR_LIST)
776     {
777 	list_T		*list = our_tv->vval.v_list;
778 	listitem_T	*curr;
779 
780 	if (list == NULL)
781 	    return NULL;
782 
783 	if (!(ret = PyList_New(0)))
784 	    return NULL;
785 
786 	if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
787 	{
788 	    Py_DECREF(ret);
789 	    return NULL;
790 	}
791 
792 	CHECK_LIST_MATERIALIZE(list);
793 	FOR_ALL_LIST_ITEMS(list, curr)
794 	{
795 	    if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
796 	    {
797 		Py_DECREF(ret);
798 		return NULL;
799 	    }
800 	    if (PyList_Append(ret, newObj))
801 	    {
802 		Py_DECREF(newObj);
803 		Py_DECREF(ret);
804 		return NULL;
805 	    }
806 	    Py_DECREF(newObj);
807 	}
808     }
809     else if (our_tv->v_type == VAR_DICT)
810     {
811 
812 	hashtab_T	*ht;
813 	long_u		todo;
814 	hashitem_T	*hi;
815 	dictitem_T	*di;
816 
817 	if (our_tv->vval.v_dict == NULL)
818 	    return NULL;
819 	ht = &our_tv->vval.v_dict->dv_hashtab;
820 
821 	if (!(ret = PyDict_New()))
822 	    return NULL;
823 
824 	if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
825 	{
826 	    Py_DECREF(ret);
827 	    return NULL;
828 	}
829 
830 	todo = ht->ht_used;
831 	for (hi = ht->ht_array; todo > 0; ++hi)
832 	{
833 	    if (!HASHITEM_EMPTY(hi))
834 	    {
835 		--todo;
836 
837 		di = dict_lookup(hi);
838 		if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
839 		{
840 		    Py_DECREF(ret);
841 		    return NULL;
842 		}
843 		if (PyDict_SetItemString(ret, (char *)hi->hi_key, newObj))
844 		{
845 		    Py_DECREF(ret);
846 		    Py_DECREF(newObj);
847 		    return NULL;
848 		}
849 	    }
850 	}
851     }
852     else if (our_tv->v_type == VAR_BOOL)
853     {
854 	if (our_tv->vval.v_number == VVAL_FALSE)
855 	{
856 	    ret = Py_False;
857 	    Py_INCREF(ret);
858 	}
859 	else
860 	{
861 	    ret = Py_True;
862 	    Py_INCREF(ret);
863 	}
864 	return ret;
865     }
866     else if (our_tv->v_type == VAR_SPECIAL)
867     {
868 	Py_INCREF(Py_None);
869 	ret = Py_None;
870 	return ret;
871     }
872     else if (our_tv->v_type == VAR_BLOB)
873 	ret = PyBytes_FromStringAndSize(
874 		(char*) our_tv->vval.v_blob->bv_ga.ga_data,
875 		(Py_ssize_t) our_tv->vval.v_blob->bv_ga.ga_len);
876     else
877     {
878 	Py_INCREF(Py_None);
879 	ret = Py_None;
880     }
881 
882     return ret;
883 }
884 
885     static PyObject *
VimEval(PyObject * self UNUSED,PyObject * args)886 VimEval(PyObject *self UNUSED, PyObject *args)
887 {
888     char_u	*expr;
889     typval_T	*our_tv;
890     PyObject	*string;
891     PyObject	*todecref;
892     PyObject	*ret;
893     PyObject	*lookup_dict;
894 
895     if (!PyArg_ParseTuple(args, "O", &string))
896 	return NULL;
897 
898     if (!(expr = StringToChars(string, &todecref)))
899 	return NULL;
900 
901     Py_BEGIN_ALLOW_THREADS
902     Python_Lock_Vim();
903     VimTryStart();
904     our_tv = eval_expr(expr, NULL);
905     Python_Release_Vim();
906     Py_END_ALLOW_THREADS
907 
908     Py_XDECREF(todecref);
909 
910     if (VimTryEnd())
911 	return NULL;
912 
913     if (our_tv == NULL)
914     {
915 	PyErr_SET_VIM(N_("invalid expression"));
916 	return NULL;
917     }
918 
919     // Convert the Vim type into a Python type.  Create a dictionary that's
920     // used to check for recursive loops.
921     if (!(lookup_dict = PyDict_New()))
922 	ret = NULL;
923     else
924     {
925 	ret = VimToPython(our_tv, 1, lookup_dict);
926 	Py_DECREF(lookup_dict);
927     }
928 
929 
930     Py_BEGIN_ALLOW_THREADS
931     Python_Lock_Vim();
932     free_tv(our_tv);
933     Python_Release_Vim();
934     Py_END_ALLOW_THREADS
935 
936     return ret;
937 }
938 
939 static PyObject *ConvertToPyObject(typval_T *);
940 
941     static PyObject *
VimEvalPy(PyObject * self UNUSED,PyObject * string)942 VimEvalPy(PyObject *self UNUSED, PyObject *string)
943 {
944     typval_T	*our_tv;
945     PyObject	*ret;
946     char_u	*expr;
947     PyObject	*todecref;
948 
949     if (!(expr = StringToChars(string, &todecref)))
950 	return NULL;
951 
952     Py_BEGIN_ALLOW_THREADS
953     Python_Lock_Vim();
954     VimTryStart();
955     our_tv = eval_expr(expr, NULL);
956     Python_Release_Vim();
957     Py_END_ALLOW_THREADS
958 
959     Py_XDECREF(todecref);
960 
961     if (VimTryEnd())
962 	return NULL;
963 
964     if (our_tv == NULL)
965     {
966 	PyErr_SET_VIM(N_("invalid expression"));
967 	return NULL;
968     }
969 
970     ret = ConvertToPyObject(our_tv);
971     Py_BEGIN_ALLOW_THREADS
972     Python_Lock_Vim();
973     free_tv(our_tv);
974     Python_Release_Vim();
975     Py_END_ALLOW_THREADS
976 
977     return ret;
978 }
979 
980     static PyObject *
VimStrwidth(PyObject * self UNUSED,PyObject * string)981 VimStrwidth(PyObject *self UNUSED, PyObject *string)
982 {
983     char_u	*str;
984     PyObject	*todecref;
985     int		len;
986 
987     if (!(str = StringToChars(string, &todecref)))
988 	return NULL;
989 
990     len = mb_string2cells(str, (int)STRLEN(str));
991 
992     Py_XDECREF(todecref);
993 
994     return PyLong_FromLong(len);
995 }
996 
997     static PyObject *
_VimChdir(PyObject * _chdir,PyObject * args,PyObject * kwargs)998 _VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
999 {
1000     PyObject	*ret;
1001     PyObject	*newwd;
1002     PyObject	*todecref;
1003     char_u	*new_dir;
1004 
1005     if (_chdir == NULL)
1006 	return NULL;
1007     if (!(ret = PyObject_Call(_chdir, args, kwargs)))
1008 	return NULL;
1009 
1010     if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
1011     {
1012 	Py_DECREF(ret);
1013 	return NULL;
1014     }
1015 
1016     if (!(new_dir = StringToChars(newwd, &todecref)))
1017     {
1018 	Py_DECREF(ret);
1019 	Py_DECREF(newwd);
1020 	return NULL;
1021     }
1022 
1023     VimTryStart();
1024 
1025     if (vim_chdir(new_dir))
1026     {
1027 	Py_DECREF(ret);
1028 	Py_DECREF(newwd);
1029 	Py_XDECREF(todecref);
1030 
1031 	if (VimTryEnd())
1032 	    return NULL;
1033 
1034 	PyErr_SET_VIM(N_("failed to change directory"));
1035 	return NULL;
1036     }
1037 
1038     Py_DECREF(newwd);
1039     Py_XDECREF(todecref);
1040 
1041     post_chdir(CDSCOPE_GLOBAL);
1042 
1043     if (VimTryEnd())
1044     {
1045 	Py_DECREF(ret);
1046 	return NULL;
1047     }
1048 
1049     return ret;
1050 }
1051 
1052     static PyObject *
VimChdir(PyObject * self UNUSED,PyObject * args,PyObject * kwargs)1053 VimChdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
1054 {
1055     return _VimChdir(py_chdir, args, kwargs);
1056 }
1057 
1058     static PyObject *
VimFchdir(PyObject * self UNUSED,PyObject * args,PyObject * kwargs)1059 VimFchdir(PyObject *self UNUSED, PyObject *args, PyObject *kwargs)
1060 {
1061     return _VimChdir(py_fchdir, args, kwargs);
1062 }
1063 
1064 typedef struct {
1065     PyObject	*callable;
1066     PyObject	*result;
1067 } map_rtp_data;
1068 
1069     static void
map_rtp_callback(char_u * path,void * _data)1070 map_rtp_callback(char_u *path, void *_data)
1071 {
1072     void	**data = (void **) _data;
1073     PyObject	*pathObject;
1074     map_rtp_data	*mr_data = *((map_rtp_data **) data);
1075 
1076     if (!(pathObject = PyString_FromString((char *)path)))
1077     {
1078 	*data = NULL;
1079 	return;
1080     }
1081 
1082     mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
1083 						   pathObject, NULL);
1084 
1085     Py_DECREF(pathObject);
1086 
1087     if (!mr_data->result || mr_data->result != Py_None)
1088 	*data = NULL;
1089     else
1090     {
1091 	Py_DECREF(mr_data->result);
1092 	mr_data->result = NULL;
1093     }
1094 }
1095 
1096     static PyObject *
VimForeachRTP(PyObject * self UNUSED,PyObject * callable)1097 VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
1098 {
1099     map_rtp_data	data;
1100 
1101     data.callable = callable;
1102     data.result = NULL;
1103 
1104     do_in_runtimepath(NULL, 0, &map_rtp_callback, &data);
1105 
1106     if (data.result == NULL)
1107     {
1108 	if (PyErr_Occurred())
1109 	    return NULL;
1110 	else
1111 	{
1112 	    Py_INCREF(Py_None);
1113 	    return Py_None;
1114 	}
1115     }
1116     return data.result;
1117 }
1118 
1119 /*
1120  * _vim_runtimepath_ special path implementation.
1121  */
1122 
1123     static void
map_finder_callback(char_u * path,void * _data)1124 map_finder_callback(char_u *path, void *_data)
1125 {
1126     void	**data = (void **) _data;
1127     PyObject	*list = *((PyObject **) data);
1128     PyObject	*pathObject1, *pathObject2;
1129     char	*pathbuf;
1130     size_t	pathlen;
1131 
1132     pathlen = STRLEN(path);
1133 
1134 #if PY_MAJOR_VERSION < 3
1135 # define PY_MAIN_DIR_STRING "python2"
1136 #else
1137 # define PY_MAIN_DIR_STRING "python3"
1138 #endif
1139 #define PY_ALTERNATE_DIR_STRING "pythonx"
1140 
1141 #define PYTHONX_STRING_LENGTH 7 // STRLEN("pythonx")
1142     if (!(pathbuf = PyMem_New(char,
1143 		    pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
1144     {
1145 	PyErr_NoMemory();
1146 	*data = NULL;
1147 	return;
1148     }
1149 
1150     mch_memmove(pathbuf, path, pathlen + 1);
1151     add_pathsep((char_u *) pathbuf);
1152 
1153     pathlen = STRLEN(pathbuf);
1154     mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
1155 	    PYTHONX_STRING_LENGTH + 1);
1156 
1157     if (!(pathObject1 = PyString_FromString(pathbuf)))
1158     {
1159 	*data = NULL;
1160 	PyMem_Free(pathbuf);
1161 	return;
1162     }
1163 
1164     mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
1165 	    PYTHONX_STRING_LENGTH + 1);
1166 
1167     if (!(pathObject2 = PyString_FromString(pathbuf)))
1168     {
1169 	Py_DECREF(pathObject1);
1170 	PyMem_Free(pathbuf);
1171 	*data = NULL;
1172 	return;
1173     }
1174 
1175     PyMem_Free(pathbuf);
1176 
1177     if (PyList_Append(list, pathObject1)
1178 	    || PyList_Append(list, pathObject2))
1179 	*data = NULL;
1180 
1181     Py_DECREF(pathObject1);
1182     Py_DECREF(pathObject2);
1183 }
1184 
1185     static PyObject *
Vim_GetPaths(PyObject * self UNUSED,PyObject * args UNUSED)1186 Vim_GetPaths(PyObject *self UNUSED, PyObject *args UNUSED)
1187 {
1188     PyObject	*ret;
1189 
1190     if (!(ret = PyList_New(0)))
1191 	return NULL;
1192 
1193     do_in_runtimepath(NULL, 0, &map_finder_callback, ret);
1194 
1195     if (PyErr_Occurred())
1196     {
1197 	Py_DECREF(ret);
1198 	return NULL;
1199     }
1200 
1201     return ret;
1202 }
1203 
1204 #if PY_VERSION_HEX >= 0x030700f0
1205     static PyObject *
FinderFindSpec(PyObject * self,PyObject * args)1206 FinderFindSpec(PyObject *self, PyObject *args)
1207 {
1208     char	*fullname;
1209     PyObject	*paths;
1210     PyObject	*target = Py_None;
1211     PyObject	*spec;
1212 
1213     if (!PyArg_ParseTuple(args, "s|O", &fullname, &target))
1214 	return NULL;
1215 
1216     if (!(paths = Vim_GetPaths(self, NULL)))
1217 	return NULL;
1218 
1219     spec = PyObject_CallFunction(py_find_spec, "sOO", fullname, paths, target);
1220 
1221     Py_DECREF(paths);
1222 
1223     if (!spec)
1224     {
1225 	if (PyErr_Occurred())
1226 	    return NULL;
1227 
1228 	Py_INCREF(Py_None);
1229 	return Py_None;
1230     }
1231 
1232     return spec;
1233 }
1234 
1235     static PyObject *
FinderFindModule(PyObject * self UNUSED,PyObject * args UNUSED)1236 FinderFindModule(PyObject* self UNUSED, PyObject* args UNUSED)
1237 {
1238     // Apparently returning None works.
1239     Py_INCREF(Py_None);
1240     return Py_None;
1241 }
1242 #else
1243     static PyObject *
call_load_module(char * name,int len,PyObject * find_module_result)1244 call_load_module(char *name, int len, PyObject *find_module_result)
1245 {
1246     PyObject	*fd, *pathname, *description;
1247 
1248     if (!PyTuple_Check(find_module_result))
1249     {
1250 	PyErr_FORMAT(PyExc_TypeError,
1251 		N_("expected 3-tuple as imp.find_module() result, but got %s"),
1252 		Py_TYPE_NAME(find_module_result));
1253 	return NULL;
1254     }
1255     if (PyTuple_GET_SIZE(find_module_result) != 3)
1256     {
1257 	PyErr_FORMAT(PyExc_TypeError,
1258 		N_("expected 3-tuple as imp.find_module() result, but got "
1259 		   "tuple of size %d"),
1260 		(int) PyTuple_GET_SIZE(find_module_result));
1261 	return NULL;
1262     }
1263 
1264     if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
1265 	    || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
1266 	    || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
1267     {
1268 	PyErr_SET_STRING(PyExc_RuntimeError,
1269 		N_("internal error: imp.find_module returned tuple with NULL"));
1270 	return NULL;
1271     }
1272 
1273     return PyObject_CallFunction(py_load_module,
1274 	    "s#OOO", name, len, fd, pathname, description);
1275 }
1276 
1277     static PyObject *
find_module(char * fullname,char * tail,PyObject * new_path)1278 find_module(char *fullname, char *tail, PyObject *new_path)
1279 {
1280     PyObject	*find_module_result;
1281     PyObject	*module;
1282     char	*dot;
1283 
1284     if ((dot = (char *)vim_strchr((char_u *) tail, '.')))
1285     {
1286 	/*
1287 	 * There is a dot in the name: call find_module recursively without the
1288 	 * first component
1289 	 */
1290 	PyObject	*newest_path;
1291 	int		partlen = (int) (dot - 1 - tail);
1292 
1293 	if (!(find_module_result = PyObject_CallFunction(py_find_module,
1294 			"s#O", tail, partlen, new_path)))
1295 	{
1296 	    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1297 		PyErr_Clear();
1298 	    return NULL;
1299 	}
1300 
1301 	if (!(module = call_load_module(
1302 			fullname,
1303 			((int) (tail - fullname)) + partlen,
1304 			find_module_result)))
1305 	{
1306 	    Py_DECREF(find_module_result);
1307 	    return NULL;
1308 	}
1309 
1310 	Py_DECREF(find_module_result);
1311 
1312 	if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
1313 	{
1314 	    Py_DECREF(module);
1315 	    return NULL;
1316 	}
1317 
1318 	Py_DECREF(module);
1319 
1320 	find_module_result = find_module(fullname, dot + 1, newest_path);
1321 
1322 	Py_DECREF(newest_path);
1323 
1324 	return find_module_result;
1325     }
1326     else
1327     {
1328 	if (!(find_module_result = PyObject_CallFunction(py_find_module,
1329 			"sO", tail, new_path)))
1330 	{
1331 	    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_ImportError))
1332 		PyErr_Clear();
1333 	    return NULL;
1334 	}
1335 
1336 	return find_module_result;
1337     }
1338 }
1339 
1340     static PyObject *
FinderFindModule(PyObject * self,PyObject * args)1341 FinderFindModule(PyObject *self, PyObject *args)
1342 {
1343     char	*fullname;
1344     PyObject	*result;
1345     PyObject	*new_path;
1346     LoaderObject	*loader;
1347 
1348     if (!PyArg_ParseTuple(args, "s", &fullname))
1349 	return NULL;
1350 
1351     if (!(new_path = Vim_GetPaths(self, NULL)))
1352 	return NULL;
1353 
1354     result = find_module(fullname, fullname, new_path);
1355 
1356     Py_DECREF(new_path);
1357 
1358     if (!result)
1359     {
1360 	if (PyErr_Occurred())
1361 	    return NULL;
1362 
1363 	Py_INCREF(Py_None);
1364 	return Py_None;
1365     }
1366 
1367     if (!(fullname = (char *)vim_strsave((char_u *)fullname)))
1368     {
1369 	Py_DECREF(result);
1370 	PyErr_NoMemory();
1371 	return NULL;
1372     }
1373 
1374     if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
1375     {
1376 	vim_free(fullname);
1377 	Py_DECREF(result);
1378 	return NULL;
1379     }
1380 
1381     loader->fullname = fullname;
1382     loader->result = result;
1383 
1384     return (PyObject *) loader;
1385 }
1386 #endif
1387 
1388     static PyObject *
VimPathHook(PyObject * self UNUSED,PyObject * args)1389 VimPathHook(PyObject *self UNUSED, PyObject *args)
1390 {
1391     char	*path;
1392 
1393     if (PyArg_ParseTuple(args, "s", &path)
1394 	    && STRCMP(path, vim_special_path) == 0)
1395     {
1396 	Py_INCREF(vim_module);
1397 	return vim_module;
1398     }
1399 
1400     PyErr_Clear();
1401     PyErr_SetNone(PyExc_ImportError);
1402     return NULL;
1403 }
1404 
1405 /*
1406  * Vim module - Definitions
1407  */
1408 
1409 static struct PyMethodDef VimMethods[] = {
1410     // name,	    function,			calling,			documentation
1411     {"command",	    VimCommand,			METH_O,				"Execute a Vim ex-mode command" },
1412     {"eval",	    VimEval,			METH_VARARGS,			"Evaluate an expression using Vim evaluator" },
1413     {"bindeval",    VimEvalPy,			METH_O,				"Like eval(), but returns objects attached to Vim ones"},
1414     {"strwidth",    VimStrwidth,		METH_O,				"Screen string width, counts <Tab> as having width 1"},
1415     {"chdir",	    (PyCFunction)(void *)VimChdir,	METH_VARARGS|METH_KEYWORDS,	"Change directory"},
1416     {"fchdir",	    (PyCFunction)(void *)VimFchdir,	METH_VARARGS|METH_KEYWORDS,	"Change directory"},
1417     {"foreach_rtp", VimForeachRTP,		METH_O,				"Call given callable for each path in &rtp"},
1418 #if PY_VERSION_HEX >= 0x030700f0
1419     {"find_spec",   FinderFindSpec,		METH_VARARGS,			"Internal use only, returns spec object for any input it receives"},
1420 #endif
1421     {"find_module", FinderFindModule,		METH_VARARGS,			"Internal use only, returns loader object for any input it receives"},
1422     {"path_hook",   VimPathHook,		METH_VARARGS,			"Hook function to install in sys.path_hooks"},
1423     {"_get_paths",  (PyCFunction)Vim_GetPaths,	METH_NOARGS,			"Get &rtp-based additions to sys.path"},
1424     { NULL,	    NULL,			0,				NULL}
1425 };
1426 
1427 /*
1428  * Generic iterator object
1429  */
1430 
1431 static PyTypeObject IterType;
1432 
1433 typedef PyObject *(*nextfun)(void **);
1434 typedef void (*destructorfun)(void *);
1435 typedef int (*traversefun)(void *, visitproc, void *);
1436 typedef int (*clearfun)(void **);
1437 
1438 // Main purpose of this object is removing the need for do python
1439 // initialization (i.e. PyType_Ready and setting type attributes) for a big
1440 // bunch of objects.
1441 typedef struct
1442 {
1443     PyObject_HEAD
1444     void *cur;
1445     nextfun next;
1446     destructorfun destruct;
1447     traversefun traverse;
1448     clearfun clear;
1449     PyObject *iter_object;
1450 } IterObject;
1451 
1452     static PyObject *
IterNew(void * start,destructorfun destruct,nextfun next,traversefun traverse,clearfun clear,PyObject * iter_object)1453 IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
1454 	clearfun clear, PyObject *iter_object)
1455 {
1456     IterObject *self;
1457 
1458     self = PyObject_GC_New(IterObject, &IterType);
1459     self->cur = start;
1460     self->next = next;
1461     self->destruct = destruct;
1462     self->traverse = traverse;
1463     self->clear = clear;
1464     self->iter_object = iter_object;
1465 
1466     if (iter_object)
1467 	Py_INCREF(iter_object);
1468 
1469     return (PyObject *)(self);
1470 }
1471 
1472     static void
IterDestructor(IterObject * self)1473 IterDestructor(IterObject *self)
1474 {
1475     if (self->iter_object)
1476 	Py_DECREF(self->iter_object);
1477     PyObject_GC_UnTrack((void *)(self));
1478     self->destruct(self->cur);
1479     PyObject_GC_Del((void *)(self));
1480 }
1481 
1482     static int
IterTraverse(IterObject * self,visitproc visit,void * arg)1483 IterTraverse(IterObject *self, visitproc visit, void *arg)
1484 {
1485     if (self->traverse != NULL)
1486 	return self->traverse(self->cur, visit, arg);
1487     else
1488 	return 0;
1489 }
1490 
1491 // Mac OSX defines clear() somewhere.
1492 #ifdef clear
1493 # undef clear
1494 #endif
1495 
1496     static int
IterClear(IterObject * self)1497 IterClear(IterObject *self)
1498 {
1499     if (self->clear != NULL)
1500 	return self->clear(&self->cur);
1501     else
1502 	return 0;
1503 }
1504 
1505     static PyObject *
IterNext(IterObject * self)1506 IterNext(IterObject *self)
1507 {
1508     return self->next(&self->cur);
1509 }
1510 
1511     static PyObject *
IterIter(PyObject * self)1512 IterIter(PyObject *self)
1513 {
1514     Py_INCREF(self);
1515     return self;
1516 }
1517 
1518 typedef struct pylinkedlist_S {
1519     struct pylinkedlist_S	*pll_next;
1520     struct pylinkedlist_S	*pll_prev;
1521     PyObject			*pll_obj;
1522 } pylinkedlist_T;
1523 
1524 static pylinkedlist_T *lastdict = NULL;
1525 static pylinkedlist_T *lastlist = NULL;
1526 static pylinkedlist_T *lastfunc = NULL;
1527 
1528     static void
pyll_remove(pylinkedlist_T * ref,pylinkedlist_T ** last)1529 pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
1530 {
1531     if (ref->pll_prev == NULL)
1532     {
1533 	if (ref->pll_next == NULL)
1534 	{
1535 	    *last = NULL;
1536 	    return;
1537 	}
1538     }
1539     else
1540 	ref->pll_prev->pll_next = ref->pll_next;
1541 
1542     if (ref->pll_next == NULL)
1543 	*last = ref->pll_prev;
1544     else
1545 	ref->pll_next->pll_prev = ref->pll_prev;
1546 }
1547 
1548     static void
pyll_add(PyObject * self,pylinkedlist_T * ref,pylinkedlist_T ** last)1549 pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
1550 {
1551     if (*last == NULL)
1552 	ref->pll_prev = NULL;
1553     else
1554     {
1555 	(*last)->pll_next = ref;
1556 	ref->pll_prev = *last;
1557     }
1558     ref->pll_next = NULL;
1559     ref->pll_obj = self;
1560     *last = ref;
1561 }
1562 
1563 static PyTypeObject DictionaryType;
1564 
1565 typedef struct
1566 {
1567     PyObject_HEAD
1568     dict_T	*dict;
1569     pylinkedlist_T	ref;
1570 } DictionaryObject;
1571 
1572 static PyObject *DictionaryUpdate(DictionaryObject *, PyObject *, PyObject *);
1573 
1574 #define NEW_DICTIONARY(dict) DictionaryNew(&DictionaryType, dict)
1575 
1576     static PyObject *
DictionaryNew(PyTypeObject * subtype,dict_T * dict)1577 DictionaryNew(PyTypeObject *subtype, dict_T *dict)
1578 {
1579     DictionaryObject	*self;
1580 
1581     self = (DictionaryObject *) subtype->tp_alloc(subtype, 0);
1582     if (self == NULL)
1583 	return NULL;
1584     self->dict = dict;
1585     ++dict->dv_refcount;
1586 
1587     pyll_add((PyObject *)(self), &self->ref, &lastdict);
1588 
1589     return (PyObject *)(self);
1590 }
1591 
1592     static dict_T *
py_dict_alloc(void)1593 py_dict_alloc(void)
1594 {
1595     dict_T	*ret;
1596 
1597     if (!(ret = dict_alloc()))
1598     {
1599 	PyErr_NoMemory();
1600 	return NULL;
1601     }
1602     ++ret->dv_refcount;
1603 
1604     return ret;
1605 }
1606 
1607     static PyObject *
DictionaryConstructor(PyTypeObject * subtype,PyObject * args,PyObject * kwargs)1608 DictionaryConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
1609 {
1610     DictionaryObject	*self;
1611     dict_T	*dict;
1612 
1613     if (!(dict = py_dict_alloc()))
1614 	return NULL;
1615 
1616     self = (DictionaryObject *) DictionaryNew(subtype, dict);
1617 
1618     --dict->dv_refcount;
1619 
1620     if (kwargs || PyTuple_Size(args))
1621     {
1622 	PyObject	*tmp;
1623 	if (!(tmp = DictionaryUpdate(self, args, kwargs)))
1624 	{
1625 	    Py_DECREF(self);
1626 	    return NULL;
1627 	}
1628 
1629 	Py_DECREF(tmp);
1630     }
1631 
1632     return (PyObject *)(self);
1633 }
1634 
1635     static void
DictionaryDestructor(DictionaryObject * self)1636 DictionaryDestructor(DictionaryObject *self)
1637 {
1638     pyll_remove(&self->ref, &lastdict);
1639     dict_unref(self->dict);
1640 
1641     DESTRUCTOR_FINISH(self);
1642 }
1643 
1644 static char *DictionaryAttrs[] = {
1645     "locked", "scope",
1646     NULL
1647 };
1648 
1649     static PyObject *
DictionaryDir(PyObject * self,PyObject * args UNUSED)1650 DictionaryDir(PyObject *self, PyObject *args UNUSED)
1651 {
1652     return ObjectDir(self, DictionaryAttrs);
1653 }
1654 
1655     static int
DictionarySetattr(DictionaryObject * self,char * name,PyObject * valObject)1656 DictionarySetattr(DictionaryObject *self, char *name, PyObject *valObject)
1657 {
1658     if (valObject == NULL)
1659     {
1660 	PyErr_SET_STRING(PyExc_AttributeError,
1661 		N_("cannot delete vim.Dictionary attributes"));
1662 	return -1;
1663     }
1664 
1665     if (strcmp(name, "locked") == 0)
1666     {
1667 	if (self->dict->dv_lock == VAR_FIXED)
1668 	{
1669 	    PyErr_SET_STRING(PyExc_TypeError,
1670 		    N_("cannot modify fixed dictionary"));
1671 	    return -1;
1672 	}
1673 	else
1674 	{
1675 	    int		istrue = PyObject_IsTrue(valObject);
1676 	    if (istrue == -1)
1677 		return -1;
1678 	    else if (istrue)
1679 		self->dict->dv_lock = VAR_LOCKED;
1680 	    else
1681 		self->dict->dv_lock = 0;
1682 	}
1683 	return 0;
1684     }
1685     else
1686     {
1687 	PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
1688 	return -1;
1689     }
1690 }
1691 
1692     static PyInt
DictionaryLength(DictionaryObject * self)1693 DictionaryLength(DictionaryObject *self)
1694 {
1695     return ((PyInt) (self->dict->dv_hashtab.ht_used));
1696 }
1697 
1698 #define DICT_FLAG_HAS_DEFAULT	0x01
1699 #define DICT_FLAG_POP		0x02
1700 #define DICT_FLAG_NONE_DEFAULT	0x04
1701 #define DICT_FLAG_RETURN_BOOL	0x08 // Incompatible with DICT_FLAG_POP
1702 #define DICT_FLAG_RETURN_PAIR	0x10
1703 
1704     static PyObject *
_DictionaryItem(DictionaryObject * self,PyObject * args,int flags)1705 _DictionaryItem(DictionaryObject *self, PyObject *args, int flags)
1706 {
1707     PyObject	*keyObject;
1708     PyObject	*defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
1709     PyObject	*ret;
1710     char_u	*key;
1711     dictitem_T	*di;
1712     dict_T	*dict = self->dict;
1713     hashitem_T	*hi;
1714     PyObject	*todecref;
1715 
1716     if (flags & DICT_FLAG_HAS_DEFAULT)
1717     {
1718 	if (!PyArg_ParseTuple(args, "O|O", &keyObject, &defObject))
1719 	    return NULL;
1720     }
1721     else
1722 	keyObject = args;
1723 
1724     if (flags & DICT_FLAG_RETURN_BOOL)
1725 	defObject = Py_False;
1726 
1727     if (!(key = StringToChars(keyObject, &todecref)))
1728 	return NULL;
1729 
1730     if (*key == NUL)
1731     {
1732 	RAISE_NO_EMPTY_KEYS;
1733 	Py_XDECREF(todecref);
1734 	return NULL;
1735     }
1736 
1737     hi = hash_find(&dict->dv_hashtab, key);
1738 
1739     Py_XDECREF(todecref);
1740 
1741     if (HASHITEM_EMPTY(hi))
1742     {
1743 	if (defObject)
1744 	{
1745 	    Py_INCREF(defObject);
1746 	    return defObject;
1747 	}
1748 	else
1749 	{
1750 	    PyErr_SetObject(PyExc_KeyError, keyObject);
1751 	    return NULL;
1752 	}
1753     }
1754     else if (flags & DICT_FLAG_RETURN_BOOL)
1755     {
1756 	ret = Py_True;
1757 	Py_INCREF(ret);
1758 	return ret;
1759     }
1760 
1761     di = dict_lookup(hi);
1762 
1763     if (!(ret = ConvertToPyObject(&di->di_tv)))
1764 	return NULL;
1765 
1766     if (flags & DICT_FLAG_POP)
1767     {
1768 	if (dict->dv_lock)
1769 	{
1770 	    RAISE_LOCKED_DICTIONARY;
1771 	    Py_DECREF(ret);
1772 	    return NULL;
1773 	}
1774 
1775 	hash_remove(&dict->dv_hashtab, hi);
1776 	dictitem_free(di);
1777     }
1778 
1779     return ret;
1780 }
1781 
1782     static PyObject *
DictionaryItem(DictionaryObject * self,PyObject * keyObject)1783 DictionaryItem(DictionaryObject *self, PyObject *keyObject)
1784 {
1785     return _DictionaryItem(self, keyObject, 0);
1786 }
1787 
1788     static int
DictionaryContains(DictionaryObject * self,PyObject * keyObject)1789 DictionaryContains(DictionaryObject *self, PyObject *keyObject)
1790 {
1791     PyObject	*rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
1792     int		ret;
1793 
1794     if (rObj == NULL)
1795 	return -1;
1796 
1797     ret = (rObj == Py_True);
1798 
1799     Py_DECREF(rObj);
1800 
1801     return ret;
1802 }
1803 
1804 typedef struct
1805 {
1806     int		dii_changed;
1807     hashtab_T	*dii_ht;
1808     hashitem_T	*dii_hi;
1809     long_u	dii_todo;
1810 } dictiterinfo_T;
1811 
1812     static PyObject *
DictionaryIterNext(dictiterinfo_T ** dii)1813 DictionaryIterNext(dictiterinfo_T **dii)
1814 {
1815     PyObject	*ret;
1816 
1817     if (!(*dii)->dii_todo)
1818 	return NULL;
1819 
1820     if ((*dii)->dii_ht->ht_changed != (*dii)->dii_changed)
1821     {
1822 	PyErr_SET_STRING(PyExc_RuntimeError,
1823 		N_("hashtab changed during iteration"));
1824 	return NULL;
1825     }
1826 
1827     while (((*dii)->dii_todo) && HASHITEM_EMPTY((*dii)->dii_hi))
1828 	++((*dii)->dii_hi);
1829 
1830     --((*dii)->dii_todo);
1831 
1832     if (!(ret = PyBytes_FromString((char *)(*dii)->dii_hi->hi_key)))
1833 	return NULL;
1834 
1835     return ret;
1836 }
1837 
1838     static PyObject *
DictionaryIter(DictionaryObject * self)1839 DictionaryIter(DictionaryObject *self)
1840 {
1841     dictiterinfo_T	*dii;
1842     hashtab_T		*ht;
1843 
1844     if (!(dii = PyMem_New(dictiterinfo_T, 1)))
1845     {
1846 	PyErr_NoMemory();
1847 	return NULL;
1848     }
1849 
1850     ht = &self->dict->dv_hashtab;
1851     dii->dii_changed = ht->ht_changed;
1852     dii->dii_ht = ht;
1853     dii->dii_hi = ht->ht_array;
1854     dii->dii_todo = ht->ht_used;
1855 
1856     return IterNew(dii,
1857 	    (destructorfun)(void *) PyMem_Free, (nextfun) DictionaryIterNext,
1858 	    NULL, NULL, (PyObject *)self);
1859 }
1860 
1861     static int
DictionaryAssItem(DictionaryObject * self,PyObject * keyObject,PyObject * valObject)1862 DictionaryAssItem(
1863 	DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
1864 {
1865     char_u	*key;
1866     typval_T	tv;
1867     dict_T	*dict = self->dict;
1868     dictitem_T	*di;
1869     PyObject	*todecref;
1870 
1871     if (dict->dv_lock)
1872     {
1873 	RAISE_LOCKED_DICTIONARY;
1874 	return -1;
1875     }
1876 
1877     if (!(key = StringToChars(keyObject, &todecref)))
1878 	return -1;
1879 
1880     if (*key == NUL)
1881     {
1882 	RAISE_NO_EMPTY_KEYS;
1883 	Py_XDECREF(todecref);
1884 	return -1;
1885     }
1886 
1887     di = dict_find(dict, key, -1);
1888 
1889     if (valObject == NULL)
1890     {
1891 	hashitem_T	*hi;
1892 
1893 	if (di == NULL)
1894 	{
1895 	    Py_XDECREF(todecref);
1896 	    PyErr_SetObject(PyExc_KeyError, keyObject);
1897 	    return -1;
1898 	}
1899 	hi = hash_find(&dict->dv_hashtab, di->di_key);
1900 	hash_remove(&dict->dv_hashtab, hi);
1901 	dictitem_free(di);
1902 	Py_XDECREF(todecref);
1903 	return 0;
1904     }
1905 
1906     if (ConvertFromPyObject(valObject, &tv) == -1)
1907     {
1908 	Py_XDECREF(todecref);
1909 	return -1;
1910     }
1911 
1912     if (di == NULL)
1913     {
1914 	if (!(di = dictitem_alloc(key)))
1915 	{
1916 	    Py_XDECREF(todecref);
1917 	    PyErr_NoMemory();
1918 	    return -1;
1919 	}
1920 	di->di_tv.v_type = VAR_UNKNOWN;
1921 
1922 	if (dict_add(dict, di) == FAIL)
1923 	{
1924 	    dictitem_free(di);
1925 	    RAISE_KEY_ADD_FAIL(key);
1926 	    Py_XDECREF(todecref);
1927 	    return -1;
1928 	}
1929     }
1930     else
1931 	clear_tv(&di->di_tv);
1932 
1933     Py_XDECREF(todecref);
1934 
1935     copy_tv(&tv, &di->di_tv);
1936     clear_tv(&tv);
1937     return 0;
1938 }
1939 
1940 typedef PyObject *(*hi_to_py)(hashitem_T *);
1941 
1942     static PyObject *
DictionaryListObjects(DictionaryObject * self,hi_to_py hiconvert)1943 DictionaryListObjects(DictionaryObject *self, hi_to_py hiconvert)
1944 {
1945     dict_T	*dict = self->dict;
1946     long_u	todo = dict->dv_hashtab.ht_used;
1947     Py_ssize_t	i = 0;
1948     PyObject	*ret;
1949     hashitem_T	*hi;
1950     PyObject	*newObj;
1951 
1952     ret = PyList_New(todo);
1953     for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1954     {
1955 	if (!HASHITEM_EMPTY(hi))
1956 	{
1957 	    if (!(newObj = hiconvert(hi)))
1958 	    {
1959 		Py_DECREF(ret);
1960 		return NULL;
1961 	    }
1962 	    PyList_SET_ITEM(ret, i, newObj);
1963 	    --todo;
1964 	    ++i;
1965 	}
1966     }
1967     return ret;
1968 }
1969 
1970     static PyObject *
dict_key(hashitem_T * hi)1971 dict_key(hashitem_T *hi)
1972 {
1973     return PyBytes_FromString((char *)(hi->hi_key));
1974 }
1975 
1976     static PyObject *
DictionaryListKeys(DictionaryObject * self,PyObject * args UNUSED)1977 DictionaryListKeys(DictionaryObject *self, PyObject *args UNUSED)
1978 {
1979     return DictionaryListObjects(self, dict_key);
1980 }
1981 
1982     static PyObject *
dict_val(hashitem_T * hi)1983 dict_val(hashitem_T *hi)
1984 {
1985     dictitem_T	*di;
1986 
1987     di = dict_lookup(hi);
1988     return ConvertToPyObject(&di->di_tv);
1989 }
1990 
1991     static PyObject *
DictionaryListValues(DictionaryObject * self,PyObject * args UNUSED)1992 DictionaryListValues(DictionaryObject *self, PyObject *args UNUSED)
1993 {
1994     return DictionaryListObjects(self, dict_val);
1995 }
1996 
1997     static PyObject *
dict_item(hashitem_T * hi)1998 dict_item(hashitem_T *hi)
1999 {
2000     PyObject	*keyObject;
2001     PyObject	*valObject;
2002     PyObject	*ret;
2003 
2004     if (!(keyObject = dict_key(hi)))
2005 	return NULL;
2006 
2007     if (!(valObject = dict_val(hi)))
2008     {
2009 	Py_DECREF(keyObject);
2010 	return NULL;
2011     }
2012 
2013     ret = Py_BuildValue("(OO)", keyObject, valObject);
2014 
2015     Py_DECREF(keyObject);
2016     Py_DECREF(valObject);
2017 
2018     return ret;
2019 }
2020 
2021     static PyObject *
DictionaryListItems(DictionaryObject * self,PyObject * args UNUSED)2022 DictionaryListItems(DictionaryObject *self, PyObject *args UNUSED)
2023 {
2024     return DictionaryListObjects(self, dict_item);
2025 }
2026 
2027     static PyObject *
DictionaryUpdate(DictionaryObject * self,PyObject * args,PyObject * kwargs)2028 DictionaryUpdate(DictionaryObject *self, PyObject *args, PyObject *kwargs)
2029 {
2030     dict_T	*dict = self->dict;
2031 
2032     if (dict->dv_lock)
2033     {
2034 	RAISE_LOCKED_DICTIONARY;
2035 	return NULL;
2036     }
2037 
2038     if (kwargs)
2039     {
2040 	typval_T	tv;
2041 
2042 	if (ConvertFromPyMapping(kwargs, &tv) == -1)
2043 	    return NULL;
2044 
2045 	VimTryStart();
2046 	dict_extend(self->dict, tv.vval.v_dict, (char_u *) "force", NULL);
2047 	clear_tv(&tv);
2048 	if (VimTryEnd())
2049 	    return NULL;
2050     }
2051     else
2052     {
2053 	PyObject	*obj = NULL;
2054 
2055 	if (!PyArg_ParseTuple(args, "|O", &obj))
2056 	    return NULL;
2057 
2058 	if (obj == NULL)
2059 	{
2060 	    Py_INCREF(Py_None);
2061 	    return Py_None;
2062 	}
2063 
2064 	if (PyObject_HasAttrString(obj, "keys"))
2065 	    return DictionaryUpdate(self, NULL, obj);
2066 	else
2067 	{
2068 	    PyObject	*iterator;
2069 	    PyObject	*item;
2070 
2071 	    if (!(iterator = PyObject_GetIter(obj)))
2072 		return NULL;
2073 
2074 	    while ((item = PyIter_Next(iterator)))
2075 	    {
2076 		PyObject	*fast;
2077 		PyObject	*keyObject;
2078 		PyObject	*valObject;
2079 		PyObject	*todecref;
2080 		char_u		*key;
2081 		dictitem_T	*di;
2082 		hashitem_T	*hi;
2083 
2084 		if (!(fast = PySequence_Fast(item, "")))
2085 		{
2086 		    Py_DECREF(iterator);
2087 		    Py_DECREF(item);
2088 		    return NULL;
2089 		}
2090 
2091 		Py_DECREF(item);
2092 
2093 		if (PySequence_Fast_GET_SIZE(fast) != 2)
2094 		{
2095 		    Py_DECREF(iterator);
2096 		    Py_DECREF(fast);
2097 		    PyErr_FORMAT(PyExc_ValueError,
2098 			    N_("expected sequence element of size 2, "
2099 			    "but got sequence of size %d"),
2100 			    (int) PySequence_Fast_GET_SIZE(fast));
2101 		    return NULL;
2102 		}
2103 
2104 		keyObject = PySequence_Fast_GET_ITEM(fast, 0);
2105 
2106 		if (!(key = StringToChars(keyObject, &todecref)))
2107 		{
2108 		    Py_DECREF(iterator);
2109 		    Py_DECREF(fast);
2110 		    return NULL;
2111 		}
2112 
2113 		di = dictitem_alloc(key);
2114 
2115 		Py_XDECREF(todecref);
2116 
2117 		if (di == NULL)
2118 		{
2119 		    Py_DECREF(fast);
2120 		    Py_DECREF(iterator);
2121 		    PyErr_NoMemory();
2122 		    return NULL;
2123 		}
2124 		di->di_tv.v_type = VAR_UNKNOWN;
2125 
2126 		valObject = PySequence_Fast_GET_ITEM(fast, 1);
2127 
2128 		if (ConvertFromPyObject(valObject, &di->di_tv) == -1)
2129 		{
2130 		    Py_DECREF(iterator);
2131 		    Py_DECREF(fast);
2132 		    dictitem_free(di);
2133 		    return NULL;
2134 		}
2135 
2136 		Py_DECREF(fast);
2137 
2138 		hi = hash_find(&dict->dv_hashtab, di->di_key);
2139 		if (!HASHITEM_EMPTY(hi) || dict_add(dict, di) == FAIL)
2140 		{
2141 		    RAISE_KEY_ADD_FAIL(di->di_key);
2142 		    Py_DECREF(iterator);
2143 		    dictitem_free(di);
2144 		    return NULL;
2145 		}
2146 	    }
2147 
2148 	    Py_DECREF(iterator);
2149 
2150 	    // Iterator may have finished due to an exception
2151 	    if (PyErr_Occurred())
2152 		return NULL;
2153 	}
2154     }
2155     Py_INCREF(Py_None);
2156     return Py_None;
2157 }
2158 
2159     static PyObject *
DictionaryGet(DictionaryObject * self,PyObject * args)2160 DictionaryGet(DictionaryObject *self, PyObject *args)
2161 {
2162     return _DictionaryItem(self, args,
2163 			    DICT_FLAG_HAS_DEFAULT|DICT_FLAG_NONE_DEFAULT);
2164 }
2165 
2166     static PyObject *
DictionaryPop(DictionaryObject * self,PyObject * args)2167 DictionaryPop(DictionaryObject *self, PyObject *args)
2168 {
2169     return _DictionaryItem(self, args, DICT_FLAG_HAS_DEFAULT|DICT_FLAG_POP);
2170 }
2171 
2172     static PyObject *
DictionaryPopItem(DictionaryObject * self,PyObject * args UNUSED)2173 DictionaryPopItem(DictionaryObject *self, PyObject *args UNUSED)
2174 {
2175     hashitem_T	*hi;
2176     PyObject	*ret;
2177     PyObject	*valObject;
2178     dictitem_T	*di;
2179 
2180     if (self->dict->dv_hashtab.ht_used == 0)
2181     {
2182 	PyErr_SetNone(PyExc_KeyError);
2183 	return NULL;
2184     }
2185 
2186     hi = self->dict->dv_hashtab.ht_array;
2187     while (HASHITEM_EMPTY(hi))
2188 	++hi;
2189 
2190     di = dict_lookup(hi);
2191 
2192     if (!(valObject = ConvertToPyObject(&di->di_tv)))
2193 	return NULL;
2194 
2195     if (!(ret = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
2196     {
2197 	Py_DECREF(valObject);
2198 	return NULL;
2199     }
2200 
2201     hash_remove(&self->dict->dv_hashtab, hi);
2202     dictitem_free(di);
2203 
2204     return ret;
2205 }
2206 
2207     static PyObject *
DictionaryHasKey(DictionaryObject * self,PyObject * keyObject)2208 DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
2209 {
2210     return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
2211 }
2212 
2213 static PySequenceMethods DictionaryAsSeq = {
2214     0,					// sq_length
2215     0,					// sq_concat
2216     0,					// sq_repeat
2217     0,					// sq_item
2218     0,					// sq_slice
2219     0,					// sq_ass_item
2220     0,					// sq_ass_slice
2221     (objobjproc) DictionaryContains,	// sq_contains
2222     0,					// sq_inplace_concat
2223     0,					// sq_inplace_repeat
2224 };
2225 
2226 static PyMappingMethods DictionaryAsMapping = {
2227     (lenfunc)       DictionaryLength,
2228     (binaryfunc)    DictionaryItem,
2229     (objobjargproc) DictionaryAssItem,
2230 };
2231 
2232 static struct PyMethodDef DictionaryMethods[] = {
2233     {"keys",	(PyCFunction)DictionaryListKeys,	METH_NOARGS,	""},
2234     {"values",	(PyCFunction)DictionaryListValues,	METH_NOARGS,	""},
2235     {"items",	(PyCFunction)DictionaryListItems,	METH_NOARGS,	""},
2236     {"update",	(PyCFunction)(void *)DictionaryUpdate,		METH_VARARGS|METH_KEYWORDS, ""},
2237     {"get",	(PyCFunction)DictionaryGet,		METH_VARARGS,	""},
2238     {"pop",	(PyCFunction)DictionaryPop,		METH_VARARGS,	""},
2239     {"popitem",	(PyCFunction)DictionaryPopItem,		METH_NOARGS,	""},
2240     {"has_key",	(PyCFunction)DictionaryHasKey,		METH_O,		""},
2241     {"__dir__",	(PyCFunction)DictionaryDir,		METH_NOARGS,	""},
2242     { NULL,	NULL,					0,		NULL}
2243 };
2244 
2245 static PyTypeObject ListType;
2246 
2247 typedef struct
2248 {
2249     PyObject_HEAD
2250     list_T	*list;
2251     pylinkedlist_T	ref;
2252 } ListObject;
2253 
2254 #define NEW_LIST(list) ListNew(&ListType, list)
2255 
2256     static PyObject *
ListNew(PyTypeObject * subtype,list_T * list)2257 ListNew(PyTypeObject *subtype, list_T *list)
2258 {
2259     ListObject	*self;
2260 
2261     if (list == NULL)
2262 	return NULL;
2263 
2264     self = (ListObject *) subtype->tp_alloc(subtype, 0);
2265     if (self == NULL)
2266 	return NULL;
2267     self->list = list;
2268     ++list->lv_refcount;
2269     CHECK_LIST_MATERIALIZE(list);
2270 
2271     pyll_add((PyObject *)(self), &self->ref, &lastlist);
2272 
2273     return (PyObject *)(self);
2274 }
2275 
2276     static list_T *
py_list_alloc(void)2277 py_list_alloc(void)
2278 {
2279     list_T	*ret;
2280 
2281     if (!(ret = list_alloc()))
2282     {
2283 	PyErr_NoMemory();
2284 	return NULL;
2285     }
2286     ++ret->lv_refcount;
2287 
2288     return ret;
2289 }
2290 
2291     static int
list_py_concat(list_T * l,PyObject * obj,PyObject * lookup_dict)2292 list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
2293 {
2294     PyObject	*iterator;
2295     PyObject	*item;
2296     listitem_T	*li;
2297 
2298     if (!(iterator = PyObject_GetIter(obj)))
2299 	return -1;
2300 
2301     while ((item = PyIter_Next(iterator)))
2302     {
2303 	if (!(li = listitem_alloc()))
2304 	{
2305 	    PyErr_NoMemory();
2306 	    Py_DECREF(item);
2307 	    Py_DECREF(iterator);
2308 	    return -1;
2309 	}
2310 	li->li_tv.v_lock = 0;
2311 	li->li_tv.v_type = VAR_UNKNOWN;
2312 
2313 	if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
2314 	{
2315 	    Py_DECREF(item);
2316 	    Py_DECREF(iterator);
2317 	    listitem_free(l, li);
2318 	    return -1;
2319 	}
2320 
2321 	Py_DECREF(item);
2322 
2323 	list_append(l, li);
2324     }
2325 
2326     Py_DECREF(iterator);
2327 
2328     // Iterator may have finished due to an exception
2329     if (PyErr_Occurred())
2330 	return -1;
2331 
2332     return 0;
2333 }
2334 
2335     static PyObject *
ListConstructor(PyTypeObject * subtype,PyObject * args,PyObject * kwargs)2336 ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
2337 {
2338     list_T	*list;
2339     PyObject	*obj = NULL;
2340 
2341     if (kwargs)
2342     {
2343 	PyErr_SET_STRING(PyExc_TypeError,
2344 		N_("list constructor does not accept keyword arguments"));
2345 	return NULL;
2346     }
2347 
2348     if (!PyArg_ParseTuple(args, "|O", &obj))
2349 	return NULL;
2350 
2351     if (!(list = py_list_alloc()))
2352 	return NULL;
2353 
2354     if (obj)
2355     {
2356 	PyObject	*lookup_dict;
2357 
2358 	if (!(lookup_dict = PyDict_New()))
2359 	{
2360 	    list_unref(list);
2361 	    return NULL;
2362 	}
2363 
2364 	if (list_py_concat(list, obj, lookup_dict) == -1)
2365 	{
2366 	    Py_DECREF(lookup_dict);
2367 	    list_unref(list);
2368 	    return NULL;
2369 	}
2370 
2371 	Py_DECREF(lookup_dict);
2372     }
2373 
2374     return ListNew(subtype, list);
2375 }
2376 
2377     static void
ListDestructor(ListObject * self)2378 ListDestructor(ListObject *self)
2379 {
2380     pyll_remove(&self->ref, &lastlist);
2381     list_unref(self->list);
2382 
2383     DESTRUCTOR_FINISH(self);
2384 }
2385 
2386     static PyInt
ListLength(ListObject * self)2387 ListLength(ListObject *self)
2388 {
2389     return ((PyInt) (self->list->lv_len));
2390 }
2391 
2392     static PyObject *
ListIndex(ListObject * self,Py_ssize_t index)2393 ListIndex(ListObject *self, Py_ssize_t index)
2394 {
2395     listitem_T	*li;
2396 
2397     if (index >= ListLength(self))
2398     {
2399 	PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
2400 	return NULL;
2401     }
2402     li = list_find(self->list, (long) index);
2403     if (li == NULL)
2404     {
2405 	// No more suitable format specifications in python-2.3
2406 	PyErr_VIM_FORMAT(N_("internal error: failed to get Vim list item %d"),
2407 		(int) index);
2408 	return NULL;
2409     }
2410     return ConvertToPyObject(&li->li_tv);
2411 }
2412 
2413     static PyObject *
ListSlice(ListObject * self,Py_ssize_t first,Py_ssize_t step,Py_ssize_t slicelen)2414 ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step,
2415 	  Py_ssize_t slicelen)
2416 {
2417     PyInt	i;
2418     PyObject	*list;
2419 
2420     if (step == 0)
2421     {
2422 	PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2423 	return NULL;
2424     }
2425 
2426     list = PyList_New(slicelen);
2427     if (list == NULL)
2428 	return NULL;
2429 
2430     for (i = 0; i < slicelen; ++i)
2431     {
2432 	PyObject	*item;
2433 
2434 	item = ListIndex(self, first + i*step);
2435 	if (item == NULL)
2436 	{
2437 	    Py_DECREF(list);
2438 	    return NULL;
2439 	}
2440 
2441 	PyList_SET_ITEM(list, i, item);
2442     }
2443 
2444     return list;
2445 }
2446 
2447     static PyObject *
ListItem(ListObject * self,PyObject * idx)2448 ListItem(ListObject *self, PyObject* idx)
2449 {
2450 #if PY_MAJOR_VERSION < 3
2451     if (PyInt_Check(idx))
2452     {
2453 	long _idx = PyInt_AsLong(idx);
2454 	return ListIndex(self, _idx);
2455     }
2456     else
2457 #endif
2458     if (PyLong_Check(idx))
2459     {
2460 	long _idx = PyLong_AsLong(idx);
2461 	return ListIndex(self, _idx);
2462     }
2463     else if (PySlice_Check(idx))
2464     {
2465 	Py_ssize_t start, stop, step, slicelen;
2466 
2467 	if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
2468 				 &start, &stop, &step, &slicelen) < 0)
2469 	    return NULL;
2470 	return ListSlice(self, start, step, slicelen);
2471     }
2472     else
2473     {
2474 	RAISE_INVALID_INDEX_TYPE(idx);
2475 	return NULL;
2476     }
2477 }
2478 
2479     static void
list_restore(Py_ssize_t numadded,Py_ssize_t numreplaced,Py_ssize_t slicelen,list_T * l,listitem_T ** lis,listitem_T * lastaddedli)2480 list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen,
2481 	list_T *l, listitem_T **lis, listitem_T *lastaddedli)
2482 {
2483     while (numreplaced--)
2484     {
2485 	list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]);
2486 	listitem_remove(l, lis[slicelen + numreplaced]);
2487     }
2488     while (numadded--)
2489     {
2490 	listitem_T	*next;
2491 
2492 	next = lastaddedli->li_prev;
2493 	listitem_remove(l, lastaddedli);
2494 	lastaddedli = next;
2495     }
2496 }
2497 
2498     static int
ListAssSlice(ListObject * self,Py_ssize_t first,Py_ssize_t step,Py_ssize_t slicelen,PyObject * obj)2499 ListAssSlice(ListObject *self, Py_ssize_t first,
2500 	     Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj)
2501 {
2502     PyObject	*iterator;
2503     PyObject	*item;
2504     listitem_T	*li;
2505     listitem_T	*lastaddedli = NULL;
2506     listitem_T	*next;
2507     typval_T	v;
2508     list_T	*l = self->list;
2509     PyInt	i;
2510     PyInt	j;
2511     PyInt	numreplaced = 0;
2512     PyInt	numadded = 0;
2513     PyInt	size;
2514     listitem_T	**lis = NULL;
2515 
2516     size = ListLength(self);
2517 
2518     if (l->lv_lock)
2519     {
2520 	RAISE_LOCKED_LIST;
2521 	return -1;
2522     }
2523 
2524     if (step == 0)
2525     {
2526 	PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
2527 	return -1;
2528     }
2529 
2530     if (step != 1 && slicelen == 0)
2531     {
2532 	// Nothing to do. Only error out if obj has some items.
2533 	int		ret = 0;
2534 
2535 	if (obj == NULL)
2536 	    return 0;
2537 
2538 	if (!(iterator = PyObject_GetIter(obj)))
2539 	    return -1;
2540 
2541 	if ((item = PyIter_Next(iterator)))
2542 	{
2543 	    PyErr_FORMAT(PyExc_ValueError,
2544 		    N_("attempt to assign sequence of size greater than %d "
2545 			"to extended slice"), 0);
2546 	    Py_DECREF(item);
2547 	    ret = -1;
2548 	}
2549 	Py_DECREF(iterator);
2550 	return ret;
2551     }
2552 
2553     if (obj != NULL)
2554 	// XXX May allocate zero bytes.
2555 	if (!(lis = PyMem_New(listitem_T *, slicelen * 2)))
2556 	{
2557 	    PyErr_NoMemory();
2558 	    return -1;
2559 	}
2560 
2561     if (first == size)
2562 	li = NULL;
2563     else
2564     {
2565 	li = list_find(l, (long) first);
2566 	if (li == NULL)
2567 	{
2568 	    PyErr_VIM_FORMAT(N_("internal error: no Vim list item %d"),
2569 		    (int)first);
2570 	    if (obj != NULL)
2571 		PyMem_Free(lis);
2572 	    return -1;
2573 	}
2574 	i = slicelen;
2575 	while (i-- && li != NULL)
2576 	{
2577 	    j = step;
2578 	    next = li;
2579 	    if (step > 0)
2580 		while (next != NULL && ((next = next->li_next) != NULL) && --j);
2581 	    else
2582 		while (next != NULL && ((next = next->li_prev) != NULL) && ++j);
2583 
2584 	    if (obj == NULL)
2585 		listitem_remove(l, li);
2586 	    else
2587 		lis[slicelen - i - 1] = li;
2588 
2589 	    li = next;
2590 	}
2591 	if (li == NULL && i != -1)
2592 	{
2593 	    PyErr_SET_VIM(N_("internal error: not enough list items"));
2594 	    if (obj != NULL)
2595 		PyMem_Free(lis);
2596 	    return -1;
2597 	}
2598     }
2599 
2600     if (obj == NULL)
2601 	return 0;
2602 
2603     if (!(iterator = PyObject_GetIter(obj)))
2604     {
2605 	PyMem_Free(lis);
2606 	return -1;
2607     }
2608 
2609     i = 0;
2610     while ((item = PyIter_Next(iterator)))
2611     {
2612 	if (ConvertFromPyObject(item, &v) == -1)
2613 	{
2614 	    Py_DECREF(iterator);
2615 	    Py_DECREF(item);
2616 	    PyMem_Free(lis);
2617 	    return -1;
2618 	}
2619 	Py_DECREF(item);
2620 	if (list_insert_tv(l, &v, numreplaced < slicelen
2621 				    ? lis[numreplaced]
2622 				    : li) == FAIL)
2623 	{
2624 	    clear_tv(&v);
2625 	    PyErr_SET_VIM(N_("internal error: failed to add item to list"));
2626 	    list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2627 	    PyMem_Free(lis);
2628 	    return -1;
2629 	}
2630 	if (numreplaced < slicelen)
2631 	{
2632 	    lis[slicelen + numreplaced] = lis[numreplaced]->li_prev;
2633 	    vimlist_remove(l, lis[numreplaced], lis[numreplaced]);
2634 	    numreplaced++;
2635 	}
2636 	else
2637 	{
2638 	    if (li)
2639 		lastaddedli = li->li_prev;
2640 	    else
2641 		lastaddedli = l->lv_u.mat.lv_last;
2642 	    numadded++;
2643 	}
2644 	clear_tv(&v);
2645 	if (step != 1 && i >= slicelen)
2646 	{
2647 	    Py_DECREF(iterator);
2648 	    PyErr_FORMAT(PyExc_ValueError,
2649 		    N_("attempt to assign sequence of size greater than %d "
2650 			"to extended slice"), (int) slicelen);
2651 	    list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2652 	    PyMem_Free(lis);
2653 	    return -1;
2654 	}
2655 	++i;
2656     }
2657     Py_DECREF(iterator);
2658 
2659     if (step != 1 && i != slicelen)
2660     {
2661 	PyErr_FORMAT2(PyExc_ValueError,
2662 		N_("attempt to assign sequence of size %d to extended slice "
2663 		    "of size %d"), (int) i, (int) slicelen);
2664 	list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2665 	PyMem_Free(lis);
2666 	return -1;
2667     }
2668 
2669     if (PyErr_Occurred())
2670     {
2671 	list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
2672 	PyMem_Free(lis);
2673 	return -1;
2674     }
2675 
2676     for (i = 0; i < numreplaced; i++)
2677 	listitem_free(l, lis[i]);
2678     if (step == 1)
2679 	for (i = numreplaced; i < slicelen; i++)
2680 	    listitem_remove(l, lis[i]);
2681 
2682     PyMem_Free(lis);
2683 
2684     return 0;
2685 }
2686 
2687     static int
ListAssIndex(ListObject * self,Py_ssize_t index,PyObject * obj)2688 ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
2689 {
2690     typval_T	tv;
2691     list_T	*l = self->list;
2692     listitem_T	*li;
2693     Py_ssize_t	length = ListLength(self);
2694 
2695     if (l->lv_lock)
2696     {
2697 	RAISE_LOCKED_LIST;
2698 	return -1;
2699     }
2700     if (index > length || (index == length && obj == NULL))
2701     {
2702 	PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
2703 	return -1;
2704     }
2705 
2706     if (obj == NULL)
2707     {
2708 	li = list_find(l, (long) index);
2709 	if (li == NULL)
2710 	{
2711 	    PyErr_VIM_FORMAT(N_("internal error: failed to get Vim "
2712 			"list item %d"), (int) index);
2713 	    return -1;
2714 	}
2715 	vimlist_remove(l, li, li);
2716 	clear_tv(&li->li_tv);
2717 	vim_free(li);
2718 	return 0;
2719     }
2720 
2721     if (ConvertFromPyObject(obj, &tv) == -1)
2722 	return -1;
2723 
2724     if (index == length)
2725     {
2726 	if (list_append_tv(l, &tv) == FAIL)
2727 	{
2728 	    clear_tv(&tv);
2729 	    PyErr_SET_VIM(N_("failed to add item to list"));
2730 	    return -1;
2731 	}
2732     }
2733     else
2734     {
2735 	li = list_find(l, (long) index);
2736 	if (li == NULL)
2737 	{
2738 	    PyErr_VIM_FORMAT(N_("internal error: failed to get Vim "
2739 			"list item %d"), (int) index);
2740 	    return -1;
2741 	}
2742 	clear_tv(&li->li_tv);
2743 	copy_tv(&tv, &li->li_tv);
2744 	clear_tv(&tv);
2745     }
2746     return 0;
2747 }
2748 
2749     static int
ListAssItem(ListObject * self,PyObject * idx,PyObject * obj)2750 ListAssItem(ListObject *self, PyObject *idx, PyObject *obj)
2751 {
2752 #if PY_MAJOR_VERSION < 3
2753     if (PyInt_Check(idx))
2754     {
2755 	long _idx = PyInt_AsLong(idx);
2756 	return (int)ListAssIndex(self, _idx, obj);
2757     }
2758     else
2759 #endif
2760     if (PyLong_Check(idx))
2761     {
2762 	long _idx = PyLong_AsLong(idx);
2763 	return (int)ListAssIndex(self, _idx, obj);
2764     }
2765     else if (PySlice_Check(idx))
2766     {
2767 	Py_ssize_t start, stop, step, slicelen;
2768 
2769 	if (PySlice_GetIndicesEx((PySliceObject_T *)idx, ListLength(self),
2770 				 &start, &stop, &step, &slicelen) < 0)
2771 	    return -1;
2772 	return (int)ListAssSlice(self, start, step, slicelen,
2773 		obj);
2774     }
2775     else
2776     {
2777 	RAISE_INVALID_INDEX_TYPE(idx);
2778 	return -1;
2779     }
2780 }
2781 
2782     static PyObject *
ListConcatInPlace(ListObject * self,PyObject * obj)2783 ListConcatInPlace(ListObject *self, PyObject *obj)
2784 {
2785     list_T	*l = self->list;
2786     PyObject	*lookup_dict;
2787 
2788     if (l->lv_lock)
2789     {
2790 	RAISE_LOCKED_LIST;
2791 	return NULL;
2792     }
2793 
2794     if (!(lookup_dict = PyDict_New()))
2795 	return NULL;
2796 
2797     if (list_py_concat(l, obj, lookup_dict) == -1)
2798     {
2799 	Py_DECREF(lookup_dict);
2800 	return NULL;
2801     }
2802     Py_DECREF(lookup_dict);
2803 
2804     Py_INCREF(self);
2805     return (PyObject *)(self);
2806 }
2807 
2808 typedef struct
2809 {
2810     listwatch_T	lw;
2811     list_T	*list;
2812 } listiterinfo_T;
2813 
2814     static void
ListIterDestruct(listiterinfo_T * lii)2815 ListIterDestruct(listiterinfo_T *lii)
2816 {
2817     list_rem_watch(lii->list, &lii->lw);
2818     list_unref(lii->list);
2819     PyMem_Free(lii);
2820 }
2821 
2822     static PyObject *
ListIterNext(listiterinfo_T ** lii)2823 ListIterNext(listiterinfo_T **lii)
2824 {
2825     PyObject	*ret;
2826 
2827     if (!((*lii)->lw.lw_item))
2828 	return NULL;
2829 
2830     if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
2831 	return NULL;
2832 
2833     (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
2834 
2835     return ret;
2836 }
2837 
2838     static PyObject *
ListIter(ListObject * self)2839 ListIter(ListObject *self)
2840 {
2841     listiterinfo_T	*lii;
2842     list_T	*l = self->list;
2843 
2844     if (!(lii = PyMem_New(listiterinfo_T, 1)))
2845     {
2846 	PyErr_NoMemory();
2847 	return NULL;
2848     }
2849 
2850     CHECK_LIST_MATERIALIZE(l);
2851     list_add_watch(l, &lii->lw);
2852     lii->lw.lw_item = l->lv_first;
2853     lii->list = l;
2854     ++l->lv_refcount;
2855 
2856     return IterNew(lii,
2857 	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
2858 	    NULL, NULL, (PyObject *)self);
2859 }
2860 
2861 static char *ListAttrs[] = {
2862     "locked",
2863     NULL
2864 };
2865 
2866     static PyObject *
ListDir(PyObject * self,PyObject * args UNUSED)2867 ListDir(PyObject *self, PyObject *args UNUSED)
2868 {
2869     return ObjectDir(self, ListAttrs);
2870 }
2871 
2872     static int
ListSetattr(ListObject * self,char * name,PyObject * valObject)2873 ListSetattr(ListObject *self, char *name, PyObject *valObject)
2874 {
2875     if (valObject == NULL)
2876     {
2877 	PyErr_SET_STRING(PyExc_AttributeError,
2878 		N_("cannot delete vim.List attributes"));
2879 	return -1;
2880     }
2881 
2882     if (strcmp(name, "locked") == 0)
2883     {
2884 	if (self->list->lv_lock == VAR_FIXED)
2885 	{
2886 	    PyErr_SET_STRING(PyExc_TypeError, N_("cannot modify fixed list"));
2887 	    return -1;
2888 	}
2889 	else
2890 	{
2891 	    int		istrue = PyObject_IsTrue(valObject);
2892 	    if (istrue == -1)
2893 		return -1;
2894 	    else if (istrue)
2895 		self->list->lv_lock = VAR_LOCKED;
2896 	    else
2897 		self->list->lv_lock = 0;
2898 	}
2899 	return 0;
2900     }
2901     else
2902     {
2903 	PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
2904 	return -1;
2905     }
2906 }
2907 
2908 static PySequenceMethods ListAsSeq = {
2909     (lenfunc)		ListLength,	 // sq_length,	  len(x)
2910     (binaryfunc)	0,		 // RangeConcat, sq_concat,  x+y
2911     0,					 // RangeRepeat, sq_repeat,  x*n
2912     (PyIntArgFunc)	ListIndex,	 // sq_item,	  x[i]
2913     0,					 // was_sq_slice,     x[i:j]
2914     (PyIntObjArgProc)	ListAssIndex,	 // sq_as_item,  x[i]=v
2915     0,					 // was_sq_ass_slice, x[i:j]=v
2916     0,					 // sq_contains
2917     (binaryfunc)	ListConcatInPlace,// sq_inplace_concat
2918     0,					 // sq_inplace_repeat
2919 };
2920 
2921 static PyMappingMethods ListAsMapping = {
2922     /* mp_length	*/ (lenfunc) ListLength,
2923     /* mp_subscript     */ (binaryfunc) ListItem,
2924     /* mp_ass_subscript */ (objobjargproc) ListAssItem,
2925 };
2926 
2927 static struct PyMethodDef ListMethods[] = {
2928     {"extend",	(PyCFunction)ListConcatInPlace,	METH_O,		""},
2929     {"__dir__",	(PyCFunction)ListDir,		METH_NOARGS,	""},
2930     { NULL,	NULL,				0,		NULL}
2931 };
2932 
2933 typedef struct
2934 {
2935     PyObject_HEAD
2936     char_u	*name;
2937     int		argc;
2938     typval_T	*argv;
2939     dict_T	*self;
2940     pylinkedlist_T	ref;
2941     int		auto_rebind;
2942 } FunctionObject;
2943 
2944 static PyTypeObject FunctionType;
2945 
2946 #define NEW_FUNCTION(name, argc, argv, self, pt_auto) \
2947     FunctionNew(&FunctionType, (name), (argc), (argv), (self), (pt_auto))
2948 
2949     static PyObject *
FunctionNew(PyTypeObject * subtype,char_u * name,int argc,typval_T * argv,dict_T * selfdict,int auto_rebind)2950 FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
2951 	dict_T *selfdict, int auto_rebind)
2952 {
2953     FunctionObject	*self;
2954 
2955     self = (FunctionObject *)subtype->tp_alloc(subtype, 0);
2956     if (self == NULL)
2957 	return NULL;
2958 
2959     if (isdigit(*name))
2960     {
2961 	if (!translated_function_exists(name, FALSE))
2962 	{
2963 	    PyErr_FORMAT(PyExc_ValueError,
2964 		    N_("unnamed function %s does not exist"), name);
2965 	    return NULL;
2966 	}
2967 	self->name = vim_strsave(name);
2968     }
2969     else
2970     {
2971 	char_u *p;
2972 
2973 	if ((p = get_expanded_name(name,
2974 			    vim_strchr(name, AUTOLOAD_CHAR) == NULL)) == NULL)
2975 	{
2976 	    PyErr_FORMAT(PyExc_ValueError,
2977 		    N_("function %s does not exist"), name);
2978 	    return NULL;
2979 	}
2980 
2981 	if (p[0] == K_SPECIAL && p[1] == KS_EXTRA && p[2] == (int)KE_SNR)
2982 	{
2983 	    char_u *np;
2984 	    size_t len = STRLEN(p) + 1;
2985 
2986 	    if ((np = alloc(len + 2)) == NULL)
2987 	    {
2988 		vim_free(p);
2989 		return NULL;
2990 	    }
2991 	    mch_memmove(np, "<SNR>", 5);
2992 	    mch_memmove(np + 5, p + 3, len - 3);
2993 	    vim_free(p);
2994 	    self->name = np;
2995 	}
2996 	else
2997 	    self->name = p;
2998     }
2999 
3000     func_ref(self->name);
3001     self->argc = argc;
3002     self->argv = argv;
3003     self->self = selfdict;
3004     self->auto_rebind = selfdict == NULL ? TRUE : auto_rebind;
3005 
3006     if (self->argv || self->self)
3007 	pyll_add((PyObject *)(self), &self->ref, &lastfunc);
3008 
3009     return (PyObject *)(self);
3010 }
3011 
3012     static PyObject *
FunctionConstructor(PyTypeObject * subtype,PyObject * args,PyObject * kwargs)3013 FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
3014 {
3015     PyObject	*self;
3016     PyObject	*selfdictObject;
3017     PyObject	*autoRebindObject;
3018     PyObject	*argsObject = NULL;
3019     char_u	*name;
3020     typval_T	selfdicttv;
3021     typval_T	argstv;
3022     list_T	*argslist = NULL;
3023     dict_T	*selfdict = NULL;
3024     int		argc = 0;
3025     int		auto_rebind = TRUE;
3026     typval_T	*argv = NULL;
3027     typval_T	*curtv;
3028     listitem_T	*li;
3029 
3030     if (kwargs != NULL)
3031     {
3032 	selfdictObject = PyDict_GetItemString(kwargs, "self");
3033 	if (selfdictObject != NULL)
3034 	{
3035 	    if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
3036 		return NULL;
3037 	    selfdict = selfdicttv.vval.v_dict;
3038 	}
3039 	argsObject = PyDict_GetItemString(kwargs, "args");
3040 	if (argsObject != NULL)
3041 	{
3042 	    if (ConvertFromPySequence(argsObject, &argstv) == -1)
3043 	    {
3044 		dict_unref(selfdict);
3045 		return NULL;
3046 	    }
3047 	    argslist = argstv.vval.v_list;
3048 	    CHECK_LIST_MATERIALIZE(argslist);
3049 
3050 	    argc = argslist->lv_len;
3051 	    if (argc != 0)
3052 	    {
3053 		argv = PyMem_New(typval_T, (size_t) argc);
3054 		if (argv == NULL)
3055 		{
3056 		    PyErr_NoMemory();
3057 		    dict_unref(selfdict);
3058 		    list_unref(argslist);
3059 		    return NULL;
3060 		}
3061 		curtv = argv;
3062 		FOR_ALL_LIST_ITEMS(argslist, li)
3063 		    copy_tv(&li->li_tv, curtv++);
3064 	    }
3065 	    list_unref(argslist);
3066 	}
3067 	if (selfdict != NULL)
3068 	{
3069 	    auto_rebind = FALSE;
3070 	    autoRebindObject = PyDict_GetItemString(kwargs, "auto_rebind");
3071 	    if (autoRebindObject != NULL)
3072 	    {
3073 		auto_rebind = PyObject_IsTrue(autoRebindObject);
3074 		if (auto_rebind == -1)
3075 		{
3076 		    dict_unref(selfdict);
3077 		    list_unref(argslist);
3078 		    return NULL;
3079 		}
3080 	    }
3081 	}
3082     }
3083 
3084     if (!PyArg_ParseTuple(args, "et", "ascii", &name))
3085     {
3086 	dict_unref(selfdict);
3087 	while (argc--)
3088 	    clear_tv(&argv[argc]);
3089 	PyMem_Free(argv);
3090 	return NULL;
3091     }
3092 
3093     self = FunctionNew(subtype, name, argc, argv, selfdict, auto_rebind);
3094 
3095     PyMem_Free(name);
3096 
3097     return self;
3098 }
3099 
3100     static void
FunctionDestructor(FunctionObject * self)3101 FunctionDestructor(FunctionObject *self)
3102 {
3103     int i;
3104     func_unref(self->name);
3105     vim_free(self->name);
3106     for (i = 0; i < self->argc; ++i)
3107 	clear_tv(&self->argv[i]);
3108     PyMem_Free(self->argv);
3109     dict_unref(self->self);
3110     if (self->argv || self->self)
3111 	pyll_remove(&self->ref, &lastfunc);
3112 
3113     DESTRUCTOR_FINISH(self);
3114 }
3115 
3116 static char *FunctionAttrs[] = {
3117     "softspace", "args", "self", "auto_rebind",
3118     NULL
3119 };
3120 
3121     static PyObject *
FunctionDir(PyObject * self,PyObject * args UNUSED)3122 FunctionDir(PyObject *self, PyObject *args UNUSED)
3123 {
3124     return ObjectDir(self, FunctionAttrs);
3125 }
3126 
3127     static PyObject *
FunctionAttr(FunctionObject * self,char * name)3128 FunctionAttr(FunctionObject *self, char *name)
3129 {
3130     list_T *list;
3131     int i;
3132     if (strcmp(name, "name") == 0)
3133 	return PyString_FromString((char *)(self->name));
3134     else if (strcmp(name, "args") == 0)
3135     {
3136 	if (self->argv == NULL || (list = list_alloc()) == NULL)
3137 	    return ALWAYS_NONE;
3138 
3139 	for (i = 0; i < self->argc; ++i)
3140 	    list_append_tv(list, &self->argv[i]);
3141 	return NEW_LIST(list);
3142     }
3143     else if (strcmp(name, "self") == 0)
3144 	return self->self == NULL
3145 	    ? ALWAYS_NONE
3146 	    : NEW_DICTIONARY(self->self);
3147     else if (strcmp(name, "auto_rebind") == 0)
3148 	return self->auto_rebind
3149 	    ? ALWAYS_TRUE
3150 	    : ALWAYS_FALSE;
3151     else if (strcmp(name, "__members__") == 0)
3152 	return ObjectDir(NULL, FunctionAttrs);
3153     return NULL;
3154 }
3155 
3156 /*
3157  * Populate partial_T given function object.
3158  *
3159  * "exported" should be set to true when it is needed to construct a partial
3160  * that may be stored in a variable (i.e. may be freed by Vim).
3161  */
3162     static void
set_partial(FunctionObject * self,partial_T * pt,int exported)3163 set_partial(FunctionObject *self, partial_T *pt, int exported)
3164 {
3165     int i;
3166 
3167     pt->pt_name = self->name;
3168     if (self->argv)
3169     {
3170 	pt->pt_argc = self->argc;
3171 	if (exported)
3172 	{
3173 	    pt->pt_argv = ALLOC_CLEAR_MULT(typval_T, self->argc);
3174 	    for (i = 0; i < pt->pt_argc; ++i)
3175 		copy_tv(&self->argv[i], &pt->pt_argv[i]);
3176 	}
3177 	else
3178 	    pt->pt_argv = self->argv;
3179     }
3180     else
3181     {
3182 	pt->pt_argc = 0;
3183 	pt->pt_argv = NULL;
3184     }
3185     pt->pt_auto = self->auto_rebind || !exported;
3186     pt->pt_dict = self->self;
3187     if (exported && self->self)
3188 	++pt->pt_dict->dv_refcount;
3189     if (exported)
3190 	pt->pt_name = vim_strsave(pt->pt_name);
3191     pt->pt_refcount = 1;
3192 }
3193 
3194     static PyObject *
FunctionCall(FunctionObject * self,PyObject * argsObject,PyObject * kwargs)3195 FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
3196 {
3197     char_u	*name = self->name;
3198     typval_T	args;
3199     typval_T	selfdicttv;
3200     typval_T	rettv;
3201     dict_T	*selfdict = NULL;
3202     PyObject	*selfdictObject;
3203     PyObject	*ret;
3204     int		error;
3205     partial_T	pt;
3206     partial_T	*pt_ptr = NULL;
3207 
3208     if (ConvertFromPySequence(argsObject, &args) == -1)
3209 	return NULL;
3210 
3211     if (kwargs != NULL)
3212     {
3213 	selfdictObject = PyDict_GetItemString(kwargs, "self");
3214 	if (selfdictObject != NULL)
3215 	{
3216 	    if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
3217 	    {
3218 		clear_tv(&args);
3219 		return NULL;
3220 	    }
3221 	    selfdict = selfdicttv.vval.v_dict;
3222 	}
3223     }
3224 
3225     if (self->argv || self->self)
3226     {
3227 	CLEAR_FIELD(pt);
3228 	set_partial(self, &pt, FALSE);
3229 	pt_ptr = &pt;
3230     }
3231 
3232     Py_BEGIN_ALLOW_THREADS
3233     Python_Lock_Vim();
3234 
3235     VimTryStart();
3236     error = func_call(name, &args, pt_ptr, selfdict, &rettv);
3237 
3238     Python_Release_Vim();
3239     Py_END_ALLOW_THREADS
3240 
3241     if (VimTryEnd())
3242 	ret = NULL;
3243     else if (error != OK)
3244     {
3245 	ret = NULL;
3246 	PyErr_VIM_FORMAT(N_("failed to run function %s"), (char *)name);
3247     }
3248     else
3249 	ret = ConvertToPyObject(&rettv);
3250 
3251     clear_tv(&args);
3252     clear_tv(&rettv);
3253     if (selfdict != NULL)
3254 	clear_tv(&selfdicttv);
3255 
3256     return ret;
3257 }
3258 
3259     static PyObject *
FunctionRepr(FunctionObject * self)3260 FunctionRepr(FunctionObject *self)
3261 {
3262     PyObject *ret;
3263     garray_T repr_ga;
3264     int i;
3265     char_u *tofree = NULL;
3266     typval_T tv;
3267     char_u numbuf[NUMBUFLEN];
3268 
3269     ga_init2(&repr_ga, (int)sizeof(char), 70);
3270     ga_concat(&repr_ga, (char_u *)"<vim.Function '");
3271     if (self->name)
3272 	ga_concat(&repr_ga, self->name);
3273     else
3274 	ga_concat(&repr_ga, (char_u *)"<NULL>");
3275     ga_append(&repr_ga, '\'');
3276     if (self->argv)
3277     {
3278 	ga_concat(&repr_ga, (char_u *)", args=[");
3279 	++emsg_silent;
3280 	for (i = 0; i < self->argc; i++)
3281 	{
3282 	    if (i != 0)
3283 		ga_concat(&repr_ga, (char_u *)", ");
3284 	    ga_concat(&repr_ga, tv2string(&self->argv[i], &tofree, numbuf,
3285 			get_copyID()));
3286 	    vim_free(tofree);
3287 	}
3288 	--emsg_silent;
3289 	ga_append(&repr_ga, ']');
3290     }
3291     if (self->self)
3292     {
3293 	ga_concat(&repr_ga, (char_u *)", self=");
3294 	tv.v_type = VAR_DICT;
3295 	tv.vval.v_dict = self->self;
3296 	++emsg_silent;
3297 	ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID()));
3298 	--emsg_silent;
3299 	vim_free(tofree);
3300 	if (self->auto_rebind)
3301 	    ga_concat(&repr_ga, (char_u *)", auto_rebind=True");
3302     }
3303     ga_append(&repr_ga, '>');
3304     ret = PyString_FromString((char *)repr_ga.ga_data);
3305     ga_clear(&repr_ga);
3306     return ret;
3307 }
3308 
3309 static struct PyMethodDef FunctionMethods[] = {
3310     {"__dir__",	(PyCFunction)FunctionDir,   METH_NOARGS,		""},
3311     { NULL,	NULL,			0,				NULL}
3312 };
3313 
3314 /*
3315  * Options object
3316  */
3317 
3318 static PyTypeObject OptionsType;
3319 
3320 typedef int (*checkfun)(void *);
3321 
3322 typedef struct
3323 {
3324     PyObject_HEAD
3325     int		opt_type;
3326     void	*from;
3327     checkfun	Check;
3328     PyObject	*fromObj;
3329 } OptionsObject;
3330 
3331     static int
dummy_check(void * arg UNUSED)3332 dummy_check(void *arg UNUSED)
3333 {
3334     return 0;
3335 }
3336 
3337     static PyObject *
OptionsNew(int opt_type,void * from,checkfun Check,PyObject * fromObj)3338 OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
3339 {
3340     OptionsObject	*self;
3341 
3342     self = PyObject_GC_New(OptionsObject, &OptionsType);
3343     if (self == NULL)
3344 	return NULL;
3345 
3346     self->opt_type = opt_type;
3347     self->from = from;
3348     self->Check = Check;
3349     self->fromObj = fromObj;
3350     if (fromObj)
3351 	Py_INCREF(fromObj);
3352 
3353     return (PyObject *)(self);
3354 }
3355 
3356     static void
OptionsDestructor(OptionsObject * self)3357 OptionsDestructor(OptionsObject *self)
3358 {
3359     PyObject_GC_UnTrack((void *)(self));
3360     Py_XDECREF(self->fromObj);
3361     PyObject_GC_Del((void *)(self));
3362 }
3363 
3364     static int
OptionsTraverse(OptionsObject * self,visitproc visit,void * arg)3365 OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
3366 {
3367     Py_VISIT(self->fromObj);
3368     return 0;
3369 }
3370 
3371     static int
OptionsClear(OptionsObject * self)3372 OptionsClear(OptionsObject *self)
3373 {
3374     Py_CLEAR(self->fromObj);
3375     return 0;
3376 }
3377 
3378     static PyObject *
OptionsItem(OptionsObject * self,PyObject * keyObject)3379 OptionsItem(OptionsObject *self, PyObject *keyObject)
3380 {
3381     char_u	*key;
3382     int		flags;
3383     long	numval;
3384     char_u	*stringval;
3385     PyObject	*todecref;
3386 
3387     if (self->Check(self->fromObj))
3388 	return NULL;
3389 
3390     if (!(key = StringToChars(keyObject, &todecref)))
3391 	return NULL;
3392 
3393     if (*key == NUL)
3394     {
3395 	RAISE_NO_EMPTY_KEYS;
3396 	Py_XDECREF(todecref);
3397 	return NULL;
3398     }
3399 
3400     flags = get_option_value_strict(key, &numval, &stringval,
3401 				    self->opt_type, self->from);
3402 
3403     Py_XDECREF(todecref);
3404 
3405     if (flags == 0)
3406     {
3407 	PyErr_SetObject(PyExc_KeyError, keyObject);
3408 	return NULL;
3409     }
3410 
3411     if (flags & SOPT_UNSET)
3412     {
3413 	Py_INCREF(Py_None);
3414 	return Py_None;
3415     }
3416     else if (flags & SOPT_BOOL)
3417     {
3418 	PyObject	*ret;
3419 	ret = numval ? Py_True : Py_False;
3420 	Py_INCREF(ret);
3421 	return ret;
3422     }
3423     else if (flags & SOPT_NUM)
3424 	return PyInt_FromLong(numval);
3425     else if (flags & SOPT_STRING)
3426     {
3427 	if (stringval)
3428 	{
3429 	    PyObject	*ret = PyBytes_FromString((char *)stringval);
3430 	    vim_free(stringval);
3431 	    return ret;
3432 	}
3433 	else
3434 	{
3435 	    PyErr_SET_STRING(PyExc_RuntimeError,
3436 		    N_("unable to get option value"));
3437 	    return NULL;
3438 	}
3439     }
3440     else
3441     {
3442 	PyErr_SET_VIM(N_("internal error: unknown option type"));
3443 	return NULL;
3444     }
3445 }
3446 
3447     static int
OptionsContains(OptionsObject * self,PyObject * keyObject)3448 OptionsContains(OptionsObject *self, PyObject *keyObject)
3449 {
3450     char_u	*key;
3451     PyObject	*todecref;
3452 
3453     if (!(key = StringToChars(keyObject, &todecref)))
3454 	return -1;
3455 
3456     if (*key == NUL)
3457     {
3458 	Py_XDECREF(todecref);
3459 	return 0;
3460     }
3461 
3462     if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL))
3463     {
3464 	Py_XDECREF(todecref);
3465 	return 1;
3466     }
3467     else
3468     {
3469 	Py_XDECREF(todecref);
3470 	return 0;
3471     }
3472 }
3473 
3474 typedef struct
3475 {
3476     void	*lastoption;
3477     int		opt_type;
3478 } optiterinfo_T;
3479 
3480     static PyObject *
OptionsIterNext(optiterinfo_T ** oii)3481 OptionsIterNext(optiterinfo_T **oii)
3482 {
3483     char_u	*name;
3484 
3485     if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type)))
3486 	return PyString_FromString((char *)name);
3487 
3488     return NULL;
3489 }
3490 
3491     static PyObject *
OptionsIter(OptionsObject * self)3492 OptionsIter(OptionsObject *self)
3493 {
3494     optiterinfo_T	*oii;
3495 
3496     if (!(oii = PyMem_New(optiterinfo_T, 1)))
3497     {
3498 	PyErr_NoMemory();
3499 	return NULL;
3500     }
3501 
3502     oii->opt_type = self->opt_type;
3503     oii->lastoption = NULL;
3504 
3505     return IterNew(oii,
3506 	    (destructorfun)(void *) PyMem_Free, (nextfun) OptionsIterNext,
3507 	    NULL, NULL, (PyObject *)self);
3508 }
3509 
3510     static int
set_option_value_err(char_u * key,int numval,char_u * stringval,int opt_flags)3511 set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
3512 {
3513     char	*errmsg;
3514 
3515     if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
3516     {
3517 	if (VimTryEnd())
3518 	    return FAIL;
3519 	PyErr_SetVim(errmsg);
3520 	return FAIL;
3521     }
3522     return OK;
3523 }
3524 
3525     static int
set_option_value_for(char_u * key,int numval,char_u * stringval,int opt_flags,int opt_type,void * from)3526 set_option_value_for(
3527 	char_u *key,
3528 	int numval,
3529 	char_u *stringval,
3530 	int opt_flags,
3531 	int opt_type,
3532 	void *from)
3533 {
3534     win_T	*save_curwin = NULL;
3535     tabpage_T	*save_curtab = NULL;
3536     bufref_T	save_curbuf;
3537     int		set_ret = 0;
3538 
3539     VimTryStart();
3540     switch (opt_type)
3541     {
3542 	case SREQ_WIN:
3543 	    if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
3544 			      win_find_tabpage((win_T *)from), FALSE) == FAIL)
3545 	    {
3546 		restore_win(save_curwin, save_curtab, TRUE);
3547 		if (VimTryEnd())
3548 		    return -1;
3549 		PyErr_SET_VIM(N_("problem while switching windows"));
3550 		return -1;
3551 	    }
3552 	    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3553 	    restore_win(save_curwin, save_curtab, TRUE);
3554 	    break;
3555 	case SREQ_BUF:
3556 	    switch_buffer(&save_curbuf, (buf_T *)from);
3557 	    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3558 	    restore_buffer(&save_curbuf);
3559 	    break;
3560 	case SREQ_GLOBAL:
3561 	    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
3562 	    break;
3563     }
3564     if (set_ret == FAIL)
3565 	return -1;
3566     return VimTryEnd();
3567 }
3568 
3569     static int
OptionsAssItem(OptionsObject * self,PyObject * keyObject,PyObject * valObject)3570 OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
3571 {
3572     char_u	*key;
3573     int		flags;
3574     int		opt_flags;
3575     int		ret = 0;
3576     PyObject	*todecref;
3577 
3578     if (self->Check(self->fromObj))
3579 	return -1;
3580 
3581     if (!(key = StringToChars(keyObject, &todecref)))
3582 	return -1;
3583 
3584     if (*key == NUL)
3585     {
3586 	RAISE_NO_EMPTY_KEYS;
3587 	Py_XDECREF(todecref);
3588 	return -1;
3589     }
3590 
3591     flags = get_option_value_strict(key, NULL, NULL,
3592 				    self->opt_type, self->from);
3593 
3594     if (flags == 0)
3595     {
3596 	PyErr_SetObject(PyExc_KeyError, keyObject);
3597 	Py_XDECREF(todecref);
3598 	return -1;
3599     }
3600 
3601     if (valObject == NULL)
3602     {
3603 	if (self->opt_type == SREQ_GLOBAL)
3604 	{
3605 	    PyErr_FORMAT(PyExc_ValueError,
3606 		    N_("unable to unset global option %s"), key);
3607 	    Py_XDECREF(todecref);
3608 	    return -1;
3609 	}
3610 	else if (!(flags & SOPT_GLOBAL))
3611 	{
3612 	    PyErr_FORMAT(PyExc_ValueError,
3613 		    N_("unable to unset option %s "
3614 		       "which does not have global value"), key);
3615 	    Py_XDECREF(todecref);
3616 	    return -1;
3617 	}
3618 	else
3619 	{
3620 	    unset_global_local_option(key, self->from);
3621 	    Py_XDECREF(todecref);
3622 	    return 0;
3623 	}
3624     }
3625 
3626     opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
3627 
3628     if (flags & SOPT_BOOL)
3629     {
3630 	int	istrue = PyObject_IsTrue(valObject);
3631 
3632 	if (istrue == -1)
3633 	    ret = -1;
3634 	else
3635 	    ret = set_option_value_for(key, istrue, NULL,
3636 				    opt_flags, self->opt_type, self->from);
3637     }
3638     else if (flags & SOPT_NUM)
3639     {
3640 	long	val;
3641 
3642 	if (NumberToLong(valObject, &val, NUMBER_INT))
3643 	{
3644 	    Py_XDECREF(todecref);
3645 	    return -1;
3646 	}
3647 
3648 	ret = set_option_value_for(key, (int) val, NULL, opt_flags,
3649 				self->opt_type, self->from);
3650     }
3651     else
3652     {
3653 	char_u		*val;
3654 	PyObject	*todecref2;
3655 
3656 	if ((val = StringToChars(valObject, &todecref2)))
3657 	{
3658 	    ret = set_option_value_for(key, 0, val, opt_flags,
3659 				    self->opt_type, self->from);
3660 	    Py_XDECREF(todecref2);
3661 	}
3662 	else
3663 	    ret = -1;
3664     }
3665 
3666     Py_XDECREF(todecref);
3667 
3668     return ret;
3669 }
3670 
3671 static PySequenceMethods OptionsAsSeq = {
3672     0,					// sq_length
3673     0,					// sq_concat
3674     0,					// sq_repeat
3675     0,					// sq_item
3676     0,					// sq_slice
3677     0,					// sq_ass_item
3678     0,					// sq_ass_slice
3679     (objobjproc) OptionsContains,	// sq_contains
3680     0,					// sq_inplace_concat
3681     0,					// sq_inplace_repeat
3682 };
3683 
3684 static PyMappingMethods OptionsAsMapping = {
3685     (lenfunc)       NULL,
3686     (binaryfunc)    OptionsItem,
3687     (objobjargproc) OptionsAssItem,
3688 };
3689 
3690 // Tabpage object
3691 
3692 typedef struct
3693 {
3694     PyObject_HEAD
3695     tabpage_T	*tab;
3696 } TabPageObject;
3697 
3698 static PyObject *WinListNew(TabPageObject *tabObject);
3699 
3700 static PyTypeObject TabPageType;
3701 
3702     static int
CheckTabPage(TabPageObject * self)3703 CheckTabPage(TabPageObject *self)
3704 {
3705     if (self->tab == INVALID_TABPAGE_VALUE)
3706     {
3707 	PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
3708 	return -1;
3709     }
3710 
3711     return 0;
3712 }
3713 
3714     static PyObject *
TabPageNew(tabpage_T * tab)3715 TabPageNew(tabpage_T *tab)
3716 {
3717     TabPageObject *self;
3718 
3719     if (TAB_PYTHON_REF(tab))
3720     {
3721 	self = TAB_PYTHON_REF(tab);
3722 	Py_INCREF(self);
3723     }
3724     else
3725     {
3726 	self = PyObject_NEW(TabPageObject, &TabPageType);
3727 	if (self == NULL)
3728 	    return NULL;
3729 	self->tab = tab;
3730 	TAB_PYTHON_REF(tab) = self;
3731     }
3732 
3733     return (PyObject *)(self);
3734 }
3735 
3736     static void
TabPageDestructor(TabPageObject * self)3737 TabPageDestructor(TabPageObject *self)
3738 {
3739     if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
3740 	TAB_PYTHON_REF(self->tab) = NULL;
3741 
3742     DESTRUCTOR_FINISH(self);
3743 }
3744 
3745 static char *TabPageAttrs[] = {
3746     "windows", "number", "vars", "window", "valid",
3747     NULL
3748 };
3749 
3750     static PyObject *
TabPageDir(PyObject * self,PyObject * args UNUSED)3751 TabPageDir(PyObject *self, PyObject *args UNUSED)
3752 {
3753     return ObjectDir(self, TabPageAttrs);
3754 }
3755 
3756     static PyObject *
TabPageAttrValid(TabPageObject * self,char * name)3757 TabPageAttrValid(TabPageObject *self, char *name)
3758 {
3759     PyObject	*ret;
3760 
3761     if (strcmp(name, "valid") != 0)
3762 	return NULL;
3763 
3764     ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
3765     Py_INCREF(ret);
3766     return ret;
3767 }
3768 
3769     static PyObject *
TabPageAttr(TabPageObject * self,char * name)3770 TabPageAttr(TabPageObject *self, char *name)
3771 {
3772     if (strcmp(name, "windows") == 0)
3773 	return WinListNew(self);
3774     else if (strcmp(name, "number") == 0)
3775 	return PyLong_FromLong((long) get_tab_number(self->tab));
3776     else if (strcmp(name, "vars") == 0)
3777 	return NEW_DICTIONARY(self->tab->tp_vars);
3778     else if (strcmp(name, "window") == 0)
3779     {
3780 	// For current tab window.c does not bother to set or update tp_curwin
3781 	if (self->tab == curtab)
3782 	    return WindowNew(curwin, curtab);
3783 	else
3784 	    return WindowNew(self->tab->tp_curwin, self->tab);
3785     }
3786     else if (strcmp(name, "__members__") == 0)
3787 	return ObjectDir(NULL, TabPageAttrs);
3788     return NULL;
3789 }
3790 
3791     static PyObject *
TabPageRepr(TabPageObject * self)3792 TabPageRepr(TabPageObject *self)
3793 {
3794     if (self->tab == INVALID_TABPAGE_VALUE)
3795 	return PyString_FromFormat("<tabpage object (deleted) at %p>", (self));
3796     else
3797     {
3798 	int	t = get_tab_number(self->tab);
3799 
3800 	if (t == 0)
3801 	    return PyString_FromFormat("<tabpage object (unknown) at %p>",
3802 					(self));
3803 	else
3804 	    return PyString_FromFormat("<tabpage %d>", t - 1);
3805     }
3806 }
3807 
3808 static struct PyMethodDef TabPageMethods[] = {
3809     // name,	    function,			calling,	documentation
3810     {"__dir__",	    (PyCFunction)TabPageDir,	METH_NOARGS,	""},
3811     { NULL,	    NULL,			0,		NULL}
3812 };
3813 
3814 /*
3815  * Window list object
3816  */
3817 
3818 static PyTypeObject TabListType;
3819 static PySequenceMethods TabListAsSeq;
3820 
3821 typedef struct
3822 {
3823     PyObject_HEAD
3824 } TabListObject;
3825 
3826     static PyInt
TabListLength(PyObject * self UNUSED)3827 TabListLength(PyObject *self UNUSED)
3828 {
3829     tabpage_T	*tp = first_tabpage;
3830     PyInt	n = 0;
3831 
3832     while (tp != NULL)
3833     {
3834 	++n;
3835 	tp = tp->tp_next;
3836     }
3837 
3838     return n;
3839 }
3840 
3841     static PyObject *
TabListItem(PyObject * self UNUSED,PyInt n)3842 TabListItem(PyObject *self UNUSED, PyInt n)
3843 {
3844     tabpage_T	*tp;
3845 
3846     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
3847 	if (n == 0)
3848 	    return TabPageNew(tp);
3849 
3850     PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
3851     return NULL;
3852 }
3853 
3854 /*
3855  * Window object
3856  */
3857 
3858 typedef struct
3859 {
3860     PyObject_HEAD
3861     win_T	*win;
3862     TabPageObject	*tabObject;
3863 } WindowObject;
3864 
3865 static PyTypeObject WindowType;
3866 
3867     static int
CheckWindow(WindowObject * self)3868 CheckWindow(WindowObject *self)
3869 {
3870     if (self->win == INVALID_WINDOW_VALUE)
3871     {
3872 	PyErr_SET_VIM(N_("attempt to refer to deleted window"));
3873 	return -1;
3874     }
3875 
3876     return 0;
3877 }
3878 
3879     static PyObject *
WindowNew(win_T * win,tabpage_T * tab)3880 WindowNew(win_T *win, tabpage_T *tab)
3881 {
3882     /*
3883      * We need to handle deletion of windows underneath us.
3884      * If we add a "w_python*_ref" field to the win_T structure,
3885      * then we can get at it in win_free() in vim. We then
3886      * need to create only ONE Python object per window - if
3887      * we try to create a second, just INCREF the existing one
3888      * and return it. The (single) Python object referring to
3889      * the window is stored in "w_python*_ref".
3890      * On a win_free() we set the Python object's win_T* field
3891      * to an invalid value. We trap all uses of a window
3892      * object, and reject them if the win_T* field is invalid.
3893      *
3894      * Python2 and Python3 get different fields and different objects:
3895      * w_python_ref and w_python3_ref fields respectively.
3896      */
3897 
3898     WindowObject *self;
3899 
3900     if (WIN_PYTHON_REF(win))
3901     {
3902 	self = WIN_PYTHON_REF(win);
3903 	Py_INCREF(self);
3904     }
3905     else
3906     {
3907 	self = PyObject_GC_New(WindowObject, &WindowType);
3908 	if (self == NULL)
3909 	    return NULL;
3910 	self->win = win;
3911 	WIN_PYTHON_REF(win) = self;
3912     }
3913 
3914     self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
3915 
3916     return (PyObject *)(self);
3917 }
3918 
3919     static void
WindowDestructor(WindowObject * self)3920 WindowDestructor(WindowObject *self)
3921 {
3922     PyObject_GC_UnTrack((void *)(self));
3923     if (self->win && self->win != INVALID_WINDOW_VALUE)
3924 	WIN_PYTHON_REF(self->win) = NULL;
3925     Py_XDECREF(((PyObject *)(self->tabObject)));
3926     PyObject_GC_Del((void *)(self));
3927 }
3928 
3929     static int
WindowTraverse(WindowObject * self,visitproc visit,void * arg)3930 WindowTraverse(WindowObject *self, visitproc visit, void *arg)
3931 {
3932     Py_VISIT(((PyObject *)(self->tabObject)));
3933     return 0;
3934 }
3935 
3936     static int
WindowClear(WindowObject * self)3937 WindowClear(WindowObject *self)
3938 {
3939     Py_CLEAR(self->tabObject);
3940     return 0;
3941 }
3942 
3943     static win_T *
get_firstwin(TabPageObject * tabObject)3944 get_firstwin(TabPageObject *tabObject)
3945 {
3946     if (tabObject)
3947     {
3948 	if (CheckTabPage(tabObject))
3949 	    return NULL;
3950 	// For current tab window.c does not bother to set or update tp_firstwin
3951 	else if (tabObject->tab == curtab)
3952 	    return firstwin;
3953 	else
3954 	    return tabObject->tab->tp_firstwin;
3955     }
3956     else
3957 	return firstwin;
3958 }
3959 
3960 // Use the same order as in the WindowAttr() function.
3961 static char *WindowAttrs[] = {
3962     "buffer",
3963     "cursor",
3964     "height",
3965     "row",
3966     "width",
3967     "col",
3968     "vars",
3969     "options",
3970     "number",
3971     "tabpage",
3972     "valid",
3973     NULL
3974 };
3975 
3976     static PyObject *
WindowDir(PyObject * self,PyObject * args UNUSED)3977 WindowDir(PyObject *self, PyObject *args UNUSED)
3978 {
3979     return ObjectDir(self, WindowAttrs);
3980 }
3981 
3982     static PyObject *
WindowAttrValid(WindowObject * self,char * name)3983 WindowAttrValid(WindowObject *self, char *name)
3984 {
3985     PyObject	*ret;
3986 
3987     if (strcmp(name, "valid") != 0)
3988 	return NULL;
3989 
3990     ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
3991     Py_INCREF(ret);
3992     return ret;
3993 }
3994 
3995     static PyObject *
WindowAttr(WindowObject * self,char * name)3996 WindowAttr(WindowObject *self, char *name)
3997 {
3998     if (strcmp(name, "buffer") == 0)
3999 	return (PyObject *)BufferNew(self->win->w_buffer);
4000     else if (strcmp(name, "cursor") == 0)
4001     {
4002 	pos_T *pos = &self->win->w_cursor;
4003 
4004 	return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
4005     }
4006     else if (strcmp(name, "height") == 0)
4007 	return PyLong_FromLong((long)(self->win->w_height));
4008     else if (strcmp(name, "row") == 0)
4009 	return PyLong_FromLong((long)(self->win->w_winrow));
4010     else if (strcmp(name, "width") == 0)
4011 	return PyLong_FromLong((long)(self->win->w_width));
4012     else if (strcmp(name, "col") == 0)
4013 	return PyLong_FromLong((long)(self->win->w_wincol));
4014     else if (strcmp(name, "vars") == 0)
4015 	return NEW_DICTIONARY(self->win->w_vars);
4016     else if (strcmp(name, "options") == 0)
4017 	return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
4018 			(PyObject *) self);
4019     else if (strcmp(name, "number") == 0)
4020     {
4021 	if (CheckTabPage(self->tabObject))
4022 	    return NULL;
4023 	return PyLong_FromLong((long)
4024 		get_win_number(self->win, get_firstwin(self->tabObject)));
4025     }
4026     else if (strcmp(name, "tabpage") == 0)
4027     {
4028 	Py_INCREF(self->tabObject);
4029 	return (PyObject *)(self->tabObject);
4030     }
4031     else if (strcmp(name, "__members__") == 0)
4032 	return ObjectDir(NULL, WindowAttrs);
4033     else
4034 	return NULL;
4035 }
4036 
4037     static int
WindowSetattr(WindowObject * self,char * name,PyObject * valObject)4038 WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
4039 {
4040     if (CheckWindow(self))
4041 	return -1;
4042 
4043     if (strcmp(name, "buffer") == 0)
4044     {
4045 	PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
4046 	return -1;
4047     }
4048     else if (strcmp(name, "cursor") == 0)
4049     {
4050 	long lnum;
4051 	long col;
4052 
4053 	if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
4054 	    return -1;
4055 
4056 	if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
4057 	{
4058 	    PyErr_SET_VIM(N_("cursor position outside buffer"));
4059 	    return -1;
4060 	}
4061 
4062 	// Check for keyboard interrupts
4063 	if (VimCheckInterrupt())
4064 	    return -1;
4065 
4066 	self->win->w_cursor.lnum = lnum;
4067 	self->win->w_cursor.col = col;
4068 	self->win->w_set_curswant = TRUE;
4069 	self->win->w_cursor.coladd = 0;
4070 	// When column is out of range silently correct it.
4071 	check_cursor_col_win(self->win);
4072 
4073 	update_screen(VALID);
4074 	return 0;
4075     }
4076     else if (strcmp(name, "height") == 0)
4077     {
4078 	long	height;
4079 	win_T	*savewin;
4080 
4081 	if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
4082 	    return -1;
4083 
4084 #ifdef FEAT_GUI
4085 	need_mouse_correct = TRUE;
4086 #endif
4087 	savewin = curwin;
4088 	curwin = self->win;
4089 
4090 	VimTryStart();
4091 	win_setheight((int) height);
4092 	curwin = savewin;
4093 	if (VimTryEnd())
4094 	    return -1;
4095 
4096 	return 0;
4097     }
4098     else if (strcmp(name, "width") == 0)
4099     {
4100 	long	width;
4101 	win_T	*savewin;
4102 
4103 	if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
4104 	    return -1;
4105 
4106 #ifdef FEAT_GUI
4107 	need_mouse_correct = TRUE;
4108 #endif
4109 	savewin = curwin;
4110 	curwin = self->win;
4111 
4112 	VimTryStart();
4113 	win_setwidth((int) width);
4114 	curwin = savewin;
4115 	if (VimTryEnd())
4116 	    return -1;
4117 
4118 	return 0;
4119     }
4120     else
4121     {
4122 	PyErr_SetString(PyExc_AttributeError, name);
4123 	return -1;
4124     }
4125 }
4126 
4127     static PyObject *
WindowRepr(WindowObject * self)4128 WindowRepr(WindowObject *self)
4129 {
4130     if (self->win == INVALID_WINDOW_VALUE)
4131 	return PyString_FromFormat("<window object (deleted) at %p>", (self));
4132     else
4133     {
4134 	int	w = get_win_number(self->win, firstwin);
4135 
4136 	if (w == 0)
4137 	    return PyString_FromFormat("<window object (unknown) at %p>",
4138 								      (self));
4139 	else
4140 	    return PyString_FromFormat("<window %d>", w - 1);
4141     }
4142 }
4143 
4144 static struct PyMethodDef WindowMethods[] = {
4145     // name,	    function,			calling,	documentation
4146     {"__dir__",	    (PyCFunction)WindowDir,	METH_NOARGS,	""},
4147     { NULL,	    NULL,			0,		NULL}
4148 };
4149 
4150 /*
4151  * Window list object
4152  */
4153 
4154 static PyTypeObject WinListType;
4155 static PySequenceMethods WinListAsSeq;
4156 
4157 typedef struct
4158 {
4159     PyObject_HEAD
4160     TabPageObject	*tabObject;
4161 } WinListObject;
4162 
4163     static PyObject *
WinListNew(TabPageObject * tabObject)4164 WinListNew(TabPageObject *tabObject)
4165 {
4166     WinListObject	*self;
4167 
4168     self = PyObject_NEW(WinListObject, &WinListType);
4169     self->tabObject = tabObject;
4170     Py_INCREF(tabObject);
4171 
4172     return (PyObject *)(self);
4173 }
4174 
4175     static void
WinListDestructor(WinListObject * self)4176 WinListDestructor(WinListObject *self)
4177 {
4178     TabPageObject	*tabObject = self->tabObject;
4179 
4180     if (tabObject)
4181     {
4182 	Py_DECREF((PyObject *)(tabObject));
4183     }
4184 
4185     DESTRUCTOR_FINISH(self);
4186 }
4187 
4188     static PyInt
WinListLength(WinListObject * self)4189 WinListLength(WinListObject *self)
4190 {
4191     win_T	*w;
4192     PyInt	n = 0;
4193 
4194     if (!(w = get_firstwin(self->tabObject)))
4195 	return -1;
4196 
4197     while (w != NULL)
4198     {
4199 	++n;
4200 	w = W_NEXT(w);
4201     }
4202 
4203     return n;
4204 }
4205 
4206     static PyObject *
WinListItem(WinListObject * self,PyInt n)4207 WinListItem(WinListObject *self, PyInt n)
4208 {
4209     win_T *w;
4210 
4211     if (!(w = get_firstwin(self->tabObject)))
4212 	return NULL;
4213 
4214     for (; w != NULL; w = W_NEXT(w), --n)
4215 	if (n == 0)
4216 	    return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
4217 
4218     PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
4219     return NULL;
4220 }
4221 
4222 /*
4223  * Convert a Python string into a Vim line.
4224  *
4225  * The result is in allocated memory. All internal nulls are replaced by
4226  * newline characters. It is an error for the string to contain newline
4227  * characters.
4228  *
4229  * On errors, the Python exception data is set, and NULL is returned.
4230  */
4231     static char *
StringToLine(PyObject * obj)4232 StringToLine(PyObject *obj)
4233 {
4234     char	*str;
4235     char	*save;
4236     PyObject	*bytes = NULL;
4237     Py_ssize_t	len = 0;
4238     PyInt	i;
4239     char	*p;
4240 
4241     if (PyBytes_Check(obj))
4242     {
4243 	if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
4244 		|| str == NULL)
4245 	    return NULL;
4246     }
4247     else if (PyUnicode_Check(obj))
4248     {
4249 	if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT,
4250 							   ERRORS_ENCODE_ARG)))
4251 	    return NULL;
4252 
4253 	if (PyBytes_AsStringAndSize(bytes, &str, &len) == -1
4254 		|| str == NULL)
4255 	{
4256 	    Py_DECREF(bytes);
4257 	    return NULL;
4258 	}
4259     }
4260     else
4261     {
4262 #if PY_MAJOR_VERSION < 3
4263 	PyErr_FORMAT(PyExc_TypeError,
4264 		N_("expected str() or unicode() instance, but got %s"),
4265 		Py_TYPE_NAME(obj));
4266 #else
4267 	PyErr_FORMAT(PyExc_TypeError,
4268 		N_("expected bytes() or str() instance, but got %s"),
4269 		Py_TYPE_NAME(obj));
4270 #endif
4271 	return NULL;
4272     }
4273 
4274     /*
4275      * Error checking: String must not contain newlines, as we
4276      * are replacing a single line, and we must replace it with
4277      * a single line.
4278      * A trailing newline is removed, so that append(f.readlines()) works.
4279      */
4280     p = memchr(str, '\n', len);
4281     if (p != NULL)
4282     {
4283 	if (p == str + len - 1)
4284 	    --len;
4285 	else
4286 	{
4287 	    PyErr_SET_VIM(N_("string cannot contain newlines"));
4288 	    Py_XDECREF(bytes);
4289 	    return NULL;
4290 	}
4291     }
4292 
4293     /*
4294      * Create a copy of the string, with internal nulls replaced by
4295      * newline characters, as is the Vim convention.
4296      */
4297     save = alloc(len+1);
4298     if (save == NULL)
4299     {
4300 	PyErr_NoMemory();
4301 	Py_XDECREF(bytes);
4302 	return NULL;
4303     }
4304 
4305     for (i = 0; i < len; ++i)
4306     {
4307 	if (str[i] == '\0')
4308 	    save[i] = '\n';
4309 	else
4310 	    save[i] = str[i];
4311     }
4312 
4313     save[i] = '\0';
4314     Py_XDECREF(bytes);  // Python 2 does nothing here
4315 
4316     return save;
4317 }
4318 
4319 /*
4320  * Get a line from the specified buffer. The line number is
4321  * in Vim format (1-based). The line is returned as a Python
4322  * string object.
4323  */
4324     static PyObject *
GetBufferLine(buf_T * buf,PyInt n)4325 GetBufferLine(buf_T *buf, PyInt n)
4326 {
4327     return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
4328 }
4329 
4330 
4331 /*
4332  * Get a list of lines from the specified buffer. The line numbers
4333  * are in Vim format (1-based). The range is from lo up to, but not
4334  * including, hi. The list is returned as a Python list of string objects.
4335  */
4336     static PyObject *
GetBufferLineList(buf_T * buf,PyInt lo,PyInt hi)4337 GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
4338 {
4339     PyInt	i;
4340     PyInt	n = hi - lo;
4341     PyObject	*list = PyList_New(n);
4342 
4343     if (list == NULL)
4344 	return NULL;
4345 
4346     for (i = 0; i < n; ++i)
4347     {
4348 	linenr_T	lnum = (linenr_T)(lo + i);
4349 	char		*text;
4350 	PyObject	*string;
4351 
4352 	if (lnum > buf->b_ml.ml_line_count)
4353 	    text = "";
4354 	else
4355 	    text = (char *)ml_get_buf(buf, lnum, FALSE);
4356 	string = LineToString(text);
4357 	if (string == NULL)
4358 	{
4359 	    Py_DECREF(list);
4360 	    return NULL;
4361 	}
4362 
4363 	PyList_SET_ITEM(list, i, string);
4364     }
4365 
4366     // The ownership of the Python list is passed to the caller (ie,
4367     // the caller should Py_DECREF() the object when it is finished
4368     // with it).
4369 
4370     return list;
4371 }
4372 
4373 /*
4374  * Check if deleting lines made the cursor position invalid.
4375  * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
4376  * deleted).
4377  */
4378     static void
py_fix_cursor(linenr_T lo,linenr_T hi,linenr_T extra)4379 py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
4380 {
4381     if (curwin->w_cursor.lnum >= lo)
4382     {
4383 	// Adjust the cursor position if it's in/after the changed
4384 	// lines.
4385 	if (curwin->w_cursor.lnum >= hi)
4386 	{
4387 	    curwin->w_cursor.lnum += extra;
4388 	    check_cursor_col();
4389 	}
4390 	else if (extra < 0)
4391 	{
4392 	    curwin->w_cursor.lnum = lo;
4393 	    check_cursor();
4394 	}
4395 	else
4396 	    check_cursor_col();
4397 	changed_cline_bef_curs();
4398     }
4399     invalidate_botline();
4400 }
4401 
4402 /*
4403  * Replace a line in the specified buffer. The line number is
4404  * in Vim format (1-based). The replacement line is given as
4405  * a Python string object. The object is checked for validity
4406  * and correct format. Errors are returned as a value of FAIL.
4407  * The return value is OK on success.
4408  * If OK is returned and len_change is not NULL, *len_change
4409  * is set to the change in the buffer length.
4410  */
4411     static int
SetBufferLine(buf_T * buf,PyInt n,PyObject * line,PyInt * len_change)4412 SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
4413 {
4414     bufref_T	save_curbuf = {NULL, 0, 0};
4415     win_T	*save_curwin = NULL;
4416     tabpage_T	*save_curtab = NULL;
4417 
4418     // First of all, we check the type of the supplied Python object.
4419     // There are three cases:
4420     //	  1. NULL, or None - this is a deletion.
4421     //	  2. A string	   - this is a replacement.
4422     //	  3. Anything else - this is an error.
4423     if (line == Py_None || line == NULL)
4424     {
4425 	PyErr_Clear();
4426 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4427 
4428 	VimTryStart();
4429 
4430 	if (u_savedel((linenr_T)n, 1L) == FAIL)
4431 	    RAISE_UNDO_FAIL;
4432 	else if (ml_delete((linenr_T)n) == FAIL)
4433 	    RAISE_DELETE_LINE_FAIL;
4434 	else
4435 	{
4436 	    if (buf == curbuf && (save_curwin != NULL
4437 					   || save_curbuf.br_buf == NULL))
4438 		// Using an existing window for the buffer, adjust the cursor
4439 		// position.
4440 		py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
4441 	    if (save_curbuf.br_buf == NULL)
4442 		// Only adjust marks if we managed to switch to a window that
4443 		// holds the buffer, otherwise line numbers will be invalid.
4444 		deleted_lines_mark((linenr_T)n, 1L);
4445 	}
4446 
4447 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4448 
4449 	if (VimTryEnd())
4450 	    return FAIL;
4451 
4452 	if (len_change)
4453 	    *len_change = -1;
4454 
4455 	return OK;
4456     }
4457     else if (PyBytes_Check(line) || PyUnicode_Check(line))
4458     {
4459 	char	*save = StringToLine(line);
4460 
4461 	if (save == NULL)
4462 	    return FAIL;
4463 
4464 	VimTryStart();
4465 
4466 	// We do not need to free "save" if ml_replace() consumes it.
4467 	PyErr_Clear();
4468 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4469 
4470 	if (u_savesub((linenr_T)n) == FAIL)
4471 	{
4472 	    RAISE_UNDO_FAIL;
4473 	    vim_free(save);
4474 	}
4475 	else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
4476 	{
4477 	    RAISE_REPLACE_LINE_FAIL;
4478 	    vim_free(save);
4479 	}
4480 	else
4481 	    changed_bytes((linenr_T)n, 0);
4482 
4483 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4484 
4485 	// Check that the cursor is not beyond the end of the line now.
4486 	if (buf == curbuf)
4487 	    check_cursor_col();
4488 
4489 	if (VimTryEnd())
4490 	    return FAIL;
4491 
4492 	if (len_change)
4493 	    *len_change = 0;
4494 
4495 	return OK;
4496     }
4497     else
4498     {
4499 	PyErr_BadArgument();
4500 	return FAIL;
4501     }
4502 }
4503 
4504 /*
4505  * Replace a range of lines in the specified buffer. The line numbers are in
4506  * Vim format (1-based). The range is from lo up to, but not including, hi.
4507  * The replacement lines are given as a Python list of string objects. The
4508  * list is checked for validity and correct format. Errors are returned as a
4509  * value of FAIL.  The return value is OK on success.
4510  * If OK is returned and len_change is not NULL, *len_change
4511  * is set to the change in the buffer length.
4512  */
4513     static int
SetBufferLineList(buf_T * buf,PyInt lo,PyInt hi,PyObject * list,PyInt * len_change)4514 SetBufferLineList(
4515 	buf_T *buf,
4516 	PyInt lo,
4517 	PyInt hi,
4518 	PyObject *list,
4519 	PyInt *len_change)
4520 {
4521     bufref_T	save_curbuf = {NULL, 0, 0};
4522     win_T	*save_curwin = NULL;
4523     tabpage_T	*save_curtab = NULL;
4524 
4525     // First of all, we check the type of the supplied Python object.
4526     // There are three cases:
4527     //	  1. NULL, or None - this is a deletion.
4528     //	  2. A list	   - this is a replacement.
4529     //	  3. Anything else - this is an error.
4530     if (list == Py_None || list == NULL)
4531     {
4532 	PyInt	i;
4533 	PyInt	n = (int)(hi - lo);
4534 
4535 	PyErr_Clear();
4536 	VimTryStart();
4537 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4538 
4539 	if (u_savedel((linenr_T)lo, (long)n) == FAIL)
4540 	    RAISE_UNDO_FAIL;
4541 	else
4542 	{
4543 	    for (i = 0; i < n; ++i)
4544 	    {
4545 		if (ml_delete((linenr_T)lo) == FAIL)
4546 		{
4547 		    RAISE_DELETE_LINE_FAIL;
4548 		    break;
4549 		}
4550 	    }
4551 	    if (buf == curbuf && (save_curwin != NULL
4552 					       || save_curbuf.br_buf == NULL))
4553 		// Using an existing window for the buffer, adjust the cursor
4554 		// position.
4555 		py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
4556 	    if (save_curbuf.br_buf == NULL)
4557 		// Only adjust marks if we managed to switch to a window that
4558 		// holds the buffer, otherwise line numbers will be invalid.
4559 		deleted_lines_mark((linenr_T)lo, (long)i);
4560 	}
4561 
4562 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4563 
4564 	if (VimTryEnd())
4565 	    return FAIL;
4566 
4567 	if (len_change)
4568 	    *len_change = -n;
4569 
4570 	return OK;
4571     }
4572     else if (PyList_Check(list))
4573     {
4574 	PyInt	i;
4575 	PyInt	new_len = PyList_Size(list);
4576 	PyInt	old_len = hi - lo;
4577 	PyInt	extra = 0;	// lines added to text, can be negative
4578 	char	**array;
4579 
4580 	if (new_len == 0)	// avoid allocating zero bytes
4581 	    array = NULL;
4582 	else
4583 	{
4584 	    array = PyMem_New(char *, new_len);
4585 	    if (array == NULL)
4586 	    {
4587 		PyErr_NoMemory();
4588 		return FAIL;
4589 	    }
4590 	}
4591 
4592 	for (i = 0; i < new_len; ++i)
4593 	{
4594 	    PyObject *line;
4595 
4596 	    if (!(line = PyList_GetItem(list, i)) ||
4597 		!(array[i] = StringToLine(line)))
4598 	    {
4599 		while (i)
4600 		    vim_free(array[--i]);
4601 		PyMem_Free(array);
4602 		return FAIL;
4603 	    }
4604 	}
4605 
4606 	VimTryStart();
4607 	PyErr_Clear();
4608 
4609 	// START of region without "return".  Must call restore_buffer()!
4610 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4611 
4612 	if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
4613 	    RAISE_UNDO_FAIL;
4614 
4615 	// If the size of the range is reducing (ie, new_len < old_len) we
4616 	// need to delete some old_len. We do this at the start, by
4617 	// repeatedly deleting line "lo".
4618 	if (!PyErr_Occurred())
4619 	{
4620 	    for (i = 0; i < old_len - new_len; ++i)
4621 		if (ml_delete((linenr_T)lo) == FAIL)
4622 		{
4623 		    RAISE_DELETE_LINE_FAIL;
4624 		    break;
4625 		}
4626 	    extra -= i;
4627 	}
4628 
4629 	// For as long as possible, replace the existing old_len with the
4630 	// new old_len. This is a more efficient operation, as it requires
4631 	// less memory allocation and freeing.
4632 	if (!PyErr_Occurred())
4633 	{
4634 	    for (i = 0; i < old_len && i < new_len; ++i)
4635 		if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
4636 								      == FAIL)
4637 		{
4638 		    RAISE_REPLACE_LINE_FAIL;
4639 		    break;
4640 		}
4641 	}
4642 	else
4643 	    i = 0;
4644 
4645 	// Now we may need to insert the remaining new old_len. If we do, we
4646 	// must free the strings as we finish with them (we can't pass the
4647 	// responsibility to Vim in this case).
4648 	if (!PyErr_Occurred())
4649 	{
4650 	    while (i < new_len)
4651 	    {
4652 		if (ml_append((linenr_T)(lo + i - 1),
4653 					(char_u *)array[i], 0, FALSE) == FAIL)
4654 		{
4655 		    RAISE_INSERT_LINE_FAIL;
4656 		    break;
4657 		}
4658 		vim_free(array[i]);
4659 		++i;
4660 		++extra;
4661 	    }
4662 	}
4663 
4664 	// Free any left-over old_len, as a result of an error
4665 	while (i < new_len)
4666 	{
4667 	    vim_free(array[i]);
4668 	    ++i;
4669 	}
4670 
4671 	// Free the array of old_len. All of its contents have now
4672 	// been dealt with (either freed, or the responsibility passed
4673 	// to vim.
4674 	PyMem_Free(array);
4675 
4676 	// Adjust marks. Invalidate any which lie in the
4677 	// changed range, and move any in the remainder of the buffer.
4678 	// Only adjust marks if we managed to switch to a window that holds
4679 	// the buffer, otherwise line numbers will be invalid.
4680 	if (save_curbuf.br_buf == NULL)
4681 	    mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
4682 						  (long)MAXLNUM, (long)extra);
4683 	changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
4684 
4685 	if (buf == curbuf && (save_curwin != NULL
4686 					   || save_curbuf.br_buf == NULL))
4687 	    // Using an existing window for the buffer, adjust the cursor
4688 	    // position.
4689 	    py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
4690 
4691 	// END of region without "return".
4692 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4693 
4694 	if (VimTryEnd())
4695 	    return FAIL;
4696 
4697 	if (len_change)
4698 	    *len_change = new_len - old_len;
4699 
4700 	return OK;
4701     }
4702     else
4703     {
4704 	PyErr_BadArgument();
4705 	return FAIL;
4706     }
4707 }
4708 
4709 /*
4710  * Insert a number of lines into the specified buffer after the specified line.
4711  * The line number is in Vim format (1-based). The lines to be inserted are
4712  * given as a Python list of string objects or as a single string. The lines
4713  * to be added are checked for validity and correct format. Errors are
4714  * returned as a value of FAIL.  The return value is OK on success.
4715  * If OK is returned and len_change is not NULL, *len_change
4716  * is set to the change in the buffer length.
4717  */
4718     static int
InsertBufferLines(buf_T * buf,PyInt n,PyObject * lines,PyInt * len_change)4719 InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
4720 {
4721     bufref_T	save_curbuf = {NULL, 0, 0};
4722     win_T	*save_curwin = NULL;
4723     tabpage_T	*save_curtab = NULL;
4724 
4725     // First of all, we check the type of the supplied Python object.
4726     // It must be a string or a list, or the call is in error.
4727     if (PyBytes_Check(lines) || PyUnicode_Check(lines))
4728     {
4729 	char		*str = StringToLine(lines);
4730 
4731 	if (str == NULL)
4732 	    return FAIL;
4733 
4734 	PyErr_Clear();
4735 	VimTryStart();
4736 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4737 
4738 	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
4739 	    RAISE_UNDO_FAIL;
4740 	else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
4741 	    RAISE_INSERT_LINE_FAIL;
4742 	else if (save_curbuf.br_buf == NULL)
4743 	    // Only adjust marks if we managed to switch to a window that
4744 	    // holds the buffer, otherwise line numbers will be invalid.
4745 	    appended_lines_mark((linenr_T)n, 1L);
4746 
4747 	vim_free(str);
4748 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4749 	update_screen(VALID);
4750 
4751 	if (VimTryEnd())
4752 	    return FAIL;
4753 
4754 	if (len_change)
4755 	    *len_change = 1;
4756 
4757 	return OK;
4758     }
4759     else if (PyList_Check(lines))
4760     {
4761 	PyInt	i;
4762 	PyInt	size = PyList_Size(lines);
4763 	char	**array;
4764 
4765 	array = PyMem_New(char *, size);
4766 	if (array == NULL)
4767 	{
4768 	    PyErr_NoMemory();
4769 	    return FAIL;
4770 	}
4771 
4772 	for (i = 0; i < size; ++i)
4773 	{
4774 	    PyObject *line;
4775 
4776 	    if (!(line = PyList_GetItem(lines, i)) ||
4777 		!(array[i] = StringToLine(line)))
4778 	    {
4779 		while (i)
4780 		    vim_free(array[--i]);
4781 		PyMem_Free(array);
4782 		return FAIL;
4783 	    }
4784 	}
4785 
4786 	PyErr_Clear();
4787 	VimTryStart();
4788 	switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf);
4789 
4790 	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
4791 	    RAISE_UNDO_FAIL;
4792 	else
4793 	{
4794 	    for (i = 0; i < size; ++i)
4795 	    {
4796 		if (ml_append((linenr_T)(n + i),
4797 					(char_u *)array[i], 0, FALSE) == FAIL)
4798 		{
4799 		    RAISE_INSERT_LINE_FAIL;
4800 
4801 		    // Free the rest of the lines
4802 		    while (i < size)
4803 			vim_free(array[i++]);
4804 
4805 		    break;
4806 		}
4807 		vim_free(array[i]);
4808 	    }
4809 	    if (i > 0 && save_curbuf.br_buf == NULL)
4810 		// Only adjust marks if we managed to switch to a window that
4811 		// holds the buffer, otherwise line numbers will be invalid.
4812 		appended_lines_mark((linenr_T)n, (long)i);
4813 	}
4814 
4815 	// Free the array of lines. All of its contents have now
4816 	// been freed.
4817 	PyMem_Free(array);
4818 	restore_win_for_buf(save_curwin, save_curtab, &save_curbuf);
4819 
4820 	update_screen(VALID);
4821 
4822 	if (VimTryEnd())
4823 	    return FAIL;
4824 
4825 	if (len_change)
4826 	    *len_change = size;
4827 
4828 	return OK;
4829     }
4830     else
4831     {
4832 	PyErr_BadArgument();
4833 	return FAIL;
4834     }
4835 }
4836 
4837 /*
4838  * Common routines for buffers and line ranges
4839  * -------------------------------------------
4840  */
4841 
4842 typedef struct
4843 {
4844     PyObject_HEAD
4845     buf_T *buf;
4846 } BufferObject;
4847 
4848     static int
CheckBuffer(BufferObject * self)4849 CheckBuffer(BufferObject *self)
4850 {
4851     if (self->buf == INVALID_BUFFER_VALUE)
4852     {
4853 	PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
4854 	return -1;
4855     }
4856 
4857     return 0;
4858 }
4859 
4860     static PyObject *
RBItem(BufferObject * self,PyInt n,PyInt start,PyInt end)4861 RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
4862 {
4863     if (CheckBuffer(self))
4864 	return NULL;
4865 
4866     if (end == -1)
4867 	end = self->buf->b_ml.ml_line_count;
4868 
4869     if (n < 0)
4870 	n += end - start + 1;
4871 
4872     if (n < 0 || n > end - start)
4873     {
4874 	PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
4875 	return NULL;
4876     }
4877 
4878     return GetBufferLine(self->buf, n+start);
4879 }
4880 
4881     static PyObject *
RBSlice(BufferObject * self,PyInt lo,PyInt hi,PyInt start,PyInt end)4882 RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
4883 {
4884     PyInt size;
4885 
4886     if (CheckBuffer(self))
4887 	return NULL;
4888 
4889     if (end == -1)
4890 	end = self->buf->b_ml.ml_line_count;
4891 
4892     size = end - start + 1;
4893 
4894     if (lo < 0)
4895 	lo = 0;
4896     else if (lo > size)
4897 	lo = size;
4898     if (hi < 0)
4899 	hi = 0;
4900     if (hi < lo)
4901 	hi = lo;
4902     else if (hi > size)
4903 	hi = size;
4904 
4905     return GetBufferLineList(self->buf, lo+start, hi+start);
4906 }
4907 
4908     static PyInt
RBAsItem(BufferObject * self,PyInt n,PyObject * valObject,PyInt start,PyInt end,PyInt * new_end)4909 RBAsItem(
4910 	BufferObject *self,
4911 	PyInt n,
4912 	PyObject *valObject,
4913 	PyInt start,
4914 	PyInt end,
4915 	PyInt *new_end)
4916 {
4917     PyInt len_change;
4918 
4919     if (CheckBuffer(self))
4920 	return -1;
4921 
4922     if (end == -1)
4923 	end = self->buf->b_ml.ml_line_count;
4924 
4925     if (n < 0)
4926 	n += end - start + 1;
4927 
4928     if (n < 0 || n > end - start)
4929     {
4930 	PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
4931 	return -1;
4932     }
4933 
4934     if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
4935 	return -1;
4936 
4937     if (new_end)
4938 	*new_end = end + len_change;
4939 
4940     return 0;
4941 }
4942 
4943     static PyInt
RBAsSlice(BufferObject * self,PyInt lo,PyInt hi,PyObject * valObject,PyInt start,PyInt end,PyInt * new_end)4944 RBAsSlice(
4945 	BufferObject *self,
4946 	PyInt lo,
4947 	PyInt hi,
4948 	PyObject *valObject,
4949 	PyInt start,
4950 	PyInt end,
4951 	PyInt *new_end)
4952 {
4953     PyInt size;
4954     PyInt len_change;
4955 
4956     // Self must be a valid buffer
4957     if (CheckBuffer(self))
4958 	return -1;
4959 
4960     if (end == -1)
4961 	end = self->buf->b_ml.ml_line_count;
4962 
4963     // Sort out the slice range
4964     size = end - start + 1;
4965 
4966     if (lo < 0)
4967 	lo = 0;
4968     else if (lo > size)
4969 	lo = size;
4970     if (hi < 0)
4971 	hi = 0;
4972     if (hi < lo)
4973 	hi = lo;
4974     else if (hi > size)
4975 	hi = size;
4976 
4977     if (SetBufferLineList(self->buf, lo + start, hi + start,
4978 						valObject, &len_change) == FAIL)
4979 	return -1;
4980 
4981     if (new_end)
4982 	*new_end = end + len_change;
4983 
4984     return 0;
4985 }
4986 
4987 
4988     static PyObject *
RBAppend(BufferObject * self,PyObject * args,PyInt start,PyInt end,PyInt * new_end)4989 RBAppend(
4990 	BufferObject *self,
4991 	PyObject *args,
4992 	PyInt start,
4993 	PyInt end,
4994 	PyInt *new_end)
4995 {
4996     PyObject *lines;
4997     PyInt len_change;
4998     PyInt max;
4999     PyInt n;
5000 
5001     if (CheckBuffer(self))
5002 	return NULL;
5003 
5004     if (end == -1)
5005 	end = self->buf->b_ml.ml_line_count;
5006 
5007     max = n = end - start + 1;
5008 
5009     if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
5010 	return NULL;
5011 
5012     if (n < 0 || n > max)
5013     {
5014 	PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
5015 	return NULL;
5016     }
5017 
5018     if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
5019 	return NULL;
5020 
5021     if (new_end)
5022 	*new_end = end + len_change;
5023 
5024     Py_INCREF(Py_None);
5025     return Py_None;
5026 }
5027 
5028 // Range object
5029 
5030 static PyTypeObject RangeType;
5031 static PySequenceMethods RangeAsSeq;
5032 static PyMappingMethods RangeAsMapping;
5033 
5034 typedef struct
5035 {
5036     PyObject_HEAD
5037     BufferObject *buf;
5038     PyInt start;
5039     PyInt end;
5040 } RangeObject;
5041 
5042     static PyObject *
RangeNew(buf_T * buf,PyInt start,PyInt end)5043 RangeNew(buf_T *buf, PyInt start, PyInt end)
5044 {
5045     BufferObject *bufr;
5046     RangeObject *self;
5047     self = PyObject_GC_New(RangeObject, &RangeType);
5048     if (self == NULL)
5049 	return NULL;
5050 
5051     bufr = (BufferObject *)BufferNew(buf);
5052     if (bufr == NULL)
5053     {
5054 	Py_DECREF(self);
5055 	return NULL;
5056     }
5057     Py_INCREF(bufr);
5058 
5059     self->buf = bufr;
5060     self->start = start;
5061     self->end = end;
5062 
5063     return (PyObject *)(self);
5064 }
5065 
5066     static void
RangeDestructor(RangeObject * self)5067 RangeDestructor(RangeObject *self)
5068 {
5069     PyObject_GC_UnTrack((void *)(self));
5070     Py_XDECREF(self->buf);
5071     PyObject_GC_Del((void *)(self));
5072 }
5073 
5074     static int
RangeTraverse(RangeObject * self,visitproc visit,void * arg)5075 RangeTraverse(RangeObject *self, visitproc visit, void *arg)
5076 {
5077     Py_VISIT(((PyObject *)(self->buf)));
5078     return 0;
5079 }
5080 
5081     static int
RangeClear(RangeObject * self)5082 RangeClear(RangeObject *self)
5083 {
5084     Py_CLEAR(self->buf);
5085     return 0;
5086 }
5087 
5088     static PyInt
RangeLength(RangeObject * self)5089 RangeLength(RangeObject *self)
5090 {
5091     // HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION?
5092     if (CheckBuffer(self->buf))
5093 	return -1; // ???
5094 
5095     return (self->end - self->start + 1);
5096 }
5097 
5098     static PyObject *
RangeItem(RangeObject * self,PyInt n)5099 RangeItem(RangeObject *self, PyInt n)
5100 {
5101     return RBItem(self->buf, n, self->start, self->end);
5102 }
5103 
5104     static PyObject *
RangeSlice(RangeObject * self,PyInt lo,PyInt hi)5105 RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
5106 {
5107     return RBSlice(self->buf, lo, hi, self->start, self->end);
5108 }
5109 
5110 static char *RangeAttrs[] = {
5111     "start", "end",
5112     NULL
5113 };
5114 
5115     static PyObject *
RangeDir(PyObject * self,PyObject * args UNUSED)5116 RangeDir(PyObject *self, PyObject *args UNUSED)
5117 {
5118     return ObjectDir(self, RangeAttrs);
5119 }
5120 
5121     static PyObject *
RangeAppend(RangeObject * self,PyObject * args)5122 RangeAppend(RangeObject *self, PyObject *args)
5123 {
5124     return RBAppend(self->buf, args, self->start, self->end, &self->end);
5125 }
5126 
5127     static PyObject *
RangeRepr(RangeObject * self)5128 RangeRepr(RangeObject *self)
5129 {
5130     if (self->buf->buf == INVALID_BUFFER_VALUE)
5131 	return PyString_FromFormat("<range object (for deleted buffer) at %p>",
5132 				    (self));
5133     else
5134     {
5135 	char *name = (char *)self->buf->buf->b_fname;
5136 
5137 	if (name == NULL)
5138 	    name = "";
5139 
5140 	return PyString_FromFormat("<range %s (%d:%d)>",
5141 				    name, (int)self->start, (int)self->end);
5142     }
5143 }
5144 
5145 static struct PyMethodDef RangeMethods[] = {
5146     // name,	function,			calling,	documentation
5147     {"append",	(PyCFunction)RangeAppend,	METH_VARARGS,	"Append data to the Vim range" },
5148     {"__dir__",	(PyCFunction)RangeDir,		METH_NOARGS,	""},
5149     { NULL,	NULL,				0,		NULL}
5150 };
5151 
5152 static PyTypeObject BufferType;
5153 static PySequenceMethods BufferAsSeq;
5154 static PyMappingMethods BufferAsMapping;
5155 
5156     static PyObject *
BufferNew(buf_T * buf)5157 BufferNew(buf_T *buf)
5158 {
5159     /*
5160      * We need to handle deletion of buffers underneath us.
5161      * If we add a "b_python*_ref" field to the buf_T structure,
5162      * then we can get at it in buf_freeall() in vim. We then
5163      * need to create only ONE Python object per buffer - if
5164      * we try to create a second, just INCREF the existing one
5165      * and return it. The (single) Python object referring to
5166      * the buffer is stored in "b_python*_ref".
5167      * Question: what to do on a buf_freeall(). We'll probably
5168      * have to either delete the Python object (DECREF it to
5169      * zero - a bad idea, as it leaves dangling refs!) or
5170      * set the buf_T * value to an invalid value (-1?), which
5171      * means we need checks in all access functions... Bah.
5172      *
5173      * Python2 and Python3 get different fields and different objects:
5174      * b_python_ref and b_python3_ref fields respectively.
5175      */
5176 
5177     BufferObject *self;
5178 
5179     if (BUF_PYTHON_REF(buf) != NULL)
5180     {
5181 	self = BUF_PYTHON_REF(buf);
5182 	Py_INCREF(self);
5183     }
5184     else
5185     {
5186 	self = PyObject_NEW(BufferObject, &BufferType);
5187 	if (self == NULL)
5188 	    return NULL;
5189 	self->buf = buf;
5190 	BUF_PYTHON_REF(buf) = self;
5191     }
5192 
5193     return (PyObject *)(self);
5194 }
5195 
5196     static void
BufferDestructor(BufferObject * self)5197 BufferDestructor(BufferObject *self)
5198 {
5199     if (self->buf && self->buf != INVALID_BUFFER_VALUE)
5200 	BUF_PYTHON_REF(self->buf) = NULL;
5201 
5202     DESTRUCTOR_FINISH(self);
5203 }
5204 
5205     static PyInt
BufferLength(BufferObject * self)5206 BufferLength(BufferObject *self)
5207 {
5208     // HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION?
5209     if (CheckBuffer(self))
5210 	return -1; // ???
5211 
5212     return (PyInt)(self->buf->b_ml.ml_line_count);
5213 }
5214 
5215     static PyObject *
BufferItem(BufferObject * self,PyInt n)5216 BufferItem(BufferObject *self, PyInt n)
5217 {
5218     return RBItem(self, n, 1, -1);
5219 }
5220 
5221     static PyObject *
BufferSlice(BufferObject * self,PyInt lo,PyInt hi)5222 BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
5223 {
5224     return RBSlice(self, lo, hi, 1, -1);
5225 }
5226 
5227 static char *BufferAttrs[] = {
5228     "name", "number", "vars", "options", "valid",
5229     NULL
5230 };
5231 
5232     static PyObject *
BufferDir(PyObject * self,PyObject * args UNUSED)5233 BufferDir(PyObject *self, PyObject *args UNUSED)
5234 {
5235     return ObjectDir(self, BufferAttrs);
5236 }
5237 
5238     static PyObject *
BufferAttrValid(BufferObject * self,char * name)5239 BufferAttrValid(BufferObject *self, char *name)
5240 {
5241     PyObject	*ret;
5242 
5243     if (strcmp(name, "valid") != 0)
5244 	return NULL;
5245 
5246     ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
5247     Py_INCREF(ret);
5248     return ret;
5249 }
5250 
5251     static PyObject *
BufferAttr(BufferObject * self,char * name)5252 BufferAttr(BufferObject *self, char *name)
5253 {
5254     if (strcmp(name, "name") == 0)
5255 	return PyString_FromString((self->buf->b_ffname == NULL
5256 				    ? "" : (char *)self->buf->b_ffname));
5257     else if (strcmp(name, "number") == 0)
5258 	return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
5259     else if (strcmp(name, "vars") == 0)
5260 	return NEW_DICTIONARY(self->buf->b_vars);
5261     else if (strcmp(name, "options") == 0)
5262 	return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
5263 			(PyObject *) self);
5264     else if (strcmp(name, "__members__") == 0)
5265 	return ObjectDir(NULL, BufferAttrs);
5266     else
5267 	return NULL;
5268 }
5269 
5270     static int
BufferSetattr(BufferObject * self,char * name,PyObject * valObject)5271 BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
5272 {
5273     if (CheckBuffer(self))
5274 	return -1;
5275 
5276     if (strcmp(name, "name") == 0)
5277     {
5278 	char_u		*val;
5279 	aco_save_T	aco;
5280 	int		ren_ret;
5281 	PyObject	*todecref;
5282 
5283 	if (!(val = StringToChars(valObject, &todecref)))
5284 	    return -1;
5285 
5286 	VimTryStart();
5287 	// Using aucmd_*: autocommands will be executed by rename_buffer
5288 	aucmd_prepbuf(&aco, self->buf);
5289 	ren_ret = rename_buffer(val);
5290 	aucmd_restbuf(&aco);
5291 	Py_XDECREF(todecref);
5292 	if (VimTryEnd())
5293 	    return -1;
5294 
5295 	if (ren_ret == FAIL)
5296 	{
5297 	    PyErr_SET_VIM(N_("failed to rename buffer"));
5298 	    return -1;
5299 	}
5300 	return 0;
5301     }
5302     else
5303     {
5304 	PyErr_SetString(PyExc_AttributeError, name);
5305 	return -1;
5306     }
5307 }
5308 
5309     static PyObject *
BufferAppend(BufferObject * self,PyObject * args)5310 BufferAppend(BufferObject *self, PyObject *args)
5311 {
5312     return RBAppend(self, args, 1, -1, NULL);
5313 }
5314 
5315     static PyObject *
BufferMark(BufferObject * self,PyObject * pmarkObject)5316 BufferMark(BufferObject *self, PyObject *pmarkObject)
5317 {
5318     pos_T	*posp;
5319     char_u	*pmark;
5320     char_u	mark;
5321     bufref_T	savebuf;
5322     PyObject	*todecref;
5323 
5324     if (CheckBuffer(self))
5325 	return NULL;
5326 
5327     if (!(pmark = StringToChars(pmarkObject, &todecref)))
5328 	return NULL;
5329 
5330     if (pmark[0] == '\0' || pmark[1] != '\0')
5331     {
5332 	PyErr_SET_STRING(PyExc_ValueError,
5333 		N_("mark name must be a single character"));
5334 	Py_XDECREF(todecref);
5335 	return NULL;
5336     }
5337 
5338     mark = *pmark;
5339 
5340     Py_XDECREF(todecref);
5341 
5342     VimTryStart();
5343     switch_buffer(&savebuf, self->buf);
5344     posp = getmark(mark, FALSE);
5345     restore_buffer(&savebuf);
5346     if (VimTryEnd())
5347 	return NULL;
5348 
5349     if (posp == NULL)
5350     {
5351 	PyErr_SET_VIM(N_("invalid mark name"));
5352 	return NULL;
5353     }
5354 
5355     if (posp->lnum <= 0)
5356     {
5357 	// Or raise an error?
5358 	Py_INCREF(Py_None);
5359 	return Py_None;
5360     }
5361 
5362     return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
5363 }
5364 
5365     static PyObject *
BufferRange(BufferObject * self,PyObject * args)5366 BufferRange(BufferObject *self, PyObject *args)
5367 {
5368     PyInt start;
5369     PyInt end;
5370 
5371     if (CheckBuffer(self))
5372 	return NULL;
5373 
5374     if (!PyArg_ParseTuple(args, "nn", &start, &end))
5375 	return NULL;
5376 
5377     return RangeNew(self->buf, start, end);
5378 }
5379 
5380     static PyObject *
BufferRepr(BufferObject * self)5381 BufferRepr(BufferObject *self)
5382 {
5383     if (self->buf == INVALID_BUFFER_VALUE)
5384 	return PyString_FromFormat("<buffer object (deleted) at %p>", self);
5385     else
5386     {
5387 	char	*name = (char *)self->buf->b_fname;
5388 
5389 	if (name == NULL)
5390 	    name = "";
5391 
5392 	return PyString_FromFormat("<buffer %s>", name);
5393     }
5394 }
5395 
5396 static struct PyMethodDef BufferMethods[] = {
5397     // name,	    function,			calling,	documentation
5398     {"append",	    (PyCFunction)BufferAppend,	METH_VARARGS,	"Append data to Vim buffer" },
5399     {"mark",	    (PyCFunction)BufferMark,	METH_O,		"Return (row,col) representing position of named mark" },
5400     {"range",	    (PyCFunction)BufferRange,	METH_VARARGS,	"Return a range object which represents the part of the given buffer between line numbers s and e" },
5401     {"__dir__",	    (PyCFunction)BufferDir,	METH_NOARGS,	""},
5402     { NULL,	    NULL,			0,		NULL}
5403 };
5404 
5405 /*
5406  * Buffer list object - Implementation
5407  */
5408 
5409 static PyTypeObject BufMapType;
5410 
5411 typedef struct
5412 {
5413     PyObject_HEAD
5414 } BufMapObject;
5415 
5416     static PyInt
BufMapLength(PyObject * self UNUSED)5417 BufMapLength(PyObject *self UNUSED)
5418 {
5419     buf_T	*b = firstbuf;
5420     PyInt	n = 0;
5421 
5422     while (b)
5423     {
5424 	++n;
5425 	b = b->b_next;
5426     }
5427 
5428     return n;
5429 }
5430 
5431     static PyObject *
BufMapItem(PyObject * self UNUSED,PyObject * keyObject)5432 BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
5433 {
5434     buf_T	*b;
5435     long	bnr;
5436 
5437     if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
5438 	return NULL;
5439 
5440     b = buflist_findnr((int) bnr);
5441 
5442     if (b)
5443 	return BufferNew(b);
5444     else
5445     {
5446 	PyErr_SetObject(PyExc_KeyError, keyObject);
5447 	return NULL;
5448     }
5449 }
5450 
5451     static void
BufMapIterDestruct(PyObject * buffer)5452 BufMapIterDestruct(PyObject *buffer)
5453 {
5454     // Iteration was stopped before all buffers were processed
5455     if (buffer)
5456     {
5457 	Py_DECREF(buffer);
5458     }
5459 }
5460 
5461     static int
BufMapIterTraverse(PyObject * buffer,visitproc visit,void * arg)5462 BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
5463 {
5464     if (buffer)
5465 	Py_VISIT(buffer);
5466     return 0;
5467 }
5468 
5469     static int
BufMapIterClear(PyObject ** buffer)5470 BufMapIterClear(PyObject **buffer)
5471 {
5472     if (*buffer)
5473 	Py_CLEAR(*buffer);
5474     return 0;
5475 }
5476 
5477     static PyObject *
BufMapIterNext(PyObject ** buffer)5478 BufMapIterNext(PyObject **buffer)
5479 {
5480     PyObject	*next;
5481     PyObject	*ret;
5482 
5483     if (!*buffer)
5484 	return NULL;
5485 
5486     ret = *buffer;
5487 
5488     if (CheckBuffer((BufferObject *)(ret)))
5489     {
5490 	*buffer = NULL;
5491 	return NULL;
5492     }
5493 
5494     if (!((BufferObject *)(ret))->buf->b_next)
5495 	next = NULL;
5496     else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
5497 	return NULL;
5498     *buffer = next;
5499     // Do not increment reference: we no longer hold it (decref), but whoever
5500     // on other side will hold (incref). Decref+incref = nothing.
5501     return ret;
5502 }
5503 
5504     static PyObject *
BufMapIter(PyObject * self)5505 BufMapIter(PyObject *self)
5506 {
5507     PyObject *buffer;
5508 
5509     buffer = BufferNew(firstbuf);
5510     return IterNew(buffer,
5511 	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
5512 	    (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear,
5513 	    (PyObject *)self);
5514 }
5515 
5516 static PyMappingMethods BufMapAsMapping = {
5517     (lenfunc)       BufMapLength,
5518     (binaryfunc)    BufMapItem,
5519     (objobjargproc) 0,
5520 };
5521 
5522 // Current items object
5523 
5524 static char *CurrentAttrs[] = {
5525     "buffer", "window", "line", "range", "tabpage",
5526     NULL
5527 };
5528 
5529     static PyObject *
CurrentDir(PyObject * self,PyObject * args UNUSED)5530 CurrentDir(PyObject *self, PyObject *args UNUSED)
5531 {
5532     return ObjectDir(self, CurrentAttrs);
5533 }
5534 
5535     static PyObject *
CurrentGetattr(PyObject * self UNUSED,char * name)5536 CurrentGetattr(PyObject *self UNUSED, char *name)
5537 {
5538     if (strcmp(name, "buffer") == 0)
5539 	return (PyObject *)BufferNew(curbuf);
5540     else if (strcmp(name, "window") == 0)
5541 	return (PyObject *)WindowNew(curwin, curtab);
5542     else if (strcmp(name, "tabpage") == 0)
5543 	return (PyObject *)TabPageNew(curtab);
5544     else if (strcmp(name, "line") == 0)
5545 	return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
5546     else if (strcmp(name, "range") == 0)
5547 	return RangeNew(curbuf, RangeStart, RangeEnd);
5548     else if (strcmp(name, "__members__") == 0)
5549 	return ObjectDir(NULL, CurrentAttrs);
5550     else
5551 #if PY_MAJOR_VERSION < 3
5552 	return Py_FindMethod(WindowMethods, self, name);
5553 #else
5554 	return NULL;
5555 #endif
5556 }
5557 
5558     static int
CurrentSetattr(PyObject * self UNUSED,char * name,PyObject * valObject)5559 CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
5560 {
5561     if (strcmp(name, "line") == 0)
5562     {
5563 	if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
5564 			  NULL) == FAIL)
5565 	    return -1;
5566 
5567 	return 0;
5568     }
5569     else if (strcmp(name, "buffer") == 0)
5570     {
5571 	int count;
5572 
5573 	if (valObject->ob_type != &BufferType)
5574 	{
5575 	    PyErr_FORMAT(PyExc_TypeError,
5576 		    N_("expected vim.Buffer object, but got %s"),
5577 		    Py_TYPE_NAME(valObject));
5578 	    return -1;
5579 	}
5580 
5581 	if (CheckBuffer((BufferObject *)(valObject)))
5582 	    return -1;
5583 	count = ((BufferObject *)(valObject))->buf->b_fnum;
5584 
5585 	VimTryStart();
5586 	if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
5587 	{
5588 	    if (VimTryEnd())
5589 		return -1;
5590 	    PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
5591 	    return -1;
5592 	}
5593 
5594 	return VimTryEnd();
5595     }
5596     else if (strcmp(name, "window") == 0)
5597     {
5598 	int count;
5599 
5600 	if (valObject->ob_type != &WindowType)
5601 	{
5602 	    PyErr_FORMAT(PyExc_TypeError,
5603 		    N_("expected vim.Window object, but got %s"),
5604 		    Py_TYPE_NAME(valObject));
5605 	    return -1;
5606 	}
5607 
5608 	if (CheckWindow((WindowObject *)(valObject)))
5609 	    return -1;
5610 	count = get_win_number(((WindowObject *)(valObject))->win, firstwin);
5611 
5612 	if (!count)
5613 	{
5614 	    PyErr_SET_STRING(PyExc_ValueError,
5615 		    N_("failed to find window in the current tab page"));
5616 	    return -1;
5617 	}
5618 
5619 	VimTryStart();
5620 	win_goto(((WindowObject *)(valObject))->win);
5621 	if (((WindowObject *)(valObject))->win != curwin)
5622 	{
5623 	    if (VimTryEnd())
5624 		return -1;
5625 	    PyErr_SET_STRING(PyExc_RuntimeError,
5626 		    N_("did not switch to the specified window"));
5627 	    return -1;
5628 	}
5629 
5630 	return VimTryEnd();
5631     }
5632     else if (strcmp(name, "tabpage") == 0)
5633     {
5634 	if (valObject->ob_type != &TabPageType)
5635 	{
5636 	    PyErr_FORMAT(PyExc_TypeError,
5637 		    N_("expected vim.TabPage object, but got %s"),
5638 		    Py_TYPE_NAME(valObject));
5639 	    return -1;
5640 	}
5641 
5642 	if (CheckTabPage((TabPageObject *)(valObject)))
5643 	    return -1;
5644 
5645 	VimTryStart();
5646 	goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
5647 	if (((TabPageObject *)(valObject))->tab != curtab)
5648 	{
5649 	    if (VimTryEnd())
5650 		return -1;
5651 	    PyErr_SET_STRING(PyExc_RuntimeError,
5652 		    N_("did not switch to the specified tab page"));
5653 	    return -1;
5654 	}
5655 
5656 	return VimTryEnd();
5657     }
5658     else
5659     {
5660 	PyErr_SetString(PyExc_AttributeError, name);
5661 	return -1;
5662     }
5663 }
5664 
5665 static struct PyMethodDef CurrentMethods[] = {
5666     // name,	    function,			calling,	documentation
5667     {"__dir__",	    (PyCFunction)CurrentDir,	METH_NOARGS,	""},
5668     { NULL,	    NULL,			0,		NULL}
5669 };
5670 
5671     static void
init_range_cmd(exarg_T * eap)5672 init_range_cmd(exarg_T *eap)
5673 {
5674     RangeStart = eap->line1;
5675     RangeEnd = eap->line2;
5676 }
5677 
5678     static void
init_range_eval(typval_T * rettv UNUSED)5679 init_range_eval(typval_T *rettv UNUSED)
5680 {
5681     RangeStart = (PyInt) curwin->w_cursor.lnum;
5682     RangeEnd = RangeStart;
5683 }
5684 
5685     static void
run_cmd(const char * cmd,void * arg UNUSED,PyGILState_STATE * pygilstate UNUSED)5686 run_cmd(const char *cmd, void *arg UNUSED
5687 #ifdef PY_CAN_RECURSE
5688 	, PyGILState_STATE *pygilstate UNUSED
5689 #endif
5690 	)
5691 {
5692     PyObject	*run_ret;
5693     run_ret = PyRun_String((char *)cmd, Py_file_input, globals, globals);
5694     if (run_ret != NULL)
5695     {
5696 	Py_DECREF(run_ret);
5697     }
5698     else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5699     {
5700 	semsg(_(e_py_systemexit), "python");
5701 	PyErr_Clear();
5702     }
5703     else
5704 	PyErr_PrintEx(1);
5705 }
5706 
5707 static const char	*code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
5708 static int		code_hdr_len = 30;
5709 
5710     static void
run_do(const char * cmd,void * arg UNUSED,PyGILState_STATE * pygilstate)5711 run_do(const char *cmd, void *arg UNUSED
5712 #ifdef PY_CAN_RECURSE
5713 	, PyGILState_STATE *pygilstate
5714 #endif
5715 	)
5716 {
5717     PyInt	lnum;
5718     size_t	len;
5719     char	*code;
5720     int		status;
5721     PyObject	*pyfunc, *pymain;
5722     PyObject	*run_ret;
5723     buf_T	*was_curbuf = curbuf;
5724 
5725     if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
5726     {
5727 	emsg(_("cannot save undo information"));
5728 	return;
5729     }
5730 
5731     len = code_hdr_len + STRLEN(cmd);
5732     code = PyMem_New(char, len + 1);
5733     memcpy(code, code_hdr, code_hdr_len);
5734     STRCPY(code + code_hdr_len, cmd);
5735     run_ret = PyRun_String(code, Py_file_input, globals, globals);
5736     status = -1;
5737     if (run_ret != NULL)
5738     {
5739 	status = 0;
5740 	Py_DECREF(run_ret);
5741     }
5742     else if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5743     {
5744 	PyMem_Free(code);
5745 	semsg(_(e_py_systemexit), "python");
5746 	PyErr_Clear();
5747 	return;
5748     }
5749     else
5750 	PyErr_PrintEx(1);
5751 
5752     PyMem_Free(code);
5753 
5754     if (status)
5755     {
5756 	emsg(_("failed to run the code"));
5757 	return;
5758     }
5759 
5760     status = 0;
5761     pymain = PyImport_AddModule("__main__");
5762     pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
5763 #ifdef PY_CAN_RECURSE
5764     PyGILState_Release(*pygilstate);
5765 #endif
5766 
5767     for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
5768     {
5769 	PyObject	*line;
5770 	PyObject	*linenr;
5771 	PyObject	*ret;
5772 
5773 #ifdef PY_CAN_RECURSE
5774 	*pygilstate = PyGILState_Ensure();
5775 #endif
5776 	// Check the line number, the command my have deleted lines.
5777 	if (lnum > curbuf->b_ml.ml_line_count
5778 		|| !(line = GetBufferLine(curbuf, lnum)))
5779 	    goto err;
5780 	if (!(linenr = PyInt_FromLong((long) lnum)))
5781 	{
5782 	    Py_DECREF(line);
5783 	    goto err;
5784 	}
5785 	ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
5786 	Py_DECREF(line);
5787 	Py_DECREF(linenr);
5788 	if (!ret)
5789 	    goto err;
5790 
5791 	// Check that the command didn't switch to another buffer.
5792 	if (curbuf != was_curbuf)
5793 	{
5794 	    Py_XDECREF(ret);
5795 	    goto err;
5796 	}
5797 
5798 	if (ret != Py_None)
5799 	    if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
5800 	    {
5801 		Py_XDECREF(ret);
5802 		goto err;
5803 	    }
5804 
5805 	Py_XDECREF(ret);
5806 	PythonIO_Flush();
5807 #ifdef PY_CAN_RECURSE
5808 	PyGILState_Release(*pygilstate);
5809 #endif
5810     }
5811     goto out;
5812 err:
5813 #ifdef PY_CAN_RECURSE
5814     *pygilstate = PyGILState_Ensure();
5815 #endif
5816     PyErr_PrintEx(0);
5817     PythonIO_Flush();
5818     status = 1;
5819 out:
5820 #ifdef PY_CAN_RECURSE
5821     if (!status)
5822 	*pygilstate = PyGILState_Ensure();
5823 #endif
5824     Py_DECREF(pyfunc);
5825     PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
5826     if (status)
5827 	return;
5828     check_cursor();
5829     update_curbuf(NOT_VALID);
5830 }
5831 
5832     static void
run_eval(const char * cmd,typval_T * rettv,PyGILState_STATE * pygilstate UNUSED)5833 run_eval(const char *cmd, typval_T *rettv
5834 #ifdef PY_CAN_RECURSE
5835 	, PyGILState_STATE *pygilstate UNUSED
5836 #endif
5837 	)
5838 {
5839     PyObject	*run_ret;
5840 
5841     run_ret = PyRun_String((char *)cmd, Py_eval_input, globals, globals);
5842     if (run_ret == NULL)
5843     {
5844 	if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit))
5845 	{
5846 	    semsg(_(e_py_systemexit), "python");
5847 	    PyErr_Clear();
5848 	}
5849 	else
5850 	{
5851 	    if (PyErr_Occurred() && !msg_silent)
5852 		PyErr_PrintEx(0);
5853 	    emsg(_("E858: Eval did not return a valid python object"));
5854 	}
5855     }
5856     else
5857     {
5858 	if (ConvertFromPyObject(run_ret, rettv) == -1)
5859 	    emsg(_("E859: Failed to convert returned python object to a Vim value"));
5860 	Py_DECREF(run_ret);
5861     }
5862     PyErr_Clear();
5863 }
5864 
5865     static int
set_ref_in_py(const int copyID)5866 set_ref_in_py(const int copyID)
5867 {
5868     pylinkedlist_T	*cur;
5869     list_T		*ll;
5870     int			i;
5871     int			abort = FALSE;
5872     FunctionObject	*func;
5873 
5874     if (lastdict != NULL)
5875     {
5876 	for (cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
5877 	    abort = set_ref_in_dict(((DictionaryObject *)(cur->pll_obj))->dict,
5878 								       copyID);
5879     }
5880 
5881     if (lastlist != NULL)
5882     {
5883 	for (cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
5884 	{
5885 	    ll = ((ListObject *) (cur->pll_obj))->list;
5886 	    abort = set_ref_in_list(ll, copyID);
5887 	}
5888     }
5889 
5890     if (lastfunc != NULL)
5891     {
5892 	for (cur = lastfunc ; !abort && cur != NULL ; cur = cur->pll_prev)
5893 	{
5894 	    func = (FunctionObject *) cur->pll_obj;
5895 	    abort = set_ref_in_dict(func->self, copyID);
5896 	    if (func->argc)
5897 		for (i = 0; !abort && i < func->argc; ++i)
5898 		    abort = abort
5899 			|| set_ref_in_item(&func->argv[i], copyID, NULL, NULL);
5900 	}
5901     }
5902 
5903     return abort;
5904 }
5905 
5906     static int
set_string_copy(char_u * str,typval_T * tv)5907 set_string_copy(char_u *str, typval_T *tv)
5908 {
5909     tv->vval.v_string = vim_strsave(str);
5910     if (tv->vval.v_string == NULL)
5911     {
5912 	PyErr_NoMemory();
5913 	return -1;
5914     }
5915     return 0;
5916 }
5917 
5918     static int
pydict_to_tv(PyObject * obj,typval_T * tv,PyObject * lookup_dict)5919 pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
5920 {
5921     dict_T	*dict;
5922     char_u	*key;
5923     dictitem_T	*di;
5924     PyObject	*keyObject;
5925     PyObject	*valObject;
5926     Py_ssize_t	iter = 0;
5927 
5928     if (!(dict = py_dict_alloc()))
5929 	return -1;
5930 
5931     tv->v_type = VAR_DICT;
5932     tv->vval.v_dict = dict;
5933 
5934     while (PyDict_Next(obj, &iter, &keyObject, &valObject))
5935     {
5936 	PyObject	*todecref = NULL;
5937 
5938 	if (keyObject == NULL || valObject == NULL)
5939 	{
5940 	    dict_unref(dict);
5941 	    return -1;
5942 	}
5943 
5944 	if (!(key = StringToChars(keyObject, &todecref)))
5945 	{
5946 	    dict_unref(dict);
5947 	    return -1;
5948 	}
5949 
5950 	if (*key == NUL)
5951 	{
5952 	    dict_unref(dict);
5953 	    Py_XDECREF(todecref);
5954 	    RAISE_NO_EMPTY_KEYS;
5955 	    return -1;
5956 	}
5957 
5958 	di = dictitem_alloc(key);
5959 
5960 	Py_XDECREF(todecref);
5961 
5962 	if (di == NULL)
5963 	{
5964 	    PyErr_NoMemory();
5965 	    dict_unref(dict);
5966 	    return -1;
5967 	}
5968 
5969 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
5970 	{
5971 	    vim_free(di);
5972 	    dict_unref(dict);
5973 	    return -1;
5974 	}
5975 
5976 	if (dict_add(dict, di) == FAIL)
5977 	{
5978 	    RAISE_KEY_ADD_FAIL(di->di_key);
5979 	    clear_tv(&di->di_tv);
5980 	    vim_free(di);
5981 	    dict_unref(dict);
5982 	    return -1;
5983 	}
5984     }
5985 
5986     --dict->dv_refcount;
5987     return 0;
5988 }
5989 
5990     static int
pymap_to_tv(PyObject * obj,typval_T * tv,PyObject * lookup_dict)5991 pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
5992 {
5993     dict_T	*dict;
5994     char_u	*key;
5995     dictitem_T	*di;
5996     PyObject	*list;
5997     PyObject	*iterator;
5998     PyObject	*keyObject;
5999     PyObject	*valObject;
6000 
6001     if (!(dict = py_dict_alloc()))
6002 	return -1;
6003 
6004     tv->v_type = VAR_DICT;
6005     tv->vval.v_dict = dict;
6006 
6007     if (!(list = PyMapping_Keys(obj)))
6008     {
6009 	dict_unref(dict);
6010 	return -1;
6011     }
6012 
6013     if (!(iterator = PyObject_GetIter(list)))
6014     {
6015 	dict_unref(dict);
6016 	Py_DECREF(list);
6017 	return -1;
6018     }
6019     Py_DECREF(list);
6020 
6021     while ((keyObject = PyIter_Next(iterator)))
6022     {
6023 	PyObject	*todecref;
6024 
6025 	if (!(key = StringToChars(keyObject, &todecref)))
6026 	{
6027 	    Py_DECREF(keyObject);
6028 	    Py_DECREF(iterator);
6029 	    dict_unref(dict);
6030 	    return -1;
6031 	}
6032 
6033 	if (*key == NUL)
6034 	{
6035 	    Py_DECREF(keyObject);
6036 	    Py_DECREF(iterator);
6037 	    Py_XDECREF(todecref);
6038 	    dict_unref(dict);
6039 	    RAISE_NO_EMPTY_KEYS;
6040 	    return -1;
6041 	}
6042 
6043 	if (!(valObject = PyObject_GetItem(obj, keyObject)))
6044 	{
6045 	    Py_DECREF(keyObject);
6046 	    Py_DECREF(iterator);
6047 	    Py_XDECREF(todecref);
6048 	    dict_unref(dict);
6049 	    return -1;
6050 	}
6051 
6052 	di = dictitem_alloc(key);
6053 
6054 	Py_DECREF(keyObject);
6055 	Py_XDECREF(todecref);
6056 
6057 	if (di == NULL)
6058 	{
6059 	    Py_DECREF(iterator);
6060 	    Py_DECREF(valObject);
6061 	    dict_unref(dict);
6062 	    PyErr_NoMemory();
6063 	    return -1;
6064 	}
6065 
6066 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
6067 	{
6068 	    Py_DECREF(iterator);
6069 	    Py_DECREF(valObject);
6070 	    vim_free(di);
6071 	    dict_unref(dict);
6072 	    return -1;
6073 	}
6074 
6075 	Py_DECREF(valObject);
6076 
6077 	if (dict_add(dict, di) == FAIL)
6078 	{
6079 	    RAISE_KEY_ADD_FAIL(di->di_key);
6080 	    Py_DECREF(iterator);
6081 	    dictitem_free(di);
6082 	    dict_unref(dict);
6083 	    return -1;
6084 	}
6085     }
6086     Py_DECREF(iterator);
6087     --dict->dv_refcount;
6088     return 0;
6089 }
6090 
6091     static int
pyseq_to_tv(PyObject * obj,typval_T * tv,PyObject * lookup_dict)6092 pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
6093 {
6094     list_T	*l;
6095 
6096     if (!(l = py_list_alloc()))
6097 	return -1;
6098 
6099     tv->v_type = VAR_LIST;
6100     tv->vval.v_list = l;
6101 
6102     if (list_py_concat(l, obj, lookup_dict) == -1)
6103     {
6104 	list_unref(l);
6105 	return -1;
6106     }
6107 
6108     --l->lv_refcount;
6109     return 0;
6110 }
6111 
6112 typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
6113 
6114     static int
convert_dl(PyObject * obj,typval_T * tv,pytotvfunc py_to_tv,PyObject * lookup_dict)6115 convert_dl(PyObject *obj, typval_T *tv,
6116 				    pytotvfunc py_to_tv, PyObject *lookup_dict)
6117 {
6118     PyObject	*capsule;
6119     char	hexBuf[sizeof(void *) * 2 + 3];
6120 
6121     sprintf(hexBuf, "%p", (void *)obj);
6122 
6123 #ifdef PY_USE_CAPSULE
6124     capsule = PyDict_GetItemString(lookup_dict, hexBuf);
6125 #else
6126     capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
6127 #endif
6128     if (capsule == NULL)
6129     {
6130 #ifdef PY_USE_CAPSULE
6131 	capsule = PyCapsule_New(tv, NULL, NULL);
6132 #else
6133 	capsule = PyCObject_FromVoidPtr(tv, NULL);
6134 #endif
6135 	if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
6136 	{
6137 	    Py_DECREF(capsule);
6138 	    tv->v_type = VAR_UNKNOWN;
6139 	    return -1;
6140 	}
6141 
6142 	Py_DECREF(capsule);
6143 
6144 	if (py_to_tv(obj, tv, lookup_dict) == -1)
6145 	{
6146 	    tv->v_type = VAR_UNKNOWN;
6147 	    return -1;
6148 	}
6149 	// As we are not using copy_tv which increments reference count we must
6150 	// do it ourself.
6151 	if (tv->v_type == VAR_DICT)
6152 	    ++tv->vval.v_dict->dv_refcount;
6153 	else if (tv->v_type == VAR_LIST)
6154 	    ++tv->vval.v_list->lv_refcount;
6155     }
6156     else
6157     {
6158 	typval_T	*v;
6159 
6160 #ifdef PY_USE_CAPSULE
6161 	v = PyCapsule_GetPointer(capsule, NULL);
6162 #else
6163 	v = PyCObject_AsVoidPtr(capsule);
6164 #endif
6165 	copy_tv(v, tv);
6166     }
6167     return 0;
6168 }
6169 
6170     static int
ConvertFromPyMapping(PyObject * obj,typval_T * tv)6171 ConvertFromPyMapping(PyObject *obj, typval_T *tv)
6172 {
6173     PyObject	*lookup_dict;
6174     int		ret;
6175 
6176     if (!(lookup_dict = PyDict_New()))
6177 	return -1;
6178 
6179     if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
6180     {
6181 	tv->v_type = VAR_DICT;
6182 	tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
6183 	++tv->vval.v_dict->dv_refcount;
6184 	ret = 0;
6185     }
6186     else if (PyDict_Check(obj))
6187 	ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
6188     else if (PyMapping_Check(obj))
6189 	ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
6190     else
6191     {
6192 	PyErr_FORMAT(PyExc_TypeError,
6193 		N_("unable to convert %s to a Vim dictionary"),
6194 		Py_TYPE_NAME(obj));
6195 	ret = -1;
6196     }
6197     Py_DECREF(lookup_dict);
6198     return ret;
6199 }
6200 
6201     static int
ConvertFromPySequence(PyObject * obj,typval_T * tv)6202 ConvertFromPySequence(PyObject *obj, typval_T *tv)
6203 {
6204     PyObject	*lookup_dict;
6205     int		ret;
6206 
6207     if (!(lookup_dict = PyDict_New()))
6208 	return -1;
6209 
6210     if (PyType_IsSubtype(obj->ob_type, &ListType))
6211     {
6212 	tv->v_type = VAR_LIST;
6213 	tv->vval.v_list = (((ListObject *)(obj))->list);
6214 	++tv->vval.v_list->lv_refcount;
6215 	ret = 0;
6216     }
6217     else if (PyIter_Check(obj) || PySequence_Check(obj))
6218 	ret = convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
6219     else
6220     {
6221 	PyErr_FORMAT(PyExc_TypeError,
6222 		N_("unable to convert %s to a Vim list"),
6223 		Py_TYPE_NAME(obj));
6224 	ret = -1;
6225     }
6226     Py_DECREF(lookup_dict);
6227     return ret;
6228 }
6229 
6230     static int
ConvertFromPyObject(PyObject * obj,typval_T * tv)6231 ConvertFromPyObject(PyObject *obj, typval_T *tv)
6232 {
6233     PyObject	*lookup_dict;
6234     int		ret;
6235 
6236     if (!(lookup_dict = PyDict_New()))
6237 	return -1;
6238     ret = _ConvertFromPyObject(obj, tv, lookup_dict);
6239     Py_DECREF(lookup_dict);
6240     return ret;
6241 }
6242 
6243     static int
_ConvertFromPyObject(PyObject * obj,typval_T * tv,PyObject * lookup_dict)6244 _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
6245 {
6246     if (PyType_IsSubtype(obj->ob_type, &DictionaryType))
6247     {
6248 	tv->v_type = VAR_DICT;
6249 	tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
6250 	++tv->vval.v_dict->dv_refcount;
6251     }
6252     else if (PyType_IsSubtype(obj->ob_type, &ListType))
6253     {
6254 	tv->v_type = VAR_LIST;
6255 	tv->vval.v_list = (((ListObject *)(obj))->list);
6256 	++tv->vval.v_list->lv_refcount;
6257     }
6258     else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
6259     {
6260 	FunctionObject *func = (FunctionObject *) obj;
6261 	if (func->self != NULL || func->argv != NULL)
6262 	{
6263 	    partial_T *pt = ALLOC_CLEAR_ONE(partial_T);
6264 
6265 	    set_partial(func, pt, TRUE);
6266 	    tv->vval.v_partial = pt;
6267 	    tv->v_type = VAR_PARTIAL;
6268 	}
6269 	else
6270 	{
6271 	    if (set_string_copy(func->name, tv) == -1)
6272 		return -1;
6273 
6274 	    tv->v_type = VAR_FUNC;
6275 	}
6276 	func_ref(func->name);
6277     }
6278     else if (PyBytes_Check(obj))
6279     {
6280 	char_u	*str;
6281 
6282 	if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
6283 	    return -1;
6284 	if (str == NULL)
6285 	    return -1;
6286 
6287 	if (set_string_copy(str, tv) == -1)
6288 	    return -1;
6289 
6290 	tv->v_type = VAR_STRING;
6291     }
6292     else if (PyUnicode_Check(obj))
6293     {
6294 	PyObject	*bytes;
6295 	char_u	*str;
6296 
6297 	bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, ERRORS_ENCODE_ARG);
6298 	if (bytes == NULL)
6299 	    return -1;
6300 
6301 	if (PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
6302 	    return -1;
6303 	if (str == NULL)
6304 	    return -1;
6305 
6306 	if (set_string_copy(str, tv))
6307 	{
6308 	    Py_XDECREF(bytes);
6309 	    return -1;
6310 	}
6311 	Py_XDECREF(bytes);
6312 
6313 	tv->v_type = VAR_STRING;
6314     }
6315 #if PY_MAJOR_VERSION < 3
6316     else if (PyInt_Check(obj))
6317     {
6318 	tv->v_type = VAR_NUMBER;
6319 	tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
6320 	if (PyErr_Occurred())
6321 	    return -1;
6322     }
6323 #endif
6324     else if (PyLong_Check(obj))
6325     {
6326 	tv->v_type = VAR_NUMBER;
6327 	tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
6328 	if (PyErr_Occurred())
6329 	    return -1;
6330     }
6331     else if (PyDict_Check(obj))
6332 	return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
6333 #ifdef FEAT_FLOAT
6334     else if (PyFloat_Check(obj))
6335     {
6336 	tv->v_type = VAR_FLOAT;
6337 	tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
6338     }
6339 #endif
6340     else if (PyObject_HasAttrString(obj, "keys"))
6341 	return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
6342     // PyObject_GetIter can create built-in iterator for any sequence object
6343     else if (PyIter_Check(obj) || PySequence_Check(obj))
6344 	return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
6345     else if (PyMapping_Check(obj))
6346 	return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
6347     else if (PyNumber_Check(obj))
6348     {
6349 	PyObject	*num;
6350 
6351 	if (!(num = PyNumber_Long(obj)))
6352 	    return -1;
6353 
6354 	tv->v_type = VAR_NUMBER;
6355 	tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
6356 
6357 	Py_DECREF(num);
6358     }
6359     else if (obj == Py_None)
6360     {
6361 	tv->v_type = VAR_SPECIAL;
6362 	tv->vval.v_number = VVAL_NONE;
6363     }
6364     else
6365     {
6366 	PyErr_FORMAT(PyExc_TypeError,
6367 		N_("unable to convert %s to a Vim structure"),
6368 		Py_TYPE_NAME(obj));
6369 	return -1;
6370     }
6371     return 0;
6372 }
6373 
6374     static PyObject *
ConvertToPyObject(typval_T * tv)6375 ConvertToPyObject(typval_T *tv)
6376 {
6377     typval_T *argv;
6378     int i;
6379     if (tv == NULL)
6380     {
6381 	PyErr_SET_VIM(N_("internal error: NULL reference passed"));
6382 	return NULL;
6383     }
6384     switch (tv->v_type)
6385     {
6386 	case VAR_STRING:
6387 	    return PyBytes_FromString(tv->vval.v_string == NULL
6388 					    ? "" : (char *)tv->vval.v_string);
6389 	case VAR_NUMBER:
6390 	    return PyLong_FromLong((long) tv->vval.v_number);
6391 	case VAR_FLOAT:
6392 #ifdef FEAT_FLOAT
6393 	    return PyFloat_FromDouble((double) tv->vval.v_float);
6394 #endif
6395 	case VAR_LIST:
6396 	    return NEW_LIST(tv->vval.v_list);
6397 	case VAR_DICT:
6398 	    return NEW_DICTIONARY(tv->vval.v_dict);
6399 	case VAR_FUNC:
6400 	    return NEW_FUNCTION(tv->vval.v_string == NULL
6401 					  ? (char_u *)"" : tv->vval.v_string,
6402 					  0, NULL, NULL, TRUE);
6403 	case VAR_PARTIAL:
6404 	    if (tv->vval.v_partial->pt_argc)
6405 	    {
6406 		argv = PyMem_New(typval_T, (size_t)tv->vval.v_partial->pt_argc);
6407 		for (i = 0; i < tv->vval.v_partial->pt_argc; i++)
6408 		    copy_tv(&tv->vval.v_partial->pt_argv[i], &argv[i]);
6409 	    }
6410 	    else
6411 		argv = NULL;
6412 	    if (tv->vval.v_partial->pt_dict != NULL)
6413 		tv->vval.v_partial->pt_dict->dv_refcount++;
6414 	    return NEW_FUNCTION(tv->vval.v_partial == NULL
6415 			     ? (char_u *)"" : partial_name(tv->vval.v_partial),
6416 				tv->vval.v_partial->pt_argc, argv,
6417 				tv->vval.v_partial->pt_dict,
6418 				tv->vval.v_partial->pt_auto);
6419 	case VAR_BLOB:
6420 	    return PyBytes_FromStringAndSize(
6421 		(char*) tv->vval.v_blob->bv_ga.ga_data,
6422 		(Py_ssize_t) tv->vval.v_blob->bv_ga.ga_len);
6423 	case VAR_UNKNOWN:
6424 	case VAR_ANY:
6425 	case VAR_VOID:
6426 	case VAR_CHANNEL:
6427 	case VAR_JOB:
6428 	case VAR_INSTR:
6429 	    Py_INCREF(Py_None);
6430 	    return Py_None;
6431 	case VAR_BOOL:
6432 	case VAR_SPECIAL:
6433 	    switch (tv->vval.v_number)
6434 	    {
6435 		case VVAL_FALSE: return ALWAYS_FALSE;
6436 		case VVAL_TRUE:  return ALWAYS_TRUE;
6437 		case VVAL_NONE:
6438 		case VVAL_NULL:  return ALWAYS_NONE;
6439 	    }
6440 	    PyErr_SET_VIM(N_("internal error: invalid value type"));
6441 	    return NULL;
6442     }
6443     return NULL;
6444 }
6445 
6446 typedef struct
6447 {
6448     PyObject_HEAD
6449 } CurrentObject;
6450 static PyTypeObject CurrentType;
6451 
6452     static void
init_structs(void)6453 init_structs(void)
6454 {
6455     CLEAR_FIELD(OutputType);
6456     OutputType.tp_name = "vim.message";
6457     OutputType.tp_basicsize = sizeof(OutputObject);
6458     OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
6459     OutputType.tp_doc = "vim message object";
6460     OutputType.tp_methods = OutputMethods;
6461 #if PY_MAJOR_VERSION >= 3
6462     OutputType.tp_getattro = (getattrofunc)OutputGetattro;
6463     OutputType.tp_setattro = (setattrofunc)OutputSetattro;
6464     OutputType.tp_alloc = call_PyType_GenericAlloc;
6465     OutputType.tp_new = call_PyType_GenericNew;
6466     OutputType.tp_free = call_PyObject_Free;
6467     OutputType.tp_base = &PyStdPrinter_Type;
6468 #else
6469     OutputType.tp_getattr = (getattrfunc)OutputGetattr;
6470     OutputType.tp_setattr = (setattrfunc)OutputSetattr;
6471     // Disabled, because this causes a crash in test86
6472     // OutputType.tp_base = &PyFile_Type;
6473 #endif
6474 
6475     CLEAR_FIELD(IterType);
6476     IterType.tp_name = "vim.iter";
6477     IterType.tp_basicsize = sizeof(IterObject);
6478     IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6479     IterType.tp_doc = "generic iterator object";
6480     IterType.tp_iter = (getiterfunc)IterIter;
6481     IterType.tp_iternext = (iternextfunc)IterNext;
6482     IterType.tp_dealloc = (destructor)IterDestructor;
6483     IterType.tp_traverse = (traverseproc)IterTraverse;
6484     IterType.tp_clear = (inquiry)IterClear;
6485 
6486     CLEAR_FIELD(BufferType);
6487     BufferType.tp_name = "vim.buffer";
6488     BufferType.tp_basicsize = sizeof(BufferType);
6489     BufferType.tp_dealloc = (destructor)BufferDestructor;
6490     BufferType.tp_repr = (reprfunc)BufferRepr;
6491     BufferType.tp_as_sequence = &BufferAsSeq;
6492     BufferType.tp_as_mapping = &BufferAsMapping;
6493     BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
6494     BufferType.tp_doc = "vim buffer object";
6495     BufferType.tp_methods = BufferMethods;
6496 #if PY_MAJOR_VERSION >= 3
6497     BufferType.tp_getattro = (getattrofunc)BufferGetattro;
6498     BufferType.tp_setattro = (setattrofunc)BufferSetattro;
6499     BufferType.tp_alloc = call_PyType_GenericAlloc;
6500     BufferType.tp_new = call_PyType_GenericNew;
6501     BufferType.tp_free = call_PyObject_Free;
6502 #else
6503     BufferType.tp_getattr = (getattrfunc)BufferGetattr;
6504     BufferType.tp_setattr = (setattrfunc)BufferSetattr;
6505 #endif
6506 
6507     CLEAR_FIELD(WindowType);
6508     WindowType.tp_name = "vim.window";
6509     WindowType.tp_basicsize = sizeof(WindowObject);
6510     WindowType.tp_dealloc = (destructor)WindowDestructor;
6511     WindowType.tp_repr = (reprfunc)WindowRepr;
6512     WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6513     WindowType.tp_doc = "vim Window object";
6514     WindowType.tp_methods = WindowMethods;
6515     WindowType.tp_traverse = (traverseproc)WindowTraverse;
6516     WindowType.tp_clear = (inquiry)WindowClear;
6517 #if PY_MAJOR_VERSION >= 3
6518     WindowType.tp_getattro = (getattrofunc)WindowGetattro;
6519     WindowType.tp_setattro = (setattrofunc)WindowSetattro;
6520     WindowType.tp_alloc = call_PyType_GenericAlloc;
6521     WindowType.tp_new = call_PyType_GenericNew;
6522     WindowType.tp_free = call_PyObject_Free;
6523 #else
6524     WindowType.tp_getattr = (getattrfunc)WindowGetattr;
6525     WindowType.tp_setattr = (setattrfunc)WindowSetattr;
6526 #endif
6527 
6528     CLEAR_FIELD(TabPageType);
6529     TabPageType.tp_name = "vim.tabpage";
6530     TabPageType.tp_basicsize = sizeof(TabPageObject);
6531     TabPageType.tp_dealloc = (destructor)TabPageDestructor;
6532     TabPageType.tp_repr = (reprfunc)TabPageRepr;
6533     TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
6534     TabPageType.tp_doc = "vim tab page object";
6535     TabPageType.tp_methods = TabPageMethods;
6536 #if PY_MAJOR_VERSION >= 3
6537     TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
6538     TabPageType.tp_alloc = call_PyType_GenericAlloc;
6539     TabPageType.tp_new = call_PyType_GenericNew;
6540     TabPageType.tp_free = call_PyObject_Free;
6541 #else
6542     TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
6543 #endif
6544 
6545     CLEAR_FIELD(BufMapType);
6546     BufMapType.tp_name = "vim.bufferlist";
6547     BufMapType.tp_basicsize = sizeof(BufMapObject);
6548     BufMapType.tp_as_mapping = &BufMapAsMapping;
6549     BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
6550     BufMapType.tp_iter = BufMapIter;
6551     BufferType.tp_doc = "vim buffer list";
6552 
6553     CLEAR_FIELD(WinListType);
6554     WinListType.tp_name = "vim.windowlist";
6555     WinListType.tp_basicsize = sizeof(WinListType);
6556     WinListType.tp_as_sequence = &WinListAsSeq;
6557     WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
6558     WinListType.tp_doc = "vim window list";
6559     WinListType.tp_dealloc = (destructor)WinListDestructor;
6560 
6561     CLEAR_FIELD(TabListType);
6562     TabListType.tp_name = "vim.tabpagelist";
6563     TabListType.tp_basicsize = sizeof(TabListType);
6564     TabListType.tp_as_sequence = &TabListAsSeq;
6565     TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
6566     TabListType.tp_doc = "vim tab page list";
6567 
6568     CLEAR_FIELD(RangeType);
6569     RangeType.tp_name = "vim.range";
6570     RangeType.tp_basicsize = sizeof(RangeObject);
6571     RangeType.tp_dealloc = (destructor)RangeDestructor;
6572     RangeType.tp_repr = (reprfunc)RangeRepr;
6573     RangeType.tp_as_sequence = &RangeAsSeq;
6574     RangeType.tp_as_mapping = &RangeAsMapping;
6575     RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6576     RangeType.tp_doc = "vim Range object";
6577     RangeType.tp_methods = RangeMethods;
6578     RangeType.tp_traverse = (traverseproc)RangeTraverse;
6579     RangeType.tp_clear = (inquiry)RangeClear;
6580 #if PY_MAJOR_VERSION >= 3
6581     RangeType.tp_getattro = (getattrofunc)RangeGetattro;
6582     RangeType.tp_alloc = call_PyType_GenericAlloc;
6583     RangeType.tp_new = call_PyType_GenericNew;
6584     RangeType.tp_free = call_PyObject_Free;
6585 #else
6586     RangeType.tp_getattr = (getattrfunc)RangeGetattr;
6587 #endif
6588 
6589     CLEAR_FIELD(CurrentType);
6590     CurrentType.tp_name = "vim.currentdata";
6591     CurrentType.tp_basicsize = sizeof(CurrentObject);
6592     CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
6593     CurrentType.tp_doc = "vim current object";
6594     CurrentType.tp_methods = CurrentMethods;
6595 #if PY_MAJOR_VERSION >= 3
6596     CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
6597     CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
6598 #else
6599     CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
6600     CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
6601 #endif
6602 
6603     CLEAR_FIELD(DictionaryType);
6604     DictionaryType.tp_name = "vim.dictionary";
6605     DictionaryType.tp_basicsize = sizeof(DictionaryObject);
6606     DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
6607     DictionaryType.tp_as_sequence = &DictionaryAsSeq;
6608     DictionaryType.tp_as_mapping = &DictionaryAsMapping;
6609     DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
6610     DictionaryType.tp_doc = "dictionary pushing modifications to Vim structure";
6611     DictionaryType.tp_methods = DictionaryMethods;
6612     DictionaryType.tp_iter = (getiterfunc)DictionaryIter;
6613     DictionaryType.tp_new = (newfunc)DictionaryConstructor;
6614     DictionaryType.tp_alloc = (allocfunc)PyType_GenericAlloc;
6615 #if PY_MAJOR_VERSION >= 3
6616     DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
6617     DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
6618 #else
6619     DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
6620     DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
6621 #endif
6622 
6623     CLEAR_FIELD(ListType);
6624     ListType.tp_name = "vim.list";
6625     ListType.tp_dealloc = (destructor)ListDestructor;
6626     ListType.tp_basicsize = sizeof(ListObject);
6627     ListType.tp_as_sequence = &ListAsSeq;
6628     ListType.tp_as_mapping = &ListAsMapping;
6629     ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
6630     ListType.tp_doc = "list pushing modifications to Vim structure";
6631     ListType.tp_methods = ListMethods;
6632     ListType.tp_iter = (getiterfunc)ListIter;
6633     ListType.tp_new = (newfunc)ListConstructor;
6634     ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
6635 #if PY_MAJOR_VERSION >= 3
6636     ListType.tp_getattro = (getattrofunc)ListGetattro;
6637     ListType.tp_setattro = (setattrofunc)ListSetattro;
6638 #else
6639     ListType.tp_getattr = (getattrfunc)ListGetattr;
6640     ListType.tp_setattr = (setattrfunc)ListSetattr;
6641 #endif
6642 
6643     CLEAR_FIELD(FunctionType);
6644     FunctionType.tp_name = "vim.function";
6645     FunctionType.tp_basicsize = sizeof(FunctionObject);
6646     FunctionType.tp_dealloc = (destructor)FunctionDestructor;
6647     FunctionType.tp_call = (ternaryfunc)FunctionCall;
6648     FunctionType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
6649     FunctionType.tp_doc = "object that calls Vim function";
6650     FunctionType.tp_methods = FunctionMethods;
6651     FunctionType.tp_repr = (reprfunc)FunctionRepr;
6652     FunctionType.tp_new = (newfunc)FunctionConstructor;
6653     FunctionType.tp_alloc = (allocfunc)PyType_GenericAlloc;
6654 #if PY_MAJOR_VERSION >= 3
6655     FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
6656 #else
6657     FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
6658 #endif
6659 
6660     CLEAR_FIELD(OptionsType);
6661     OptionsType.tp_name = "vim.options";
6662     OptionsType.tp_basicsize = sizeof(OptionsObject);
6663     OptionsType.tp_as_sequence = &OptionsAsSeq;
6664     OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
6665     OptionsType.tp_doc = "object for manipulating options";
6666     OptionsType.tp_iter = (getiterfunc)OptionsIter;
6667     OptionsType.tp_as_mapping = &OptionsAsMapping;
6668     OptionsType.tp_dealloc = (destructor)OptionsDestructor;
6669     OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
6670     OptionsType.tp_clear = (inquiry)OptionsClear;
6671 
6672 #if PY_VERSION_HEX < 0x030700f0
6673     CLEAR_FIELD(LoaderType);
6674     LoaderType.tp_name = "vim.Loader";
6675     LoaderType.tp_basicsize = sizeof(LoaderObject);
6676     LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
6677     LoaderType.tp_doc = "vim message object";
6678     LoaderType.tp_methods = LoaderMethods;
6679     LoaderType.tp_dealloc = (destructor)LoaderDestructor;
6680 #endif
6681 
6682 #if PY_MAJOR_VERSION >= 3
6683     CLEAR_FIELD(vimmodule);
6684     vimmodule.m_name = "vim";
6685     vimmodule.m_doc = "Vim Python interface\n";
6686     vimmodule.m_size = -1;
6687     vimmodule.m_methods = VimMethods;
6688 #endif
6689 }
6690 
6691 #define PYTYPE_READY(type) \
6692     if (PyType_Ready(&type)) \
6693 	return -1;
6694 
6695     static int
init_types(void)6696 init_types(void)
6697 {
6698     PYTYPE_READY(IterType);
6699     PYTYPE_READY(BufferType);
6700     PYTYPE_READY(RangeType);
6701     PYTYPE_READY(WindowType);
6702     PYTYPE_READY(TabPageType);
6703     PYTYPE_READY(BufMapType);
6704     PYTYPE_READY(WinListType);
6705     PYTYPE_READY(TabListType);
6706     PYTYPE_READY(CurrentType);
6707     PYTYPE_READY(DictionaryType);
6708     PYTYPE_READY(ListType);
6709     PYTYPE_READY(FunctionType);
6710     PYTYPE_READY(OptionsType);
6711     PYTYPE_READY(OutputType);
6712 #if PY_VERSION_HEX < 0x030700f0
6713     PYTYPE_READY(LoaderType);
6714 #endif
6715     return 0;
6716 }
6717 
6718     static int
init_sys_path(void)6719 init_sys_path(void)
6720 {
6721     PyObject	*path;
6722     PyObject	*path_hook;
6723     PyObject	*path_hooks;
6724 
6725     if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
6726 	return -1;
6727 
6728     if (!(path_hooks = PySys_GetObject("path_hooks")))
6729     {
6730 	PyErr_Clear();
6731 	path_hooks = PyList_New(1);
6732 	PyList_SET_ITEM(path_hooks, 0, path_hook);
6733 	if (PySys_SetObject("path_hooks", path_hooks))
6734 	{
6735 	    Py_DECREF(path_hooks);
6736 	    return -1;
6737 	}
6738 	Py_DECREF(path_hooks);
6739     }
6740     else if (PyList_Check(path_hooks))
6741     {
6742 	if (PyList_Append(path_hooks, path_hook))
6743 	{
6744 	    Py_DECREF(path_hook);
6745 	    return -1;
6746 	}
6747 	Py_DECREF(path_hook);
6748     }
6749     else
6750     {
6751 	VimTryStart();
6752 	emsg(_("Failed to set path hook: sys.path_hooks is not a list\n"
6753 	       "You should now do the following:\n"
6754 	       "- append vim.path_hook to sys.path_hooks\n"
6755 	       "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
6756 	VimTryEnd(); // Discard the error
6757 	Py_DECREF(path_hook);
6758 	return 0;
6759     }
6760 
6761     if (!(path = PySys_GetObject("path")))
6762     {
6763 	PyErr_Clear();
6764 	path = PyList_New(1);
6765 	Py_INCREF(vim_special_path_object);
6766 	PyList_SET_ITEM(path, 0, vim_special_path_object);
6767 	if (PySys_SetObject("path", path))
6768 	{
6769 	    Py_DECREF(path);
6770 	    return -1;
6771 	}
6772 	Py_DECREF(path);
6773     }
6774     else if (PyList_Check(path))
6775     {
6776 	if (PyList_Append(path, vim_special_path_object))
6777 	    return -1;
6778     }
6779     else
6780     {
6781 	VimTryStart();
6782 	emsg(_("Failed to set path: sys.path is not a list\n"
6783 	       "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
6784 	VimTryEnd(); // Discard the error
6785     }
6786 
6787     return 0;
6788 }
6789 
6790 static BufMapObject TheBufferMap =
6791 {
6792     PyObject_HEAD_INIT(&BufMapType)
6793 };
6794 
6795 static WinListObject TheWindowList =
6796 {
6797     PyObject_HEAD_INIT(&WinListType)
6798     NULL
6799 };
6800 
6801 static CurrentObject TheCurrent =
6802 {
6803     PyObject_HEAD_INIT(&CurrentType)
6804 };
6805 
6806 static TabListObject TheTabPageList =
6807 {
6808     PyObject_HEAD_INIT(&TabListType)
6809 };
6810 
6811 static struct numeric_constant {
6812     char	*name;
6813     int		val;
6814 } numeric_constants[] = {
6815     {"VAR_LOCKED",	VAR_LOCKED},
6816     {"VAR_FIXED",	VAR_FIXED},
6817     {"VAR_SCOPE",	VAR_SCOPE},
6818     {"VAR_DEF_SCOPE",	VAR_DEF_SCOPE},
6819 };
6820 
6821 static struct object_constant {
6822     char	*name;
6823     PyObject	*valObject;
6824 } object_constants[] = {
6825     {"buffers",  (PyObject *)(void *)&TheBufferMap},
6826     {"windows",  (PyObject *)(void *)&TheWindowList},
6827     {"tabpages", (PyObject *)(void *)&TheTabPageList},
6828     {"current",  (PyObject *)(void *)&TheCurrent},
6829 
6830     {"Buffer",     (PyObject *)&BufferType},
6831     {"Range",      (PyObject *)&RangeType},
6832     {"Window",     (PyObject *)&WindowType},
6833     {"TabPage",    (PyObject *)&TabPageType},
6834     {"Dictionary", (PyObject *)&DictionaryType},
6835     {"List",       (PyObject *)&ListType},
6836     {"Function",   (PyObject *)&FunctionType},
6837     {"Options",    (PyObject *)&OptionsType},
6838 #if PY_VERSION_HEX < 0x030700f0
6839     {"_Loader",    (PyObject *)&LoaderType},
6840 #endif
6841 };
6842 
6843 #define ADD_OBJECT(m, name, obj) \
6844     if (PyModule_AddObject(m, name, obj)) \
6845 	return -1;
6846 
6847 #define ADD_CHECKED_OBJECT(m, name, obj) \
6848     { \
6849 	PyObject	*valObject = obj; \
6850 	if (!valObject) \
6851 	    return -1; \
6852 	ADD_OBJECT(m, name, valObject); \
6853     }
6854 
6855     static int
populate_module(PyObject * m)6856 populate_module(PyObject *m)
6857 {
6858     int		i;
6859     PyObject	*other_module;
6860     PyObject	*attr;
6861     PyObject	*imp;
6862 #if PY_VERSION_HEX >= 0x030700f0
6863     PyObject	*dict;
6864     PyObject	*cls;
6865 #endif
6866 
6867     for (i = 0; i < (int)(sizeof(numeric_constants)
6868 					   / sizeof(struct numeric_constant));
6869 	    ++i)
6870 	ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
6871 		PyInt_FromLong(numeric_constants[i].val));
6872 
6873     for (i = 0; i < (int)(sizeof(object_constants)
6874 					    / sizeof(struct object_constant));
6875 	    ++i)
6876     {
6877 	PyObject	*valObject;
6878 
6879 	valObject = object_constants[i].valObject;
6880 	Py_INCREF(valObject);
6881 	ADD_OBJECT(m, object_constants[i].name, valObject);
6882     }
6883 
6884     if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
6885 	return -1;
6886     ADD_OBJECT(m, "error", VimError);
6887 
6888     ADD_CHECKED_OBJECT(m, "vars",  NEW_DICTIONARY(get_globvar_dict()));
6889     ADD_CHECKED_OBJECT(m, "vvars", NEW_DICTIONARY(get_vimvar_dict()));
6890     ADD_CHECKED_OBJECT(m, "options",
6891 	    OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
6892 
6893     if (!(other_module = PyImport_ImportModule("os")))
6894 	return -1;
6895     ADD_OBJECT(m, "os", other_module);
6896 
6897 #if PY_MAJOR_VERSION >= 3
6898     if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwd")))
6899 	return -1;
6900 #else
6901     if (!(py_getcwd = PyObject_GetAttrString(other_module, "getcwdu")))
6902 	return -1;
6903 #endif
6904     ADD_OBJECT(m, "_getcwd", py_getcwd)
6905 
6906     if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
6907 	return -1;
6908     ADD_OBJECT(m, "_chdir", py_chdir);
6909     if (!(attr = PyObject_GetAttrString(m, "chdir")))
6910 	return -1;
6911     if (PyObject_SetAttrString(other_module, "chdir", attr))
6912     {
6913 	Py_DECREF(attr);
6914 	return -1;
6915     }
6916     Py_DECREF(attr);
6917 
6918     if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
6919     {
6920 	ADD_OBJECT(m, "_fchdir", py_fchdir);
6921 	if (!(attr = PyObject_GetAttrString(m, "fchdir")))
6922 	    return -1;
6923 	if (PyObject_SetAttrString(other_module, "fchdir", attr))
6924 	{
6925 	    Py_DECREF(attr);
6926 	    return -1;
6927 	}
6928 	Py_DECREF(attr);
6929     }
6930     else
6931 	PyErr_Clear();
6932 
6933     if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
6934 	return -1;
6935 
6936     ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
6937 
6938 #if PY_VERSION_HEX >= 0x030700f0
6939     if (!(imp = PyImport_ImportModule("importlib.machinery")))
6940 	return -1;
6941 
6942     dict = PyModule_GetDict(imp);
6943 
6944     if (!(cls = PyDict_GetItemString(dict, "PathFinder")))
6945     {
6946 	Py_DECREF(imp);
6947 	return -1;
6948     }
6949 
6950     if (!(py_find_spec = PyObject_GetAttrString(cls, "find_spec")))
6951     {
6952 	Py_DECREF(imp);
6953 	return -1;
6954     }
6955 
6956     if ((py_find_module = PyObject_GetAttrString(cls, "find_module")))
6957     {
6958 	// find_module() is deprecated, this may stop working in some later
6959 	// version.
6960         ADD_OBJECT(m, "_find_module", py_find_module);
6961     }
6962 
6963     Py_DECREF(imp);
6964 
6965     ADD_OBJECT(m, "_find_spec", py_find_spec);
6966 #else
6967     if (!(imp = PyImport_ImportModule("imp")))
6968 	return -1;
6969 
6970     if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
6971     {
6972 	Py_DECREF(imp);
6973 	return -1;
6974     }
6975 
6976     if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
6977     {
6978 	Py_DECREF(py_find_module);
6979 	Py_DECREF(imp);
6980 	return -1;
6981     }
6982 
6983     Py_DECREF(imp);
6984 
6985     ADD_OBJECT(m, "_find_module", py_find_module);
6986     ADD_OBJECT(m, "_load_module", py_load_module);
6987 #endif
6988 
6989     return 0;
6990 }
6991