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