source: trunk/pymigemo/pymigemo.c @ 35

Revision 35, 10.4 KB checked in by atzm, 14 years ago (diff)
  • get_operator(): fixed error handing (invalid opindex was given)
  • Property svn:keywords set to Id
RevLine 
[21]1/*
2 * pymigemo.c - C/Migemo wrapper for Python
[30]3 * Copyright(C) 2005-2009, Atzm WATANABE <atzm@atzm.org>
[21]4 *
5 * $Id$
6 */
7
8#include <Python.h>
[30]9#include <structmember.h>
10#include <migemo.h>
[34]11#include <stdbool.h>
[30]12#include <string.h>
[21]13
[34]14#define PYMIGEMO_VERSION "0.3"
[21]15
16/* for dereference migemo object members */
[30]17struct _migemo {
18    int   enable;
19    void *mtree;
20    int   charset;
21    void *roma2hira;
22    void *hira2kata;
23    void *han2zen;
24    void *zen2han;
25    void *rx;
26    void *addword;
27    void *char2int;
[21]28};
29
30typedef struct {
[30]31    PyObject_HEAD
32    migemo *migemo_obj;
[21]33} Migemo;
34
[34]35static bool
36get_encoding(char *encoding, size_t size, int charset)
37{
38    char *enc;
39
40    switch(charset) {
41    case 1:
42        enc = "cp932";
43        break;
44    case 2:
45        enc = "euc_jp";
46        break;
47    case 3:
48        enc = "utf_8";
49        break;
50    default:
51        enc = "ascii";
52    }
53
54    if (strlen(enc) < size) {
55        strcpy(encoding, enc);
56        return true;
57    }
58
59    return false;
60}
61
[21]62static void
63Migemo_dealloc(Migemo *self)
64{
[30]65    if (self->migemo_obj) {
66        migemo_close(self->migemo_obj);
67    }
[21]68
[30]69    self->ob_type->tp_free((PyObject *)self);
[21]70}
71
72static PyObject *
73Migemo_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
74{
[30]75    Migemo *self;
[21]76
[30]77    self = (Migemo *)type->tp_alloc(type, 0);
[21]78
[30]79    if (self != NULL) {
80        self->migemo_obj = NULL;
81    }
82
83    return (PyObject *)self;
[21]84}
85
86static int
87Migemo_init(Migemo *self, PyObject *args, PyObject *kwds)
88{
[30]89    migemo *migemo_obj;
90    char   *dictionary;
[21]91
[30]92    static char *kwlist[] = {"dictionary", NULL};
[21]93
[30]94    if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &dictionary)) {
95        return -1;
96    }
[21]97
[30]98    if (dictionary) {
99        if (self->migemo_obj) {
100            migemo_close(self->migemo_obj);
101        }
[21]102
[30]103        migemo_obj = migemo_open(dictionary);
[21]104
[30]105        if (migemo_obj) {
106            self->migemo_obj = migemo_obj;
107        }
108        else {
[34]109            PyErr_SetString(PyExc_AssertionError, "migemo_open() failed");
[30]110            return -1;
111        }
112    }
113
114    return 0;
[21]115}
116
117static PyObject *
118Migemo_get_encoding(Migemo *self)
119{
[30]120    char encoding[7];
121
122    if (!get_encoding(encoding, sizeof(encoding), self->migemo_obj->charset)) {
[34]123        PyErr_SetString(PyExc_AssertionError, "get_encoding() failed");
[30]124        return NULL;
125    }
126
127    return PyString_FromString(encoding);
[21]128}
129
130static PyObject *
131Migemo_query(Migemo *self, PyObject *args, PyObject *kwds)
132{
[34]133    PyObject      *result, *pyquery, *pyrestr;
[30]134    char          *query, encoding[7];
135    unsigned char *regex;
[21]136
[30]137    static char *kwlist[] = {"query", NULL};
[21]138
[34]139    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &pyquery)) {
[30]140        return NULL;
141    }
[21]142
[30]143    if (!get_encoding(encoding, sizeof(encoding), self->migemo_obj->charset)) {
[34]144        PyErr_SetString(PyExc_AssertionError, "get_encoding() failed");
[30]145        return NULL;
146    }
[21]147
[34]148    if (PyUnicode_Check(pyquery)) {
149        PyObject *q = PyUnicode_AsEncodedString(pyquery, encoding, "strict");
150
151        if (q == NULL) {
152            return NULL;
153        }
154
155        query = PyString_AS_STRING(q);
156        Py_DECREF(q);
[30]157    }
[34]158    else if (PyString_Check(pyquery)) {
159        query = PyString_AS_STRING(pyquery);
[30]160    }
161    else {
[34]162        PyErr_SetString(PyExc_ValueError, "argument must be string");
[30]163        return NULL;
164    }
[34]165    if (query == NULL) {
166        return NULL;
167    }
[21]168
[34]169    regex = migemo_query(self->migemo_obj, query);
170    if (regex == NULL) {
171        PyErr_SetString(PyExc_AssertionError, "migemo_query() failed");
172        return NULL;
[21]173    }
174
[34]175    pyrestr = PyString_FromString(regex);
176    migemo_release(self->migemo_obj, regex);
177    if (pyrestr == NULL) {
[30]178        return NULL;
179    }
[21]180
[34]181    result = PyUnicode_FromEncodedObject(pyrestr, encoding, "strict");
182    Py_DECREF(pyrestr);
[30]183    return result;
[21]184}
185
186static PyObject *
187Migemo_set_operator(Migemo *self, PyObject *args, PyObject *kwds)
188{
[35]189    PyObject *result = NULL;
[30]190    char     *op;
191    int       index;
[21]192 
[30]193    static char *kwlist[] = {"index", "op", NULL};
[21]194
[30]195    if (!PyArg_ParseTupleAndKeywords(args, kwds, "is", kwlist, &index, &op)) {
196        return NULL;
197    }
[21]198
[30]199    if (op) {
[34]200        result = PyBool_FromLong((long)migemo_set_operator(self->migemo_obj, index, op));
[30]201    }
[21]202
[30]203    return result;
[21]204}
205
206static PyObject *
207Migemo_get_operator(Migemo *self, PyObject *args, PyObject *kwds)
208{
[35]209    PyObject            *result = NULL;
[34]210    const unsigned char *op;
211    int                  index;
[21]212 
[30]213    static char *kwlist[] = {"index", NULL};
[21]214
[30]215    if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", kwlist, &index)) {
216        return NULL;
217    }
[21]218
[30]219    if (op = migemo_get_operator(self->migemo_obj, index)) {
220        result = PyString_FromString(op);
221    }
[35]222    else {
223        PyErr_SetString(PyExc_ValueError, "invalid opindex");
[30]224    }
225
226    return result;
[21]227}
228
229static PyObject *
230Migemo_load(Migemo *self, PyObject *args, PyObject *kwds)
231{
[35]232    PyObject *result = NULL;
[30]233    char     *dict_file;
234    int       dict_id;
[21]235 
[30]236    static char *kwlist[] = {"dict_id", "dict_file", NULL};
[21]237
[30]238    if (!PyArg_ParseTupleAndKeywords(args, kwds, "is", kwlist, &dict_id, &dict_file)) {
239        return NULL;
240    }
[21]241
[30]242    if (dict_file) {
243        result = PyInt_FromLong((long)migemo_load(self->migemo_obj, dict_id, dict_file));
244    }
[21]245
[30]246    return result;
[21]247}
248
249static PyObject *
250Migemo_is_enable(Migemo *self)
251{
[34]252    return PyBool_FromLong((long)migemo_is_enable(self->migemo_obj));
[21]253}
254
255static PyMethodDef Migemo_methods[] = {
[30]256    {"query", (PyCFunction)Migemo_query, METH_KEYWORDS,
257     "return regex from romaji string\n\
[21]258\n\
259def query(query)\n\
260  query: romaji string (str or unicode)\n\
261\n\
262  returns: regex string as Unicode object"},
[30]263    {"set_operator", (PyCFunction)Migemo_set_operator, METH_KEYWORDS,
264     "set operator string as the meta character of regex\n\
[21]265\n\
266def set_operator(index, op):\n\
267  index: (OPINDEX_NEST_IN|OPINDEX_NEST_OUT|OPINDEX_NEWLINE|\n\
268          OPINDEX_OR|OPINDEX_SELECT_IN|OPINDEX_SELECT_OUT)\n\
269  op: operator string (str)\n\
270\n\
271  returns: boolean value"},
[30]272    {"get_operator", (PyCFunction)Migemo_get_operator, METH_KEYWORDS,
273     "get operator string as the meta character of regex\n\
[21]274\n\
275def get_operator(index)\n\
276  index: (OPINDEX_NEST_IN|OPINDEX_NEST_OUT|OPINDEX_NEWLINE|\n\
277          OPINDEX_OR|OPINDEX_SELECT_IN|OPINDEX_SELECT_OUT)\n\
278\n\
279  returns: operator string (str)"},
[30]280    {"load", (PyCFunction)Migemo_load, METH_KEYWORDS,
281     "add dictionary to Migemo object\n\
[21]282\n\
283def load(dict_id, dict_file)\n\
284  dict_id: (DICTID_HAN2ZEN|DICTID_HIRA2KATA|DICTID_MIGEMO|\n\
285            DICTID_ROMA2HIRA|DICTID_ZEN2HAN)\n\
286  dict_file: path to dictionary file (str)\n\
287\n\
288  returns: boolean value"},
[30]289    {"is_enable", (PyCFunction)Migemo_is_enable, METH_NOARGS,
290     "check internal migemo_dict\n\
[21]291\n\
292def is_enable()\n\
293  returns: boolean value"},
[30]294    {"get_encoding", (PyCFunction)Migemo_get_encoding, METH_NOARGS,
295     "get dictionary encoding\n\
[21]296\n\
297def get_encoding()\n\
298  returns: encoding string (str)"},
[30]299    {NULL} /* Sentinel */
[21]300};
301
302static PyMemberDef Migemo_members[] = {
[30]303    {NULL} /* Sentinel */
[21]304};
305
306static PyTypeObject MigemoType = {
[30]307    PyObject_HEAD_INIT(NULL)
308    0,                          /*ob_size*/
309    "migemo.Migemo",            /*tp_name*/
310    sizeof(Migemo),             /*tp_basicsize*/
311    0,                          /*tp_itemsize*/
312    (destructor)Migemo_dealloc, /*tp_dealloc*/
313    0,                          /*tp_print*/
314    0,                          /*tp_getattr*/
315    0,                          /*tp_setattr*/
316    0,                          /*tp_compare*/
317    0,                          /*tp_repr*/
318    0,                          /*tp_as_number*/
319    0,                          /*tp_as_sequence*/
320    0,                          /*tp_as_mapping*/
321    0,                          /*tp_hash */
322    0,                          /*tp_call*/
323    0,                          /*tp_str*/
324    0,                          /*tp_getattro*/
325    0,                          /*tp_setattro*/
326    0,                          /*tp_as_buffer*/
327    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
328    "Migemo wrapper object",    /* tp_doc */
329    0,                          /* tp_traverse */
330    0,                          /* tp_clear */
331    0,                          /* tp_richcompare */
332    0,                          /* tp_weaklistoffset */
333    0,                          /* tp_iter */
334    0,                          /* tp_iternext */
335    Migemo_methods,             /* tp_methods */
336    Migemo_members,             /* tp_members */
337    0,                          /* tp_getset */
338    0,                          /* tp_base */
339    0,                          /* tp_dict */
340    0,                          /* tp_descr_get */
341    0,                          /* tp_descr_set */
342    0,                          /* tp_dictoffset */
343    (initproc)Migemo_init,      /* tp_init */
344    0,                          /* tp_alloc */
345    Migemo_new,                 /* tp_new */
[21]346};
347
348static PyMethodDef module_methods[] = {
[30]349    {NULL} /* Sentinel */
[21]350};
351
352#ifndef PyMODINIT_FUNC
353#define PyMODINIT_FUNC void
354#endif
355PyMODINIT_FUNC
356initmigemo(void) 
357{
[30]358    PyObject* m;
[21]359
[30]360    if (PyType_Ready(&MigemoType) < 0)
361        return;
[21]362
[30]363    m = Py_InitModule3("migemo", module_methods, "C/Migemo wrapper");
[21]364
[30]365    Py_INCREF(&MigemoType);
366    PyModule_AddObject(m, "Migemo", (PyObject *)&MigemoType);
367    PyModule_AddObject(m, "PYMIGEMO_VERSION", Py_BuildValue("s", PYMIGEMO_VERSION));
[21]368
[30]369    PyModule_AddObject(m, "MIGEMO_VERSION", Py_BuildValue("s", MIGEMO_VERSION));
[21]370
[30]371    PyModule_AddObject(m, "DICTID_INVALID", Py_BuildValue("i", MIGEMO_DICTID_INVALID));
372    PyModule_AddObject(m, "DICTID_MIGEMO", Py_BuildValue("i", MIGEMO_DICTID_MIGEMO));
373    PyModule_AddObject(m, "DICTID_ROMA2HIRA", Py_BuildValue("i", MIGEMO_DICTID_ROMA2HIRA));
374    PyModule_AddObject(m, "DICTID_HIRA2KATA", Py_BuildValue("i", MIGEMO_DICTID_HIRA2KATA));
375    PyModule_AddObject(m, "DICTID_HAN2ZEN", Py_BuildValue("i", MIGEMO_DICTID_HAN2ZEN));
376    PyModule_AddObject(m, "DICTID_ZEN2HAN", Py_BuildValue("i", MIGEMO_DICTID_ZEN2HAN));
[21]377
[30]378    PyModule_AddObject(m, "OPINDEX_OR", Py_BuildValue("i", MIGEMO_OPINDEX_OR));
379    PyModule_AddObject(m, "OPINDEX_NEST_IN", Py_BuildValue("i", MIGEMO_OPINDEX_NEST_IN));
380    PyModule_AddObject(m, "OPINDEX_NEST_OUT", Py_BuildValue("i", MIGEMO_OPINDEX_NEST_OUT));
381    PyModule_AddObject(m, "OPINDEX_SELECT_IN", Py_BuildValue("i", MIGEMO_OPINDEX_SELECT_IN));
382    PyModule_AddObject(m, "OPINDEX_SELECT_OUT", Py_BuildValue("i", MIGEMO_OPINDEX_SELECT_OUT));
383    PyModule_AddObject(m, "OPINDEX_NEWLINE", Py_BuildValue("i", MIGEMO_OPINDEX_NEWLINE));
[21]384}
Note: See TracBrowser for help on using the repository browser.