diff options
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/python/Makefile | 9 | ||||
-rw-r--r-- | bindings/python/pyhangul.c | 220 | ||||
-rw-r--r-- | bindings/python/setup.py | 50 | ||||
-rw-r--r-- | bindings/python/test_pyhangul.py | 28 | ||||
-rw-r--r-- | bindings/ruby/extconf.rb | 7 | ||||
-rw-r--r-- | bindings/ruby/hangul.c | 124 | ||||
-rw-r--r-- | bindings/ruby/test-hangul.rb | 23 |
7 files changed, 461 insertions, 0 deletions
diff --git a/bindings/python/Makefile b/bindings/python/Makefile new file mode 100644 index 0000000..1cfeda8 --- /dev/null +++ b/bindings/python/Makefile @@ -0,0 +1,9 @@ + +all: + python setup.py build + +clean: + rm -rf build + +install: + python setup.py install diff --git a/bindings/python/pyhangul.c b/bindings/python/pyhangul.c new file mode 100644 index 0000000..b91944e --- /dev/null +++ b/bindings/python/pyhangul.c @@ -0,0 +1,220 @@ +#include <Python.h> + +#include <stdio.h> +#include <unistd.h> + +#include <string.h> +#include <stdlib.h> +#include <alloca.h> + +#include "../hangul/hangul.h" + +static PyObject *_pyhangul_error; + +/* User defined Object */ +typedef struct { + PyObject_HEAD +} PY_HANGUL; + +typedef struct { + PyObject_HEAD + + HangulInputContext *hic; +} PY_HANGULIC; + +extern PyTypeObject PY_HANGULIC_Type; + +static int ucscharlen(const ucschar *str) +{ + const ucschar *end = str; + while (*end != 0) + end++; + return end - str; +} + +static PyObject *_create_ic(PY_HANGUL *self, PyObject *args) +{ + PY_HANGULIC *imObject; + int keyboard; + + if(!PyArg_ParseTuple(args,"i",&keyboard)) { + PyErr_SetString(_pyhangul_error, + "Usage: create_ic(keyboard)\n" + "\tkeyboard: hangul2, hangul3{2,90,f,s}"); + return NULL; + } + + imObject = PyObject_NEW(PY_HANGULIC, &PY_HANGULIC_Type); + if(imObject == NULL) { + PyErr_SetString(_pyhangul_error,"Fail to create PY_HANGULIC Object"); + return NULL; + } + + imObject->hic = hangul_ic_new(keyboard); + + return (PyObject *)imObject; +} + +static PyMethodDef _pyhangul_methods[] = { + { "create_ic", (PyCFunction) _create_ic, METH_VARARGS, NULL }, + { NULL, NULL, 0, NULL } +}; + +void inithangul(void) +{ + PyObject *m, *d; + + m = Py_InitModule("hangul", _pyhangul_methods); + PyModule_AddIntConstant(m, "hangul2", HANGUL_KEYBOARD_2); + PyModule_AddIntConstant(m, "hangul32", HANGUL_KEYBOARD_32); + PyModule_AddIntConstant(m, "hangul390", HANGUL_KEYBOARD_390); + PyModule_AddIntConstant(m, "hangul3f", HANGUL_KEYBOARD_3FINAL); + PyModule_AddIntConstant(m, "hangul3s", HANGUL_KEYBOARD_3NOSHIFT); + /* PyModule_AddIntConstant(m, "Hangul3_Yetgeul", HANGUL_KEYBOARD_3YETGUL); */ + + d = PyModule_GetDict(m); + _pyhangul_error = PyErr_NewException("_pyhangul.error", NULL, NULL); + PyDict_SetItemString(d, "error", _pyhangul_error); +} + +/* im's member function */ +static PyObject *_pyhangulic_process(PY_HANGULIC *self, PyObject *args) +{ + int ret; + int ascii; + + if(!PyArg_ParseTuple(args,"i", &ascii)) { + PyErr_SetString(_pyhangul_error,"Usage: process(ascii)"); + return NULL; + } + + ret = hangul_ic_process(self->hic, ascii); + + return Py_BuildValue("i", ret); +} + +static PyObject *_pyhangulic_reset(PY_HANGULIC *self, PyObject *args) +{ + hangul_ic_reset(self->hic); + + return Py_None; +} + +static PyObject *_pyhangulic_flush(PY_HANGULIC *self, PyObject *args) +{ + hangul_ic_flush(self->hic); + + return Py_None; +} + +static PyObject *_pyhangulic_backspace(PY_HANGULIC *self, PyObject *args) +{ + int ret; + + ret = hangul_ic_backspace(self->hic); + + return Py_BuildValue("i", ret); +} + +static PyObject *_pyhangulic_preedit_string(PY_HANGULIC *self, PyObject *args) +{ +#ifndef Py_UNICODE_WIDE + int i; + Py_UNICODE *buf; +#endif /* !Py_UNICODE_WIDE */ + int len; + const ucschar *str; + + str = hangul_ic_get_preedit_string(self->hic); + len = ucscharlen(str); + +#ifdef Py_UNICODE_WIDE + return PyUnicode_FromUnicode((Py_UNICODE*)str, len); +#else /* Py_UNICODE_WIDE */ + buf = alloca(sizeof(Py_UNICODE) * len); + for (i = 0; i < len; i++) + buf[i] = str[i]; + return PyUnicode_FromUnicode(buf, len); +#endif /* Py_UNICODE_WIDE */ +} + +static PyObject *_pyhangulic_commit_string(PY_HANGULIC *self, PyObject *args) +{ +#ifndef Py_UNICODE_WIDE + int i; + Py_UNICODE *buf; +#endif /* !Py_UNICODE_WIDE */ + int len; + const ucschar *str; + + str = hangul_ic_get_commit_string(self->hic); + len = ucscharlen(str); + +#ifdef Py_UNICODE_WIDE + return PyUnicode_FromUnicode((Py_UNICODE*)str, len); +#else /* Py_UNICODE_WIDE */ + buf = alloca(sizeof(Py_UNICODE) * len); + for (i = 0; i < len; i++) + buf[i] = str[i]; + return PyUnicode_FromUnicode(buf, len); +#endif /* Py_UNICODE_WIDE */ +} + +/* PY_HANGULIC methods */ +static PyMethodDef PY_HANGULIC_methods[] = { + { "process", (PyCFunction)_pyhangulic_process, METH_VARARGS, NULL}, + { "reset", (PyCFunction)_pyhangulic_reset, METH_VARARGS, NULL}, + { "flush", (PyCFunction)_pyhangulic_flush, METH_VARARGS, NULL}, + { "backspace", (PyCFunction)_pyhangulic_backspace, METH_VARARGS, NULL}, + { "preedit_string",(PyCFunction)_pyhangulic_preedit_string, METH_VARARGS, NULL}, + { "commit_string", (PyCFunction)_pyhangulic_commit_string, METH_VARARGS, NULL}, + { NULL, NULL, 0, NULL } +}; + +/* PY_HANGULIC dealloc */ +static void PY_HANGULIC_dealloc(PY_HANGULIC *self) +{ + hangul_ic_delete(self->hic); + self->hic = NULL; + PyMem_Free((char *) self); +} + +/* PY_HANGULIC getattr */ +static PyObject * PY_HANGULIC_getattr(PY_HANGULIC *self, char *name) +{ + PyObject *res; + res = Py_FindMethod(PY_HANGULIC_methods, (PyObject *)self, name); + if(res != NULL) + return res; + PyErr_Clear(); + PyErr_SetString(_pyhangul_error,"UnKnown method"); + return NULL; +} + +/* PY_HANGULIC repr */ +static PyObject * PY_HANGULIC_repr(PY_HANGULIC *self) +{ + char buf[300]; + sprintf(buf,"<Class pyhangul at %lx>",(long)self); + return PyString_FromString(buf); +} + + +/* PY_HANGUL Type */ +PyTypeObject PY_HANGULIC_Type = { +#ifndef MS_WIN32 + PyObject_HEAD_INIT(&PyType_Type) +#else + PyObject_HEAD_INIT(NULL) +#endif + 0, + "hangul.hangulic", + sizeof(PY_HANGULIC), + 0, + (destructor)PY_HANGULIC_dealloc, + 0, + (getattrfunc)PY_HANGULIC_getattr, + 0, + 0, + (reprfunc)PY_HANGULIC_repr, +}; diff --git a/bindings/python/setup.py b/bindings/python/setup.py new file mode 100644 index 0000000..59add16 --- /dev/null +++ b/bindings/python/setup.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +import sys +from distutils.core import setup, Extension + +classifiers = """\ +Development Status :: 4 - Beta +Intended Audience :: Developers +License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) +Programming Language :: Python +Programming Language :: C +Topic :: Software Development :: Libraries :: Python Modules +Operating System :: Microsoft :: Windows +Operating System :: Unix +""" + +if sys.platform == "win32": # for MinGW + include_dirs = [r'\MinGW\include', r'..\hangul'] + library_dirs = [r'\MinGW\lib', r'..\hangul'] + libraries = ['hangul'] + data_files = [] + +else: + include_dirs = [ '../hangul' ] + library_dirs = [ '../hangul/.libs' ] + libraries = ['hangul'] + data_files = [] + +if sys.version_info < (2, 3): + _setup = setup + def setup(**kwargs): + if kwargs.has_key("classifiers"): + del kwargs["classifiers"] + _setup(**kwargs) + +setup(name = "pyhangul", + version = "0.0.1", + description="libhangul for Python.", + author = "Joon-cheol Park", + author_email="jooncheol@gmail.com", + license = "LGPL", + url="http://hangul.kldp.net", + ext_modules=[Extension("hangul", ["pyhangul.c"], + include_dirs = include_dirs, + library_dirs = library_dirs, + libraries = libraries)], + classifiers = filter(None, classifiers.split("\n")), + data_files=data_files + ) + diff --git a/bindings/python/test_pyhangul.py b/bindings/python/test_pyhangul.py new file mode 100644 index 0000000..9fd5b24 --- /dev/null +++ b/bindings/python/test_pyhangul.py @@ -0,0 +1,28 @@ +# coding: utf-8 +# +# Author: Gyoung-Yoon Noh <nohmad@gmail.com> +# License: Same as libhangul. + +import sys +import hangul +import unittest + +class TestHangul(unittest.TestCase): + def setUp(self): + self.ic = hangul.create_ic(hangul.hangul2) + + def testSimpleString(self): + input = u"vkdlTjs gksrmf fkdlqmfjfl xptmxm" + output = u"파이썬 한글 라이브러리 테스트" + buffer = u'' + for i in input: + ret = self.ic.filter(ord(i)) + buffer += self.ic.commit_string() + if not ret: + buffer += str(i) + self.ic.flush() + buffer += self.ic.commit_string() + self.assertEqual(output, buffer) + +if __name__ == '__main__': + unittest.main() diff --git a/bindings/ruby/extconf.rb b/bindings/ruby/extconf.rb new file mode 100644 index 0000000..d443963 --- /dev/null +++ b/bindings/ruby/extconf.rb @@ -0,0 +1,7 @@ +require 'mkmf' + +dir_config('hangul') +have_library('hangul', 'hangul_ic_new') +create_makefile('hangul') + +# vim: set sts=2 sw=2 et: diff --git a/bindings/ruby/hangul.c b/bindings/ruby/hangul.c new file mode 100644 index 0000000..664b634 --- /dev/null +++ b/bindings/ruby/hangul.c @@ -0,0 +1,124 @@ +/* + * Ruby extenstion library for libhangul. + * + * * Author: Gyoung-Yoon Noh <nohmad@sub-port.net> + * * License: Same as libhangul. + */ + +#include <locale.h> + +#include "ruby.h" +#include "hangul.h" + +static void +rbhic_free(HangulInputContext *hic) +{ + hangul_ic_delete(hic); +} + +static VALUE +rbhic_alloc(VALUE klass) +{ + setlocale(LC_CTYPE, ""); + HangulInputContext *hic = hangul_ic_new(HANGUL_KEYBOARD_2); + return Data_Wrap_Struct(klass, 0, rbhic_free, hic); +} + +static VALUE +rbhic_initialize(int argc, VALUE *argv, VALUE self) +{ + HangulInputContext *hic; + Data_Get_Struct(self, HangulInputContext, hic); + VALUE keyboard; + rb_scan_args(argc, argv, "01", &keyboard); + if (argc > 0) { + Check_Type(keyboard, T_FIXNUM); + hangul_ic_set_keyboard(hic, FIX2INT(keyboard)); + } + return self; +} + +static VALUE +rbhic_filter(VALUE self, VALUE ch) +{ + Check_Type(ch, T_FIXNUM); + HangulInputContext *hic; + Data_Get_Struct(self, HangulInputContext, hic); + + bool ret = hangul_ic_filter(hic, NUM2CHR(ch)); + return ret ? Qtrue : Qfalse; +} + +static VALUE +rbhic_preedit_string(VALUE self) +{ +} + +static VALUE +rbhic_commit_string(VALUE self) +{ + HangulInputContext *hic; + Data_Get_Struct(self, HangulInputContext, hic); + + char cbuf[32] = { '\0', }; + wchar_t *wstr = (wchar_t *) hangul_ic_get_commit_string(hic); + int len = wcstombs(cbuf, wstr, sizeof(cbuf)); + if (strlen(cbuf) > 0) + return rb_str_new(cbuf, len); + else + return Qnil; +} + +static VALUE +rbhic_backspace(VALUE self) +{ +} + +static VALUE +rbhic_reset(VALUE self) +{ + HangulInputContext *hic; + Data_Get_Struct(self, HangulInputContext, hic); + hangul_ic_reset(hic); + return Qnil; +} + +static VALUE +rbhic_flush(VALUE self) +{ + HangulInputContext *hic; + Data_Get_Struct(self, HangulInputContext, hic); + hangul_ic_flush(hic); + return Qnil; +} + +void +Init_hangul(void) +{ + /* ::Hangul module. */ + VALUE rb_mHangul; + rb_mHangul = rb_define_module("Hangul"); + + /* Hangul::InputContext class. */ + VALUE rb_cInputContext; + rb_cInputContext = rb_define_class_under(rb_mHangul, "InputContext", rb_cObject); + rb_define_alloc_func(rb_cInputContext, rbhic_alloc); + + /* Hangul::InputContext methods. */ + rb_define_method(rb_cInputContext, "initialize", rbhic_initialize, -1); + rb_define_method(rb_cInputContext, "filter", rbhic_filter, 1); + rb_define_method(rb_cInputContext, "commit_string", rbhic_commit_string, 0); + rb_define_method(rb_cInputContext, "preedit_string", rbhic_preedit_string, 0); + rb_define_method(rb_cInputContext, "backspace", rbhic_backspace, 0); + rb_define_method(rb_cInputContext, "flush", rbhic_flush, 0); + rb_define_method(rb_cInputContext, "reset", rbhic_reset, 0); + + /* Hangul::KEYBOARD_* constants. */ + rb_define_const(rb_mHangul, "KEYBOARD_2", INT2FIX(HANGUL_KEYBOARD_2)); + rb_define_const(rb_mHangul, "KEYBOARD_32", INT2FIX(HANGUL_KEYBOARD_32)); + rb_define_const(rb_mHangul, "KEYBOARD_3FINAL", INT2FIX(HANGUL_KEYBOARD_3FINAL)); + rb_define_const(rb_mHangul, "KEYBOARD_390", INT2FIX(HANGUL_KEYBOARD_390)); + rb_define_const(rb_mHangul, "KEYBOARD_3NOSHIFT", INT2FIX(HANGUL_KEYBOARD_3NOSHIFT)); + rb_define_const(rb_mHangul, "KEYBOARD_3YETGUL", INT2FIX(HANGUL_KEYBOARD_3YETGUL)); +} + diff --git a/bindings/ruby/test-hangul.rb b/bindings/ruby/test-hangul.rb new file mode 100644 index 0000000..f38abe1 --- /dev/null +++ b/bindings/ruby/test-hangul.rb @@ -0,0 +1,23 @@ +require 'test/unit' +require 'hangul' + +class TestHangulInputContext < Test::Unit::TestCase + def setup + @hic = Hangul::InputContext.new(Hangul::KEYBOARD_2) + end + def test_2bul_string + input = "fnql gksrmf fkdlqmfjfl xptmxm" + expected = "루비 한글 라이브러리 테스트" + buffer = '' + input.each_byte do |c| + ret = @hic.filter(c) + buffer << @hic.commit_string.to_s + buffer << c.chr unless ret + end + @hic.flush + buffer << @hic.commit_string.to_s + assert_equal expected, buffer + end +end + +# vim: set sts=2 sw=2 et: |