OSDN Git Service

Merge pull request #8 from slic-io/devlop
[nkf/nkf.git] / NKF.python3 / NKF_python.c
1 /*
2 Changes.
3 2009.6.2    Remove WISH_TRUE, use get_guessed_code() for nkf-2.0.9
4                  by SATOH Fumiyasu (fumiyas @ osstech co jp)
5 2008.7.17   Change the type of strlen from long to int, by SATOH Fumiyasu.
6 2007.2.1    Add guess() function.
7 2007.1.13   Remove pynkf_parseopts(), by SATOH Fumiyasu.
8 */
9 /**  Python Interface to NKF
10 ***************************************************************************
11 **  Copyright (c) 2005 Matsumoto, Tadashi <ma2@city.plala.jp>
12 **  All Rights Reserved.
13 **
14 **    Everyone is permitted to do anything on this program
15 **    including copying, modifying, improving,
16 **    as long as you don't try to pretend that you wrote it.
17 **    i.e., the above copyright notice has to appear in all copies.
18 **    Binary distribution requires original version messages.
19 **    You don't have to ask before copying, redistribution or publishing.
20 **    THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
21 ***************************************************************************/
22
23 #define PY_SSIZE_T_CLEAN
24
25 #include "Python.h"
26 #include <setjmp.h>
27
28 #undef getc
29 #undef ungetc
30 #define getc(f)         pynkf_getc(f)         
31 #define ungetc(c,f)     pynkf_ungetc(c,f)
32
33 #undef putchar
34 #undef TRUE
35 #undef FALSE
36 #define putchar(c)      pynkf_putchar(c)
37
38 static Py_ssize_t pynkf_ibufsize, pynkf_obufsize;
39 static unsigned char *pynkf_inbuf, *pynkf_outbuf;
40 static int pynkf_icount,pynkf_ocount;
41 static unsigned char *pynkf_iptr, *pynkf_optr;
42 static jmp_buf env;
43 static int pynkf_guess_flag;
44
45 static int 
46 pynkf_getc(FILE *f)
47 {
48   unsigned char c;
49   if (pynkf_icount >= pynkf_ibufsize) return EOF;
50   c = *pynkf_iptr++;
51   pynkf_icount++;
52   return (int)c;
53 }
54
55 static int 
56 pynkf_ungetc(int c, FILE *f)
57 {
58   if (pynkf_icount--){
59     *(--pynkf_iptr) = c;
60     return c;
61   }else{ return EOF; }
62 }
63
64 static void
65 pynkf_putchar(int c)
66 {
67   Py_ssize_t size;
68   unsigned char *p;
69
70   if (pynkf_guess_flag) {
71     return;
72   }
73
74   if (pynkf_ocount--){
75     *pynkf_optr++ = c;
76   }else{
77     size = pynkf_obufsize + pynkf_obufsize;
78     p = (unsigned char *)PyMem_Realloc(pynkf_outbuf, size + 1);
79     if (pynkf_outbuf == NULL){ longjmp(env, 1); }
80     pynkf_outbuf = p;
81     pynkf_optr = pynkf_outbuf + pynkf_obufsize;
82     pynkf_ocount = pynkf_obufsize;
83     pynkf_obufsize = size;
84     *pynkf_optr++ = c;
85     pynkf_ocount--;
86   }
87 }
88
89 #define PERL_XS 1
90 #include "../utf8tbl.c"
91 #include "../nkf.c"
92
93 static PyObject *
94 pynkf_convert(unsigned char* str, Py_ssize_t strlen, char* opts, Py_ssize_t optslen)
95 {
96   PyObject * res;
97
98   pynkf_ibufsize = strlen + 1;
99   pynkf_obufsize = pynkf_ibufsize * 1.5 + 256;
100   pynkf_outbuf = (unsigned char *)PyMem_Malloc(pynkf_obufsize);
101   if (pynkf_outbuf == NULL){
102     PyErr_NoMemory();
103     return NULL;
104   }
105   pynkf_outbuf[0] = '\0';
106   pynkf_ocount = pynkf_obufsize;
107   pynkf_optr = pynkf_outbuf;
108   pynkf_icount = 0;
109   pynkf_inbuf  = str;
110   pynkf_iptr = pynkf_inbuf;
111   pynkf_guess_flag = 0;
112
113   if (setjmp(env) == 0){
114
115     reinit();
116
117     options(opts);
118
119     kanji_convert(NULL);
120
121   }else{
122     PyMem_Free(pynkf_outbuf);
123     PyErr_NoMemory();
124     return NULL;
125   }
126
127   *pynkf_optr = 0;
128   res = PyBytes_FromString(pynkf_outbuf);
129   PyMem_Free(pynkf_outbuf);
130   return res;
131 }
132
133 static PyObject *
134 pynkf_convert_guess(unsigned char* str, int strlen)
135 {
136   PyObject * res;
137   const char *codename;
138
139   pynkf_ibufsize = strlen + 1;
140   pynkf_icount = 0;
141   pynkf_inbuf  = str;
142   pynkf_iptr = pynkf_inbuf;
143
144   pynkf_guess_flag = 1;
145   reinit();
146   guess_f = 1;
147
148   kanji_convert(NULL);
149
150   codename = get_guessed_code();
151
152   res = PyUnicode_FromString(codename);
153   return res;
154 }
155
156 #ifndef EXTERN_NKF
157 static
158 #endif
159 PyObject *pynkf_nkf(PyObject *self, PyObject *args)
160 {
161   unsigned char *str;
162   Py_ssize_t strlen;
163   char *opts;
164   Py_ssize_t optslen;
165   PyObject* res;
166
167   if (!PyArg_ParseTuple(args, "s#s#", &opts, &optslen, &str, &strlen)) {
168     return NULL;
169   }
170   res = pynkf_convert(str, strlen, opts, optslen);
171   return res;
172 }
173
174 #ifndef EXTERN_NKF
175 static
176 #endif
177 PyObject *pynkf_guess(PyObject *self, PyObject *args)
178 {
179   unsigned char *str;
180   int strlen;
181   PyObject* res;
182
183   if (!PyArg_ParseTuple(args, "s#", &str, &strlen)) {
184     return NULL;
185   }
186   res = pynkf_convert_guess(str, strlen);
187   return res;
188 }
189
190 #ifndef EXTERN_NKF
191 static PyMethodDef
192 nkfMethods[] = {
193   {"nkf", pynkf_nkf, METH_VARARGS, ""},
194   {"guess", pynkf_guess, METH_VARARGS, ""},
195   {NULL, NULL, 0, NULL}
196 };
197
198 static struct PyModuleDef nkfmodule = {
199   PyModuleDef_HEAD_INIT,
200   "nkf",
201   "",
202   -1,
203   nkfMethods
204 };
205
206 /* Module initialization function */
207 PyMODINIT_FUNC
208 PyInit_nkf(void)
209 {
210   return PyModule_Create(&nkfmodule);
211 }
212 #endif