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