1/* vi:set ts=8 sts=4 sw=4:
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.
11 *
12 * Common code for if_python.c and if_python3.c.
13 */
14
15/*
16 * obtain a lock on the Vim data structures
17 */
18    static void
19Python_Lock_Vim(void)
20{
21}
22
23/*
24 * release a lock on the Vim data structures
25 */
26    static void
27Python_Release_Vim(void)
28{
29}
30
31/* Output object definition
32 */
33
34static PyObject *OutputWrite(PyObject *, PyObject *);
35static PyObject *OutputWritelines(PyObject *, PyObject *);
36
37typedef void (*writefn)(char_u *);
38static void writer(writefn fn, char_u *str, PyInt n);
39
40typedef struct
41{
42    PyObject_HEAD
43    long softspace;
44    long error;
45} OutputObject;
46
47static struct PyMethodDef OutputMethods[] = {
48    /* name,	    function,		calling,    documentation */
49    {"write",	    OutputWrite,	1,	    "" },
50    {"writelines",  OutputWritelines,	1,	    "" },
51    { NULL,	    NULL,		0,	    NULL }
52};
53
54#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
55
56/*************/
57
58/* Output buffer management
59 */
60
61    static PyObject *
62OutputWrite(PyObject *self, PyObject *args)
63{
64    int len;
65    char *str;
66    int error = ((OutputObject *)(self))->error;
67
68    if (!PyArg_ParseTuple(args, "s#", &str, &len))
69	return NULL;
70
71    Py_BEGIN_ALLOW_THREADS
72    Python_Lock_Vim();
73    writer((writefn)(error ? emsg : msg), (char_u *)str, len);
74    Python_Release_Vim();
75    Py_END_ALLOW_THREADS
76
77    Py_INCREF(Py_None);
78    return Py_None;
79}
80
81    static PyObject *
82OutputWritelines(PyObject *self, PyObject *args)
83{
84    PyInt n;
85    PyInt i;
86    PyObject *list;
87    int error = ((OutputObject *)(self))->error;
88
89    if (!PyArg_ParseTuple(args, "O", &list))
90	return NULL;
91    Py_INCREF(list);
92
93    if (!PyList_Check(list)) {
94	PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
95	Py_DECREF(list);
96	return NULL;
97    }
98
99    n = PyList_Size(list);
100
101    for (i = 0; i < n; ++i)
102    {
103	PyObject *line = PyList_GetItem(list, i);
104	char *str;
105	PyInt len;
106
107	if (!PyArg_Parse(line, "s#", &str, &len)) {
108	    PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
109	    Py_DECREF(list);
110	    return NULL;
111	}
112
113	Py_BEGIN_ALLOW_THREADS
114	Python_Lock_Vim();
115	writer((writefn)(error ? emsg : msg), (char_u *)str, len);
116	Python_Release_Vim();
117	Py_END_ALLOW_THREADS
118    }
119
120    Py_DECREF(list);
121    Py_INCREF(Py_None);
122    return Py_None;
123}
124
125static char_u *buffer = NULL;
126static PyInt buffer_len = 0;
127static PyInt buffer_size = 0;
128
129static writefn old_fn = NULL;
130
131    static void
132buffer_ensure(PyInt n)
133{
134    PyInt new_size;
135    char_u *new_buffer;
136
137    if (n < buffer_size)
138	return;
139
140    new_size = buffer_size;
141    while (new_size < n)
142	new_size += 80;
143
144    if (new_size != buffer_size)
145    {
146	new_buffer = alloc((unsigned)new_size);
147	if (new_buffer == NULL)
148	    return;
149
150	if (buffer)
151	{
152	    memcpy(new_buffer, buffer, buffer_len);
153	    vim_free(buffer);
154	}
155
156	buffer = new_buffer;
157	buffer_size = new_size;
158    }
159}
160
161    static void
162PythonIO_Flush(void)
163{
164    if (old_fn && buffer_len)
165    {
166	buffer[buffer_len] = 0;
167	old_fn(buffer);
168    }
169
170    buffer_len = 0;
171}
172
173    static void
174writer(writefn fn, char_u *str, PyInt n)
175{
176    char_u *ptr;
177
178    if (fn != old_fn && old_fn != NULL)
179	PythonIO_Flush();
180
181    old_fn = fn;
182
183    while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
184    {
185	PyInt len = ptr - str;
186
187	buffer_ensure(buffer_len + len + 1);
188
189	memcpy(buffer + buffer_len, str, len);
190	buffer_len += len;
191	buffer[buffer_len] = 0;
192	fn(buffer);
193	str = ptr + 1;
194	n -= len + 1;
195	buffer_len = 0;
196    }
197
198    /* Put the remaining text into the buffer for later printing */
199    buffer_ensure(buffer_len + n + 1);
200    memcpy(buffer + buffer_len, str, n);
201    buffer_len += n;
202}
203
204/***************/
205
206static PyTypeObject OutputType;
207
208static OutputObject Output =
209{
210    PyObject_HEAD_INIT(&OutputType)
211    0,
212    0
213};
214
215static OutputObject Error =
216{
217    PyObject_HEAD_INIT(&OutputType)
218    0,
219    1
220};
221
222    static int
223PythonIO_Init_io(void)
224{
225    PySys_SetObject("stdout", (PyObject *)(void *)&Output);
226    PySys_SetObject("stderr", (PyObject *)(void *)&Error);
227
228    if (PyErr_Occurred())
229    {
230	EMSG(_("E264: Python: Error initialising I/O objects"));
231	return -1;
232    }
233
234    return 0;
235}
236
237
238static PyObject *VimError;
239
240/* Check to see whether a Vim error has been reported, or a keyboard
241 * interrupt has been detected.
242 */
243    static int
244VimErrorCheck(void)
245{
246    if (got_int)
247    {
248	PyErr_SetNone(PyExc_KeyboardInterrupt);
249	return 1;
250    }
251    else if (did_emsg && !PyErr_Occurred())
252    {
253	PyErr_SetNone(VimError);
254	return 1;
255    }
256
257    return 0;
258}
259
260/* Vim module - Implementation
261 */
262    static PyObject *
263VimCommand(PyObject *self UNUSED, PyObject *args)
264{
265    char *cmd;
266    PyObject *result;
267
268    if (!PyArg_ParseTuple(args, "s", &cmd))
269	return NULL;
270
271    PyErr_Clear();
272
273    Py_BEGIN_ALLOW_THREADS
274    Python_Lock_Vim();
275
276    do_cmdline_cmd((char_u *)cmd);
277    update_screen(VALID);
278
279    Python_Release_Vim();
280    Py_END_ALLOW_THREADS
281
282    if (VimErrorCheck())
283	result = NULL;
284    else
285	result = Py_None;
286
287    Py_XINCREF(result);
288    return result;
289}
290
291#ifdef FEAT_EVAL
292/*
293 * Function to translate a typval_T into a PyObject; this will recursively
294 * translate lists/dictionaries into their Python equivalents.
295 *
296 * The depth parameter is to avoid infinite recursion, set it to 1 when
297 * you call VimToPython.
298 */
299    static PyObject *
300VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
301{
302    PyObject	*result;
303    PyObject	*newObj;
304    char	ptrBuf[NUMBUFLEN];
305
306    /* Avoid infinite recursion */
307    if (depth > 100)
308    {
309	Py_INCREF(Py_None);
310	result = Py_None;
311	return result;
312    }
313
314    /* Check if we run into a recursive loop.  The item must be in lookupDict
315     * then and we can use it again. */
316    if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
317	    || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
318    {
319	sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
320		our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
321					   : (long_u)our_tv->vval.v_dict);
322	result = PyDict_GetItemString(lookupDict, ptrBuf);
323	if (result != NULL)
324	{
325	    Py_INCREF(result);
326	    return result;
327	}
328    }
329
330    if (our_tv->v_type == VAR_STRING)
331    {
332	result = Py_BuildValue("s", our_tv->vval.v_string);
333    }
334    else if (our_tv->v_type == VAR_NUMBER)
335    {
336	char buf[NUMBUFLEN];
337
338	/* For backwards compatibility numbers are stored as strings. */
339	sprintf(buf, "%ld", (long)our_tv->vval.v_number);
340	result = Py_BuildValue("s", buf);
341    }
342# ifdef FEAT_FLOAT
343    else if (our_tv->v_type == VAR_FLOAT)
344    {
345	char buf[NUMBUFLEN];
346
347	sprintf(buf, "%f", our_tv->vval.v_float);
348	result = Py_BuildValue("s", buf);
349    }
350# endif
351    else if (our_tv->v_type == VAR_LIST)
352    {
353	list_T		*list = our_tv->vval.v_list;
354	listitem_T	*curr;
355
356	result = PyList_New(0);
357
358	if (list != NULL)
359	{
360	    PyDict_SetItemString(lookupDict, ptrBuf, result);
361
362	    for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
363	    {
364		newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
365		PyList_Append(result, newObj);
366		Py_DECREF(newObj);
367	    }
368	}
369    }
370    else if (our_tv->v_type == VAR_DICT)
371    {
372	result = PyDict_New();
373
374	if (our_tv->vval.v_dict != NULL)
375	{
376	    hashtab_T	*ht = &our_tv->vval.v_dict->dv_hashtab;
377	    long_u	todo = ht->ht_used;
378	    hashitem_T	*hi;
379	    dictitem_T	*di;
380
381	    PyDict_SetItemString(lookupDict, ptrBuf, result);
382
383	    for (hi = ht->ht_array; todo > 0; ++hi)
384	    {
385		if (!HASHITEM_EMPTY(hi))
386		{
387		    --todo;
388
389		    di = dict_lookup(hi);
390		    newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
391		    PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
392		    Py_DECREF(newObj);
393		}
394	    }
395	}
396    }
397    else
398    {
399	Py_INCREF(Py_None);
400	result = Py_None;
401    }
402
403    return result;
404}
405#endif
406
407    static PyObject *
408VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
409{
410#ifdef FEAT_EVAL
411    char	*expr;
412    typval_T	*our_tv;
413    PyObject	*result;
414    PyObject    *lookup_dict;
415
416    if (!PyArg_ParseTuple(args, "s", &expr))
417	return NULL;
418
419    Py_BEGIN_ALLOW_THREADS
420    Python_Lock_Vim();
421    our_tv = eval_expr((char_u *)expr, NULL);
422
423    Python_Release_Vim();
424    Py_END_ALLOW_THREADS
425
426    if (our_tv == NULL)
427    {
428	PyErr_SetVim(_("invalid expression"));
429	return NULL;
430    }
431
432    /* Convert the Vim type into a Python type.  Create a dictionary that's
433     * used to check for recursive loops. */
434    lookup_dict = PyDict_New();
435    result = VimToPython(our_tv, 1, lookup_dict);
436    Py_DECREF(lookup_dict);
437
438
439    Py_BEGIN_ALLOW_THREADS
440    Python_Lock_Vim();
441    free_tv(our_tv);
442    Python_Release_Vim();
443    Py_END_ALLOW_THREADS
444
445    return result;
446#else
447    PyErr_SetVim(_("expressions disabled at compile time"));
448    return NULL;
449#endif
450}
451
452/*
453 * Vim module - Definitions
454 */
455
456static struct PyMethodDef VimMethods[] = {
457    /* name,	     function,		calling,    documentation */
458    {"command",	     VimCommand,	1,	    "Execute a Vim ex-mode command" },
459    {"eval",	     VimEval,		1,	    "Evaluate an expression using Vim evaluator" },
460    { NULL,	     NULL,		0,	    NULL }
461};
462
463typedef struct
464{
465    PyObject_HEAD
466    buf_T *buf;
467}
468BufferObject;
469
470#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
471
472/*
473 * Buffer list object - Implementation
474 */
475
476    static PyInt
477BufListLength(PyObject *self UNUSED)
478{
479    buf_T	*b = firstbuf;
480    PyInt	n = 0;
481
482    while (b)
483    {
484	++n;
485	b = b->b_next;
486    }
487
488    return n;
489}
490
491    static PyObject *
492BufListItem(PyObject *self UNUSED, PyInt n)
493{
494    buf_T *b;
495
496    for (b = firstbuf; b; b = b->b_next, --n)
497    {
498	if (n == 0)
499	    return BufferNew(b);
500    }
501
502    PyErr_SetString(PyExc_IndexError, _("no such buffer"));
503    return NULL;
504}
505
506typedef struct
507{
508    PyObject_HEAD
509    win_T	*win;
510} WindowObject;
511
512#define INVALID_WINDOW_VALUE ((win_T *)(-1))
513
514    static int
515CheckWindow(WindowObject *this)
516{
517    if (this->win == INVALID_WINDOW_VALUE)
518    {
519	PyErr_SetVim(_("attempt to refer to deleted window"));
520	return -1;
521    }
522
523    return 0;
524}
525
526static int WindowSetattr(PyObject *, char *, PyObject *);
527static PyObject *WindowRepr(PyObject *);
528
529    static int
530WindowSetattr(PyObject *self, char *name, PyObject *val)
531{
532    WindowObject *this = (WindowObject *)(self);
533
534    if (CheckWindow(this))
535	return -1;
536
537    if (strcmp(name, "buffer") == 0)
538    {
539	PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
540	return -1;
541    }
542    else if (strcmp(name, "cursor") == 0)
543    {
544	long lnum;
545	long col;
546	long len;
547
548	if (!PyArg_Parse(val, "(ll)", &lnum, &col))
549	    return -1;
550
551	if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
552	{
553	    PyErr_SetVim(_("cursor position outside buffer"));
554	    return -1;
555	}
556
557	/* Check for keyboard interrupts */
558	if (VimErrorCheck())
559	    return -1;
560
561	/* When column is out of range silently correct it. */
562	len = (long)STRLEN(ml_get_buf(this->win->w_buffer, lnum, FALSE));
563	if (col > len)
564	    col = len;
565
566	this->win->w_cursor.lnum = lnum;
567	this->win->w_cursor.col = col;
568#ifdef FEAT_VIRTUALEDIT
569	this->win->w_cursor.coladd = 0;
570#endif
571	update_screen(VALID);
572
573	return 0;
574    }
575    else if (strcmp(name, "height") == 0)
576    {
577	int	height;
578	win_T	*savewin;
579
580	if (!PyArg_Parse(val, "i", &height))
581	    return -1;
582
583#ifdef FEAT_GUI
584	need_mouse_correct = TRUE;
585#endif
586	savewin = curwin;
587	curwin = this->win;
588	win_setheight(height);
589	curwin = savewin;
590
591	/* Check for keyboard interrupts */
592	if (VimErrorCheck())
593	    return -1;
594
595	return 0;
596    }
597#ifdef FEAT_VERTSPLIT
598    else if (strcmp(name, "width") == 0)
599    {
600	int	width;
601	win_T	*savewin;
602
603	if (!PyArg_Parse(val, "i", &width))
604	    return -1;
605
606#ifdef FEAT_GUI
607	need_mouse_correct = TRUE;
608#endif
609	savewin = curwin;
610	curwin = this->win;
611	win_setwidth(width);
612	curwin = savewin;
613
614	/* Check for keyboard interrupts */
615	if (VimErrorCheck())
616	    return -1;
617
618	return 0;
619    }
620#endif
621    else
622    {
623	PyErr_SetString(PyExc_AttributeError, name);
624	return -1;
625    }
626}
627
628    static PyObject *
629WindowRepr(PyObject *self)
630{
631    static char repr[100];
632    WindowObject *this = (WindowObject *)(self);
633
634    if (this->win == INVALID_WINDOW_VALUE)
635    {
636	vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
637	return PyString_FromString(repr);
638    }
639    else
640    {
641	int	i = 0;
642	win_T	*w;
643
644	for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
645	    ++i;
646
647	if (w == NULL)
648	    vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
649								      (self));
650	else
651	    vim_snprintf(repr, 100, _("<window %d>"), i);
652
653	return PyString_FromString(repr);
654    }
655}
656
657/*
658 * Window list object - Implementation
659 */
660    static PyInt
661WinListLength(PyObject *self UNUSED)
662{
663    win_T	*w = firstwin;
664    PyInt	n = 0;
665
666    while (w != NULL)
667    {
668	++n;
669	w = W_NEXT(w);
670    }
671
672    return n;
673}
674
675    static PyObject *
676WinListItem(PyObject *self UNUSED, PyInt n)
677{
678    win_T *w;
679
680    for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
681	if (n == 0)
682	    return WindowNew(w);
683
684    PyErr_SetString(PyExc_IndexError, _("no such window"));
685    return NULL;
686}
687
688/* Convert a Python string into a Vim line.
689 *
690 * The result is in allocated memory. All internal nulls are replaced by
691 * newline characters. It is an error for the string to contain newline
692 * characters.
693 *
694 * On errors, the Python exception data is set, and NULL is returned.
695 */
696    static char *
697StringToLine(PyObject *obj)
698{
699    const char *str;
700    char *save;
701    PyInt len;
702    PyInt i;
703    char *p;
704
705    if (obj == NULL || !PyString_Check(obj))
706    {
707	PyErr_BadArgument();
708	return NULL;
709    }
710
711    str = PyString_AsString(obj);
712    len = PyString_Size(obj);
713
714    /*
715     * Error checking: String must not contain newlines, as we
716     * are replacing a single line, and we must replace it with
717     * a single line.
718     * A trailing newline is removed, so that append(f.readlines()) works.
719     */
720    p = memchr(str, '\n', len);
721    if (p != NULL)
722    {
723	if (p == str + len - 1)
724	    --len;
725	else
726	{
727	    PyErr_SetVim(_("string cannot contain newlines"));
728	    return NULL;
729	}
730    }
731
732    /* Create a copy of the string, with internal nulls replaced by
733     * newline characters, as is the vim convention.
734     */
735    save = (char *)alloc((unsigned)(len+1));
736    if (save == NULL)
737    {
738	PyErr_NoMemory();
739	return NULL;
740    }
741
742    for (i = 0; i < len; ++i)
743    {
744	if (str[i] == '\0')
745	    save[i] = '\n';
746	else
747	    save[i] = str[i];
748    }
749
750    save[i] = '\0';
751
752    return save;
753}
754
755/* Get a line from the specified buffer. The line number is
756 * in Vim format (1-based). The line is returned as a Python
757 * string object.
758 */
759    static PyObject *
760GetBufferLine(buf_T *buf, PyInt n)
761{
762    return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
763}
764
765
766/* Get a list of lines from the specified buffer. The line numbers
767 * are in Vim format (1-based). The range is from lo up to, but not
768 * including, hi. The list is returned as a Python list of string objects.
769 */
770    static PyObject *
771GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
772{
773    PyInt i;
774    PyInt n = hi - lo;
775    PyObject *list = PyList_New(n);
776
777    if (list == NULL)
778	return NULL;
779
780    for (i = 0; i < n; ++i)
781    {
782	PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
783
784	/* Error check - was the Python string creation OK? */
785	if (str == NULL)
786	{
787	    Py_DECREF(list);
788	    return NULL;
789	}
790
791	/* Set the list item */
792	if (PyList_SetItem(list, i, str))
793	{
794	    Py_DECREF(str);
795	    Py_DECREF(list);
796	    return NULL;
797	}
798    }
799
800    /* The ownership of the Python list is passed to the caller (ie,
801     * the caller should Py_DECREF() the object when it is finished
802     * with it).
803     */
804
805    return list;
806}
807
808/*
809 * Check if deleting lines made the cursor position invalid.
810 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
811 * deleted).
812 */
813    static void
814py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
815{
816    if (curwin->w_cursor.lnum >= lo)
817    {
818	/* Adjust the cursor position if it's in/after the changed
819	 * lines. */
820	if (curwin->w_cursor.lnum >= hi)
821	{
822	    curwin->w_cursor.lnum += extra;
823	    check_cursor_col();
824	}
825	else if (extra < 0)
826	{
827	    curwin->w_cursor.lnum = lo;
828	    check_cursor();
829	}
830	else
831	    check_cursor_col();
832	changed_cline_bef_curs();
833    }
834    invalidate_botline();
835}
836
837/* Replace a line in the specified buffer. The line number is
838 * in Vim format (1-based). The replacement line is given as
839 * a Python string object. The object is checked for validity
840 * and correct format. Errors are returned as a value of FAIL.
841 * The return value is OK on success.
842 * If OK is returned and len_change is not NULL, *len_change
843 * is set to the change in the buffer length.
844 */
845    static int
846SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
847{
848    /* First of all, we check the thpe of the supplied Python object.
849     * There are three cases:
850     *	  1. NULL, or None - this is a deletion.
851     *	  2. A string	   - this is a replacement.
852     *	  3. Anything else - this is an error.
853     */
854    if (line == Py_None || line == NULL)
855    {
856	buf_T *savebuf = curbuf;
857
858	PyErr_Clear();
859	curbuf = buf;
860
861	if (u_savedel((linenr_T)n, 1L) == FAIL)
862	    PyErr_SetVim(_("cannot save undo information"));
863	else if (ml_delete((linenr_T)n, FALSE) == FAIL)
864	    PyErr_SetVim(_("cannot delete line"));
865	else
866	{
867	    if (buf == curwin->w_buffer)
868		py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
869	    deleted_lines_mark((linenr_T)n, 1L);
870	}
871
872	curbuf = savebuf;
873
874	if (PyErr_Occurred() || VimErrorCheck())
875	    return FAIL;
876
877	if (len_change)
878	    *len_change = -1;
879
880	return OK;
881    }
882    else if (PyString_Check(line))
883    {
884	char *save = StringToLine(line);
885	buf_T *savebuf = curbuf;
886
887	if (save == NULL)
888	    return FAIL;
889
890	/* We do not need to free "save" if ml_replace() consumes it. */
891	PyErr_Clear();
892	curbuf = buf;
893
894	if (u_savesub((linenr_T)n) == FAIL)
895	{
896	    PyErr_SetVim(_("cannot save undo information"));
897	    vim_free(save);
898	}
899	else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
900	{
901	    PyErr_SetVim(_("cannot replace line"));
902	    vim_free(save);
903	}
904	else
905	    changed_bytes((linenr_T)n, 0);
906
907	curbuf = savebuf;
908
909	/* Check that the cursor is not beyond the end of the line now. */
910	if (buf == curwin->w_buffer)
911	    check_cursor_col();
912
913	if (PyErr_Occurred() || VimErrorCheck())
914	    return FAIL;
915
916	if (len_change)
917	    *len_change = 0;
918
919	return OK;
920    }
921    else
922    {
923	PyErr_BadArgument();
924	return FAIL;
925    }
926}
927
928
929/* Insert a number of lines into the specified buffer after the specifed line.
930 * The line number is in Vim format (1-based). The lines to be inserted are
931 * given as a Python list of string objects or as a single string. The lines
932 * to be added are checked for validity and correct format. Errors are
933 * returned as a value of FAIL.  The return value is OK on success.
934 * If OK is returned and len_change is not NULL, *len_change
935 * is set to the change in the buffer length.
936 */
937    static int
938InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
939{
940    /* First of all, we check the type of the supplied Python object.
941     * It must be a string or a list, or the call is in error.
942     */
943    if (PyString_Check(lines))
944    {
945	char	*str = StringToLine(lines);
946	buf_T	*savebuf;
947
948	if (str == NULL)
949	    return FAIL;
950
951	savebuf = curbuf;
952
953	PyErr_Clear();
954	curbuf = buf;
955
956	if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
957	    PyErr_SetVim(_("cannot save undo information"));
958	else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
959	    PyErr_SetVim(_("cannot insert line"));
960	else
961	    appended_lines_mark((linenr_T)n, 1L);
962
963	vim_free(str);
964	curbuf = savebuf;
965	update_screen(VALID);
966
967	if (PyErr_Occurred() || VimErrorCheck())
968	    return FAIL;
969
970	if (len_change)
971	    *len_change = 1;
972
973	return OK;
974    }
975    else if (PyList_Check(lines))
976    {
977	PyInt	i;
978	PyInt	size = PyList_Size(lines);
979	char	**array;
980	buf_T	*savebuf;
981
982	array = (char **)alloc((unsigned)(size * sizeof(char *)));
983	if (array == NULL)
984	{
985	    PyErr_NoMemory();
986	    return FAIL;
987	}
988
989	for (i = 0; i < size; ++i)
990	{
991	    PyObject *line = PyList_GetItem(lines, i);
992	    array[i] = StringToLine(line);
993
994	    if (array[i] == NULL)
995	    {
996		while (i)
997		    vim_free(array[--i]);
998		vim_free(array);
999		return FAIL;
1000	    }
1001	}
1002
1003	savebuf = curbuf;
1004
1005	PyErr_Clear();
1006	curbuf = buf;
1007
1008	if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
1009	    PyErr_SetVim(_("cannot save undo information"));
1010	else
1011	{
1012	    for (i = 0; i < size; ++i)
1013	    {
1014		if (ml_append((linenr_T)(n + i),
1015					(char_u *)array[i], 0, FALSE) == FAIL)
1016		{
1017		    PyErr_SetVim(_("cannot insert line"));
1018
1019		    /* Free the rest of the lines */
1020		    while (i < size)
1021			vim_free(array[i++]);
1022
1023		    break;
1024		}
1025		vim_free(array[i]);
1026	    }
1027	    if (i > 0)
1028		appended_lines_mark((linenr_T)n, (long)i);
1029	}
1030
1031	/* Free the array of lines. All of its contents have now
1032	 * been freed.
1033	 */
1034	vim_free(array);
1035
1036	curbuf = savebuf;
1037	update_screen(VALID);
1038
1039	if (PyErr_Occurred() || VimErrorCheck())
1040	    return FAIL;
1041
1042	if (len_change)
1043	    *len_change = size;
1044
1045	return OK;
1046    }
1047    else
1048    {
1049	PyErr_BadArgument();
1050	return FAIL;
1051    }
1052}
1053
1054/*
1055 * Common routines for buffers and line ranges
1056 * -------------------------------------------
1057 */
1058
1059    static int
1060CheckBuffer(BufferObject *this)
1061{
1062    if (this->buf == INVALID_BUFFER_VALUE)
1063    {
1064	PyErr_SetVim(_("attempt to refer to deleted buffer"));
1065	return -1;
1066    }
1067
1068    return 0;
1069}
1070
1071    static PyObject *
1072RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
1073{
1074    if (CheckBuffer(self))
1075	return NULL;
1076
1077    if (n < 0 || n > end - start)
1078    {
1079	PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1080	return NULL;
1081    }
1082
1083    return GetBufferLine(self->buf, n+start);
1084}
1085
1086    static PyObject *
1087RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
1088{
1089    PyInt size;
1090
1091    if (CheckBuffer(self))
1092	return NULL;
1093
1094    size = end - start + 1;
1095
1096    if (lo < 0)
1097	lo = 0;
1098    else if (lo > size)
1099	lo = size;
1100    if (hi < 0)
1101	hi = 0;
1102    if (hi < lo)
1103	hi = lo;
1104    else if (hi > size)
1105	hi = size;
1106
1107    return GetBufferLineList(self->buf, lo+start, hi+start);
1108}
1109
1110    static PyInt
1111RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
1112{
1113    PyInt len_change;
1114
1115    if (CheckBuffer(self))
1116	return -1;
1117
1118    if (n < 0 || n > end - start)
1119    {
1120	PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1121	return -1;
1122    }
1123
1124    if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1125	return -1;
1126
1127    if (new_end)
1128	*new_end = end + len_change;
1129
1130    return 0;
1131}
1132
1133
1134    static PyObject *
1135RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
1136{
1137    PyObject *lines;
1138    PyInt len_change;
1139    PyInt max;
1140    PyInt n;
1141
1142    if (CheckBuffer(self))
1143	return NULL;
1144
1145    max = n = end - start + 1;
1146
1147    if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
1148	return NULL;
1149
1150    if (n < 0 || n > max)
1151    {
1152	PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1153	return NULL;
1154    }
1155
1156    if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
1157	return NULL;
1158
1159    if (new_end)
1160	*new_end = end + len_change;
1161
1162    Py_INCREF(Py_None);
1163    return Py_None;
1164}
1165
1166
1167/* Buffer object - Definitions
1168 */
1169
1170typedef struct
1171{
1172    PyObject_HEAD
1173    BufferObject *buf;
1174    PyInt start;
1175    PyInt end;
1176} RangeObject;
1177
1178    static PyObject *
1179RangeNew(buf_T *buf, PyInt start, PyInt end)
1180{
1181    BufferObject *bufr;
1182    RangeObject *self;
1183    self = PyObject_NEW(RangeObject, &RangeType);
1184    if (self == NULL)
1185	return NULL;
1186
1187    bufr = (BufferObject *)BufferNew(buf);
1188    if (bufr == NULL)
1189    {
1190	Py_DECREF(self);
1191	return NULL;
1192    }
1193    Py_INCREF(bufr);
1194
1195    self->buf = bufr;
1196    self->start = start;
1197    self->end = end;
1198
1199    return (PyObject *)(self);
1200}
1201
1202    static PyObject *
1203BufferAppend(PyObject *self, PyObject *args)
1204{
1205    return RBAppend((BufferObject *)(self), args, 1,
1206		    (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1207		    NULL);
1208}
1209
1210    static PyObject *
1211BufferMark(PyObject *self, PyObject *args)
1212{
1213    pos_T	*posp;
1214    char	*pmark;
1215    char	mark;
1216    buf_T	*curbuf_save;
1217
1218    if (CheckBuffer((BufferObject *)(self)))
1219	return NULL;
1220
1221    if (!PyArg_ParseTuple(args, "s", &pmark))
1222	return NULL;
1223    mark = *pmark;
1224
1225    curbuf_save = curbuf;
1226    curbuf = ((BufferObject *)(self))->buf;
1227    posp = getmark(mark, FALSE);
1228    curbuf = curbuf_save;
1229
1230    if (posp == NULL)
1231    {
1232	PyErr_SetVim(_("invalid mark name"));
1233	return NULL;
1234    }
1235
1236    /* Ckeck for keyboard interrupt */
1237    if (VimErrorCheck())
1238	return NULL;
1239
1240    if (posp->lnum <= 0)
1241    {
1242	/* Or raise an error? */
1243	Py_INCREF(Py_None);
1244	return Py_None;
1245    }
1246
1247    return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1248}
1249
1250    static PyObject *
1251BufferRange(PyObject *self, PyObject *args)
1252{
1253    PyInt start;
1254    PyInt end;
1255
1256    if (CheckBuffer((BufferObject *)(self)))
1257	return NULL;
1258
1259    if (!PyArg_ParseTuple(args, "nn", &start, &end))
1260	return NULL;
1261
1262    return RangeNew(((BufferObject *)(self))->buf, start, end);
1263}
1264
1265static struct PyMethodDef BufferMethods[] = {
1266    /* name,	    function,		calling,    documentation */
1267    {"append",	    BufferAppend,	1,	    "Append data to Vim buffer" },
1268    {"mark",	    BufferMark,		1,	    "Return (row,col) representing position of named mark" },
1269    {"range",	    BufferRange,	1,	    "Return a range object which represents the part of the given buffer between line numbers s and e" },
1270    { NULL,	    NULL,		0,	    NULL }
1271};
1272
1273    static PyObject *
1274RangeAppend(PyObject *self, PyObject *args)
1275{
1276    return RBAppend(((RangeObject *)(self))->buf, args,
1277		    ((RangeObject *)(self))->start,
1278		    ((RangeObject *)(self))->end,
1279		    &((RangeObject *)(self))->end);
1280}
1281
1282    static PyInt
1283RangeLength(PyObject *self)
1284{
1285    /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1286    if (CheckBuffer(((RangeObject *)(self))->buf))
1287	return -1; /* ??? */
1288
1289    return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1290}
1291
1292    static PyObject *
1293RangeItem(PyObject *self, PyInt n)
1294{
1295    return RBItem(((RangeObject *)(self))->buf, n,
1296		  ((RangeObject *)(self))->start,
1297		  ((RangeObject *)(self))->end);
1298}
1299
1300    static PyObject *
1301RangeRepr(PyObject *self)
1302{
1303    static char repr[100];
1304    RangeObject *this = (RangeObject *)(self);
1305
1306    if (this->buf->buf == INVALID_BUFFER_VALUE)
1307    {
1308	vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1309								      (self));
1310	return PyString_FromString(repr);
1311    }
1312    else
1313    {
1314	char *name = (char *)this->buf->buf->b_fname;
1315	int len;
1316
1317	if (name == NULL)
1318	    name = "";
1319	len = (int)strlen(name);
1320
1321	if (len > 45)
1322	    name = name + (45 - len);
1323
1324	vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1325		len > 45 ? "..." : "", name,
1326		this->start, this->end);
1327
1328	return PyString_FromString(repr);
1329    }
1330}
1331
1332    static PyObject *
1333RangeSlice(PyObject *self, PyInt lo, PyInt hi)
1334{
1335    return RBSlice(((RangeObject *)(self))->buf, lo, hi,
1336		   ((RangeObject *)(self))->start,
1337		   ((RangeObject *)(self))->end);
1338}
1339
1340/*
1341 * Line range object - Definitions
1342 */
1343
1344static struct PyMethodDef RangeMethods[] = {
1345    /* name,	    function,		calling,    documentation */
1346    {"append",	    RangeAppend,	1,	    "Append data to the Vim range" },
1347    { NULL,	    NULL,		0,	    NULL }
1348};
1349
1350