OSDN Git Service

f275d32b79cad6d460219fb41d53a33ad7e87b7a
[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 #include "Python.h"
24 #include <setjmp.h>
25
26 #undef getc
27 #undef ungetc
28 #define getc(f)         pynkf_getc(f)         
29 #define ungetc(c,f)     pynkf_ungetc(c,f)
30
31 #undef putchar
32 #undef TRUE
33 #undef FALSE
34 #define putchar(c)      pynkf_putchar(c)
35
36 static int pynkf_ibufsize, pynkf_obufsize;
37 static unsigned char *pynkf_inbuf, *pynkf_outbuf;
38 static int pynkf_icount,pynkf_ocount;
39 static unsigned char *pynkf_iptr, *pynkf_optr;
40 static jmp_buf env;
41 static int pynkf_guess_flag;
42
43 static int 
44 pynkf_getc(FILE *f)
45 {
46   unsigned char c;
47   if (pynkf_icount >= pynkf_ibufsize) return EOF;
48   c = *pynkf_iptr++;
49   pynkf_icount++;
50   return (int)c;
51 }
52
53 static int 
54 pynkf_ungetc(int c, FILE *f)
55 {
56   if (pynkf_icount--){
57     *(--pynkf_iptr) = c;
58     return c;
59   }else{ return EOF; }
60 }
61
62 static void
63 pynkf_putchar(int c)
64 {
65   size_t size;
66   unsigned char *p;
67
68   if (pynkf_guess_flag) {
69     return;
70   }
71
72   if (pynkf_ocount--){
73     *pynkf_optr++ = c;
74   }else{
75     size = pynkf_obufsize + pynkf_obufsize;
76     p = (unsigned char *)PyMem_Realloc(pynkf_outbuf, size + 1);
77     if (pynkf_outbuf == NULL){ longjmp(env, 1); }
78     pynkf_outbuf = p;
79     pynkf_optr = pynkf_outbuf + pynkf_obufsize;
80     pynkf_ocount = pynkf_obufsize;
81     pynkf_obufsize = size;
82     *pynkf_optr++ = c;
83     pynkf_ocount--;
84   }
85 }
86
87 #define PERL_XS 1
88 #include "../utf8tbl.c"
89 #include "../nkf.c"
90
91 static PyObject *
92 pynkf_convert(unsigned char* str, int strlen, char* opts, int optslen)
93 {
94   PyObject * res;
95
96   pynkf_ibufsize = strlen + 1;
97   pynkf_obufsize = pynkf_ibufsize * 1.5 + 256;
98   pynkf_outbuf = (unsigned char *)PyMem_Malloc(pynkf_obufsize);
99   if (pynkf_outbuf == NULL){
100     PyErr_NoMemory();
101     return NULL;
102   }
103   pynkf_outbuf[0] = '\0';
104   pynkf_ocount = pynkf_obufsize;
105   pynkf_optr = pynkf_outbuf;
106   pynkf_icount = 0;
107   pynkf_inbuf  = str;
108   pynkf_iptr = pynkf_inbuf;
109   pynkf_guess_flag = 0;
110
111   if (setjmp(env) == 0){
112
113     reinit();
114
115     options(opts);
116
117     kanji_convert(NULL);
118
119   }else{
120     PyMem_Free(pynkf_outbuf);
121     PyErr_NoMemory();
122     return NULL;
123   }
124
125   *pynkf_optr = 0;
126   res = PyBytes_FromString(pynkf_outbuf);
127   PyMem_Free(pynkf_outbuf);
128   return res;
129 }
130
131 static PyObject *
132 pynkf_convert_guess(unsigned char* str, int strlen)
133 {
134   PyObject * res;
135   const char *codename;
136
137   pynkf_ibufsize = strlen + 1;
138   pynkf_icount = 0;
139   pynkf_inbuf  = str;
140   pynkf_iptr = pynkf_inbuf;
141
142   pynkf_guess_flag = 1;
143   reinit();
144   guess_f = 1;
145
146   kanji_convert(NULL);
147
148   codename = get_guessed_code();
149
150   res = PyUnicode_FromString(codename);
151   return res;
152 }
153
154 #ifndef EXTERN_NKF
155 static
156 #endif
157 PyObject *pynkf_nkf(PyObject *self, PyObject *args)
158 {
159   unsigned char *str;
160   int strlen;
161   char *opts;
162   int optslen;
163   PyObject* res;
164
165   if (!PyArg_ParseTuple(args, "s#y#", &opts, &optslen, &str, &strlen)) {
166     return NULL;
167   }
168   res = pynkf_convert(str, strlen, opts, optslen);
169   return res;
170 }
171
172 #ifndef EXTERN_NKF
173 static
174 #endif
175 PyObject *pynkf_guess(PyObject *self, PyObject *args)
176 {
177   unsigned char *str;
178   int strlen;
179   PyObject* res;
180
181   if (!PyArg_ParseTuple(args, "y#", &str, &strlen)) {
182     return NULL;
183   }
184   res = pynkf_convert_guess(str, strlen);
185   return res;
186 }
187
188 #ifndef EXTERN_NKF
189 static PyMethodDef
190 nkfMethods[] = {
191   {"nkf", pynkf_nkf, METH_VARARGS, ""},
192   {"guess", pynkf_guess, METH_VARARGS, ""},
193   {NULL, NULL, 0, NULL}
194 };
195
196 static struct PyModuleDef nkfmodule = {
197   PyModuleDef_HEAD_INIT,
198   "nkf",
199   "",
200   -1,
201   nkfMethods
202 };
203
204 /* Module initialization function */
205 PyMODINIT_FUNC
206 PyInit_nkf(void)
207 {
208   return PyModule_Create(&nkfmodule);
209 }
210 #endif