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 }