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