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