1 /* vim:set ts=8 sts=4 sw=4 tw=0: */
2 /*
3  * migemo.c -
4  *
5  * Written By:  MURAOKA Taro <koron@tka.att.ne.jp>
6  */
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <limits.h>
13 
14 #include "wordbuf.h"
15 #include "wordlist.h"
16 #include "mnode.h"
17 #include "rxgen.h"
18 #include "romaji.h"
19 #include "filename.h"
20 #include "charset.h"
21 #include "migemo.h"
22 
23 #define DICT_MIGEMO "migemo-dict"
24 #define DICT_ROMA2HIRA "roma2hira.dat"
25 #define DICT_HIRA2KATA "hira2kata.dat"
26 #define DICT_HAN2ZEN "han2zen.dat"
27 #define DICT_ZEN2HAN "zen2han.dat"
28 #define BUFLEN_DETECT_CHARSET 4096
29 
30 #ifdef __BORLANDC__
31 # define EXPORTS __declspec(dllexport)
32 #else
33 # define EXPORTS
34 #endif
35 
36 typedef int (*MIGEMO_PROC_ADDWORD)(void* data, unsigned char* word);
37 
38 /* migemo�I�u�W�F�N�g */
39 struct _migemo
40 {
41     int enable;
42     mtree_p mtree;
43     int charset;
44     romaji* roma2hira;
45     romaji* hira2kata;
46     romaji* han2zen;
47     romaji* zen2han;
48     rxgen* rx;
49     MIGEMO_PROC_ADDWORD addword;
50     CHARSET_PROC_CHAR2INT char2int;
51 };
52 
53 static const unsigned char VOWEL_CHARS[] = "aiueo";
54 
55     static int
my_strlen(const char * s)56 my_strlen(const char* s)
57 {
58     size_t len;
59 
60     len = strlen(s);
61     return len <= INT_MAX ? (int)len : INT_MAX;
62 }
63 
64     static mtree_p
load_mtree_dictionary(mtree_p mtree,const char * dict_file)65 load_mtree_dictionary(mtree_p mtree, const char* dict_file)
66 {
67     FILE *fp;
68 
69     if ((fp = fopen(dict_file, "rt")) == NULL)
70 	return NULL;			/* Can't find file */
71     mtree = mnode_load(mtree, fp);
72     fclose(fp);
73     return mtree;
74 }
75 
76     static mtree_p
load_mtree_dictionary2(migemo * obj,const char * dict_file)77 load_mtree_dictionary2(migemo* obj, const char* dict_file)
78 {
79     if (obj->charset == CHARSET_NONE)
80     {
81 	/* �����̕����Z�b�g�ɂ��킹�Đ��K�\���������̊֐���ύX���� */
82 	CHARSET_PROC_CHAR2INT char2int = NULL;
83 	CHARSET_PROC_INT2CHAR int2char = NULL;
84 	obj->charset = charset_detect_file(dict_file);
85 	charset_getproc(obj->charset, &char2int, &int2char);
86 	if (char2int)
87 	{
88 	    migemo_setproc_char2int(obj, (MIGEMO_PROC_CHAR2INT)char2int);
89 	    obj->char2int = char2int;
90 	}
91 	if (int2char)
92 	    migemo_setproc_int2char(obj, (MIGEMO_PROC_INT2CHAR)int2char);
93     }
94     return load_mtree_dictionary(obj->mtree, dict_file);
95 }
96 
97     static void
dircat(char * buf,const char * dir,const char * file)98 dircat(char* buf, const char* dir, const char* file)
99 {
100     strcpy(buf, dir);
101     strcat(buf, "/");
102     strcat(buf, file);
103 }
104 
105 /*
106  * migemo interfaces
107  */
108 
109 /**
110  * Migemo�I�u�W�F�N�g�Ɏ����A�܂��̓f�[�^�t�@�C����lj��ǂݍ��݂���B
111  * dict_file�͓ǂݍ��ރt�@�C�������w�肷��Bdict_id�͓ǂݍ��ގ����E�f�[�^��
112  * ��ނ��w�肷����̂ňȉ��̂����ǂꂩ��‚��w�肷��:
113  *
114  *  <dl>
115  *  <dt>MIGEMO_DICTID_MIGEMO</dt>
116  *	<dd>mikgemo-dict����</dd>
117  *  <dt>MIGEMO_DICTID_ROMA2HIRA</dt>
118  *	<dd>���[�}�����������ϊ��\</dd>
119  *  <dt>MIGEMO_DICTID_HIRA2KATA</dt>
120  *	<dd>���������J�^�J�i�ϊ��\</dd>
121  *  <dt>MIGEMO_DICTID_HAN2ZEN</dt>
122  *	<dd>���p���S�p�ϊ��\</dd>
123  *  <dt>MIGEMO_DICTID_ZEN2HAN</dt>
124  *	<dd>�S�p�����p�ϊ��\</dd>
125  *  </dl>
126  *
127  *  �߂�l�͎��ۂɓǂݍ�����ނ������A��L�̑��ɓǂݍ��݂Ɏ��s�������Ƃ�����
128  *  ���̉����Ԃ邱�Ƃ�����B
129  *
130  *  <dl><dt>MIGEMO_DICTID_INVALID</dt></dl>
131  * @param obj Migemo�I�u�W�F�N�g
132  * @param dict_id �����t�@�C���̎��
133  * @param dict_file �����t�@�C���̃p�X
134  */
135     EXPORTS int MIGEMO_CALLTYPE
migemo_load(migemo * obj,int dict_id,const char * dict_file)136 migemo_load(migemo* obj, int dict_id, const char* dict_file)
137 {
138     if (!obj && dict_file)
139 	return MIGEMO_DICTID_INVALID;
140 
141     if (dict_id == MIGEMO_DICTID_MIGEMO)
142     {
143 	/* migemo�����ǂݍ��� */
144 	mtree_p mtree;
145 
146 	if ((mtree = load_mtree_dictionary2(obj, dict_file)) == NULL)
147 	    return MIGEMO_DICTID_INVALID;
148 	obj->mtree = mtree;
149 	obj->enable = 1;
150 	return dict_id;			/* Loaded successfully */
151     }
152     else
153     {
154 	romaji *dict;
155 
156 	switch (dict_id)
157 	{
158 	    case MIGEMO_DICTID_ROMA2HIRA:
159 		/* ���[�}�������ǂݍ��� */
160 		dict = obj->roma2hira;
161 		break;
162 	    case MIGEMO_DICTID_HIRA2KATA:
163 		/* �J�^�J�i�����ǂݍ��� */
164 		dict = obj->hira2kata;
165 		break;
166 	    case MIGEMO_DICTID_HAN2ZEN:
167 		/* ���p���S�p�����ǂݍ��� */
168 		dict = obj->han2zen;
169 		break;
170 	    case MIGEMO_DICTID_ZEN2HAN:
171 		/* ���p���S�p�����ǂݍ��� */
172 		dict = obj->zen2han;
173 		break;
174 	    default:
175 		dict = NULL;
176 		break;
177 	}
178 	if (dict && romaji_load(dict, dict_file) == 0)
179 	    return dict_id;
180 	else
181 	    return MIGEMO_DICTID_INVALID;
182     }
183 }
184 
185 /**
186  * Migemo�I�u�W�F�N�g���쐬����B�쐬�ɐ�������ƃI�u�W�F�N�g���߂�l�Ƃ���
187  * �Ԃ�A���s�����NULL���Ԃ�Bdict�Ŏw�肵���t�@�C����migemo-dict�����Ƃ���
188  * �I�u�W�F�N�g�쐬���ɓǂݍ��܂��B�����Ɠ����f�B���N�g����:
189  *
190  *  <dl>
191  *  <dt>roma2hira.dat</dt>
192  *	<dd>���[�}�����������ϊ��\ </dd>
193  *  <dt>hira2kata.dat</dt>
194  *	<dd>���������J�^�J�i�ϊ��\ </dd>
195  *  <dt>han2zen.dat</dt>
196  *	<dd>���p���S�p�ϊ��\ </dd>
197  *  </dl>
198  *
199  * �Ƃ������O�̃t�@�C�������݂���΁A���݂������̂������ǂݍ��܂��Bdict��
200  * NULL���w�肵���ꍇ�ɂ́A�������܂߂Ă����Ȃ�t�@�C�����ǂݍ��܂�Ȃ��B
201  * �t�@�C���̓I�u�W�F�N�g�쐬��ɂ�migemo_load()�֐����g�p���邱�ƂŒlj��ǂ�
202  * ���݂��ł���B
203  * @param dict migemo-dict�����̃p�X�BNULL�̎��͎�����ǂݍ��܂Ȃ��B
204  * @returns �쐬���ꂽMigemo�I�u�W�F�N�g
205  */
206     EXPORTS migemo* MIGEMO_CALLTYPE
migemo_open(const char * dict)207 migemo_open(const char* dict)
208 {
209     migemo *obj;
210 
211     /* migemo�I�u�W�F�N�g�Ɗe�����o���\�z */
212     if (!(obj = (migemo*)calloc(1, sizeof(migemo))))
213 	return obj;
214     obj->enable = 0;
215     obj->mtree = mnode_open(NULL);
216     obj->charset = CHARSET_NONE;
217     obj->rx = rxgen_open();
218     obj->roma2hira =	romaji_open();
219     obj->hira2kata =	romaji_open();
220     obj->han2zen =	romaji_open();
221     obj->zen2han =	romaji_open();
222     if (!obj->rx || !obj->roma2hira || !obj->hira2kata || !obj->han2zen
223 	    || !obj->zen2han)
224     {
225 	migemo_close(obj);
226 	return obj = NULL;
227     }
228 
229     /* �f�t�H���gmigemo�������w�肳��Ă����烍�[�}���ƃJ�^�J�i�������T�� */
230     if (dict)
231     {
232 #ifndef _MAX_PATH
233 # define _MAX_PATH 1024 /* ���������Ȑ��l */
234 #endif
235 	char dir[_MAX_PATH];
236 	char roma_dict[_MAX_PATH];
237 	char kata_dict[_MAX_PATH];
238 	char h2z_dict[_MAX_PATH];
239 	char z2h_dict[_MAX_PATH];
240 	const char *tmp;
241 	mtree_p mtree;
242 
243 	filename_directory(dir, dict);
244 	tmp = strlen(dir) ? dir : ".";
245 	dircat(roma_dict, tmp, DICT_ROMA2HIRA);
246 	dircat(kata_dict, tmp, DICT_HIRA2KATA);
247 	dircat(h2z_dict,  tmp, DICT_HAN2ZEN);
248 	dircat(z2h_dict,  tmp, DICT_ZEN2HAN);
249 
250 	mtree = load_mtree_dictionary2(obj, dict);
251 	if (mtree)
252 	{
253 	    obj->mtree = mtree;
254 	    obj->enable = 1;
255 	    romaji_load(obj->roma2hira, roma_dict);
256 	    romaji_load(obj->hira2kata, kata_dict);
257 	    romaji_load(obj->han2zen, h2z_dict);
258 	    romaji_load(obj->zen2han, z2h_dict);
259 	}
260     }
261     return obj;
262 }
263 
264 /**
265  * Migemo�I�u�W�F�N�g��j�����A�g�p���Ă������\�[�X���������B
266  * @param obj �j������Migemo�I�u�W�F�N�g
267  */
268     EXPORTS void MIGEMO_CALLTYPE
migemo_close(migemo * obj)269 migemo_close(migemo* obj)
270 {
271     if (obj)
272     {
273 	if (obj->zen2han)
274 	    romaji_close(obj->zen2han);
275 	if (obj->han2zen)
276 	    romaji_close(obj->han2zen);
277 	if (obj->hira2kata)
278 	    romaji_close(obj->hira2kata);
279 	if (obj->roma2hira)
280 	    romaji_close(obj->roma2hira);
281 	if (obj->rx)
282 	    rxgen_close(obj->rx);
283 	if (obj->mtree)
284 	    mnode_close(obj->mtree);
285 	free(obj);
286     }
287 }
288 
289 /*
290  * query version 2
291  */
292 
293 /*
294  * mnode�̎��’P�ꃊ�X�g���K�\�������G���W���ɓ��͂���B
295  */
296     static void
migemo_query_proc(mnode * p,void * data)297 migemo_query_proc(mnode* p, void* data)
298 {
299     migemo *object = (migemo*)data;
300     wordlist_p list = p->list;
301 
302     for (; list; list = list->next)
303 	object->addword(object, list->ptr);
304 }
305 
306 /*
307  * �o�b�t�@��p�ӂ���mnode�ɍċA�ŏ������܂���
308  */
309     static void
add_mnode_query(migemo * object,unsigned char * query)310 add_mnode_query(migemo* object, unsigned char* query)
311 {
312     mnode *pnode;
313 
314     if ((pnode = mnode_query(object->mtree, query)) != NULL)
315 	mnode_traverse(pnode, migemo_query_proc, object);
316 }
317 
318 /**
319  * ���͂����[�}���牼���ɕϊ����Č����L�[�ɉ�����B
320  */
321     static int
add_roma(migemo * object,unsigned char * query)322 add_roma(migemo* object, unsigned char* query)
323 {
324     unsigned char *stop, *hira, *kata, *han;
325 
326     hira = romaji_convert(object->roma2hira, query, &stop);
327     if (!stop)
328     {
329 	object->addword(object, hira);
330 	/* �������ɂ�鎫������ */
331 	add_mnode_query(object, hira);
332 	/* �Љ�����������������ɉ����� */
333 	kata = romaji_convert2(object->hira2kata, hira, NULL, 0);
334 	object->addword(object, kata);
335 	/* TODO: ���p�J�i���������ɉ����� */
336 #if 1
337 	han = romaji_convert2(object->zen2han, kata, NULL, 0);
338 	object->addword(object, han);
339 	/*printf("kata=%s\nhan=%s\n", kata, han);*/
340 	romaji_release(object->zen2han, han);
341 #endif
342 	/* �J�^�J�i�ɂ�鎫������ */
343 	add_mnode_query(object, kata);
344 	romaji_release(object->hira2kata, kata); /* �J�^�J�i��� */
345     }
346     romaji_release(object->roma2hira, hira); /* ��������� */
347 
348     return stop ? 1 : 0;
349 }
350 
351 /**
352  * ���[�}���̖����ɕꉹ��t�������āA�e�X�������L�[�ɉ�����B
353  */
354     static void
add_dubious_vowels(migemo * object,unsigned char * buf,int index)355 add_dubious_vowels(migemo* object, unsigned char* buf, int index)
356 {
357     const unsigned char* ptr;
358     for (ptr = VOWEL_CHARS; *ptr; ++ptr)
359     {
360 	buf[index] = *ptr;
361 	add_roma(object, buf);
362     }
363 }
364 
365 /*
366  * ���[�}���ϊ����s���S���������ɁA[aiueo]�����"xn"��"xtu"�����ĕϊ�����
367  * �݂�B
368  */
369     static void
add_dubious_roma(migemo * object,rxgen * rx,unsigned char * query)370 add_dubious_roma(migemo* object, rxgen* rx, unsigned char* query)
371 {
372     int max;
373     int len;
374     char *buf;
375 
376     if (!(len = my_strlen(query)))
377 	return;
378     /*
379      * ���[�}���̖����̃A�����W�̂��߂̃o�b�t�@���m�ۂ���B
380      *	    ����: �I���W�i���̒����ANUL�A�h��(xtu)�A�⑫�ꉹ([aieuo])
381      */
382     max = len + 1 + 3 + 1;
383     buf = malloc(max);
384     if (buf == NULL)
385 	return;
386     memcpy(buf, query, len);
387     memset(&buf[len], 0, max - len);
388 
389     if (!strchr(VOWEL_CHARS, buf[len - 1]))
390     {
391 	add_dubious_vowels(object, buf, len);
392 	/* ���m��P��̒�����2�������A���m�蕶���̒��O���ꉹ�Ȃ�΁c */
393 	if (len < 2 || strchr(VOWEL_CHARS, buf[len - 2]))
394 	{
395 	    if (buf[len - 1] == 'n')
396 	    {
397 		/* �u��v�����Ă݂� */
398 		memcpy(&buf[len - 1], "xn", 2);
399 		add_roma(object, buf);
400 	    }
401 	    else
402 	    {
403 		/* �u��{���̎q��}{�ꉹ}�v�����Ă݂� */
404 		buf[len + 2] = buf[len - 1];
405 		memcpy(&buf[len - 1], "xtu", 3);
406 		add_dubious_vowels(object, buf, len + 3);
407 	    }
408 	}
409     }
410 
411     free(buf);
412 }
413 
414 /*
415  * query���߂ɕ�������B���߂̐؂�ڂ͒ʏ�A���t�@�x�b�g�̑啶���B���߂���
416  * �������̑啶���Ŏn�܂������߂͔�啶������؂�Ƃ���B
417  */
418     static wordlist_p
parse_query(migemo * object,const unsigned char * query)419 parse_query(migemo* object, const unsigned char* query)
420 {
421     const unsigned char *curr = query;
422     const unsigned char *start = NULL;
423     wordlist_p querylist = NULL, *pp = &querylist;
424 
425     while (1)
426     {
427 	int len, upper;
428         int sum = 0;
429 
430 	if (!object->char2int || (len = object->char2int(curr, NULL)) < 1)
431 	    len = 1;
432 	start = curr;
433 	upper = (len == 1 && isupper(*curr) && isupper(curr[1]));
434 	curr += len;
435         sum += len;
436 	while (1)
437 	{
438 	    if (!object->char2int || (len = object->char2int(curr, NULL)) < 1)
439 		len = 1;
440 	    if (*curr == '\0' || (len == 1 && (isupper(*curr) != 0) != upper))
441 		break;
442 	    curr += len;
443             sum += len;
444 	}
445 	/* ���߂�o�^���� */
446 	if (start && start < curr)
447 	{
448 	    *pp = wordlist_open_len(start, sum);
449 	    pp = &(*pp)->next;
450 	}
451 	if (*curr == '\0')
452 	    break;
453     }
454     return querylist;
455 }
456 
457 /*
458  * 1�‚̒P���migemo�ϊ��B�����̃`�F�b�N�͍s�Ȃ�Ȃ��B
459  */
460     static int
query_a_word(migemo * object,unsigned char * query)461 query_a_word(migemo* object, unsigned char* query)
462 {
463     unsigned char* zen;
464     unsigned char* han;
465     unsigned char* lower;
466     int len = my_strlen(query);
467 
468     /* query���M�͂��������ɉ����� */
469     object->addword(object, query);
470     /* query���̂��̂ł̎������� */
471     lower = malloc(len + 1);
472     if (!lower)
473 	add_mnode_query(object, query);
474     else
475     {
476 	int i = 0, step;
477 
478 	// MB���l�������啶�����������ϊ�
479 	while (i <= len)
480 	{
481 	    if (!object->char2int
482 		    || (step = object->char2int(&query[i], NULL)) < 1)
483 		step = 1;
484 	    if (step == 1 && isupper(query[i]))
485 		lower[i] = tolower(query[i]);
486 	    else
487 		memcpy(&lower[i], &query[i], step);
488 	    i += step;
489 	}
490 	add_mnode_query(object, lower);
491 	free(lower);
492     }
493 
494     /* query��S�p�ɂ��Č��ɉ����� */
495     zen = romaji_convert2(object->han2zen, query, NULL, 0);
496     if (zen != NULL)
497     {
498 	object->addword(object, zen);
499 	romaji_release(object->han2zen, zen);
500     }
501 
502     /* query���p�ɂ��Č��ɉ����� */
503     han = romaji_convert2(object->zen2han, query, NULL, 0);
504     if (han != NULL)
505     {
506 	object->addword(object, han);
507 	romaji_release(object->zen2han, han);
508     }
509 
510     /* �������A�J�^�J�i�A�y�т���ɂ�鎫�������lj� */
511     if (add_roma(object, query))
512 	add_dubious_roma(object, object->rx, query);
513 
514     return 1;
515 }
516 
517     static int
addword_rxgen(migemo * object,unsigned char * word)518 addword_rxgen(migemo* object, unsigned char* word)
519 {
520     /* ���K�\�������G���W���ɒlj����ꂽ�P���\������ */
521     /*printf("addword_rxgen: %s\n", word);*/
522     return rxgen_add(object->rx, word);
523 }
524 
525 /**
526  * query�ŗ^����ꂽ������(���[�}��)����{�ꌟ���̂��߂̐��K�\���֕ϊ�����B
527  * �߂�l�͕ϊ����ꂽ���ʂ̕�����(���K�\��)�ŁA�g�p���#migemo_release()�֐�
528  * �֓n�����Ƃʼn�����Ȃ���΂Ȃ�Ȃ��B
529  * @param object Migemo�I�u�W�F�N�g
530  * @param query �₢���킹������
531  * @returns ���K�\��������B#migemo_release() �ʼn������K�v�L��B
532  */
533     EXPORTS unsigned char* MIGEMO_CALLTYPE
migemo_query(migemo * object,const unsigned char * query)534 migemo_query(migemo* object, const unsigned char* query)
535 {
536     unsigned char *retval = NULL;
537     wordlist_p querylist = NULL;
538     wordbuf_p outbuf = NULL;
539 
540     if (object && object->rx && query)
541     {
542 	wordlist_p p;
543 
544 	querylist = parse_query(object, query);
545 	if (querylist == NULL)
546 	    goto MIGEMO_QUERY_END; /* ��query�̂��߃G���[ */
547 	outbuf = wordbuf_open();
548 	if (outbuf == NULL)
549 	    goto MIGEMO_QUERY_END; /* �o�͗p�̃������̈�s���̂��߃G���[ */
550 
551 	/* �P��Q��rxgen�I�u�W�F�N�g�ɓ��͂����K�\������ */
552 	object->addword = (MIGEMO_PROC_ADDWORD)addword_rxgen;
553 	rxgen_reset(object->rx);
554 	for (p = querylist; p; p = p->next)
555 	{
556 	    unsigned char* answer;
557 
558 	    /*printf("query=%s\n", p->ptr);*/
559 	    query_a_word(object, p->ptr);
560 	    /* �����p�^�[��(���K�\��)���� */
561 	    answer = rxgen_generate(object->rx);
562 	    rxgen_reset(object->rx);
563 	    wordbuf_cat(outbuf, answer);
564 	    rxgen_release(object->rx, answer);
565 	}
566     }
567 
568 MIGEMO_QUERY_END:
569     if (outbuf)
570     {
571 	retval = outbuf->buf;
572 	outbuf->buf = NULL;
573 	wordbuf_close(outbuf);
574     }
575     if (querylist)
576 	wordlist_close(querylist);
577 
578     return retval;
579 }
580 
581 /**
582  * �g���I�����migemo_query()�֐��œ���ꂽ���K�\�����������B
583  * @param p Migemo�I�u�W�F�N�g
584  * @param string ���K�\��������
585  */
586     EXPORTS void MIGEMO_CALLTYPE
migemo_release(migemo * p,unsigned char * string)587 migemo_release(migemo* p, unsigned char* string)
588 {
589     free(string);
590 }
591 
592 /**
593  * Migemo�I�u�W�F�N�g���������鐳�K�\���Ɏg�p���郁�^����(���Z�q)���w�肷
594  * ��Bindex�łǂ̃��^���������w�肵�Aop�Œu��������Bindex�ɂ͈ȉ��̒l���w
595  * ��”\�ł���:
596  *
597  *  <dl>
598  *  <dt>MIGEMO_OPINDEX_OR</dt>
599  *	<dd>�_���a�B�f�t�H���g�� "|" �Bvim�ŗ��p����ۂ� "\|" �B</dd>
600  *  <dt>MIGEMO_OPINDEX_NEST_IN</dt>
601  *	<dd>�O���[�s���O�ɗp����J�����ʁB�f�t�H���g�� "(" �Bvim�ł̓��W�X�^
602  *	\\1�`\\9�ɋL�������Ȃ��悤�ɂ��邽�߂� "\%(" ��p����BPerl�ł����l��
603  *	���Ƃ�ژ_�ނȂ�� "(?:" ���g�p�”\�B</dd>
604  *  <dt>MIGEMO_OPINDEX_NEST_OUT</dt>
605  *	<dd>�O���[�s���O�̏I����\���‚����ʁB�f�t�H���g�ł� ")" �Bvim�ł�
606  *	"\)" �B</dd>
607  *  <dt>MIGEMO_OPINDEX_SELECT_IN</dt>
608  *	<dd>�I���̊J�n��\���J���p���ʁB�f�t�H���g�ł� "[" �B</dd>
609  *  <dt>MIGEMO_OPINDEX_SELECT_OUT</dt>
610  *	<dd>�I���̏I����\���‚��p���ʁB�f�t�H���g�ł� "]" �B</dd>
611  *  <dt>MIGEMO_OPINDEX_NEWLINE</dt>
612  *	<dd>�e�����̊Ԃɑ}�������u0�ˆȏ�̋��������͉��s�Ƀ}�b�`����v
613  *	�p�^�[���B�f�t�H���g�ł� "" �ł���ݒ肳��Ȃ��Bvim�ł� "\_s*" ���w
614  *	�肷��B</dd>
615  *  </dl>
616  *
617  * �f�t�H���g�̃��^�����͓��ɒf�肪�Ȃ�����Perl�̂���Ɠ����Ӗ��ł���B�ݒ�
618  * �ɐ�������Ɩ߂�l��1(0�ȊO)�ƂȂ�A���s�����0�ɂȂ�B
619  * @param object Migemo�I�u�W�F�N�g
620  * @param index ���^�������ʎq
621  * @param op ���^����������
622  * @returns ������0�ȊO�A���s��0�B
623  */
624     EXPORTS int MIGEMO_CALLTYPE
migemo_set_operator(migemo * object,int index,const unsigned char * op)625 migemo_set_operator(migemo* object, int index, const unsigned char* op)
626 {
627     if (object)
628     {
629 	int retval = rxgen_set_operator(object->rx, index, op);
630 	return retval ? 0 : 1;
631     }
632     else
633 	return 0;
634 }
635 
636 /**
637  * Migemo�I�u�W�F�N�g���������鐳�K�\���Ɏg�p���Ă��郁�^����(���Z�q)���擾
638  * ����Bindex�ɂ‚��Ă�migemo_set_operator()�֐����Q�ƁB�߂�l�ɂ�index�̎w
639  * �肪��������΃��^�������i�[����������ւ̃|�C���^���A�s���ł����NULL��
640  * �Ԃ�B
641  * @param object Migemo�I�u�W�F�N�g
642  * @param index ���^�������ʎq
643  * @returns ���݂̃��^����������
644  */
645     EXPORTS const unsigned char* MIGEMO_CALLTYPE
migemo_get_operator(migemo * object,int index)646 migemo_get_operator(migemo* object, int index)
647 {
648     return object ? rxgen_get_operator(object->rx, index) : NULL;
649 }
650 
651 /**
652  * Migemo�I�u�W�F�N�g�ɃR�[�h�ϊ��p�̃v���V�[�W����ݒ肷��B�v���V�[�W����
653  * �‚��Ă̏ڍׂ́u�^���t�@�����X�v�Z�N�V������MIGEMO_PROC_CHAR2INT���Q�ƁB
654  * @param object Migemo�I�u�W�F�N�g
655  * @param proc �R�[�h�ϊ��p�v���V�[�W��
656  */
657     EXPORTS void MIGEMO_CALLTYPE
migemo_setproc_char2int(migemo * object,MIGEMO_PROC_CHAR2INT proc)658 migemo_setproc_char2int(migemo* object, MIGEMO_PROC_CHAR2INT proc)
659 {
660     if (object)
661 	rxgen_setproc_char2int(object->rx, (RXGEN_PROC_CHAR2INT)proc);
662 }
663 
664 /**
665  * Migemo�I�u�W�F�N�g�ɃR�[�h�ϊ��p�̃v���V�[�W����ݒ肷��B�v���V�[�W����
666  * �‚��Ă̏ڍׂ́u�^���t�@�����X�v�Z�N�V������MIGEMO_PROC_INT2CHAR���Q�ƁB
667  * @param object Migemo�I�u�W�F�N�g
668  * @param proc �R�[�h�ϊ��p�v���V�[�W��
669  */
670     EXPORTS void MIGEMO_CALLTYPE
migemo_setproc_int2char(migemo * object,MIGEMO_PROC_INT2CHAR proc)671 migemo_setproc_int2char(migemo* object, MIGEMO_PROC_INT2CHAR proc)
672 {
673     if (object)
674 	rxgen_setproc_int2char(object->rx, (RXGEN_PROC_INT2CHAR)proc);
675 }
676 
677 /**
678  * Migemo�I�u�W�F�N�g��migemo_dict���ǂݍ��߂Ă��邩���`�F�b�N����B�L����
679  * migemo_dict��ǂݍ��߂ē����ɕϊ��e�[�u�����\�z�ł��Ă����0�ȊO(TRUE)
680  * ���A�\�z�ł��Ă��Ȃ��Ƃ��ɂ�0(FALSE)��Ԃ��B
681  * @param obj Migemo�I�u�W�F�N�g
682  * @returns ������0�ȊO�A���s��0�B
683  */
684     EXPORTS int MIGEMO_CALLTYPE
migemo_is_enable(migemo * obj)685 migemo_is_enable(migemo* obj)
686 {
687     return obj ? obj->enable : 0;
688 }
689 
690 #if 1
691 /*
692  * ��Ƀf�o�b�O�p�̉B���֐�
693  */
694     EXPORTS void MIGEMO_CALLTYPE
migemo_print(migemo * object)695 migemo_print(migemo* object)
696 {
697     if (object)
698 	mnode_print(object->mtree, NULL);
699 }
700 #endif
701