Mercurial > vim
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; |