comparison src/if_py_both.h @ 2894:fe9c7da98b5e v7.3.220

updated for version 7.3.220 Problem: Python 3: vim.error is a 'str' instead of an 'Exception' object, so 'except' or 'raise' it causes a 'SystemError' exception. Buffer objects do not support slice assignment. When exchanging text between Vim and Python, multibyte texts become gabage or cause Unicode Expceptions, etc. 'py3file' tries to read in the file as Unicode, sometimes causes UnicodeDecodeException Solution: Fix the problems. (lilydjwg)
author Bram Moolenaar <bram@vim.org>
date Sun, 19 Jun 2011 00:27:51 +0200
parents 62e8d93241cd
children b67d3a44262a
comparison
equal deleted inserted replaced
2893:c6f8f1957c66 2894:fe9c7da98b5e
63 63
64 static PyObject * 64 static PyObject *
65 OutputWrite(PyObject *self, PyObject *args) 65 OutputWrite(PyObject *self, PyObject *args)
66 { 66 {
67 int len; 67 int len;
68 char *str; 68 char *str = NULL;
69 int error = ((OutputObject *)(self))->error; 69 int error = ((OutputObject *)(self))->error;
70 70
71 if (!PyArg_ParseTuple(args, "s#", &str, &len)) 71 if (!PyArg_ParseTuple(args, "es#", p_enc, &str, &len))
72 return NULL; 72 return NULL;
73 73
74 Py_BEGIN_ALLOW_THREADS 74 Py_BEGIN_ALLOW_THREADS
75 Python_Lock_Vim(); 75 Python_Lock_Vim();
76 writer((writefn)(error ? emsg : msg), (char_u *)str, len); 76 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
77 Python_Release_Vim(); 77 Python_Release_Vim();
78 Py_END_ALLOW_THREADS 78 Py_END_ALLOW_THREADS
79 PyMem_Free(str);
79 80
80 Py_INCREF(Py_None); 81 Py_INCREF(Py_None);
81 return Py_None; 82 return Py_None;
82 } 83 }
83 84
102 n = PyList_Size(list); 103 n = PyList_Size(list);
103 104
104 for (i = 0; i < n; ++i) 105 for (i = 0; i < n; ++i)
105 { 106 {
106 PyObject *line = PyList_GetItem(list, i); 107 PyObject *line = PyList_GetItem(list, i);
107 char *str; 108 char *str = NULL;
108 PyInt len; 109 PyInt len;
109 110
110 if (!PyArg_Parse(line, "s#", &str, &len)) { 111 if (!PyArg_Parse(line, "es#", p_enc, &str, &len)) {
111 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); 112 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
112 Py_DECREF(list); 113 Py_DECREF(list);
113 return NULL; 114 return NULL;
114 } 115 }
115 116
116 Py_BEGIN_ALLOW_THREADS 117 Py_BEGIN_ALLOW_THREADS
117 Python_Lock_Vim(); 118 Python_Lock_Vim();
118 writer((writefn)(error ? emsg : msg), (char_u *)str, len); 119 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
119 Python_Release_Vim(); 120 Python_Release_Vim();
120 Py_END_ALLOW_THREADS 121 Py_END_ALLOW_THREADS
122 PyMem_Free(str);
121 } 123 }
122 124
123 Py_DECREF(list); 125 Py_DECREF(list);
124 Py_INCREF(Py_None); 126 Py_INCREF(Py_None);
125 return Py_None; 127 return Py_None;
679 static char * 681 static char *
680 StringToLine(PyObject *obj) 682 StringToLine(PyObject *obj)
681 { 683 {
682 const char *str; 684 const char *str;
683 char *save; 685 char *save;
686 PyObject *bytes;
684 PyInt len; 687 PyInt len;
685 PyInt i; 688 PyInt i;
686 char *p; 689 char *p;
687 690
688 if (obj == NULL || !PyString_Check(obj)) 691 if (obj == NULL || !PyString_Check(obj))
689 { 692 {
690 PyErr_BadArgument(); 693 PyErr_BadArgument();
691 return NULL; 694 return NULL;
692 } 695 }
693 696
694 str = PyString_AsString(obj); 697 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
695 len = PyString_Size(obj); 698 str = PyString_AsString(bytes);
699 len = PyString_Size(bytes);
696 700
697 /* 701 /*
698 * Error checking: String must not contain newlines, as we 702 * Error checking: String must not contain newlines, as we
699 * are replacing a single line, and we must replace it with 703 * are replacing a single line, and we must replace it with
700 * a single line. 704 * a single line.
729 else 733 else
730 save[i] = str[i]; 734 save[i] = str[i];
731 } 735 }
732 736
733 save[i] = '\0'; 737 save[i] = '\0';
738 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
734 739
735 return save; 740 return save;
736 } 741 }
737 742
738 /* Get a line from the specified buffer. The line number is 743 /* Get a line from the specified buffer. The line number is
815 changed_cline_bef_curs(); 820 changed_cline_bef_curs();
816 } 821 }
817 invalidate_botline(); 822 invalidate_botline();
818 } 823 }
819 824
820 /* Replace a line in the specified buffer. The line number is 825 /*
826 * Replace a line in the specified buffer. The line number is
821 * in Vim format (1-based). The replacement line is given as 827 * in Vim format (1-based). The replacement line is given as
822 * a Python string object. The object is checked for validity 828 * a Python string object. The object is checked for validity
823 * and correct format. Errors are returned as a value of FAIL. 829 * and correct format. Errors are returned as a value of FAIL.
824 * The return value is OK on success. 830 * The return value is OK on success.
825 * If OK is returned and len_change is not NULL, *len_change 831 * If OK is returned and len_change is not NULL, *len_change
906 PyErr_BadArgument(); 912 PyErr_BadArgument();
907 return FAIL; 913 return FAIL;
908 } 914 }
909 } 915 }
910 916
917 /* Replace a range of lines in the specified buffer. The line numbers are in
918 * Vim format (1-based). The range is from lo up to, but not including, hi.
919 * The replacement lines are given as a Python list of string objects. The
920 * list is checked for validity and correct format. Errors are returned as a
921 * value of FAIL. The return value is OK on success.
922 * If OK is returned and len_change is not NULL, *len_change
923 * is set to the change in the buffer length.
924 */
925 static int
926 SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
927 {
928 /* First of all, we check the thpe of the supplied Python object.
929 * There are three cases:
930 * 1. NULL, or None - this is a deletion.
931 * 2. A list - this is a replacement.
932 * 3. Anything else - this is an error.
933 */
934 if (list == Py_None || list == NULL)
935 {
936 PyInt i;
937 PyInt n = (int)(hi - lo);
938 buf_T *savebuf = curbuf;
939
940 PyErr_Clear();
941 curbuf = buf;
942
943 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
944 PyErr_SetVim(_("cannot save undo information"));
945 else
946 {
947 for (i = 0; i < n; ++i)
948 {
949 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
950 {
951 PyErr_SetVim(_("cannot delete line"));
952 break;
953 }
954 }
955 if (buf == curwin->w_buffer)
956 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
957 deleted_lines_mark((linenr_T)lo, (long)i);
958 }
959
960 curbuf = savebuf;
961
962 if (PyErr_Occurred() || VimErrorCheck())
963 return FAIL;
964
965 if (len_change)
966 *len_change = -n;
967
968 return OK;
969 }
970 else if (PyList_Check(list))
971 {
972 PyInt i;
973 PyInt new_len = PyList_Size(list);
974 PyInt old_len = hi - lo;
975 PyInt extra = 0; /* lines added to text, can be negative */
976 char **array;
977 buf_T *savebuf;
978
979 if (new_len == 0) /* avoid allocating zero bytes */
980 array = NULL;
981 else
982 {
983 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
984 if (array == NULL)
985 {
986 PyErr_NoMemory();
987 return FAIL;
988 }
989 }
990
991 for (i = 0; i < new_len; ++i)
992 {
993 PyObject *line = PyList_GetItem(list, i);
994
995 array[i] = StringToLine(line);
996 if (array[i] == NULL)
997 {
998 while (i)
999 vim_free(array[--i]);
1000 vim_free(array);
1001 return FAIL;
1002 }
1003 }
1004
1005 savebuf = curbuf;
1006
1007 PyErr_Clear();
1008 curbuf = buf;
1009
1010 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
1011 PyErr_SetVim(_("cannot save undo information"));
1012
1013 /* If the size of the range is reducing (ie, new_len < old_len) we
1014 * need to delete some old_len. We do this at the start, by
1015 * repeatedly deleting line "lo".
1016 */
1017 if (!PyErr_Occurred())
1018 {
1019 for (i = 0; i < old_len - new_len; ++i)
1020 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
1021 {
1022 PyErr_SetVim(_("cannot delete line"));
1023 break;
1024 }
1025 extra -= i;
1026 }
1027
1028 /* For as long as possible, replace the existing old_len with the
1029 * new old_len. This is a more efficient operation, as it requires
1030 * less memory allocation and freeing.
1031 */
1032 if (!PyErr_Occurred())
1033 {
1034 for (i = 0; i < old_len && i < new_len; ++i)
1035 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
1036 == FAIL)
1037 {
1038 PyErr_SetVim(_("cannot replace line"));
1039 break;
1040 }
1041 }
1042 else
1043 i = 0;
1044
1045 /* Now we may need to insert the remaining new old_len. If we do, we
1046 * must free the strings as we finish with them (we can't pass the
1047 * responsibility to vim in this case).
1048 */
1049 if (!PyErr_Occurred())
1050 {
1051 while (i < new_len)
1052 {
1053 if (ml_append((linenr_T)(lo + i - 1),
1054 (char_u *)array[i], 0, FALSE) == FAIL)
1055 {
1056 PyErr_SetVim(_("cannot insert line"));
1057 break;
1058 }
1059 vim_free(array[i]);
1060 ++i;
1061 ++extra;
1062 }
1063 }
1064
1065 /* Free any left-over old_len, as a result of an error */
1066 while (i < new_len)
1067 {
1068 vim_free(array[i]);
1069 ++i;
1070 }
1071
1072 /* Free the array of old_len. All of its contents have now
1073 * been dealt with (either freed, or the responsibility passed
1074 * to vim.
1075 */
1076 vim_free(array);
1077
1078 /* Adjust marks. Invalidate any which lie in the
1079 * changed range, and move any in the remainder of the buffer.
1080 */
1081 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
1082 (long)MAXLNUM, (long)extra);
1083 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
1084
1085 if (buf == curwin->w_buffer)
1086 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
1087
1088 curbuf = savebuf;
1089
1090 if (PyErr_Occurred() || VimErrorCheck())
1091 return FAIL;
1092
1093 if (len_change)
1094 *len_change = new_len - old_len;
1095
1096 return OK;
1097 }
1098 else
1099 {
1100 PyErr_BadArgument();
1101 return FAIL;
1102 }
1103 }
911 1104
912 /* Insert a number of lines into the specified buffer after the specifed line. 1105 /* Insert a number of lines into the specified buffer after the specifed line.
913 * The line number is in Vim format (1-based). The lines to be inserted are 1106 * The line number is in Vim format (1-based). The lines to be inserted are
914 * given as a Python list of string objects or as a single string. The lines 1107 * given as a Python list of string objects or as a single string. The lines
915 * to be added are checked for validity and correct format. Errors are 1108 * to be added are checked for validity and correct format. Errors are
1111 *new_end = end + len_change; 1304 *new_end = end + len_change;
1112 1305
1113 return 0; 1306 return 0;
1114 } 1307 }
1115 1308
1309 static PyInt
1310 RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
1311 {
1312 PyInt size;
1313 PyInt len_change;
1314
1315 /* Self must be a valid buffer */
1316 if (CheckBuffer(self))
1317 return -1;
1318
1319 /* Sort out the slice range */
1320 size = end - start + 1;
1321
1322 if (lo < 0)
1323 lo = 0;
1324 else if (lo > size)
1325 lo = size;
1326 if (hi < 0)
1327 hi = 0;
1328 if (hi < lo)
1329 hi = lo;
1330 else if (hi > size)
1331 hi = size;
1332
1333 if (SetBufferLineList(self->buf, lo + start, hi + start,
1334 val, &len_change) == FAIL)
1335 return -1;
1336
1337 if (new_end)
1338 *new_end = end + len_change;
1339
1340 return 0;
1341 }
1342
1116 1343
1117 static PyObject * 1344 static PyObject *
1118 RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end) 1345 RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
1119 { 1346 {
1120 PyObject *lines; 1347 PyObject *lines;