Mercurial > genshi > mirror
annotate genshi/_speedups.c @ 724:919809e55d16 experimental-match-fastpaths
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
author | aflett |
---|---|
date | Mon, 21 Apr 2008 19:36:53 +0000 |
parents | d143dd73789b |
children | ea46fb523485 |
rev | line source |
---|---|
541 | 1 /* |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
2 * Copyright (C) 2006-2008 Edgewall Software |
541 | 3 * All rights reserved. |
4 * | |
5 * This software is licensed as described in the file COPYING, which | |
6 * you should have received as part of this distribution. The terms | |
7 * are also available at http://genshi.edgewall.org/wiki/License. | |
8 * | |
9 * This software consists of voluntary contributions made by many | |
10 * individuals. For the exact contribution history, see the revision | |
11 * history and logs, available at http://genshi.edgewall.org/log/. | |
12 */ | |
13 | |
14 #include <Python.h> | |
15 #include <structmember.h> | |
16 | |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
17 #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
18 typedef int Py_ssize_t; |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
19 #define PY_SSIZE_T_MAX INT_MAX |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
20 #define PY_SSIZE_T_MIN INT_MIN |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
21 #endif |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
22 |
541 | 23 static PyObject *amp1, *amp2, *lt1, *lt2, *gt1, *gt2, *qt1, *qt2; |
24 static PyObject *stripentities, *striptags; | |
25 | |
26 static void | |
27 init_constants(void) | |
28 { | |
29 PyObject *util = PyImport_ImportModule("genshi.util"); | |
30 stripentities = PyObject_GetAttrString(util, "stripentities"); | |
31 striptags = PyObject_GetAttrString(util, "striptags"); | |
32 Py_DECREF(util); | |
33 | |
34 amp1 = PyUnicode_DecodeASCII("&", 1, NULL); | |
35 amp2 = PyUnicode_DecodeASCII("&", 5, NULL); | |
36 lt1 = PyUnicode_DecodeASCII("<", 1, NULL); | |
37 lt2 = PyUnicode_DecodeASCII("<", 4, NULL); | |
38 gt1 = PyUnicode_DecodeASCII(">", 1, NULL); | |
39 gt2 = PyUnicode_DecodeASCII(">", 4, NULL); | |
40 qt1 = PyUnicode_DecodeASCII("\"", 1, NULL); | |
41 qt2 = PyUnicode_DecodeASCII(""", 5, NULL); | |
42 } | |
43 | |
44 /* Markup class */ | |
45 | |
46 PyAPI_DATA(PyTypeObject) MarkupType; | |
47 | |
48 PyDoc_STRVAR(Markup__doc__, | |
49 "Marks a string as being safe for inclusion in HTML/XML output without\n\ | |
50 needing to be escaped."); | |
51 | |
52 static PyObject * | |
53 escape(PyObject *text, int quotes) | |
54 { | |
55 PyObject *args, *ret; | |
56 PyUnicodeObject *in, *out; | |
57 Py_UNICODE *inp, *outp; | |
58 int len, inn, outn; | |
59 | |
60 if (PyObject_TypeCheck(text, &MarkupType)) { | |
61 Py_INCREF(text); | |
62 return text; | |
63 } | |
64 in = (PyUnicodeObject *) PyObject_Unicode(text); | |
65 if (in == NULL) { | |
66 return NULL; | |
67 } | |
68 /* First we need to figure out how long the escaped string will be */ | |
69 len = inn = 0; | |
70 inp = in->str; | |
71 while (*(inp) || in->length > inp - in->str) { | |
72 switch (*inp++) { | |
73 case '&': len += 5; inn++; break; | |
74 case '"': len += quotes ? 5 : 1; inn += quotes ? 1 : 0; break; | |
75 case '<': | |
76 case '>': len += 4; inn++; break; | |
77 default: len++; | |
78 } | |
79 } | |
80 | |
81 /* Do we need to escape anything at all? */ | |
82 if (!inn) { | |
83 args = PyTuple_New(1); | |
84 if (args == NULL) { | |
85 Py_DECREF((PyObject *) in); | |
86 return NULL; | |
87 } | |
88 PyTuple_SET_ITEM(args, 0, (PyObject *) in); | |
89 ret = MarkupType.tp_new(&MarkupType, args, NULL); | |
90 Py_DECREF(args); | |
91 return ret; | |
92 } | |
93 | |
94 out = (PyUnicodeObject*) PyUnicode_FromUnicode(NULL, len); | |
95 if (out == NULL) { | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
96 Py_DECREF((PyObject *) in); |
541 | 97 return NULL; |
98 } | |
99 | |
100 outn = 0; | |
101 inp = in->str; | |
102 outp = out->str; | |
103 while (*(inp) || in->length > inp - in->str) { | |
104 if (outn == inn) { | |
105 /* copy rest of string if we have already replaced everything */ | |
106 Py_UNICODE_COPY(outp, inp, in->length - (inp - in->str)); | |
107 break; | |
108 } | |
109 switch (*inp) { | |
110 case '&': | |
111 Py_UNICODE_COPY(outp, ((PyUnicodeObject *) amp2)->str, 5); | |
112 outp += 5; | |
113 outn++; | |
114 break; | |
115 case '"': | |
116 if (quotes) { | |
117 Py_UNICODE_COPY(outp, ((PyUnicodeObject *) qt2)->str, 5); | |
118 outp += 5; | |
119 outn++; | |
120 } else { | |
121 *outp++ = *inp; | |
122 } | |
123 break; | |
124 case '<': | |
125 Py_UNICODE_COPY(outp, ((PyUnicodeObject *) lt2)->str, 4); | |
126 outp += 4; | |
127 outn++; | |
128 break; | |
129 case '>': | |
130 Py_UNICODE_COPY(outp, ((PyUnicodeObject *) gt2)->str, 4); | |
131 outp += 4; | |
132 outn++; | |
133 break; | |
134 default: | |
135 *outp++ = *inp; | |
136 } | |
137 inp++; | |
138 } | |
139 | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
140 Py_DECREF((PyObject *) in); |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
141 |
541 | 142 args = PyTuple_New(1); |
143 if (args == NULL) { | |
144 Py_DECREF((PyObject *) out); | |
145 return NULL; | |
146 } | |
147 PyTuple_SET_ITEM(args, 0, (PyObject *) out); | |
148 ret = MarkupType.tp_new(&MarkupType, args, NULL); | |
149 Py_DECREF(args); | |
150 return ret; | |
151 } | |
152 | |
153 PyDoc_STRVAR(escape__doc__, | |
154 "Create a Markup instance from a string and escape special characters\n\ | |
155 it may contain (<, >, & and \").\n\ | |
156 \n\ | |
547 | 157 >>> escape('\"1 < 2\"')\n\ |
158 <Markup u'"1 < 2"'>\n\ | |
159 \n\ | |
541 | 160 If the `quotes` parameter is set to `False`, the \" character is left\n\ |
161 as is. Escaping quotes is generally only required for strings that are\n\ | |
547 | 162 to be used in attribute values.\n\ |
163 \n\ | |
164 >>> escape('\"1 < 2\"', quotes=False)\n\ | |
165 <Markup u'\"1 < 2\"'>\n\ | |
166 \n\ | |
167 :param text: the text to escape\n\ | |
168 :param quotes: if ``True``, double quote characters are escaped in\n\ | |
169 addition to the other special characters\n\ | |
170 :return: the escaped `Markup` string\n\ | |
171 :rtype: `Markup`\n\ | |
172 "); | |
541 | 173 |
174 static PyObject * | |
175 Markup_escape(PyTypeObject* type, PyObject *args, PyObject *kwds) | |
176 { | |
177 static char *kwlist[] = {"text", "quotes", 0}; | |
178 PyObject *text = NULL; | |
179 char quotes = 1; | |
180 | |
181 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|b", kwlist, &text, "es)) { | |
182 return NULL; | |
183 } | |
184 if (PyObject_Not(text)) { | |
185 return type->tp_new(type, args, NULL); | |
186 } | |
187 if (PyObject_TypeCheck(text, type)) { | |
188 Py_INCREF(text); | |
189 return text; | |
190 } | |
191 return escape(text, quotes); | |
192 } | |
193 | |
547 | 194 PyDoc_STRVAR(join__doc__, |
195 "Return a `Markup` object which is the concatenation of the strings\n\ | |
196 in the given sequence, where this `Markup` object is the separator\n\ | |
197 between the joined elements.\n\ | |
198 \n\ | |
199 Any element in the sequence that is not a `Markup` instance is\n\ | |
200 automatically escaped.\n\ | |
201 \n\ | |
202 :param seq: the sequence of strings to join\n\ | |
203 :param escape_quotes: whether double quote characters in the elements\n\ | |
204 should be escaped\n\ | |
205 :return: the joined `Markup` object\n\ | |
206 :rtype: `Markup`\n\ | |
207 :see: `escape`\n\ | |
208 "); | |
209 | |
541 | 210 static PyObject * |
211 Markup_join(PyObject *self, PyObject *args, PyObject *kwds) | |
212 { | |
213 static char *kwlist[] = {"seq", "escape_quotes", 0}; | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
214 PyObject *seq = NULL, *seq2, *tmp, *tmp2; |
541 | 215 char quotes = 1; |
216 int n, i; | |
217 | |
218 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|b", kwlist, &seq, "es)) { | |
219 return NULL; | |
220 } | |
221 if (!PySequence_Check(seq)) { | |
222 return NULL; | |
223 } | |
224 n = PySequence_Size(seq); | |
225 if (n < 0) { | |
226 return NULL; | |
227 } | |
228 seq2 = PyTuple_New(n); | |
229 if (seq2 == NULL) { | |
230 return NULL; | |
231 } | |
232 for (i = 0; i < n; i++) { | |
233 tmp = PySequence_GetItem(seq, i); | |
234 if (tmp == NULL) { | |
235 Py_DECREF(seq2); | |
236 return NULL; | |
237 } | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
238 tmp2 = escape(tmp, quotes); |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
239 if (tmp2 == NULL) { |
541 | 240 Py_DECREF(seq2); |
241 return NULL; | |
242 } | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
243 PyTuple_SET_ITEM(seq2, i, tmp2); |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
244 Py_DECREF(tmp); |
541 | 245 } |
246 tmp = PyUnicode_Join(self, seq2); | |
247 Py_DECREF(seq2); | |
248 if (tmp == NULL) | |
249 return NULL; | |
250 args = PyTuple_New(1); | |
251 if (args == NULL) { | |
252 Py_DECREF(tmp); | |
253 return NULL; | |
254 } | |
255 PyTuple_SET_ITEM(args, 0, tmp); | |
256 tmp = MarkupType.tp_new(&MarkupType, args, NULL); | |
257 Py_DECREF(args); | |
258 return tmp; | |
259 } | |
260 | |
261 static PyObject * | |
262 Markup_add(PyObject *self, PyObject *other) | |
263 { | |
264 PyObject *tmp, *tmp2, *args, *ret; | |
265 if (PyObject_TypeCheck(self, &MarkupType)) { | |
266 tmp = escape(other, 1); | |
267 if (tmp == NULL) | |
268 return NULL; | |
269 tmp2 = PyUnicode_Concat(self, tmp); | |
270 } else { // __radd__ | |
271 tmp = escape(self, 1); | |
272 if (tmp == NULL) | |
273 return NULL; | |
274 tmp2 = PyUnicode_Concat(tmp, other); | |
275 } | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
276 Py_DECREF(tmp); |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
277 if (tmp2 == NULL) |
541 | 278 return NULL; |
279 args = PyTuple_New(1); | |
280 if (args == NULL) { | |
281 Py_DECREF(tmp2); | |
282 return NULL; | |
283 } | |
284 PyTuple_SET_ITEM(args, 0, tmp2); | |
285 ret = MarkupType.tp_new(&MarkupType, args, NULL); | |
286 Py_DECREF(args); | |
287 return ret; | |
288 } | |
289 | |
290 static PyObject * | |
291 Markup_mod(PyObject *self, PyObject *args) | |
292 { | |
293 PyObject *tmp, *tmp2, *ret, *args2; | |
718 | 294 int i, nargs = 0; |
295 PyObject *kwds = NULL; | |
541 | 296 |
718 | 297 if (PyDict_Check(args)) { |
298 kwds = args; | |
299 } | |
300 if (kwds && PyDict_Size(kwds)) { | |
301 PyObject *kwcopy, *key, *value; | |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
302 #if PY_VERSION_HEX >= 0x02050000 |
718 | 303 Py_ssize_t pos = 0; |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
304 #else |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
305 int pos = 0; |
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
306 #endif |
718 | 307 |
308 kwcopy = PyDict_Copy( kwds ); | |
309 if (kwcopy == NULL) { | |
310 return NULL; | |
311 } | |
312 while (PyDict_Next(kwcopy, &pos, &key, &value)) { | |
313 tmp = escape(value, 1); | |
314 if (tmp == NULL) { | |
315 Py_DECREF(kwcopy); | |
316 return NULL; | |
317 } | |
318 if (PyDict_SetItem(kwcopy, key, tmp) < 0) { | |
319 Py_DECREF(tmp); | |
320 Py_DECREF(kwcopy); | |
321 return NULL; | |
322 } | |
323 } | |
324 tmp = PyUnicode_Format(self, kwcopy); | |
325 Py_DECREF(kwcopy); | |
326 if (tmp == NULL) { | |
327 return NULL; | |
328 } | |
329 } else if (PyTuple_Check(args)) { | |
541 | 330 nargs = PyTuple_GET_SIZE(args); |
331 args2 = PyTuple_New(nargs); | |
332 if (args2 == NULL) { | |
333 return NULL; | |
334 } | |
335 for (i = 0; i < nargs; i++) { | |
336 tmp = escape(PyTuple_GET_ITEM(args, i), 1); | |
337 if (tmp == NULL) { | |
338 Py_DECREF(args2); | |
339 return NULL; | |
340 } | |
341 PyTuple_SET_ITEM(args2, i, tmp); | |
342 } | |
343 tmp = PyUnicode_Format(self, args2); | |
344 Py_DECREF(args2); | |
345 if (tmp == NULL) { | |
346 return NULL; | |
347 } | |
348 } else { | |
349 tmp2 = escape(args, 1); | |
350 if (tmp2 == NULL) { | |
351 return NULL; | |
352 } | |
353 tmp = PyUnicode_Format(self, tmp2); | |
354 Py_DECREF(tmp2); | |
355 if (tmp == NULL) { | |
356 return NULL; | |
357 } | |
358 } | |
359 args = PyTuple_New(1); | |
360 if (args == NULL) { | |
361 Py_DECREF(tmp); | |
362 return NULL; | |
363 } | |
364 PyTuple_SET_ITEM(args, 0, tmp); | |
365 ret = PyUnicode_Type.tp_new(&MarkupType, args, NULL); | |
366 Py_DECREF(args); | |
367 return ret; | |
368 } | |
369 | |
370 static PyObject * | |
371 Markup_mul(PyObject *self, PyObject *num) | |
372 { | |
373 PyObject *unicode, *result, *args; | |
374 | |
375 if (PyObject_TypeCheck(self, &MarkupType)) { | |
376 unicode = PyObject_Unicode(self); | |
377 if (unicode == NULL) return NULL; | |
378 result = PyNumber_Multiply(unicode, num); | |
379 } else { // __rmul__ | |
380 unicode = PyObject_Unicode(num); | |
381 if (unicode == NULL) return NULL; | |
382 result = PyNumber_Multiply(unicode, self); | |
383 } | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
384 Py_DECREF(unicode); |
541 | 385 |
386 if (result == NULL) return NULL; | |
387 args = PyTuple_New(1); | |
388 if (args == NULL) { | |
389 Py_DECREF(result); | |
390 return NULL; | |
391 } | |
392 PyTuple_SET_ITEM(args, 0, result); | |
393 result = PyUnicode_Type.tp_new(&MarkupType, args, NULL); | |
394 Py_DECREF(args); | |
395 | |
396 return result; | |
397 } | |
398 | |
399 static PyObject * | |
400 Markup_repr(PyObject *self) | |
401 { | |
402 PyObject *format, *result, *args; | |
403 | |
404 format = PyString_FromString("<Markup %r>"); | |
405 if (format == NULL) return NULL; | |
406 result = PyObject_Unicode(self); | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
407 if (result == NULL) { |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
408 Py_DECREF(format); |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
409 return NULL; |
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
410 } |
541 | 411 args = PyTuple_New(1); |
412 if (args == NULL) { | |
665
3ee92ec99ad9
Applied patch to fix a memory leak in the C implementation of the `Markup.escape()` function. Thanks to Christian Boos for reporting and figuring out the problem. Closes #166.
cmlenz
parents:
547
diff
changeset
|
413 Py_DECREF(format); |
541 | 414 Py_DECREF(result); |
415 return NULL; | |
416 } | |
417 PyTuple_SET_ITEM(args, 0, result); | |
418 result = PyString_Format(format, args); | |
681
3e7cd32c9411
Fix another memory leak in the C speedups code. Thanks to Erik Bray for finding this one and providing a patch. Closes #166 (again).
cmlenz
parents:
665
diff
changeset
|
419 Py_DECREF(format); |
541 | 420 Py_DECREF(args); |
421 return result; | |
422 } | |
423 | |
424 PyDoc_STRVAR(unescape__doc__, | |
547 | 425 "Reverse-escapes &, <, >, and \" and returns a `unicode` object.\n\ |
426 \n\ | |
427 >>> Markup('1 < 2').unescape()\n\ | |
428 u'1 < 2'\n\ | |
429 \n\ | |
430 :return: the unescaped string\n\ | |
431 :rtype: `unicode`\n\ | |
432 :see: `genshi.core.unescape`\n\ | |
433 "); | |
541 | 434 |
435 static PyObject * | |
436 Markup_unescape(PyObject* self) | |
437 { | |
438 PyObject *tmp, *tmp2; | |
439 | |
440 tmp = PyUnicode_Replace(self, qt2, qt1, -1); | |
441 if (tmp == NULL) return NULL; | |
442 tmp2 = PyUnicode_Replace(tmp, gt2, gt1, -1); | |
443 Py_DECREF(tmp); | |
444 if (tmp2 == NULL) return NULL; | |
445 tmp = PyUnicode_Replace(tmp2, lt2, lt1, -1); | |
446 Py_DECREF(tmp2); | |
447 if (tmp == NULL) return NULL; | |
448 tmp2 = PyUnicode_Replace(tmp, amp2, amp1, -1); | |
449 Py_DECREF(tmp); | |
450 return tmp2; | |
451 } | |
452 | |
453 PyDoc_STRVAR(stripentities__doc__, | |
454 "Return a copy of the text with any character or numeric entities\n\ | |
455 replaced by the equivalent UTF-8 characters.\n\ | |
456 \n\ | |
457 If the `keepxmlentities` parameter is provided and evaluates to `True`,\n\ | |
547 | 458 the core XML entities (``&``, ``'``, ``>``, ``<`` and\n\ |
459 ``"``) are not stripped.\n\ | |
460 \n\ | |
461 :return: a `Markup` instance with entities removed\n\ | |
462 :rtype: `Markup`\n\ | |
463 :see: `genshi.util.stripentities`\n\ | |
464 "); | |
541 | 465 |
466 static PyObject * | |
467 Markup_stripentities(PyObject* self, PyObject *args, PyObject *kwds) | |
468 { | |
469 static char *kwlist[] = {"keepxmlentities", 0}; | |
470 PyObject *result, *args2; | |
471 char keepxml = 0; | |
472 | |
473 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|b", kwlist, &keepxml)) { | |
474 return NULL; | |
475 } | |
476 | |
477 if (stripentities == NULL) return NULL; | |
478 result = PyObject_CallFunction(stripentities, "Ob", self, keepxml); | |
479 if (result == NULL) return NULL; | |
480 args2 = PyTuple_New(1); | |
481 if (args2 == NULL) { | |
482 Py_DECREF(result); | |
483 return NULL; | |
484 } | |
485 PyTuple_SET_ITEM(args2, 0, result); | |
486 result = MarkupType.tp_new(&MarkupType, args2, NULL); | |
487 Py_DECREF(args2); | |
488 return result; | |
489 } | |
490 | |
491 PyDoc_STRVAR(striptags__doc__, | |
547 | 492 """Return a copy of the text with all XML/HTML tags removed.\n\ |
493 \n\ | |
494 :return: a `Markup` instance with all tags removed\n\ | |
495 :rtype: `Markup`\n\ | |
496 :see: `genshi.util.striptags`\n\ | |
497 "); | |
541 | 498 |
499 static PyObject * | |
500 Markup_striptags(PyObject* self) | |
501 { | |
502 PyObject *result, *args; | |
503 | |
504 if (striptags == NULL) return NULL; | |
505 result = PyObject_CallFunction(striptags, "O", self); | |
506 if (result == NULL) return NULL; | |
507 args = PyTuple_New(1); | |
508 if (args == NULL) { | |
509 Py_DECREF(result); | |
510 return NULL; | |
511 } | |
512 PyTuple_SET_ITEM(args, 0, result); | |
513 result = MarkupType.tp_new(&MarkupType, args, NULL); | |
514 Py_DECREF(args); | |
515 return result; | |
516 } | |
517 | |
518 typedef struct { | |
519 PyUnicodeObject HEAD; | |
520 } MarkupObject; | |
521 | |
522 static PyMethodDef Markup_methods[] = { | |
523 {"escape", (PyCFunction) Markup_escape, | |
547 | 524 METH_VARARGS|METH_CLASS|METH_KEYWORDS, escape__doc__}, |
525 {"join", (PyCFunction)Markup_join, METH_VARARGS|METH_KEYWORDS, join__doc__}, | |
541 | 526 {"unescape", (PyCFunction)Markup_unescape, METH_NOARGS, unescape__doc__}, |
527 {"stripentities", (PyCFunction) Markup_stripentities, | |
528 METH_VARARGS|METH_KEYWORDS, stripentities__doc__}, | |
529 {"striptags", (PyCFunction) Markup_striptags, METH_NOARGS, | |
530 striptags__doc__}, | |
531 {NULL} /* Sentinel */ | |
532 }; | |
533 | |
534 static PyNumberMethods Markup_as_number = { | |
547 | 535 Markup_add, /*nb_add*/ |
536 0, /*nb_subtract*/ | |
537 Markup_mul, /*nb_multiply*/ | |
538 0, /*nb_divide*/ | |
539 Markup_mod, /*nb_remainder*/ | |
541 | 540 }; |
541 | |
542 PyTypeObject MarkupType = { | |
543 PyObject_HEAD_INIT(NULL) | |
544 0, | |
545 "genshi._speedups.Markup", | |
546 sizeof(MarkupObject), | |
547 0, | |
548 0, /*tp_dealloc*/ | |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
549 0, /*tp_print*/ |
541 | 550 0, /*tp_getattr*/ |
551 0, /*tp_setattr*/ | |
552 0, /*tp_compare*/ | |
553 Markup_repr, /*tp_repr*/ | |
554 &Markup_as_number, /*tp_as_number*/ | |
555 0, /*tp_as_sequence*/ | |
556 0, /*tp_as_mapping*/ | |
557 0, /*tp_hash */ | |
558 | |
559 0, /*tp_call*/ | |
560 0, /*tp_str*/ | |
561 0, /*tp_getattro*/ | |
562 0, /*tp_setattro*/ | |
563 0, /*tp_as_buffer*/ | |
564 | |
565 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ | |
566 Markup__doc__,/*tp_doc*/ | |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
567 |
541 | 568 0, /*tp_traverse*/ |
569 0, /*tp_clear*/ | |
570 | |
571 0, /*tp_richcompare*/ | |
572 0, /*tp_weaklistoffset*/ | |
573 | |
574 0, /*tp_iter*/ | |
575 0, /*tp_iternext*/ | |
576 | |
577 /* Attribute descriptor and subclassing stuff */ | |
578 | |
579 Markup_methods,/*tp_methods*/ | |
580 0, /*tp_members*/ | |
581 0, /*tp_getset*/ | |
582 0, /*tp_base*/ | |
583 0, /*tp_dict*/ | |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
584 |
541 | 585 0, /*tp_descr_get*/ |
586 0, /*tp_descr_set*/ | |
587 0, /*tp_dictoffset*/ | |
724
919809e55d16
update to trunk to track r847, fixing python 2.4 compatibility issues in speedup (and fixing copyrights, apparently :))
aflett
parents:
718
diff
changeset
|
588 |
541 | 589 0, /*tp_init*/ |
590 0, /*tp_alloc will be set to PyType_GenericAlloc in module init*/ | |
718 | 591 0, /*tp_new*/ |
541 | 592 0, /*tp_free Low-level free-memory routine */ |
593 0, /*tp_is_gc For PyObject_IS_GC */ | |
594 0, /*tp_bases*/ | |
595 0, /*tp_mro method resolution order */ | |
596 0, /*tp_cache*/ | |
597 0, /*tp_subclasses*/ | |
598 0 /*tp_weaklist*/ | |
599 }; | |
600 | |
601 PyMODINIT_FUNC | |
602 init_speedups(void) | |
603 { | |
604 PyObject *module; | |
605 | |
606 /* Workaround for quirk in Visual Studio, see | |
607 <http://www.python.it/faq/faq-3.html#3.24> */ | |
608 MarkupType.tp_base = &PyUnicode_Type; | |
609 | |
610 if (PyType_Ready(&MarkupType) < 0) | |
611 return; | |
612 | |
613 init_constants(); | |
614 | |
615 module = Py_InitModule("_speedups", NULL); | |
616 Py_INCREF(&MarkupType); | |
617 PyModule_AddObject(module, "Markup", (PyObject *) &MarkupType); | |
618 } |