1 /* # skkinput (Simple Kana-Kanji Input)
2 *
3 * This file is part of skkinput.
4 * Copyright (C) 2002
5 * Takashi SAKAMOTO (PXG01715@nifty.ne.jp)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with skkinput; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 #include "local.h"
22 #include "jisyop.h"
23 #include "cstring.h"
24
25 #define TEXTBUFSIZE (1024)
26
27 /*
28 * Private Prototypes
29 */
30 static Boolean skkJisyo_searchWithFileptr (KFILE*, const Char*, int, Boolean, TVarbuffer*) ;
31 static Boolean skkJisyo_tryCompletionWithFileptr (KFILE*, const Char*, int, TVarbuffer*) ;
32 static Boolean skkJisyo_okuriSearchWithFileptr (KFILE*, const Char* const, const int, TVarbuffer*) ;
33 static Boolean skkJisyo_okuriSearchCheckCandidate (KFILE*, const Char* const, const int, TVarbuffer*) ;
34 static Boolean skkJisyo_okuriSearchFound (KFILE*, const Char* const, const int, TVarbuffer*) ;
35
36 /*
37 * Global Variables
38 */
39 static PSKKJISYO pLocalJisyosTop = NULL ;
40
41 /*
42 * Functions
43 */
44
45 /*
46 * ���ꤵ�줿�ѥ��μ������ꤵ�줿ʸ����沽��ˡ�Ȥ�����Ͽ����ؿ���
47 */
48 PSKKJISYO
SkkJisyo_Register(register const Char * pFileName,register int nFileName,register int nCodingSystem)49 SkkJisyo_Register (
50 register const Char* pFileName,
51 register int nFileName,
52 register int nCodingSystem)
53 {
54 TCHAR strPath [PATH_MAX] ;
55 KFILE kf ;
56 PSKKJISYO pJisyo ;
57 PSKKJISYO pPrevJisyo ;
58 PSKKJISYO pNewJisyo ;
59 int nResult ;
60
61 /* ����ɽ����ʸ�����ºݤ� OS �� filesystem �˻ȤäƤ��� coding system ��
62 * ʸ������Ѵ����롣���� ASCII �������ܤˤʤäƤ��롣*/
63 cstrtostr (strPath, pFileName, (nFileName < PATH_MAX)? nFileName : PATH_MAX) ;
64 if (nFileName < PATH_MAX) {
65 strPath [nFileName] = '\0' ;
66 } else {
67 strPath [PATH_MAX - 1] = '\0' ;
68 }
69
70 /* ������Ͽ����Ƥ��뼭��Ǥ��뤫Ĵ�٤롣*/
71 pJisyo = pLocalJisyosTop ;
72 pPrevJisyo = NULL ;
73 while (pJisyo != NULL){
74 nResult = strcmp (pJisyo->m_tszPath, strPath) ;
75 if (!nResult)
76 return pJisyo ;
77 if (nResult > 0)
78 break ;
79 pPrevJisyo = pJisyo ;
80 pJisyo = pJisyo->m_pNext ;
81 }
82
83 /* ����ե������������뤿��Υǡ����ΰ����ݤ��롣*/
84 pNewJisyo = MALLOC (sizeof (SKKJISYO)) ;
85 if (pNewJisyo == NULL)
86 return NULL ;
87 strcpy (pNewJisyo->m_tszPath, strPath) ;
88
89 KFile_Init (&kf) ;
90 if (!KFile_Open (&kf, pNewJisyo->m_tszPath, KCODING_SYSTEM_UNKNOWN)) {
91 /* ����ե����뤬¸�ߤ��ʤ���С���Ͽ���뤳�ȤϽ���ʤ���*/
92 FREE (pNewJisyo) ;
93 return NULL ;
94 }
95 /* �����ʸ����沽��ˡ�Ф��롣*/
96 pNewJisyo->m_nCodingSystem = KFile_GetCodingSystem (&kf) ;
97 KFile_Close (&kf) ;
98
99 /* ���������ꥹ�Ȥ˲ä��롣*/
100 pNewJisyo->m_pNext = pJisyo ;
101 if (pPrevJisyo == NULL){
102 pLocalJisyosTop = pNewJisyo ;
103 } else {
104 pPrevJisyo->m_pNext = pNewJisyo ;
105 }
106 return pNewJisyo ;
107 }
108
109 /*
110 * ���ꤵ�줿�ѥ��μ����������ؿ���
111 */
112 Boolean
SkkJisyo_Unregister(register const Char * pFileName,register int nFileName)113 SkkJisyo_Unregister (
114 register const Char* pFileName,
115 register int nFileName)
116 {
117 TCHAR strPath [PATH_MAX] ;
118 PSKKJISYO pJisyo ;
119 PSKKJISYO pPrevJisyo ;
120 int nResult ;
121
122 /* ����ɽ����ʸ�����ºݤ� OS �� filesystem �˻ȤäƤ��� coding system ��
123 * ʸ������Ѵ����롣���� ASCII �������ܤˤʤäƤ��롣*/
124 cstrtostr (strPath, pFileName, (nFileName < PATH_MAX)? nFileName : PATH_MAX) ;
125 if (nFileName < PATH_MAX) {
126 strPath [nFileName] = '\0' ;
127 } else {
128 strPath [PATH_MAX - 1] = '\0' ;
129 }
130
131 pJisyo = pLocalJisyosTop ;
132 pPrevJisyo = NULL ;
133 while (pJisyo != NULL){
134 nResult = strcmp (pJisyo->m_tszPath, strPath) ;
135 if (!nResult){
136 if (pPrevJisyo != NULL){
137 pLocalJisyosTop = pJisyo->m_pNext ;
138 } else {
139 pPrevJisyo->m_pNext = pJisyo->m_pNext ;
140 }
141 FREE (pJisyo) ;
142 return True ;
143 }
144 if (nResult > 0)
145 return False ;
146 pPrevJisyo = pJisyo ;
147 pJisyo = pJisyo->m_pNext ;
148 }
149 return False ;
150 }
151
152 PSKKJISYO
SkkJisyo_Find(register const Char * pFileName,register int nFileName)153 SkkJisyo_Find (
154 register const Char* pFileName,
155 register int nFileName)
156 {
157 TCHAR strPath [PATH_MAX] ;
158 PSKKJISYO pJisyo ;
159 int nResult ;
160
161 /* ����ɽ����ʸ�����ºݤ� OS �� filesystem �˻ȤäƤ��� coding system ��
162 * ʸ������Ѵ����롣���� ASCII �������ܤˤʤäƤ��롣*/
163 cstrtostr (strPath, pFileName, (nFileName < PATH_MAX)? nFileName : PATH_MAX) ;
164 if (nFileName < PATH_MAX) {
165 strPath [nFileName] = '\0' ;
166 } else {
167 strPath [PATH_MAX - 1] = '\0' ;
168 }
169
170 pJisyo = pLocalJisyosTop ;
171 while (pJisyo != NULL){
172 nResult = strcmp (pJisyo->m_tszPath, strPath) ;
173 if (!nResult)
174 return pJisyo ;
175 if (nResult > 0)
176 return NULL ;
177 pJisyo = pJisyo->m_pNext ;
178 }
179 return NULL ;
180 }
181
182 /*
183 * Ϳ����줿�����ǥ桼�����������ؿ���
184 */
185 Boolean
SkkJisyo_Search(register PSKKJISYO pJisyo,register const Char * pKey,register int nKey,register Boolean fOkuri,register TVarbuffer * pvbuf)186 SkkJisyo_Search (
187 register PSKKJISYO pJisyo,
188 register const Char* pKey,
189 register int nKey,
190 register Boolean fOkuri,
191 register TVarbuffer* pvbuf)
192 {
193 KFILE kf ;
194 Boolean fResult ;
195
196 assert (pJisyo != NULL) ;
197 /* ������������ʤ��ä��顢���顼��*/
198 if (!KFile_Open (&kf, pJisyo->m_tszPath, pJisyo->m_nCodingSystem))
199 return False ;
200 fResult = skkJisyo_searchWithFileptr (&kf, pKey, nKey, fOkuri, pvbuf) ;
201 KFile_Close (&kf) ;
202 return fResult ;
203 }
204
205 Boolean
SkkJisyo_OkuriSearch(register PSKKJISYO pJisyo,register const Char * pStrKey,register int nStrKey,register TVarbuffer * pvbuf)206 SkkJisyo_OkuriSearch (
207 register PSKKJISYO pJisyo,
208 register const Char* pStrKey,
209 register int nStrKey,
210 register TVarbuffer* pvbuf)
211 {
212 KFILE kf ;
213 register Boolean fRetval ;
214
215 /* ������������ʤ��ä��顢���顼��*/
216 if (!KFile_Open (&kf, pJisyo->m_tszPath, pJisyo->m_nCodingSystem))
217 return False ;
218 fRetval = skkJisyo_okuriSearchWithFileptr (&kf, pStrKey, nStrKey, pvbuf) ;
219 KFile_Close (&kf) ;
220 return fRetval ;
221 }
222
223 /*
224 * Ϳ����줿�������䴰�Ǥ��ʤ����桼�����������ؿ���
225 */
226 Boolean
SkkJisyo_TryCompletion(register const Char * pFileName,register int nFileName,register const Char * pKey,register int nKey,register TVarbuffer * pvbuf)227 SkkJisyo_TryCompletion (
228 register const Char* pFileName,
229 register int nFileName,
230 register const Char* pKey,
231 register int nKey,
232 register TVarbuffer* pvbuf)
233 {
234 KFILE kf ;
235 PSKKJISYO pJisyo ;
236 Boolean fResult ;
237
238 pJisyo = SkkJisyo_Find (pFileName, nFileName) ;
239 if (pJisyo == NULL)
240 return False ;
241
242 if (!KFile_Open (&kf, pJisyo->m_tszPath, pJisyo->m_nCodingSystem))
243 return False ;
244 fResult = skkJisyo_tryCompletionWithFileptr (&kf, pKey, nKey, pvbuf) ;
245 KFile_Close (&kf) ;
246 return fResult ;
247 }
248
249 /*
250 * Private Functions
251 */
252
253 /*
254 * EUC-JP ��沽���줿�桼�����������Ϳ����줿ʸ�������
255 * �����Ѵ������õ���ؿ���
256 */
257 Boolean
skkJisyo_searchWithFileptr(register KFILE * pFile,register const Char * pKey,register int nKey,register Boolean fOkuri,register TVarbuffer * pvbuf)258 skkJisyo_searchWithFileptr (
259 register KFILE* pFile,
260 register const Char* pKey,
261 register int nKey,
262 register Boolean fOkuri,
263 register TVarbuffer* pvbuf)
264 {
265 Char szBuffer [TEXTBUFSIZE] ;
266 register const Char* ptr ;
267 register int nptr ;
268 register Char* pDest ;
269 register int nDest ;
270 register Char cc ;
271 register Boolean fFound ;
272
273 if (pFile == NULL || pKey == NULL || nKey <= 0 || Char_IsNul (*pKey))
274 return True ;
275
276 KFile_Rewind (pFile) ;
277 if (fOkuri){
278 KFile_FindsAtBeginningOfLineA (pFile, ";; okuri-ari entries.") ;
279 } else {
280 KFile_FindsAtBeginningOfLineA (pFile, ";; okuri-nasi entries.") ;
281 }
282 KFile_Nextline (pFile) ;
283
284 fFound = False ;
285 ptr = NULL ;
286 for ( ; ; ){
287 cc = KFile_Getc (pFile) ;
288 if (cc != ';') {
289 ptr = pKey ;
290 nptr = nKey ;
291 while (cc != EOF && cc != '\n' && cc != '\r' && nptr > 0) {
292 if (cc != *ptr)
293 break ;
294 cc = KFile_Getc (pFile) ;
295 ptr ++ ;
296 nptr -- ;
297 }
298 if (nptr == 0) {
299 if (cc == ' ') {
300 /* ���ξ��ˤϸ���ʸ���ҥåȤ������Ȥˤʤ롣*/
301 fFound = TRUE ;
302 break ;
303 }
304 }
305 } else {
306 register const char* aptr ;
307
308 /* �⤷�����ơ����겾̾���ꥨ��ȥ�ޤ���Ƥ��ޤä��Τ���*/
309 aptr = (fOkuri)? ";; okuri-nasi entries." : ";; okuri-ari entries." ;
310 while (*aptr != '\0' && !Char_DifferenceAscii (cc, *aptr)) {
311 aptr ++ ;
312 cc = KFile_Getc (pFile) ;
313 }
314 /* ����ʾ�Υ���ȥ�����뤳�Ȥ�̵����*/
315 if (*aptr == '\0' && cc == '\n')
316 cc = EOF ;
317 }
318 /* ��Ƭ�ޤ��ɤ����Ф���*/
319 while (cc != EOF && cc != '\n' && cc != '\r')
320 cc = KFile_Getc (pFile) ;
321 /* �ե�����κǸ����Ƥ������ˤϸ������롣*/
322 if (cc == EOF)
323 break ;
324 }
325 /* ���Ĥ���ʤ��ä����ˤϲ��⤷�ʤ���*/
326 if (TFAILED (fFound))
327 return True ;
328
329 while (cc = KFile_Getc (pFile), cc == ' ')
330 ;
331
332 /* �Ĥ��ʸ��������Ĺ�Хåե���á�����ࡣ*/
333 pDest = szBuffer ;
334 nDest = NELEMENTS (szBuffer) ;
335 while (cc != EOF && cc != '\n' && cc != '\r') {
336 if (nDest == 0) {
337 TVarbuffer_Add (pvbuf, szBuffer, NELEMENTS (szBuffer)) ;
338 pDest = szBuffer ;
339 nDest = NELEMENTS (szBuffer) ;
340 }
341 *pDest ++ = cc ;
342 nDest -- ;
343 cc = KFile_Getc (pFile) ;
344 }
345 if (nDest != NELEMENTS (szBuffer))
346 TVarbuffer_Add (pvbuf, szBuffer, NELEMENTS (szBuffer) - nDest) ;
347 return True ;
348 }
349
350 Boolean
skkJisyo_tryCompletionWithFileptr(register KFILE * pFile,register const Char * pKey,register int nKey,register TVarbuffer * pvbuf)351 skkJisyo_tryCompletionWithFileptr (
352 register KFILE* pFile,
353 register const Char* pKey,
354 register int nKey,
355 register TVarbuffer* pvbuf)
356 {
357 register const Char* ptr ;
358 register int nptr ;
359 Char cc ;
360 register Boolean fFound ;
361
362 if (pFile == NULL || pKey == NULL || nKey <= 0 || Char_IsNul (*pKey))
363 return True ;
364
365 KFile_Rewind (pFile) ;
366 KFile_FindsAtBeginningOfLineA (pFile, ";; okuri-nasi entries.") ;
367 fFound = False ;
368 for ( ; ; ) {
369 /* ���ΰ��֤ǤϹ�Ƭ����Ƥ����Τȹͤ��롣*/
370 ptr = pKey ;
371 nptr = nKey ;
372 cc = KFile_Getc (pFile) ;
373 if (cc != ';'){
374 while (cc != EOF && cc != '\n' && cc != '\r' && nptr > 0) {
375 if (*ptr != cc)
376 break ;
377 ptr ++ ;
378 nptr -- ;
379 cc = KFile_Getc (pFile) ;
380 }
381 if (nptr == 0 && cc != EOF && cc != '\n' && cc != '\r') {
382 static const Char chSLASH = '/' ;
383 if (!fFound){
384 TVarbuffer_Add (pvbuf, &chSLASH, 1) ;
385 TVarbuffer_Add (pvbuf, pKey, nKey) ;
386 fFound = True ;
387 } else {
388 TVarbuffer_Add (pvbuf, pKey, nKey) ;
389 }
390 /* ���ξ��ˤϸ���ʸ���ҥåȤ������Ȥˤʤ롣*/
391 while (cc != EOF && cc != '\n' && cc != '\r' && cc != ' ') {
392 TVarbuffer_Add (pvbuf, &cc, 1) ;
393 cc = KFile_Getc (pFile) ;
394 }
395 TVarbuffer_Add (pvbuf, &chSLASH, 1) ;
396 }
397 } else {
398 register const char* aptr = ";; okuri-ari entries." ;
399
400 /* �⤷�����ơ����겾̾���ꥨ��ȥ�ޤ���Ƥ��ޤä��Τ���*/
401 while (*aptr != '\0' && !Char_DifferenceAscii (cc, *aptr)) {
402 aptr ++ ;
403 cc = KFile_Getc (pFile) ;
404 }
405 /* ����ʾ�Υ���ȥ�����뤳�Ȥ�̵����*/
406 if (*aptr == '\0' && cc == '\n')
407 cc = EOF ;
408 }
409 /* ��Ƭ�ޤ��ɤ����Ф���*/
410 while (cc != EOF && cc != '\n' && cc != '\r')
411 cc = KFile_Getc (pFile) ;
412 /* �ե�����κǸ����Ƥ������ˤϸ������롣*/
413 if (cc == EOF)
414 break ;
415 }
416 return True ;
417 }
418
419 Boolean
skkJisyo_okuriSearchWithFileptr(register KFILE * pFile,register const Char * const pStrKey,register const int nStrKey,register TVarbuffer * pvbuf)420 skkJisyo_okuriSearchWithFileptr (
421 register KFILE* pFile,
422 register const Char* const pStrKey,
423 register const int nStrKey,
424 register TVarbuffer* pvbuf)
425 {
426 register Char cc ;
427 register int nCount ;
428 register const Char* ptr ;
429 register int nptr ;
430
431 KFile_Rewind (pFile) ;
432 KFile_FindsAtBeginningOfLineA (pFile, ";; okuri-ari entries.") ;
433 while (cc = KFile_Getc (pFile), cc != EOF) {
434 if (cc != ';') {
435 /* �Ѵ������Ȳ���ޤǰ��פ��뤫��Ĵ�٤롣*/
436 ptr = pStrKey ;
437 nptr = nStrKey ;
438 while (cc == *ptr && cc != ' ' && nptr > 0) {
439 cc = KFile_Getc (pFile) ;
440 ptr ++ ;
441 nptr -- ;
442 }
443 /* ���פˤʤäƤ������(��������Ͽ����Ƥ������ζ���ʸ��
444 * �ޤDz�ʸ�����뤫��Ĵ�٤롣*/
445 nCount = 0 ;
446 while (cc != ' ' && cc != EOF && cc != '\n' && cc != '\r') {
447 cc = KFile_Getc (pFile) ;
448 nCount ++ ;
449 }
450 /* ����ʸ������1ʸ���Ǥ������� �Ȥ������Ȥϡ�``��r'' �Τ褦
451 * �ʥ����� ``��'' �ޤǰ��פ��Ƥ��뤳�Ȥ��̣���Ƥ��롣*/
452 if (nCount == 1 && cc == ' ') {
453 if (TFAILED (skkJisyo_okuriSearchCheckCandidate (pFile, ptr, nptr, pvbuf)))
454 return False ;
455 continue ;
456 }
457 } else {
458 register const char* aptr ;
459
460 /* �⤷�����ơ����겾̾���ꥨ��ȥ�ޤ���Ƥ��ޤä��Τ���*/
461 aptr = ";; okuri-nasi entries." ;
462 while (*aptr != '\0' && !Char_DifferenceAscii (cc, *aptr)) {
463 aptr ++ ;
464 cc = KFile_Getc (pFile) ;
465 }
466 /* ����ʾ�Υ���ȥ�����뤳�Ȥ�̵����*/
467 if (*aptr == '\0' && cc == '\n')
468 cc = EOF ;
469 }
470 while (cc != EOF && cc != '\n' && cc != '\r')
471 cc = KFile_Getc (pFile) ;
472 if (cc == EOF)
473 break ;
474 }
475 return True ;
476 }
477
478 Boolean
skkJisyo_okuriSearchCheckCandidate(register KFILE * pFile,register const Char * const pTail,register const int nTail,register TVarbuffer * pvbuf)479 skkJisyo_okuriSearchCheckCandidate (
480 register KFILE* pFile,
481 register const Char* const pTail,
482 register const int nTail,
483 register TVarbuffer* pvbuf)
484 {
485 register Char cc ;
486 register const Char* ptr ;
487 register int nptr ;
488
489 for ( ; ; ) {
490 ptr = pTail ;
491 nptr = nTail ;
492 do {
493 cc = KFile_Getc (pFile) ;
494 } while (cc != '[' && cc != EOF && cc != '\n' && cc != '\r') ;
495
496 if (cc != '[')
497 break ;
498
499 /* ``��Ӥ�s /�Ƥӽ�/�ƽ�/[��/�Ƥӽ�/�ƽ�/]/[��/�Ƥӽ�/�ƽ�/]/''
500 * �Τ褦�ʷ��ˤʤäƤ���Τǡ�``['' �μ���ʸ�����Ѵ������λĤ�
501 * �ȴ����˰��פ��Ƥ��뤫�ɤ�����Ƚ�ꤹ�롣*/
502 while (cc = KFile_Getc (pFile), cc != '/' && *ptr == cc && nptr > 0) {
503 ptr ++ ;
504 nptr -- ;
505 }
506 /* ���դ��ä����ɤ����� */
507 if (cc == '/')
508 return skkJisyo_okuriSearchFound (pFile, ptr, nptr, pvbuf) ;
509 }
510 /* �����⤷���ϥե�����κǸ�ޤ��ɤ����Ф�ɬ�פ����뤬�����ξ���������
511 * �Ƥ��롣(break �ξ�郎���������)
512 * while (cc != '[' && cc != EOF && cc != '\n' && cc != '\r')
513 * cc = KFile_Getc (pFile) ;
514 */
515 return True ;
516 }
517
518 Boolean
skkJisyo_okuriSearchFound(register KFILE * pFile,register const Char * const pOkuri,register const int nOkuri,register TVarbuffer * pvbuf)519 skkJisyo_okuriSearchFound (
520 register KFILE* pFile,
521 register const Char* const pOkuri,
522 register const int nOkuri,
523 register TVarbuffer* pvbuf)
524 {
525 register Char* pbuf ;
526 register int nbuf ;
527 register Char cc = '\0' ;
528 register int nUse ;
529 Char achBuf [256] ;
530
531 do {
532 pbuf = achBuf ;
533 nbuf = NELEMENTS (achBuf) ;
534 while (nbuf > 0) {
535 cc = KFile_Getc (pFile) ;
536 if (cc == '/' || cc == '[' || cc == EOF || cc == '\n' || cc == '\r')
537 break ;
538 *pbuf ++ = cc ;
539 nbuf -- ;
540 }
541 nUse = NELEMENTS (achBuf) - nbuf ;
542 if (nUse > 0) {
543 if (TFAILED (TVarbuffer_Add (pvbuf, achBuf, nUse)) ||
544 TFAILED (TVarbuffer_Add (pvbuf, pOkuri, nOkuri)))
545 return False ;
546 }
547 } while (cc != '[' && cc != EOF && cc != '\n' && cc != '\r') ;
548
549 while (cc != EOF && cc != '\n' && cc != '\r')
550 cc = KFile_Getc (pFile) ;
551 return True ;
552 }
553
554