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 <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <sys/time.h>
27 #include "lispmgrp.h"
28 #include "cstring.h"
29
30 static Boolean lispMgr_initialize (TLispManager*) ;
31 static Boolean lispMgr_collectOtherGarbage (TLispManager*, TLispEntity**) ;
32 static Boolean lispMgr_markEntityRecursively (TLispManager*, TLispEntity*) ;
33 static Boolean lispMgr_registerEntityToList (TLispManager*, TLispEntity**, TLispEntity*) ;
34
35 /* inline functions */
36 inline Boolean
lispMgr_markedEntityp(register TLispManager * pLispMgr,register TLispEntity * pEntity)37 lispMgr_markedEntityp (
38 register TLispManager* pLispMgr,
39 register TLispEntity* pEntity)
40 {
41 assert (pLispMgr != NULL) ;
42 assert (pEntity != NULL) ;
43
44 return (pEntity->m_iMarker == pLispMgr->m_iMarker)? True : False ;
45 }
46
47 inline Boolean
lispMgr_markEntity(register TLispManager * pLispMgr,register TLispEntity * pEntity)48 lispMgr_markEntity (
49 register TLispManager* pLispMgr,
50 register TLispEntity* pEntity)
51 {
52 assert (pLispMgr != NULL) ;
53 assert (pEntity != NULL) ;
54
55 pEntity->m_iMarker = pLispMgr->m_iMarker ;
56 return True ;
57 }
58
59 /* Ʊ̾/Ʊ�����Ǥ��äƤ� eq ��Ƚ��� nil ���֤� entity ��Ĥʤ���*/
60 static inline Boolean
lispMgr_registerEntityToList(register TLispManager * pLispMgr,register TLispEntity ** ppEntTop,register TLispEntity * pEntity)61 lispMgr_registerEntityToList (
62 register TLispManager* pLispMgr,
63 register TLispEntity** ppEntTop,
64 register TLispEntity* pEntity)
65 {
66 assert (pLispMgr != NULL) ;
67 assert (ppEntTop != NULL) ;
68 assert (pEntity != NULL) ;
69
70 pEntity->m_pRight = *ppEntTop ;
71 pEntity->m_pLeft = NULL ;
72 if (*ppEntTop != NULL)
73 (*ppEntTop)->m_pLeft = pEntity ;
74 *ppEntTop = pEntity ;
75 return True ;
76 }
77
78 static inline Boolean
lispMgr_unregisterEntityFromList(register TLispManager * pLispMgr,register TLispEntity ** ppEntTop,register TLispEntity * pEntity)79 lispMgr_unregisterEntityFromList (
80 register TLispManager* pLispMgr,
81 register TLispEntity** ppEntTop,
82 register TLispEntity* pEntity)
83 {
84 assert (pLispMgr != NULL) ;
85 assert (pEntity != NULL) ;
86
87 if (pEntity->m_pLeft != NULL) {
88 pEntity->m_pLeft->m_pRight = pEntity->m_pRight ;
89 } else {
90 assert (pEntity == *ppEntTop) ;
91 *ppEntTop = pEntity->m_pRight ;
92 }
93 if (pEntity->m_pRight != NULL)
94 pEntity->m_pRight->m_pLeft = pEntity->m_pLeft ;
95
96 pEntity->m_pRight = NULL ;
97 pEntity->m_pLeft = NULL ;
98
99 return True ;
100 }
101
102 /* global functions */
103 Boolean
TLispMgr_Create(register TLispManager ** const ppLispMgr)104 TLispMgr_Create (
105 register TLispManager** const ppLispMgr)
106 {
107 register TLispManager* pLispMgr ;
108 register int i ;
109
110 assert (ppLispMgr != NULL) ;
111
112 pLispMgr = MALLOC (sizeof (TLispManager)) ;
113 if (pLispMgr == NULL)
114 return False ;
115
116 for (i = 0 ; i < NELEMENTS (pLispMgr->m_apSymbolListTop) ; i ++)
117 pLispMgr->m_apSymbolListTop [i] = NULL ;
118 for (i = 0 ; i < NELEMENTS (pLispMgr->m_apIntegerListTop) ; i ++)
119 pLispMgr->m_apIntegerListTop [i] = NULL ;
120 for (i = 0 ; i < NELEMENTS (pLispMgr->m_apSubrListTop) ; i ++)
121 pLispMgr->m_apSubrListTop [i] = NULL ;
122 pLispMgr->m_pEntListNamedMutex = NULL ;
123 pLispMgr->m_pEntListNoNameMutex = NULL ;
124 pLispMgr->m_pEntMiscListTop = NULL ;
125 pLispMgr->m_pEntVoid = NULL ;
126 pLispMgr->m_pEntEmpty = NULL ;
127 for (i = 0 ; i < LISPMGR_SIZE_RESERVED ; i ++)
128 pLispMgr->m_apEntReserved [i] = NULL ;
129
130 if (TFAILED (TVarbuffer_Initialize (&pLispMgr->m_vbufLocalSymbol, sizeof (TLispEntity*))))
131 goto error ;
132 if (TFAILED (lispMgr_initialize (pLispMgr)))
133 goto error ;
134 *ppLispMgr = pLispMgr ;
135 return True ;
136
137 error:
138 FREE (pLispMgr) ;
139 return False ;
140 }
141
142 Boolean
TLispMgr_Destroy(register TLispManager * pLispMgr)143 TLispMgr_Destroy (
144 register TLispManager* pLispMgr)
145 {
146 /* �˴��λ���...*/
147 return False ;
148 }
149
150 /* ���Ȥ���Ƥ��ʤ� ENTITY ��������롣*/
151 Boolean
lispMgr_CollectGarbage(register TLispManager * pLispMgr)152 lispMgr_CollectGarbage (
153 register TLispManager* pLispMgr)
154 {
155 register TLispEntity* pEntity ;
156 #if defined (DEBUG) || 0
157 struct timeval start, end ;
158 long lEllapsed ;
159 gettimeofday (&start, NULL) ;
160 #endif
161
162 pLispMgr->m_iMarker ++ ;
163
164 /* ENTITY �λ��ȥ�������֤˸��ơ�ï����⻲�Ȥ���Ƥ��ʤ�¸�ߤ�
165 * �������롣
166 * ��������Vector �� Conscell �ˤ�äƻ��Ȥ���Ƥ�����ϻ��ȥ�����
167 * �����äƤ��ʤ��Τ���դ��뤳�ȡ�
168 * ���äơ�Vector �� Conscell ��õ���ƻ�����˥ޡ������Ƥ������Ȥ�
169 * ɬ�פȤʤ롣
170 */
171 pEntity = pLispMgr->m_pEntMiscListTop ;
172 while (pEntity != NULL) {
173 if (pEntity->m_lReferCount > 0)
174 lispMgr_markEntityRecursively (pLispMgr, pEntity) ;
175 pEntity = pEntity->m_pRight ;
176 }
177
178 lispMgr_CollectIntegerGarbage (pLispMgr) ;
179 /* ̾���դ� MUTEX �� GC ���оݤˤϷ褷�Ƥʤ�ʤ��������顢̾���դ�
180 * MUTEX ��ɤ�ɤ���������ȡ����������������ġ���դ��뤳
181 * �ȡ�*/
182 lispMgr_collectOtherGarbage (pLispMgr, &pLispMgr->m_pEntListNoNameMutex) ;
183 lispMgr_collectOtherGarbage (pLispMgr, &pLispMgr->m_pEntMiscListTop) ;
184
185 #if defined (DEBUG) && defined (WIN32)
186 fprintf (stderr, "GarbageCollect ... %ld ms\n", GetTickCount () - dwStart) ;
187 #endif
188 #if defined (DEBUG) || 0
189 gettimeofday (&end, NULL) ;
190 lEllapsed = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000 ;
191 fprintf (stderr, "GC (%ld msec)\n", lEllapsed) ;
192 #endif
193 return True ;
194 }
195
196 Boolean
lispMgr_UnregisterMisc(register TLispManager * pLispMgr,register TLispEntity * pEntity)197 lispMgr_UnregisterMisc (
198 register TLispManager* pLispMgr,
199 register TLispEntity* pEntity)
200 {
201 assert (pLispMgr != NULL) ;
202 assert (pEntity != NULL) ;
203 assert (0 < pEntity->m_iType && pEntity->m_iType < MAX_LISPENTITY_TYPE &&
204 pEntity->m_iType != LISPENTITY_INTEGER) ;
205
206 return lispMgr_unregisterEntityFromList (pLispMgr, &pLispMgr->m_pEntMiscListTop, pEntity) ;
207 }
208
209 Boolean
lispMgr_initialize(register TLispManager * pLispMgr)210 lispMgr_initialize (
211 register TLispManager* pLispMgr)
212 {
213 /* �졹����ľ���ʤ��ƺѤ�褦����Ͽ���Ƥ�����*/
214 static const char* apReservedSymbols [LISPMGR_SIZE_RESERVED] = {
215 "nil", "t", "-",
216 "lambda", "macro", "&optional",
217 "&rest", "keymap", "error",
218 "exit", "quit", "quit-flag",
219 "inhibit-quit", "features", "interactive",
220 "this-command", "last-command", "unread-command-events",
221 "pre-command-hook", "post-command-hook", "last-command-char",
222 "last-command-event", "unread-command-char", "global-map",
223 "minibuffer-local-map", "minor-mode-map-alist", "wrong-type-argument",
224 "buffer-file-name", "mode-line-format", "load-path",
225 "kill-ring", "kill-region", "kill-ring-yank-pointer",
226 "yank",
227
228 "coding-system-for-read", "coding-system-for-write", "euc-japan",
229 "euc-jp", "shift-jis", "japanese-shift-jis",
230 "sjis", "junet", "iso-2022-jp",
231 "iso-2022-jp-2", "ctext", "x-ctext",
232 "compound-text",
233
234 /* for skk */
235 "skk-server-host", "skk-server-list", "skk-portnum",
236 "skk-process-okuri-early", "j-henkan-key", "j-search-key",
237 "j-okuri-ari", "j-henkan-okurigana", "j-henkan-okuri-strictly",
238
239 /* for skk10 */
240 "skk-servers-list",
241 } ;
242 /* default �� buffer-local-symbol �Ȥ����Ѱդ���륷��ܥ롣
243 */
244 static int rnDefaultBufferSymbols [] = {
245 LISPMGR_INDEX_BUFFER_FILE_NAME,
246 } ;
247 register const char** pPtr ;
248 register int i ;
249 TLispEntity* pEntity ;
250 TLispEntity* pEntVoid ;
251 TLispEntity* pEntEmpty ;
252
253 pPtr = apReservedSymbols ;
254 for (i = 0 ; i < NELEMENTS (apReservedSymbols) ; i ++) {
255 if (TFAILED (lispMgr_InternSymbolA (pLispMgr, *pPtr, strlen (*pPtr), &pEntity)))
256 return False ;
257 lispEntity_AddRef (pLispMgr, pEntity) ;
258 pLispMgr->m_apEntReserved [i] = pEntity ;
259 pPtr ++ ;
260 }
261 if (TFAILED (lispMgr_CreateSymbolA (pLispMgr, "void", 4, &pEntVoid)))
262 return False ;
263 pEntVoid->m_iType = LISPENTITY_VOID ;
264 pLispMgr->m_pEntVoid = pEntVoid ;
265 lispEntity_AddRef (pLispMgr, pEntVoid) ;
266 if (TFAILED (lispMgr_CreateSymbolA (pLispMgr, "empty", 4, &pEntEmpty)))
267 return False ;
268 pEntEmpty->m_iType = LISPENTITY_EMPTY ;
269 pLispMgr->m_pEntEmpty = pEntEmpty ;
270
271 /* default �� buffer-local �ˤʤ� symbol ����Ͽ���Ƥ��������ߤΤȤ���
272 * buffer-file-name,
273 * �������ꤷ�Ƥ��롣
274 */
275 for (i = 0 ; i < NELEMENTS (rnDefaultBufferSymbols) ; i ++) {
276 pEntity = pLispMgr->m_apEntReserved [rnDefaultBufferSymbols [i]] ;
277 lispMgr_AddSymbolToLocalSymbols (pLispMgr, pEntity) ;
278 }
279 return True ;
280 }
281
282 Boolean
lispMgr_collectOtherGarbage(register TLispManager * pLispMgr,register TLispEntity ** ppEntTop)283 lispMgr_collectOtherGarbage (
284 register TLispManager* pLispMgr,
285 register TLispEntity** ppEntTop)
286 {
287 register TLispEntity* pNextEntity ;
288 register TLispEntity* pEntity ;
289
290 assert (pLispMgr != NULL) ;
291
292 pEntity = *ppEntTop ;
293 while (pEntity != NULL) {
294 pNextEntity = pEntity->m_pRight ;
295 if (pEntity->m_lReferCount == 0 &&
296 pEntity->m_iMarker != pLispMgr->m_iMarker) {
297 lispMgr_unregisterEntityFromList (pLispMgr, ppEntTop, pEntity) ;
298 lispMgr_DestroyEntity (pLispMgr, pEntity) ;
299 } else {
300 pEntity->m_iMarker = pLispMgr->m_iMarker ;
301 }
302 pEntity = pNextEntity ;
303 }
304 return True ;
305 }
306
307
308 Boolean
lispMgr_markEntityRecursively(register TLispManager * pLispMgr,register TLispEntity * pEntity)309 lispMgr_markEntityRecursively (
310 register TLispManager* pLispMgr,
311 register TLispEntity* pEntity)
312 {
313 lispMgr_markEntity (pLispMgr, pEntity) ;
314
315 switch (pEntity->m_iType) {
316 case LISPENTITY_CONSCELL:
317 {
318 TLispEntity* pCar ;
319 TLispEntity* pCdr ;
320
321 lispEntity_GetCar (pLispMgr, pEntity, &pCar) ;
322 lispEntity_GetCdr (pLispMgr, pEntity, &pCdr) ;
323 if (TFAILED (lispMgr_markedEntityp (pLispMgr, pCar)))
324 lispMgr_markEntityRecursively (pLispMgr, pCar) ;
325 if (TFAILED (lispMgr_markedEntityp (pLispMgr, pCdr)))
326 lispMgr_markEntityRecursively (pLispMgr, pCdr) ;
327 break ;
328 }
329
330 case LISPENTITY_VECTOR:
331 {
332 TLispEntity** ppElement ;
333 int nElement ;
334
335 lispEntity_GetVectorValue (pLispMgr, pEntity, &ppElement, &nElement) ;
336 while (nElement > 0) {
337 if (TFAILED (lispMgr_markedEntityp (pLispMgr, *ppElement)))
338 lispMgr_markEntityRecursively (pLispMgr, *ppElement) ;
339 ppElement ++ ;
340 nElement -- ;
341 }
342 break ;
343 }
344
345 default:
346 break ;
347 }
348 return True ;
349 }
350
351 #if defined (DEBUG)
352 void
lispMgr_CheckEntity(register TLispManager * pLispMgr,register TLispEntity * pEntity)353 lispMgr_CheckEntity (
354 register TLispManager* pLispMgr,
355 register TLispEntity* pEntity)
356 {
357 register TLispEntity* pNode ;
358
359 assert (pLispMgr != NULL) ;
360 assert (pEntity != NULL) ;
361
362 fprintf (stderr, " Searching: Entity(%p),Count(%ld),Type(%d) ...",
363 pEntity, pEntity->m_lReferCount, pEntity->m_iType) ;
364
365 switch (pEntity->m_iType) {
366 case LISPENTITY_INTEGER:
367 case LISPENTITY_SYMBOL:
368 fprintf (stderr, "not check\n") ;
369 break ;
370
371 default:
372 pNode = pLispMgr->m_pEntMiscListTop ;
373 while (pNode != NULL) {
374 if (pNode == pEntity) {
375 fprintf (stderr, "hit\n") ;
376 //lispMgr_CheckMark (pLispMgr, pEntity) ;
377 return ;
378 }
379 pNode = pNode->m_pRight ;
380 }
381 fprintf (stderr, "miss\n") ;
382 break ;
383 }
384 return ;
385 }
386
387 void
lispMgr_CheckMark(register TLispManager * pLispMgr,register TLispEntity * pEntity)388 lispMgr_CheckMark (
389 register TLispManager* pLispMgr,
390 register TLispEntity* pEntity)
391 {
392 register TLispEntity* pNode ;
393
394 if (pEntity->m_iType != 2)
395 return ;
396
397 fprintf (stderr, "Target(%p): Mark = %d -> ",
398 pEntity, pEntity->m_iMarker) ;
399 pLispMgr->m_iMarker ++ ;
400 pNode = pLispMgr->m_pEntMiscListTop ;
401 while (pNode != NULL) {
402 if (pNode->m_lReferCount > 0)
403 lispMgr_markEntityRecursively (pLispMgr, pNode) ;
404 pNode = pNode->m_pRight ;
405 }
406 fprintf (stderr, "%d/%d\n",
407 pEntity->m_iMarker, pLispMgr->m_iMarker) ;
408 return ;
409 }
410 #endif
411
412