1603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/*
2603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   Unicode character type helpers.
3603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
49e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh   Written by Marc-Andre Lemburg (mal@lemburg.com).
59e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh   Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com)
6603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
79e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh   Copyright (c) Corporation for National Research Initiatives.
8603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
9603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum*/
10603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
11603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum#include "Python.h"
12603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum#include "unicodeobject.h"
13603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
149e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define ALPHA_MASK 0x01
159e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define DECIMAL_MASK 0x02
169e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define DIGIT_MASK 0x04
179e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define LOWER_MASK 0x08
189e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define LINEBREAK_MASK 0x10
199e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define SPACE_MASK 0x20
209e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define TITLE_MASK 0x40
219e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#define UPPER_MASK 0x80
2224329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis#define NODELTA_MASK 0x100
23d0052d17b1a067e4aa8a69f5564a4b94e0c00502Amaury Forgeot d'Arc#define NUMERIC_MASK 0x200
249e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
259e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundhtypedef struct {
269e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const Py_UNICODE upper;
279e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const Py_UNICODE lower;
289e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const Py_UNICODE title;
299e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const unsigned char decimal;
309e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const unsigned char digit;
31974ed7cfa50b666c9ab91f7a3f8f26049d387107Hye-Shik Chang    const unsigned short flags;
329e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh} _PyUnicode_TypeRecord;
339e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
349e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh#include "unicodetype_db.h"
359e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
369e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundhstatic const _PyUnicode_TypeRecord *
37ee13dba1aa7bc54b6b78eaed508a0f9c972204dfFredrik Lundhgettyperecord(Py_UNICODE code)
389e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh{
399e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    int index;
4056cdce3070605422a655b8da8af23622ed876dadJack Jansen
417db07e697286c8bedb7d8c320203ddbc7a98bad2Hye-Shik Chang#ifdef Py_UNICODE_WIDE
429def6a3a77569214b49d1b54ef138b0e4985a6bdMartin v. Löwis    if (code >= 0x110000)
439e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh        index = 0;
447db07e697286c8bedb7d8c320203ddbc7a98bad2Hye-Shik Chang    else
457db07e697286c8bedb7d8c320203ddbc7a98bad2Hye-Shik Chang#endif
467db07e697286c8bedb7d8c320203ddbc7a98bad2Hye-Shik Chang    {
479e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh        index = index1[(code>>SHIFT)];
489e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh        index = index2[(index<<SHIFT)+(code&((1<<SHIFT)-1))];
499e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    }
50ee13dba1aa7bc54b6b78eaed508a0f9c972204dfFredrik Lundh
519e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return &_PyUnicode_TypeRecords[index];
529e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh}
5356cdce3070605422a655b8da8af23622ed876dadJack Jansen
54603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns the titlecase Unicode characters corresponding to ch or just
55603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   ch if no titlecase mapping is known. */
56603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
57ce9b5a55e164f1128756478b6a2bb548abec1980Martin v. LöwisPy_UNICODE _PyUnicode_ToTitlecase(register Py_UNICODE ch)
58603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
599e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
6099f277933e172cd035f049f2de4a9033f43a55dcMartin v. Löwis    int delta = ctype->title;
61ce9b5a55e164f1128756478b6a2bb548abec1980Martin v. Löwis
6224329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis    if (ctype->flags & NODELTA_MASK)
6324329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis	return delta;
6424329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis
65edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    if (delta >= 32768)
66edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis	    delta -= 65536;
67edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis
68edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    return ch + delta;
69603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
70603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
71603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns 1 for Unicode characters having the category 'Lt', 0
72603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   otherwise. */
73603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
7472b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsTitlecase(Py_UNICODE ch)
75603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
769e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
779e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
789e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return (ctype->flags & TITLE_MASK) != 0;
79603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
80603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
81603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns the integer decimal (0-9) for Unicode characters having
82603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   this property, -1 otherwise. */
83603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
8472b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_ToDecimalDigit(Py_UNICODE ch)
85603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
869e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
879e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
889e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return (ctype->flags & DECIMAL_MASK) ? ctype->decimal : -1;
89603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
90603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
9172b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsDecimalDigit(Py_UNICODE ch)
92603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
93603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    if (_PyUnicode_ToDecimalDigit(ch) < 0)
94603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum	return 0;
95603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    return 1;
96603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
97603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
98603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns the integer digit (0-9) for Unicode characters having
99603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   this property, -1 otherwise. */
100603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
10172b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_ToDigit(Py_UNICODE ch)
102603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
1039e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
1049e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
1059e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return (ctype->flags & DIGIT_MASK) ? ctype->digit : -1;
106603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
107603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
10872b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsDigit(Py_UNICODE ch)
109603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
110603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    if (_PyUnicode_ToDigit(ch) < 0)
111603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum	return 0;
112603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    return 1;
113603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
114603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
115603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns the numeric value as double for Unicode characters having
116603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   this property, -1.0 otherwise. */
117603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
11872b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsNumeric(Py_UNICODE ch)
119603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
120d0052d17b1a067e4aa8a69f5564a4b94e0c00502Amaury Forgeot d'Arc    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
121d0052d17b1a067e4aa8a69f5564a4b94e0c00502Amaury Forgeot d'Arc
122d0052d17b1a067e4aa8a69f5564a4b94e0c00502Amaury Forgeot d'Arc    return (ctype->flags & NUMERIC_MASK) != 0;
123603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
124603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
125603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum#ifndef WANT_WCTYPE_FUNCTIONS
126603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
127603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns 1 for Unicode characters having the category 'Ll', 0
128603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   otherwise. */
129603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
13072b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsLowercase(Py_UNICODE ch)
131603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
1329e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
1339e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
1349e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return (ctype->flags & LOWER_MASK) != 0;
135603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
136603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
137603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns 1 for Unicode characters having the category 'Lu', 0
138603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   otherwise. */
139603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
14072b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsUppercase(Py_UNICODE ch)
141603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
1429e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
1439e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh
1449e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return (ctype->flags & UPPER_MASK) != 0;
145603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
146603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
147603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns the uppercase Unicode characters corresponding to ch or just
148603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   ch if no uppercase mapping is known. */
149603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
15072b068566ace24bb49c935ba4c539f021212249aFredrik LundhPy_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
151603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
1529e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
153edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    int delta = ctype->upper;
15424329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis    if (ctype->flags & NODELTA_MASK)
15524329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis	return delta;
156edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    if (delta >= 32768)
157edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis	    delta -= 65536;
158edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    return ch + delta;
159603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
160603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
161603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Returns the lowercase Unicode characters corresponding to ch or just
162603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   ch if no lowercase mapping is known. */
163603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
16472b068566ace24bb49c935ba4c539f021212249aFredrik LundhPy_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
165603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
1669e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
167edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    int delta = ctype->lower;
16824329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis    if (ctype->flags & NODELTA_MASK)
16924329ba1762688f78ff589d0243683c4afafe096Martin v. Löwis	return delta;
170edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    if (delta >= 32768)
171edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis	    delta -= 65536;
172edf368c351ea3f75a7da19d42f12a34d76887b35Martin v. Löwis    return ch + delta;
173603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
174603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
175f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg/* Returns 1 for Unicode characters having the category 'Ll', 'Lu', 'Lt',
176f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg   'Lo' or 'Lm',  0 otherwise. */
177f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg
17872b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsAlpha(Py_UNICODE ch)
179f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg{
1809e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    const _PyUnicode_TypeRecord *ctype = gettyperecord(ch);
181f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg
1829e7dd4c185a8c14c74caa2781935a0b7ae3640b8Fredrik Lundh    return (ctype->flags & ALPHA_MASK) != 0;
183f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg}
184f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg
185603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum#else
186603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
187603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum/* Export the interfaces using the wchar_t type for portability
188603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum   reasons:  */
189603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
19072b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsLowercase(Py_UNICODE ch)
191603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
192603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    return iswlower(ch);
193603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
194603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
19572b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsUppercase(Py_UNICODE ch)
196603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
197603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    return iswupper(ch);
198603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
199603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
20072b068566ace24bb49c935ba4c539f021212249aFredrik LundhPy_UNICODE _PyUnicode_ToLowercase(Py_UNICODE ch)
201603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
202603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    return towlower(ch);
203603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
204603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
20572b068566ace24bb49c935ba4c539f021212249aFredrik LundhPy_UNICODE _PyUnicode_ToUppercase(Py_UNICODE ch)
206603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum{
207603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum    return towupper(ch);
208603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum}
209603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum
21072b068566ace24bb49c935ba4c539f021212249aFredrik Lundhint _PyUnicode_IsAlpha(Py_UNICODE ch)
211f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg{
212f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg    return iswalpha(ch);
213f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg}
214f3938f55c7db32deeb617da2c6f3239eb01cc20dMarc-André Lemburg
215603484d7594fc8d4703b9ef90c07adf21bc9cf63Guido van Rossum#endif
216