Mercurial > vim
comparison src/if_py_both.h @ 2399:76f0c4918f5c vim73
Move some common code from if_python.c and if_python3.c to if_py_both.h.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sat, 24 Jul 2010 23:51:45 +0200 |
parents | |
children | 84d353762845 |
comparison
equal
deleted
inserted
replaced
2398:0c8219a26bc9 | 2399:76f0c4918f5c |
---|---|
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 | |
19 Python_Lock_Vim(void) | |
20 { | |
21 } | |
22 | |
23 /* | |
24 * release a lock on the Vim data structures | |
25 */ | |
26 static void | |
27 Python_Release_Vim(void) | |
28 { | |
29 } | |
30 | |
31 /* Output object definition | |
32 */ | |
33 | |
34 static PyObject *OutputWrite(PyObject *, PyObject *); | |
35 static PyObject *OutputWritelines(PyObject *, PyObject *); | |
36 | |
37 typedef void (*writefn)(char_u *); | |
38 static void writer(writefn fn, char_u *str, PyInt n); | |
39 | |
40 typedef struct | |
41 { | |
42 PyObject_HEAD | |
43 long softspace; | |
44 long error; | |
45 } OutputObject; | |
46 | |
47 static struct PyMethodDef OutputMethods[] = { | |
48 /* name, function, calling, documentation */ | |
49 {"write", OutputWrite, 1, "" }, | |
50 {"writelines", OutputWritelines, 1, "" }, | |
51 { NULL, NULL, 0, NULL } | |
52 }; | |
53 | |
54 /*************/ | |
55 | |
56 /* Output buffer management | |
57 */ | |
58 | |
59 static PyObject * | |
60 OutputWrite(PyObject *self, PyObject *args) | |
61 { | |
62 int len; | |
63 char *str; | |
64 int error = ((OutputObject *)(self))->error; | |
65 | |
66 if (!PyArg_ParseTuple(args, "s#", &str, &len)) | |
67 return NULL; | |
68 | |
69 Py_BEGIN_ALLOW_THREADS | |
70 Python_Lock_Vim(); | |
71 writer((writefn)(error ? emsg : msg), (char_u *)str, len); | |
72 Python_Release_Vim(); | |
73 Py_END_ALLOW_THREADS | |
74 | |
75 Py_INCREF(Py_None); | |
76 return Py_None; | |
77 } | |
78 | |
79 static PyObject * | |
80 OutputWritelines(PyObject *self, PyObject *args) | |
81 { | |
82 PyInt n; | |
83 PyInt i; | |
84 PyObject *list; | |
85 int error = ((OutputObject *)(self))->error; | |
86 | |
87 if (!PyArg_ParseTuple(args, "O", &list)) | |
88 return NULL; | |
89 Py_INCREF(list); | |
90 | |
91 if (!PyList_Check(list)) { | |
92 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); | |
93 Py_DECREF(list); | |
94 return NULL; | |
95 } | |
96 | |
97 n = PyList_Size(list); | |
98 | |
99 for (i = 0; i < n; ++i) | |
100 { | |
101 PyObject *line = PyList_GetItem(list, i); | |
102 char *str; | |
103 PyInt len; | |
104 | |
105 if (!PyArg_Parse(line, "s#", &str, &len)) { | |
106 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); | |
107 Py_DECREF(list); | |
108 return NULL; | |
109 } | |
110 | |
111 Py_BEGIN_ALLOW_THREADS | |
112 Python_Lock_Vim(); | |
113 writer((writefn)(error ? emsg : msg), (char_u *)str, len); | |
114 Python_Release_Vim(); | |
115 Py_END_ALLOW_THREADS | |
116 } | |
117 | |
118 Py_DECREF(list); | |
119 Py_INCREF(Py_None); | |
120 return Py_None; | |
121 } | |
122 | |
123 static char_u *buffer = NULL; | |
124 static PyInt buffer_len = 0; | |
125 static PyInt buffer_size = 0; | |
126 | |
127 static writefn old_fn = NULL; | |
128 | |
129 static void | |
130 buffer_ensure(PyInt n) | |
131 { | |
132 PyInt new_size; | |
133 char_u *new_buffer; | |
134 | |
135 if (n < buffer_size) | |
136 return; | |
137 | |
138 new_size = buffer_size; | |
139 while (new_size < n) | |
140 new_size += 80; | |
141 | |
142 if (new_size != buffer_size) | |
143 { | |
144 new_buffer = alloc((unsigned)new_size); | |
145 if (new_buffer == NULL) | |
146 return; | |
147 | |
148 if (buffer) | |
149 { | |
150 memcpy(new_buffer, buffer, buffer_len); | |
151 vim_free(buffer); | |
152 } | |
153 | |
154 buffer = new_buffer; | |
155 buffer_size = new_size; | |
156 } | |
157 } | |
158 | |
159 static void | |
160 PythonIO_Flush(void) | |
161 { | |
162 if (old_fn && buffer_len) | |
163 { | |
164 buffer[buffer_len] = 0; | |
165 old_fn(buffer); | |
166 } | |
167 | |
168 buffer_len = 0; | |
169 } | |
170 | |
171 static void | |
172 writer(writefn fn, char_u *str, PyInt n) | |
173 { | |
174 char_u *ptr; | |
175 | |
176 if (fn != old_fn && old_fn != NULL) | |
177 PythonIO_Flush(); | |
178 | |
179 old_fn = fn; | |
180 | |
181 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL) | |
182 { | |
183 PyInt len = ptr - str; | |
184 | |
185 buffer_ensure(buffer_len + len + 1); | |
186 | |
187 memcpy(buffer + buffer_len, str, len); | |
188 buffer_len += len; | |
189 buffer[buffer_len] = 0; | |
190 fn(buffer); | |
191 str = ptr + 1; | |
192 n -= len + 1; | |
193 buffer_len = 0; | |
194 } | |
195 | |
196 /* Put the remaining text into the buffer for later printing */ | |
197 buffer_ensure(buffer_len + n + 1); | |
198 memcpy(buffer + buffer_len, str, n); | |
199 buffer_len += n; | |
200 } | |
201 | |
202 /***************/ | |
203 | |
204 static PyTypeObject OutputType; | |
205 | |
206 static OutputObject Output = | |
207 { | |
208 PyObject_HEAD_INIT(&OutputType) | |
209 0, | |
210 0 | |
211 }; | |
212 | |
213 static OutputObject Error = | |
214 { | |
215 PyObject_HEAD_INIT(&OutputType) | |
216 0, | |
217 1 | |
218 }; | |
219 | |
220 static int | |
221 PythonIO_Init_io(void) | |
222 { | |
223 PySys_SetObject("stdout", (PyObject *)(void *)&Output); | |
224 PySys_SetObject("stderr", (PyObject *)(void *)&Error); | |
225 | |
226 if (PyErr_Occurred()) | |
227 { | |
228 EMSG(_("E264: Python: Error initialising I/O objects")); | |
229 return -1; | |
230 } | |
231 | |
232 return 0; | |
233 } | |
234 | |
235 | |
236 static PyObject *VimError; | |
237 | |
238 /* Check to see whether a Vim error has been reported, or a keyboard | |
239 * interrupt has been detected. | |
240 */ | |
241 static int | |
242 VimErrorCheck(void) | |
243 { | |
244 if (got_int) | |
245 { | |
246 PyErr_SetNone(PyExc_KeyboardInterrupt); | |
247 return 1; | |
248 } | |
249 else if (did_emsg && !PyErr_Occurred()) | |
250 { | |
251 PyErr_SetNone(VimError); | |
252 return 1; | |
253 } | |
254 | |
255 return 0; | |
256 } |