Bump version to 0.9.1.
[python/dscho.git] / Modules / unicodedata.c
blob36c6566ad426bd6403ee26c3bfa41f520770ad65
1 /* ------------------------------------------------------------------------
3 unicodedata -- Provides access to the Unicode 3.0 data base.
5 Data was extracted from the Unicode 3.0 UnicodeData.txt file.
7 Written by Marc-Andre Lemburg (mal@lemburg.com).
9 Copyright (c) Corporation for National Research Initiatives.
11 ------------------------------------------------------------------------ */
13 #include "Python.h"
14 #include "unicodedatabase.h"
16 /* --- Helpers ------------------------------------------------------------ */
18 static
19 const _PyUnicode_DatabaseRecord *unicode_db(register int i)
21 register int page = i >> 12;
23 if (page < sizeof(_PyUnicode_Database))
24 return &_PyUnicode_Database[page][i & 0x0fff];
25 return &_PyUnicode_Database[0][0];
28 /* --- Module API --------------------------------------------------------- */
30 static PyObject *
31 unicodedata_decimal(PyObject *self,
32 PyObject *args)
34 PyUnicodeObject *v;
35 PyObject *defobj = NULL;
36 long rc;
38 if (!PyArg_ParseTuple(args, "O!|O:decimal",
39 &PyUnicode_Type, &v, &defobj))
40 goto onError;
41 if (PyUnicode_GET_SIZE(v) != 1) {
42 PyErr_SetString(PyExc_TypeError,
43 "need a single Unicode character as parameter");
44 goto onError;
46 rc = Py_UNICODE_TODECIMAL(*PyUnicode_AS_UNICODE(v));
47 if (rc < 0) {
48 if (defobj == NULL) {
49 PyErr_SetString(PyExc_ValueError,
50 "not a decimal");
51 goto onError;
53 else {
54 Py_INCREF(defobj);
55 return defobj;
58 return PyInt_FromLong(rc);
60 onError:
61 return NULL;
64 static PyObject *
65 unicodedata_digit(PyObject *self,
66 PyObject *args)
68 PyUnicodeObject *v;
69 PyObject *defobj = NULL;
70 long rc;
72 if (!PyArg_ParseTuple(args, "O!|O:digit",
73 &PyUnicode_Type, &v, &defobj))
74 goto onError;
75 if (PyUnicode_GET_SIZE(v) != 1) {
76 PyErr_SetString(PyExc_TypeError,
77 "need a single Unicode character as parameter");
78 goto onError;
80 rc = Py_UNICODE_TODIGIT(*PyUnicode_AS_UNICODE(v));
81 if (rc < 0) {
82 if (defobj == NULL) {
83 PyErr_SetString(PyExc_ValueError,
84 "not a digit");
85 goto onError;
87 else {
88 Py_INCREF(defobj);
89 return defobj;
92 return PyInt_FromLong(rc);
94 onError:
95 return NULL;
98 static PyObject *
99 unicodedata_numeric(PyObject *self,
100 PyObject *args)
102 PyUnicodeObject *v;
103 PyObject *defobj = NULL;
104 double rc;
106 if (!PyArg_ParseTuple(args, "O!|O:numeric",
107 &PyUnicode_Type, &v, &defobj))
108 goto onError;
109 if (PyUnicode_GET_SIZE(v) != 1) {
110 PyErr_SetString(PyExc_TypeError,
111 "need a single Unicode character as parameter");
112 goto onError;
114 rc = Py_UNICODE_TONUMERIC(*PyUnicode_AS_UNICODE(v));
115 if (rc < 0) {
116 if (defobj == NULL) {
117 PyErr_SetString(PyExc_ValueError,
118 "not a numeric character");
119 goto onError;
121 else {
122 Py_INCREF(defobj);
123 return defobj;
126 return PyFloat_FromDouble(rc);
128 onError:
129 return NULL;
132 static PyObject *
133 unicodedata_category(PyObject *self,
134 PyObject *args)
136 PyUnicodeObject *v;
137 int index;
139 if (!PyArg_ParseTuple(args, "O!:category",
140 &PyUnicode_Type, &v))
141 goto onError;
142 if (PyUnicode_GET_SIZE(v) != 1) {
143 PyErr_SetString(PyExc_TypeError,
144 "need a single Unicode character as parameter");
145 goto onError;
147 index = (int)unicode_db((int)*PyUnicode_AS_UNICODE(v))->category;
148 if (index < 0 ||
149 index > sizeof(_PyUnicode_CategoryNames) /
150 sizeof(_PyUnicode_CategoryNames[0])) {
151 PyErr_Format(PyExc_SystemError,
152 "category index out of range: %i",
153 index);
154 goto onError;
156 return PyString_FromString(_PyUnicode_CategoryNames[index]);
158 onError:
159 return NULL;
162 static PyObject *
163 unicodedata_bidirectional(PyObject *self,
164 PyObject *args)
166 PyUnicodeObject *v;
167 int index;
169 if (!PyArg_ParseTuple(args, "O!:bidirectional",
170 &PyUnicode_Type, &v))
171 goto onError;
172 if (PyUnicode_GET_SIZE(v) != 1) {
173 PyErr_SetString(PyExc_TypeError,
174 "need a single Unicode character as parameter");
175 goto onError;
177 index = (int)unicode_db((int)*PyUnicode_AS_UNICODE(v))->bidirectional;
178 if (index < 0 ||
179 index > sizeof(_PyUnicode_CategoryNames) /
180 sizeof(_PyUnicode_CategoryNames[0])) {
181 PyErr_Format(PyExc_SystemError,
182 "bidirectional index out of range: %i",
183 index);
184 goto onError;
186 return PyString_FromString(_PyUnicode_BidirectionalNames[index]);
188 onError:
189 return NULL;
192 static PyObject *
193 unicodedata_combining(PyObject *self,
194 PyObject *args)
196 PyUnicodeObject *v;
197 int value;
199 if (!PyArg_ParseTuple(args, "O!:combining",
200 &PyUnicode_Type, &v))
201 goto onError;
202 if (PyUnicode_GET_SIZE(v) != 1) {
203 PyErr_SetString(PyExc_TypeError,
204 "need a single Unicode character as parameter");
205 goto onError;
207 value = (int)unicode_db((int)*PyUnicode_AS_UNICODE(v))->combining;
208 return PyInt_FromLong(value);
210 onError:
211 return NULL;
214 static PyObject *
215 unicodedata_mirrored(PyObject *self,
216 PyObject *args)
218 PyUnicodeObject *v;
219 int value;
221 if (!PyArg_ParseTuple(args, "O!:mirrored",
222 &PyUnicode_Type, &v))
223 goto onError;
224 if (PyUnicode_GET_SIZE(v) != 1) {
225 PyErr_SetString(PyExc_TypeError,
226 "need a single Unicode character as parameter");
227 goto onError;
229 value = (int)unicode_db((int)*PyUnicode_AS_UNICODE(v))->mirrored;
230 return PyInt_FromLong(value);
232 onError:
233 return NULL;
236 static PyObject *
237 unicodedata_decomposition(PyObject *self,
238 PyObject *args)
240 PyUnicodeObject *v;
241 const char *value;
243 if (!PyArg_ParseTuple(args, "O!:decomposition",
244 &PyUnicode_Type, &v))
245 goto onError;
246 if (PyUnicode_GET_SIZE(v) != 1) {
247 PyErr_SetString(PyExc_TypeError,
248 "need a single Unicode character as parameter");
249 goto onError;
251 value = unicode_db((int)*PyUnicode_AS_UNICODE(v))->decomposition;
252 if (value == NULL)
253 return PyString_FromString("");
254 else
255 return PyString_FromString(value);
257 onError:
258 return NULL;
261 /* XXX Add doc strings. */
263 static PyMethodDef unicodedata_functions[] = {
264 {"decimal", unicodedata_decimal, 1},
265 {"digit", unicodedata_digit, 1},
266 {"numeric", unicodedata_numeric, 1},
267 {"category", unicodedata_category, 1},
268 {"bidirectional", unicodedata_bidirectional, 1},
269 {"combining", unicodedata_combining, 1},
270 {"mirrored", unicodedata_mirrored, 1},
271 {"decomposition", unicodedata_decomposition, 1},
272 {NULL, NULL} /* sentinel */
275 DL_EXPORT(void)
276 initunicodedata(void)
278 Py_InitModule("unicodedata", unicodedata_functions);