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 <assert.h>
24 #include "lispmgrp.h"
25
26 #define lispEntity_GetLongPtr(ptr) ((long *)((TLispEntity *)(ptr) + 1))
27 #define lispEntity_GetFloatPtr(ptr) ((float *)((TLispEntity *)(ptr) + 1))
28
29 static Boolean lispMgr_searchInteger (TLispManager*, long, TLispEntity** const) ;
30 static Boolean lispMgr_registerInteger (TLispManager*, TLispEntity*) ;
31 static Boolean lispMgr_unregisterInteger (TLispManager*, TLispEntity*) ;
32 static Boolean lispMgr_collectIntegerGarbage (TLispManager*, TLispEntity*) ;
33 static Boolean lispMgr_mathCompareNumber (TLispManager*, TLispEntity*, TLispEntity*, Boolean (*)(TLispNumber*,TLispNumber*), Boolean*) ;
34 static Boolean lispMgr_mathTestGreaterThan (TLispNumber*, TLispNumber*) ;
35 static Boolean lispMgr_mathTestGreaterEqual(TLispNumber*, TLispNumber*) ;
36 static Boolean lispMgr_mathTestLessThan (TLispNumber*, TLispNumber*) ;
37 static Boolean lispMgr_mathTestLessEqual (TLispNumber*, TLispNumber*) ;
38 static Boolean lispMgr_mathTestEqual (TLispNumber*, TLispNumber*) ;
39
40 /* inline functions */
41 inline int
lispMgr_createIntegerHashkey(register long lValue)42 lispMgr_createIntegerHashkey (register long lValue)
43 {
44 #if defined (DEBUG)
45 int iRetval = ((unsigned)lValue) % LISPMGR_SIZE_INTEGER_HASH ;
46 assert (0 <= iRetval && iRetval < LISPMGR_SIZE_INTEGER_HASH) ;
47 return iRetval ;
48 #else
49 return ((unsigned)lValue) % LISPMGR_SIZE_INTEGER_HASH ;
50 #endif
51 }
52
53
54 /* global functions */
55 Boolean
lispMgr_CreateInteger(register TLispManager * pLispMgr,register long lValue,register TLispEntity ** const ppEntReturn)56 lispMgr_CreateInteger (
57 register TLispManager* pLispMgr,
58 register long lValue,
59 register TLispEntity** const ppEntReturn)
60 {
61 TLispEntity* pEntity ;
62
63 assert (pLispMgr != NULL) ;
64 assert (ppEntReturn != NULL) ;
65
66 #if defined (DEBUG_LV99)
67 fprintf (stderr, "Garbage collecting ...") ;
68 fflush (stderr) ;
69 lispMgr_CollectGarbage (pLispMgr) ;
70 fprintf (stderr, "done.\n") ;
71 #endif
72 if (TFAILED (lispMgr_searchInteger (pLispMgr, lValue, &pEntity)))
73 return False ;
74
75 if (pEntity == NULL) {
76 register long* plValue ;
77
78 if (TFAILED (lispMgr_AllocateEntity (pLispMgr, sizeof (long), &pEntity)))
79 return False ;
80
81 pEntity->m_iType = LISPENTITY_INTEGER ;
82 plValue = lispEntity_GetLongPtr (pEntity) ;
83 *plValue = lValue ;
84 lispMgr_registerInteger (pLispMgr, pEntity) ;
85 }
86
87 *ppEntReturn = pEntity ;
88 return True ;
89 }
90
91 Boolean
lispMgr_CreateFloat(register TLispManager * pLispMgr,register float fValue,register TLispEntity ** const ppEntReturn)92 lispMgr_CreateFloat (
93 register TLispManager* pLispMgr,
94 register float fValue,
95 register TLispEntity** const ppEntReturn)
96 {
97 TLispEntity* pEntity ;
98 register float* pfValue ;
99
100 assert (pLispMgr != NULL) ;
101 assert (ppEntReturn != NULL) ;
102
103 #if defined (DEBUG_LV99)
104 fprintf (stderr, "Garbage collecting ...") ;
105 fflush (stderr) ;
106 lispMgr_CollectGarbage (pLispMgr) ;
107 fprintf (stderr, "done.\n") ;
108 #endif
109 if (TFAILED (lispMgr_AllocateEntity (pLispMgr, sizeof (float), &pEntity)))
110 return False ;
111
112 pEntity->m_iType = LISPENTITY_FLOAT ;
113 pEntity->m_lReferCount = 0 ; /* ����ľ��ϻ��ȥ����� 0��*/
114 pfValue = lispEntity_GetFloatPtr (pEntity) ;
115 *pfValue = fValue ;
116 lispMgr_RegisterMisc (pLispMgr, pEntity) ;
117 *ppEntReturn = pEntity ;
118 return True ;
119 }
120
121 Boolean
lispMgr_CollectIntegerGarbage(register TLispManager * pLispMgr)122 lispMgr_CollectIntegerGarbage (
123 register TLispManager* pLispMgr)
124 {
125 register int i ;
126
127 for (i = 0 ; i < LISPMGR_SIZE_INTEGER_HASH ; i ++)
128 lispMgr_collectIntegerGarbage (pLispMgr, pLispMgr->m_apIntegerListTop [i]) ;
129 return True ;
130 }
131
132 Boolean
lispMgr_MathGreaterThan(register TLispManager * pLispMgr,register TLispEntity * pNum1,register TLispEntity * pNum2,register Boolean * pfResult)133 lispMgr_MathGreaterThan (
134 register TLispManager* pLispMgr,
135 register TLispEntity* pNum1,
136 register TLispEntity* pNum2,
137 register Boolean* pfResult)
138 {
139 return lispMgr_mathCompareNumber (pLispMgr, pNum1, pNum2, &lispMgr_mathTestGreaterThan, pfResult) ;
140 }
141
142 Boolean
lispMgr_MathGreaterEqual(register TLispManager * pLispMgr,register TLispEntity * pNum1,register TLispEntity * pNum2,register Boolean * pfResult)143 lispMgr_MathGreaterEqual (
144 register TLispManager* pLispMgr,
145 register TLispEntity* pNum1,
146 register TLispEntity* pNum2,
147 register Boolean* pfResult)
148 {
149 return lispMgr_mathCompareNumber (pLispMgr, pNum1, pNum2, &lispMgr_mathTestGreaterEqual, pfResult) ;
150 }
151
152 Boolean
lispMgr_MathLessThan(register TLispManager * pLispMgr,register TLispEntity * pNum1,register TLispEntity * pNum2,register Boolean * pfResult)153 lispMgr_MathLessThan (
154 register TLispManager* pLispMgr,
155 register TLispEntity* pNum1,
156 register TLispEntity* pNum2,
157 register Boolean* pfResult)
158 {
159 return lispMgr_mathCompareNumber (pLispMgr, pNum1, pNum2, &lispMgr_mathTestLessThan, pfResult) ;
160 }
161
162 Boolean
lispMgr_MathLessEqual(register TLispManager * pLispMgr,register TLispEntity * pNum1,register TLispEntity * pNum2,register Boolean * pfResult)163 lispMgr_MathLessEqual (
164 register TLispManager* pLispMgr,
165 register TLispEntity* pNum1,
166 register TLispEntity* pNum2,
167 register Boolean* pfResult)
168 {
169 return lispMgr_mathCompareNumber (pLispMgr, pNum1, pNum2, &lispMgr_mathTestLessEqual, pfResult) ;
170 }
171
172 Boolean
lispMgr_MathEqual(register TLispManager * pLispMgr,register TLispEntity * pNum1,register TLispEntity * pNum2,register Boolean * pfResult)173 lispMgr_MathEqual (
174 register TLispManager* pLispMgr,
175 register TLispEntity* pNum1,
176 register TLispEntity* pNum2,
177 register Boolean* pfResult)
178 {
179 return lispMgr_mathCompareNumber (pLispMgr, pNum1, pNum2, &lispMgr_mathTestEqual, pfResult) ;
180 }
181
182 /*
183 * private functions
184 */
185 Boolean
lispMgr_searchInteger(register TLispManager * pLispMgr,register long lSearchKey,register TLispEntity ** const ppEntReturn)186 lispMgr_searchInteger (
187 register TLispManager* pLispMgr,
188 register long lSearchKey,
189 register TLispEntity** const ppEntReturn)
190 {
191 register TLispEntity* pEntity ;
192 register long* plValue ;
193 register int iHashkey ;
194
195 assert (pLispMgr != NULL) ;
196 assert (ppEntReturn != NULL) ;
197
198 iHashkey = lispMgr_createIntegerHashkey (lSearchKey) ;
199 pEntity = pLispMgr->m_apIntegerListTop [iHashkey] ;
200
201 while (pEntity != NULL) {
202 assert (pEntity->m_iType == LISPENTITY_INTEGER) ;
203 plValue = lispEntity_GetLongPtr (pEntity) ;
204 if (*plValue == lSearchKey) {
205 *ppEntReturn = pEntity ;
206 return True ;
207 }
208 if (*plValue > lSearchKey)
209 break ;
210 pEntity = pEntity->m_pRight ;
211 }
212 *ppEntReturn = NULL ;
213 return True ;
214 }
215
216 Boolean
lispMgr_registerInteger(register TLispManager * pLispMgr,register TLispEntity * pNewEntity)217 lispMgr_registerInteger (
218 register TLispManager* pLispMgr,
219 register TLispEntity* pNewEntity)
220 {
221 register const long* plValue ;
222 register long lNewValue ;
223 register int iHashkey ;
224 register TLispEntity* pPrevEntity ;
225 register TLispEntity* pNextEntity ;
226
227 assert (pLispMgr != NULL) ;
228 assert (pNewEntity != NULL) ;
229 assert (pNewEntity->m_iType == LISPENTITY_INTEGER) ;
230
231 plValue = lispEntity_GetLongPtr (pNewEntity) ;
232 lNewValue = *plValue ;
233 iHashkey = lispMgr_createIntegerHashkey (lNewValue) ;
234
235 pNextEntity = pLispMgr->m_apIntegerListTop [iHashkey] ;
236 pPrevEntity = NULL ;
237 while (pNextEntity != NULL) {
238 assert (pNextEntity->m_iType == LISPENTITY_INTEGER) ;
239
240 plValue = lispEntity_GetLongPtr (pNextEntity) ;
241 if (*plValue > lNewValue)
242 break ;
243
244 pPrevEntity = pNextEntity ;
245 pNextEntity = pNextEntity->m_pRight ;
246 }
247
248 if (pPrevEntity == NULL) {
249 pLispMgr->m_apIntegerListTop [iHashkey] = pNewEntity ;
250 } else {
251 pPrevEntity->m_pRight = pNewEntity ;
252 }
253 if (pNextEntity != NULL) {
254 pNextEntity->m_pLeft = pNewEntity ;
255 }
256
257 pNewEntity->m_pLeft = pPrevEntity ;
258 pNewEntity->m_pRight = pNextEntity ;
259
260 return True ;
261 }
262
263
264 Boolean
lispMgr_unregisterInteger(register TLispManager * pLispMgr,register TLispEntity * pEntity)265 lispMgr_unregisterInteger (
266 register TLispManager* pLispMgr,
267 register TLispEntity* pEntity)
268 {
269 assert (pLispMgr != NULL) ;
270 assert (pEntity != NULL) ;
271 assert (pEntity->m_iType == LISPENTITY_INTEGER) ;
272
273 if (pEntity->m_pLeft != NULL) {
274 pEntity->m_pLeft->m_pRight = pEntity->m_pRight ;
275 } else {
276 register const long* plValue ;
277 register int iHashkey ;
278
279 plValue = lispEntity_GetLongPtr (pEntity) ;
280 iHashkey = lispMgr_createIntegerHashkey (*plValue) ;
281 assert (pLispMgr->m_apIntegerListTop [iHashkey] == pEntity) ;
282 pLispMgr->m_apIntegerListTop [iHashkey] = pEntity->m_pRight ;
283 }
284
285 if (pEntity->m_pRight != NULL) {
286 pEntity->m_pRight->m_pLeft = pEntity->m_pLeft ;
287 }
288
289 pEntity->m_pLeft = NULL ;
290 pEntity->m_pRight = NULL ;
291
292 return True ;
293 }
294
295 Boolean
lispMgr_collectIntegerGarbage(register TLispManager * pLispMgr,register TLispEntity * pEntity)296 lispMgr_collectIntegerGarbage (
297 register TLispManager* pLispMgr,
298 register TLispEntity* pEntity)
299 {
300 register TLispEntity* pNextEntity ;
301
302 assert (pLispMgr != NULL) ;
303
304 while (pEntity != NULL) {
305 assert (pEntity != NULL) ;
306 assert (pEntity->m_iType == LISPENTITY_INTEGER) ;
307
308 pNextEntity = pEntity->m_pRight ;
309
310 if (pEntity->m_lReferCount == 0 && pEntity->m_iMarker != pLispMgr->m_iMarker) {
311 lispMgr_unregisterInteger (pLispMgr, pEntity) ;
312 lispMgr_DestroyEntity (pLispMgr, pEntity) ;
313 } else {
314 pEntity->m_iMarker = pLispMgr->m_iMarker ;
315 }
316 pEntity = pNextEntity ;
317 }
318 return True ;
319 }
320
321 Boolean
lispMgr_mathCompareNumber(register TLispManager * pLispMgr,register TLispEntity * pNum1,register TLispEntity * pNum2,register Boolean (* pCompFunc)(TLispNumber *,TLispNumber *),register Boolean * pfResult)322 lispMgr_mathCompareNumber (
323 register TLispManager* pLispMgr,
324 register TLispEntity* pNum1,
325 register TLispEntity* pNum2,
326 register Boolean (*pCompFunc)(TLispNumber*,TLispNumber*),
327 register Boolean* pfResult)
328 {
329 TLispNumber num1, num2 ;
330
331 if (TFAILED (lispEntity_GetNumberValueOrMarkerPosition (pLispMgr, pNum1, &num1)) ||
332 TFAILED (lispEntity_GetNumberValueOrMarkerPosition (pLispMgr, pNum2, &num2)))
333 return False ;
334 *pfResult = (*pCompFunc)(&num1, &num2) ;
335 return True ;
336 }
337
338 Boolean
lispMgr_mathTestGreaterThan(register TLispNumber * pNum1,register TLispNumber * pNum2)339 lispMgr_mathTestGreaterThan (
340 register TLispNumber* pNum1,
341 register TLispNumber* pNum2)
342 {
343 register Boolean fGreaterThan ;
344
345 if (pNum1->m_fFloatp) {
346 if (pNum2->m_fFloatp) {
347 fGreaterThan = (pNum1->m_Value.m_fFloat > pNum2->m_Value.m_fFloat) ;
348 } else {
349 fGreaterThan = (pNum1->m_Value.m_fFloat > pNum2->m_Value.m_lLong) ;
350 }
351 } else {
352 if (pNum2->m_fFloatp) {
353 fGreaterThan = (pNum1->m_Value.m_lLong > pNum2->m_Value.m_fFloat) ;
354 } else {
355 fGreaterThan = (pNum1->m_Value.m_lLong > pNum2->m_Value.m_lLong) ;
356 }
357 }
358 return fGreaterThan ;
359 }
360
361 Boolean
lispMgr_mathTestGreaterEqual(register TLispNumber * pNum1,register TLispNumber * pNum2)362 lispMgr_mathTestGreaterEqual (
363 register TLispNumber* pNum1,
364 register TLispNumber* pNum2)
365 {
366 register Boolean fGreaterEqual ;
367
368 if (pNum1->m_fFloatp) {
369 if (pNum2->m_fFloatp) {
370 fGreaterEqual = (pNum1->m_Value.m_fFloat >= pNum2->m_Value.m_fFloat) ;
371 } else {
372 fGreaterEqual = (pNum1->m_Value.m_fFloat >= pNum2->m_Value.m_lLong) ;
373 }
374 } else {
375 if (pNum2->m_fFloatp) {
376 fGreaterEqual = (pNum1->m_Value.m_lLong >= pNum2->m_Value.m_fFloat) ;
377 } else {
378 fGreaterEqual = (pNum1->m_Value.m_lLong >= pNum2->m_Value.m_lLong) ;
379 }
380 }
381 return fGreaterEqual ;
382 }
383
384 Boolean
lispMgr_mathTestLessThan(register TLispNumber * pNum1,register TLispNumber * pNum2)385 lispMgr_mathTestLessThan (
386 register TLispNumber* pNum1,
387 register TLispNumber* pNum2)
388 {
389 register Boolean fLessThan ;
390
391 if (pNum1->m_fFloatp) {
392 if (pNum2->m_fFloatp) {
393 fLessThan = (pNum1->m_Value.m_fFloat < pNum2->m_Value.m_fFloat) ;
394 } else {
395 fLessThan = (pNum1->m_Value.m_fFloat < pNum2->m_Value.m_lLong) ;
396 }
397 } else {
398 if (pNum2->m_fFloatp) {
399 fLessThan = (pNum1->m_Value.m_lLong < pNum2->m_Value.m_fFloat) ;
400 } else {
401 fLessThan = (pNum1->m_Value.m_lLong < pNum2->m_Value.m_lLong) ;
402 }
403 }
404 return fLessThan ;
405 }
406
407 Boolean
lispMgr_mathTestLessEqual(register TLispNumber * pNum1,register TLispNumber * pNum2)408 lispMgr_mathTestLessEqual (
409 register TLispNumber* pNum1,
410 register TLispNumber* pNum2)
411 {
412 register Boolean fLessEqual ;
413
414 if (pNum1->m_fFloatp) {
415 if (pNum2->m_fFloatp) {
416 fLessEqual = (pNum1->m_Value.m_fFloat <= pNum2->m_Value.m_fFloat) ;
417 } else {
418 fLessEqual = (pNum1->m_Value.m_fFloat <= pNum2->m_Value.m_lLong) ;
419 }
420 } else {
421 if (pNum2->m_fFloatp) {
422 fLessEqual = (pNum1->m_Value.m_lLong <= pNum2->m_Value.m_fFloat) ;
423 } else {
424 fLessEqual = (pNum1->m_Value.m_lLong <= pNum2->m_Value.m_lLong) ;
425 }
426 }
427 return fLessEqual ;
428 }
429
430 Boolean
lispMgr_mathTestEqual(register TLispNumber * pNum1,register TLispNumber * pNum2)431 lispMgr_mathTestEqual (
432 register TLispNumber* pNum1,
433 register TLispNumber* pNum2)
434 {
435 register Boolean fEqual ;
436
437 if (pNum1->m_fFloatp) {
438 if (pNum2->m_fFloatp) {
439 fEqual = (pNum1->m_Value.m_fFloat == pNum2->m_Value.m_fFloat) ;
440 } else {
441 fEqual = (pNum1->m_Value.m_fFloat == (float)pNum2->m_Value.m_lLong) ;
442 }
443 } else {
444 if (pNum2->m_fFloatp) {
445 fEqual = ((float)pNum1->m_Value.m_lLong == pNum2->m_Value.m_fFloat) ;
446 } else {
447 fEqual = (pNum1->m_Value.m_lLong == pNum2->m_Value.m_lLong) ;
448 }
449 }
450 return fEqual ;
451 }
452
453