unicodedata.c revision cfcea4921865a922744dc168dde5eaccde8fe50b
1/* ------------------------------------------------------------------------
2
3   unicodedata -- Provides access to the Unicode 3.0 data base.
4
5   Data was extracted from the Unicode 3.0 UnicodeData.txt file.
6
7   Written by Marc-Andre Lemburg (mal@lemburg.com).
8   Modified for Python 2.0 by Fredrik Lundh (fredrik@pythonware.com)
9
10   Copyright (c) Corporation for National Research Initiatives.
11
12   ------------------------------------------------------------------------ */
13
14#include "Python.h"
15#include "unicodedatabase.h"
16
17/* --- Module API --------------------------------------------------------- */
18
19static PyObject *
20unicodedata_decimal(PyObject *self,
21		    PyObject *args)
22{
23    PyUnicodeObject *v;
24    PyObject *defobj = NULL;
25    long rc;
26
27    if (!PyArg_ParseTuple(args, "O!|O:decimal",
28			  &PyUnicode_Type, &v, &defobj))
29	goto onError;
30    if (PyUnicode_GET_SIZE(v) != 1) {
31	PyErr_SetString(PyExc_TypeError,
32			"need a single Unicode character as parameter");
33	goto onError;
34    }
35    rc = Py_UNICODE_TODECIMAL(*PyUnicode_AS_UNICODE(v));
36    if (rc < 0) {
37	if (defobj == NULL) {
38	    PyErr_SetString(PyExc_ValueError,
39			    "not a decimal");
40	    goto onError;
41	}
42	else {
43	    Py_INCREF(defobj);
44	    return defobj;
45	}
46    }
47    return PyInt_FromLong(rc);
48
49 onError:
50    return NULL;
51}
52
53static PyObject *
54unicodedata_digit(PyObject *self,
55		  PyObject *args)
56{
57    PyUnicodeObject *v;
58    PyObject *defobj = NULL;
59    long rc;
60
61    if (!PyArg_ParseTuple(args, "O!|O:digit",
62			  &PyUnicode_Type, &v, &defobj))
63	goto onError;
64    if (PyUnicode_GET_SIZE(v) != 1) {
65	PyErr_SetString(PyExc_TypeError,
66			"need a single Unicode character as parameter");
67	goto onError;
68    }
69    rc = Py_UNICODE_TODIGIT(*PyUnicode_AS_UNICODE(v));
70    if (rc < 0) {
71	if (defobj == NULL) {
72	    PyErr_SetString(PyExc_ValueError,
73			    "not a digit");
74	    goto onError;
75	}
76	else {
77	    Py_INCREF(defobj);
78	    return defobj;
79	}
80    }
81    return PyInt_FromLong(rc);
82
83 onError:
84    return NULL;
85}
86
87static PyObject *
88unicodedata_numeric(PyObject *self,
89		    PyObject *args)
90{
91    PyUnicodeObject *v;
92    PyObject *defobj = NULL;
93    double rc;
94
95    if (!PyArg_ParseTuple(args, "O!|O:numeric",
96			  &PyUnicode_Type, &v, &defobj))
97	goto onError;
98    if (PyUnicode_GET_SIZE(v) != 1) {
99	PyErr_SetString(PyExc_TypeError,
100			"need a single Unicode character as parameter");
101	goto onError;
102    }
103    rc = Py_UNICODE_TONUMERIC(*PyUnicode_AS_UNICODE(v));
104    if (rc < 0) {
105	if (defobj == NULL) {
106	    PyErr_SetString(PyExc_ValueError,
107			    "not a numeric character");
108	    goto onError;
109	}
110	else {
111	    Py_INCREF(defobj);
112	    return defobj;
113	}
114    }
115    return PyFloat_FromDouble(rc);
116
117 onError:
118    return NULL;
119}
120
121static PyObject *
122unicodedata_category(PyObject *self,
123		     PyObject *args)
124{
125    PyUnicodeObject *v;
126    int index;
127
128    if (!PyArg_ParseTuple(args, "O!:category",
129			  &PyUnicode_Type, &v))
130	goto onError;
131    if (PyUnicode_GET_SIZE(v) != 1) {
132	PyErr_SetString(PyExc_TypeError,
133			"need a single Unicode character as parameter");
134	goto onError;
135    }
136    index = (int) _PyUnicode_Database_GetRecord(
137        (int) *PyUnicode_AS_UNICODE(v)
138        )->category;
139    return PyString_FromString(_PyUnicode_CategoryNames[index]);
140
141 onError:
142    return NULL;
143}
144
145static PyObject *
146unicodedata_bidirectional(PyObject *self,
147			  PyObject *args)
148{
149    PyUnicodeObject *v;
150    int index;
151
152    if (!PyArg_ParseTuple(args, "O!:bidirectional",
153			  &PyUnicode_Type, &v))
154	goto onError;
155    if (PyUnicode_GET_SIZE(v) != 1) {
156	PyErr_SetString(PyExc_TypeError,
157			"need a single Unicode character as parameter");
158	goto onError;
159    }
160    index = (int) _PyUnicode_Database_GetRecord(
161        (int) *PyUnicode_AS_UNICODE(v)
162        )->bidirectional;
163    return PyString_FromString(_PyUnicode_BidirectionalNames[index]);
164
165 onError:
166    return NULL;
167}
168
169static PyObject *
170unicodedata_combining(PyObject *self,
171		      PyObject *args)
172{
173    PyUnicodeObject *v;
174    int value;
175
176    if (!PyArg_ParseTuple(args, "O!:combining",
177			  &PyUnicode_Type, &v))
178	goto onError;
179    if (PyUnicode_GET_SIZE(v) != 1) {
180	PyErr_SetString(PyExc_TypeError,
181			"need a single Unicode character as parameter");
182	goto onError;
183    }
184    value = (int) _PyUnicode_Database_GetRecord(
185        (int) *PyUnicode_AS_UNICODE(v)
186        )->combining;
187    return PyInt_FromLong(value);
188
189 onError:
190    return NULL;
191}
192
193static PyObject *
194unicodedata_mirrored(PyObject *self,
195		     PyObject *args)
196{
197    PyUnicodeObject *v;
198    int value;
199
200    if (!PyArg_ParseTuple(args, "O!:mirrored",
201			  &PyUnicode_Type, &v))
202	goto onError;
203    if (PyUnicode_GET_SIZE(v) != 1) {
204	PyErr_SetString(PyExc_TypeError,
205			"need a single Unicode character as parameter");
206	goto onError;
207    }
208    value = (int) _PyUnicode_Database_GetRecord(
209        (int) *PyUnicode_AS_UNICODE(v)
210        )->mirrored;
211    return PyInt_FromLong(value);
212
213 onError:
214    return NULL;
215}
216
217static PyObject *
218unicodedata_decomposition(PyObject *self,
219		      PyObject *args)
220{
221    PyUnicodeObject *v;
222    const char *value;
223
224    if (!PyArg_ParseTuple(args, "O!:decomposition",
225			  &PyUnicode_Type, &v))
226	goto onError;
227    if (PyUnicode_GET_SIZE(v) != 1) {
228	PyErr_SetString(PyExc_TypeError,
229			"need a single Unicode character as parameter");
230	goto onError;
231    }
232    value = _PyUnicode_Database_GetDecomposition(
233        (int) *PyUnicode_AS_UNICODE(v)
234        );
235	return PyString_FromString(value);
236
237 onError:
238    return NULL;
239}
240
241/* XXX Add doc strings. */
242
243static PyMethodDef unicodedata_functions[] = {
244    {"decimal",		unicodedata_decimal,			1},
245    {"digit",		unicodedata_digit,			1},
246    {"numeric",		unicodedata_numeric,			1},
247    {"category",	unicodedata_category,			1},
248    {"bidirectional",	unicodedata_bidirectional,		1},
249    {"combining",	unicodedata_combining,			1},
250    {"mirrored",	unicodedata_mirrored,			1},
251    {"decomposition",	unicodedata_decomposition,		1},
252    {NULL, NULL}		/* sentinel */
253};
254
255DL_EXPORT(void)
256initunicodedata(void)
257{
258    Py_InitModule("unicodedata", unicodedata_functions);
259}
260