1 /*
2  * $Id: yincoding.c,v 2.4.2.1 2000/08/04 05:37:07 kaneda Exp $
3  */
4 /*
5 WNN6 CLIENT LIBRARY--SOFTWARE LICENSE TERMS AND CONDITIONS
6 
7 
8 Wnn6 Client Library :
9 (C) Copyright OMRON Corporation.       1995,1998,2000 all rights reserved.
10 (C) Copyright OMRON Software Co., Ltd. 1995,1998,2000 all rights reserved.
11 
12 Wnn Software :
13 (C) Copyright Kyoto University Research Institute for Mathematical Sciences
14      1987, 1988, 1989, 1990, 1991, 1992, 1993
15 (C) Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1993
16 (C) Copyright ASCTEC, Inc.  1987, 1988, 1989, 1990, 1991, 1992, 1993
17 
18 Preamble
19 
20 These Wnn6 Client Library--Software License Terms and Conditions
21  (the "License Agreement") shall state the conditions under which you are
22  permitted to copy, distribute or modify the software which can be used
23  to create Wnn6 Client Library (the "Wnn6 Client Library").  The License
24  Agreement can be freely copied and distributed verbatim, however, you
25  shall NOT add, delete or change anything on the License Agreement.
26 
27 OMRON Corporation and OMRON Software Co., Ltd. (collectively referred to
28  as "OMRON") jointly developed the Wnn6 Software (development code name
29  is FI-Wnn), based on the Wnn Software.  Starting from November, 1st, 1998,
30  OMRON publishes the source code of the Wnn6 Client Library, and OMRON
31  permits anyone to copy, distribute or change the Wnn6 Client Library under
32  the License Agreement.
33 
34 Wnn6 Client Library is based on the original version of Wnn developed by
35  Kyoto University Research Institute for Mathematical Sciences (KURIMS),
36  OMRON Corporation and ASTEC Inc.
37 
38 Article 1.  Definition.
39 
40 "Source Code" means the embodiment of the computer code, readable and
41  understandable by a programmer of ordinary skills.  It includes related
42  source code level system documentation, comments and procedural code.
43 
44 "Object File" means a file, in substantially binary form, which is directly
45  executable by a computer after linking applicable files.
46 
47 "Library" means a file, composed of several Object Files, which is directly
48  executable by a computer after linking applicable files.
49 
50 "Software" means a set of Source Code including information on its use.
51 
52 "Wnn6 Client Library" the computer program, originally supplied by OMRON,
53  which can be used to create Wnn6 Client Library.
54 
55 "Executable Module" means a file, created after linking Object Files or
56  Library, which is directly executable by a computer.
57 
58 "User" means anyone who uses the Wnn6 Client Library under the License
59  Agreement.
60 
61 Article 2.  Copyright
62 
63 2.1  OMRON Corporation and OMRON Software Co., Ltd. jointly own the Wnn6
64  Client Library, including, without limitation, its copyright.
65 
66 2.2  Following words followed by the above copyright notices appear
67  in all supporting documentation of software based on Wnn6 Client Library:
68 
69   This software is based on the original version of Wnn6 Client Library
70   developed by OMRON Corporation and OMRON Software Co., Ltd. and also based on
71   the original version of Wnn developed by Kyoto University Research Institute
72   for Mathematical Sciences (KURIMS), OMRON Corporation and ASTEC Inc.
73 
74 Article 3.  Grant
75 
76 3.1  A User is permitted to make and distribute verbatim copies of
77  the Wnn6 Client Library, including verbatim of copies of the License
78  Agreement, under the License Agreement.
79 
80 3.2  A User is permitted to modify the Wnn6 Client Library to create
81  Software ("Modified Software") under the License Agreement.  A User
82  is also permitted to make or distribute copies of Modified Software,
83  including verbatim copies of the License Agreement with the following
84  information.  Upon modifying the Wnn6 Client Library, a User MUST insert
85  comments--stating the name of the User, the reason for the modifications,
86  the date of the modifications, additional terms and conditions on the
87  part of the modifications if there is any, and potential risks of using
88  the Modified Software if they are known--right after the end of the
89  License Agreement (or the last comment, if comments are inserted already).
90 
91 3.3  A User is permitted to create Library or Executable Modules by
92  modifying the Wnn6 Client Library in whole or in part under the License
93  Agreement.  A User is also permitted to make or distribute copies of
94  Library or Executable Modules with verbatim copies of the License
95  Agreement under the License Agreement.  Upon modifying the Wnn6 Client
96  Library for creating Library or Executable Modules, except for porting
97  a computer, a User MUST add a text file to a package of the Wnn6 Client
98  Library, providing information on the name of the User, the reason for
99  the modifications, the date of the modifications, additional terms and
100  conditions on the part of the modifications if there is any, and potential
101  risks associated with using the modified Wnn6 Client Library, Library or
102  Executable Modules if they are known.
103 
104 3.4  A User is permitted to incorporate the Wnn6 Client Library in whole
105  or in part into another Software, although its license terms and
106  conditions may be different from the License Agreement, if such
107  incorporation or use associated with the incorporation does NOT violate
108  the License Agreement.
109 
110 Article 4. Warranty
111 
112 THE WNN6 CLIENT LIBRARY IS PROVIDED BY OMRON ON AN "AS IS" BAISIS.
113   OMRON EXPRESSLY DISLCIAMS ANY AND ALL WRRANTIES, EXPRESS OR IMPLIED,
114  INCLUDING, WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY AND FITNESS
115  FOR A PARTICULAR PURPOSE, IN CONNECTION WITH THE WNN6 CLIENT LIBRARY
116  OR THE USE OR OTHER DEALING IN THE WNN6 CLIENT LIBRARY.  IN NO EVENT
117  SHALL OMRON BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, PUNITIVE
118  OR CONSEQUENTIAL DAMAGES OF ANY KIND WHATSOEVER IN CONNECTION WITH THE
119  WNN6 CLIENT LIBRARY OR THE USE OR OTHER DEALING IN THE WNN6 CLIENT
120 LIBRARY.
121 
122 ***************************************************************************
123 Wnn6 Client Library :
124 (C) Copyright OMRON Corporation.       1995,1998,2000 all rights reserved.
125 (C) Copyright OMRON Software Co., Ltd. 1995,1998,2000 all rights reserved.
126 
127 Wnn Software :
128 (C) Copyright Kyoto University Research Institute for Mathematical Sciences
129      1987, 1988, 1989, 1990, 1991, 1992, 1993
130 (C) Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1993
131 (C) Copyright ASCTEC, Inc.  1987, 1988, 1989, 1990, 1991, 1992, 1993
132 ***************************************************************************
133 
134 Comments on Modifications:
135 */
136 
137 /**  cWnn  Version 1.1	 **/
138 
139 #if defined(__DragonFly__)
140 #include <string.h>
141 #endif
142 
143 #include  <stdio.h>
144 #include  <ctype.h>
145 #include  "commonhd.h"
146 #ifdef CHINESE
147 #ifdef SYSVR2
148 #include  <string.h>
149 #endif
150 #ifdef BSD42
151 #include  <strings.h>
152 #endif
153 #include  "cplib.h"
154 #include  "rk_spclval.h"
155 #include  "jh.h"
156 #include  "wnn_string.h"
157 
158 extern char  *py_table[];
159 extern char  *zy_table[];
160 unsigned char last_mark;     /* Using to reme previous auto_state() */
161 
162 /* copied from old sstrings.c */
163 static int
cwnn_sStrcpy(c,w)164 cwnn_sStrcpy(c , w)
165 register unsigned char *c;
166 register w_char *w;
167 {
168     unsigned char *c0 = c;
169     for(;*w != 0 ; w++){
170 	if ((*w & 0x8080) == 0x8000) {
171 	    *c++ = 0x8f;
172 	    *c++ = (char)((*w & 0xff00) >> 8);
173 	    *c++ = (char)((*w & 0x007f) | 0x0080);
174 	} else {
175 	  if (*w & 0xff00)
176 	    *c++ = (char)((*w & 0xff00) >> 8);
177 	  else if (*w & 0x80)
178 	    *c++ = 0x8e;
179 	  *c++ = (char)(*w & 0x00ff);
180 	}
181     }
182     *c = '\0';
183     return (c - c0);
184 }
185 
186 
187 static int
cwnn_Sstrcpy(w,c)188 cwnn_Sstrcpy(w , c )
189 w_char *w;
190 unsigned char *c;
191 {
192     w_char *w0 = w;
193 
194     for(;*c;){
195 	if (*c & 0x80) {
196 	    if (*c == 0x8e) {
197 		c++;
198 		*w++ = (unsigned short)*c++;
199 	    } else if (*c == 0x8f) {
200 		c++;
201 		*w = (unsigned short)(*c++ << 8);
202 		*w++ |= (unsigned short)(*c++ & 0x7f);
203 	    } else {
204 		*w = (unsigned short)(*c++ << 8);
205 		*w++ |= (unsigned short)*c++;
206 	    }
207 	} else {
208 	    *w++ = (unsigned short)*c++;
209 	}
210     }
211     *w = 0;
212     return(w - w0);
213 }
214 
215 static int
cwnn_Sstrcat(w,c)216 cwnn_Sstrcat(w , c )
217 w_char *w;
218 unsigned char *c;
219 {
220     w_char *w0 = w;
221 
222     for ( ; *w; w++);
223 
224     for(;*c;){
225 	if (*c & 0x80) {
226 	    if (*c == 0x8e) {
227 		c++;
228 		*w++ = (unsigned short)*c++;
229 	    } else if (*c == 0x8f) {
230 		c++;
231 		*w = (unsigned short)(*c++ << 8);
232 		*w++ |= (unsigned short)(*c++ & 0x7f);
233 	    } else {
234 		*w = (unsigned short)(*c++ << 8);
235 		*w++ |= (unsigned short)*c++;
236 	    }
237 	} else {
238 	    *w++ = (unsigned short)*c++;
239 	}
240     }
241     *w = 0;
242     return(w - w0);
243 }
244 
245 /********** py_yunmu(), zy_yunmu(): if yuyin with YunMu, return YunMu's
246 	position in YunMu table. after that, you must calculate its
247 	real yun_raw static	   if without YunMu, return -1
248 ***********/
py_yunmu(yuyin)249 static int  py_yunmu(yuyin)
250 register char	*yuyin;
251 {
252 register int	i;
253   for ( i = (PY_NUM_YUNMU*5)- 1; i >= 0 ; i-- ){
254     if ( strncmp(yuyin, py_yunmu_tbl[i], strlen(py_yunmu_tbl[i])) == 0 )
255 	return(i);
256     }
257   return(-1);
258 }
259 
zy_yunmu(yuyin)260 static int  zy_yunmu(yuyin)
261 register char	*yuyin;
262 {
263 register int	i;
264   for ( i = (ZY_NUM_YUNMU*5)- 1; i >= 0 ; i-- ){
265     if ( strncmp(yuyin, zy_yunmu_tbl[i], strlen(zy_yunmu_tbl[i])) == 0 )
266 	return(i);
267     }
268   return(-1);
269 }
270 
271 /* is_pinyin():  if is PinYin with Shengmu,	return 1   */
272 /*		if is PinYin without Shengmu ,   return 0   */
273 /*		else			     	return -1  */
274 
is_pinyin(sheng_raw,yun_raw)275 static int is_pinyin(sheng_raw, yun_raw)
276 register int 	sheng_raw;
277 register int	yun_raw;
278 {
279 
280     	 if ( (sheng_raw >= 0) && (sheng_raw < PY_NUM_SHENGMU) &&
281 	     (yun_raw >= 0) && (yun_raw < PY_NUM_YUNMU)  &&
282 	     ( pinyin_tbl[sheng_raw * PY_NUM_YUNMU + yun_raw] == 1) )  {
283 		if ( sheng_raw == EMPTY_SHENG_RAW )
284 			return(0);
285 		else 	return(1);
286 		}
287     else return(-1);
288 
289 }
290 
291 /* is_zhuyin():  if is ZhuYin with Shengmu: 	return 1   */
292 /*               if is ZhuYin without Shengmu: 	return 0   */
293 /*				    	 else:	return -1  */
294 
is_zhuyin(sheng_raw,yun_raw)295 static int is_zhuyin(sheng_raw, yun_raw)
296 register int 	sheng_raw;
297 register int	yun_raw;
298 {
299 
300     if ( (sheng_raw >= 0) && (sheng_raw < ZY_NUM_SHENGMU) &&
301 	 (yun_raw >= 0) && (yun_raw < ZY_NUM_YUNMU)  &&
302 	 ((zhuyin_tbl[sheng_raw * ZY_NUM_YUNMU + yun_raw] & 0x8000) == 0x8000) )
303 	if ( sheng_raw == EMPTY_SHENG_RAW )
304 		return ( 0);
305 	else 	return(1);
306     return(-1);
307 }
308 /* py_shengmu(), zy_shengmu():
309 	if yuyin with ShengMu, return Shengmu's position
310  	in ShengMu table.  if without ShengMu, return -1
311 */
py_shengmu(yuyin)312 static int py_shengmu(yuyin)
313 register char	*yuyin;
314 {
315 register int	i;
316   for ( i = PY_NUM_SHENGMU - 1; i > 0;  i-- )  {
317     if ( strncmp(yuyin, py_shengmu_tbl[i], strlen(py_shengmu_tbl[i])) == 0 )
318 	return (i);
319   }
320   return ( -1);
321 }
322 
zy_shengmu(yuyin)323 static int zy_shengmu(yuyin)
324 register char	*yuyin;
325 {
326    register int	i;
327    for ( i = ZY_NUM_SHENGMU - 1; i > 0;  i-- )  {
328     if ( strncmp(yuyin, zy_shengmu_tbl[i], strlen(zy_shengmu_tbl[i])) == 0 )
329 	return (i);
330    }
331   return (-1);
332 }
333 
334 
335 /* create_yincod(): input:
336 	raw in ShengMu table of PinYin, raw in YunMu table of PinYin,
337   	sisheng	 output: yincod: if is PinYin, otherwise:0.
338 */
339 
340 static w_char
create_yincod(sheng_raw,yun_raw,ss)341 create_yincod(sheng_raw, yun_raw, ss)
342 register int	sheng_raw;
343 register int	yun_raw;
344 register int	ss;
345 {
346     int ret = 0;
347     if (is_pinyin(sheng_raw, yun_raw ) == 1)  		/*Has Shengmu*/
348  	ret = 0x0080 + (((yun_raw<<1)+0x20)<<8) +
349 			((sheng_raw-1)<<2) + 0x20;
350     else if (is_pinyin(sheng_raw, yun_raw ) == 0) 	/*Not Shengmu */
351 	ret = 0x0080 + (((yun_raw<<1)+0x20)<<8) +
352 			((X_SHENG_RAW-1)<<2) + 0x20;	/*Rent this */
353     else return(ret);
354     if ((ss>0)&&(ss<=4))
355     	ret += 0x0100 + ss - 1 ;
356     return(ret);
357 }
358 
359 /* pzy_yincod()
360 	in:     The param is expected to be a PinYin or a ZhuYin.
361 	return:  a Yin_code is returned, if it is a PinYin or a ZhuYin.
362 	otherwise, 0 is returned,
363 */
364 static int
pzy_get_sheng_yun(yuyin,ss,sheng_raw,yun_raw,which)365 pzy_get_sheng_yun(yuyin, ss, sheng_raw, yun_raw, which)
366 register char  *yuyin;          /* one PinYin or ZhuYin with end of character */
367 register int   *ss;        	/* get SiSheng from PinYin or ZhuYin */
368 register int   *sheng_raw;      /* position in ShengMu table */
369 int   *yun_raw;        /* position in YunMu table */
370 int which;
371 {
372 /*
373   register int     j;
374 */
375   register char    *pzytmp;
376 
377   *ss = -1;
378   *sheng_raw = -1;
379   *yun_raw = -1;
380 
381   pzytmp = yuyin;
382 
383     if ( which == CWNN_PINYIN ){	/* for Pinyin case */
384 
385   	if ((*sheng_raw = py_shengmu(pzytmp)) == -1 ) {  /* no ShengMu  */
386 	    if ( (*yun_raw = py_yunmu(pzytmp)) == -1 )
387 		return(0);
388 	    else  {
389 		pzytmp += strlen(py_yunmu_tbl[*yun_raw]);
390 		*sheng_raw = 0;
391 		*ss = *yun_raw % 5;
392 		*yun_raw = *yun_raw / 5;
393 		return(pzytmp - yuyin);
394 	    }
395   	} else { 		/* has ShengMu */
396 /*
397 	    for ( j = 0; (int)j < (int)strlen(py_shengmu_tbl[*sheng_raw]); j++)
398 		pzytmp++;
399 */
400 	    pzytmp += strlen(py_shengmu_tbl[*sheng_raw]);
401 	    if (strlen(pzytmp) == 0 )  return(0);
402 	    if ( (*yun_raw = py_yunmu(pzytmp)) != -1 ) {
403 		pzytmp += strlen(py_yunmu_tbl[*yun_raw]);
404 	    	*ss = *yun_raw % 5;
405 	    	*yun_raw = *yun_raw / 5;
406 	    	return(pzytmp - yuyin);
407 	    } else {
408 	   	   pzytmp = yuyin;
409 	   	   if ( (*yun_raw = py_yunmu(pzytmp)) == -1 )
410 			return(0);
411 	    	   else {
412 			pzytmp += strlen(py_yunmu_tbl[*yun_raw]);
413 			*sheng_raw = 0;
414 	    		*ss = *yun_raw % 5;
415 	    		*yun_raw = *yun_raw / 5;
416 	    		return(pzytmp - yuyin);
417 		   }
418 	    }
419   	}	/* has ShengMu when Pinyin*/
420     }
421     else {				/* for Zhuyin case */
422 
423   	if ((*sheng_raw = zy_shengmu(pzytmp)) == -1 ) {   /* no ShengMu  */
424 	    if ( (*yun_raw = zy_yunmu(pzytmp)) == -1 )
425 		return(0);
426 	    else  {
427 		pzytmp += strlen(zy_yunmu_tbl[*yun_raw]);
428 		*sheng_raw = 0;
429 		*ss = *yun_raw % 5;
430 		*yun_raw = *yun_raw / 5;
431 		return(pzytmp - yuyin);
432 	     }
433   	} else { 		/* has ShengMu */
434 /*
435  	    for ( j = 0; (int)j < (int)strlen(zy_shengmu_tbl[*sheng_raw]); j++)
436 		pzytmp++;
437 */
438 	    pzytmp += strlen(zy_shengmu_tbl[*sheng_raw]);
439 	    if (strlen(pzytmp) == 0 )  return(0);
440 	    if ( (*yun_raw = zy_yunmu(pzytmp)) != -1 ) {
441 		pzytmp += strlen(zy_yunmu_tbl[*yun_raw]);
442 	   	*ss = *yun_raw % 5;
443 	     	*yun_raw = *yun_raw / 5;
444 	     	return(pzytmp - yuyin);
445 	    } else {
446 	   	pzytmp = yuyin;
447 		if ( (*yun_raw = zy_yunmu(pzytmp)) == -1 )
448 			return(0);
449 		else {
450 			pzytmp += strlen(zy_yunmu_tbl[*yun_raw]);
451 			*sheng_raw = 0;
452 	    		*ss = *yun_raw % 5;
453 	    		*yun_raw = *yun_raw / 5;
454 	    		return(pzytmp - yuyin);
455 		}
456 	    }
457 	}	/* has ShengMu when Zhuyin */
458     }	/* which */
459 }
460 
pzy_yincod(one_yuyin,len)461 static w_char pzy_yincod(one_yuyin, len)
462 register char *one_yuyin;
463 register int *len;
464 {
465   int     ss[1];
466   int     sheng_raw[1];
467   int     yun_raw[1];
468   register  int	    zytmp;
469   register int ret;
470 
471   *len = 0;
472     /* for Pinyin */
473     if((ret = pzy_get_sheng_yun(one_yuyin, ss, sheng_raw, yun_raw,
474 				CWNN_PINYIN)))
475 	if ( is_pinyin(sheng_raw[0], yun_raw[0]) != -1  ) {
476 	    *len = ret;
477 	    return(create_yincod(sheng_raw[0], yun_raw[0], ss[0]));
478 	}
479     /* for Zhuyin */
480     if((ret = pzy_get_sheng_yun(one_yuyin, ss, sheng_raw, yun_raw,
481 				CWNN_ZHUYIN))){
482 	zytmp = zhuyin_tbl[sheng_raw[0] * ZY_NUM_YUNMU + yun_raw[0]];
483 	if ( is_zhuyin(sheng_raw[0], yun_raw[0]) != -1 )  {
484 	    if ((zytmp & 0x0080 ) == 0x0080) {
485 		sheng_raw[0] = (zytmp >>8) & 0x7f;
486 		yun_raw[0] = zytmp & 0x7f;
487 	    }
488 	    *len = ret;
489 	    return(create_yincod(sheng_raw[0], yun_raw[0], ss[0]));
490 	}
491     }
492 return(0);	/* Otherwise, Not a Pinyin nor Zhuyin  */
493 }
494 
495 /* ltoScpy():  copy strings from letter type to w_char type */
496 
ltoScpy(w,l)497 static int ltoScpy(w,l)
498 register w_char *w;
499 register letter *l;
500 {
501   register w_char *w0 = w;
502 
503     for(;*l;l++){
504 	if (/* ((*l & 0x0000ffff) == PY_EOF) || isZY_EOF(*l & 0x0000ffff)
505 	    ||*/ (*l == EOLTTR)) /* add by Kuwari */
506 	       break;
507         *w++ = (*l & 0x0000ffff);
508     }
509     *w = (w_char)0;
510     return(w - w0);
511 }
512 
513 /* find_pinyin():  	find a YuYin in a string.  if there is a YuYin.
514 	 it must be at the tail of string.  return point of start YuYin
515 	 else return -1 eg. ;abcdHuang. 'Huang.' is a PinYin & return 5
516 	 012345
517 */
518 static int
find_pinyin(str)519 find_pinyin(str)
520 register char	*str;
521 {
522 register char 	*py_zy_tmp;
523 register int	i;
524 register int	pnt ;
525 int len;
526     pnt = -1;
527     if ((((*(str+strlen(str)-2)<<8)&0xff00)|
528 			(*(str+strlen(str)-1)&0x00ff))!= PY_EOF)
529 	return( -1 );
530     for ( i = strlen(str) - 1; i >= 0; i-- ) {
531 	if ( (int)(strlen(str) - i) > PY_LEN )
532 		return( pnt );
533 	py_zy_tmp = str + i;
534 	if ( pzy_yincod(py_zy_tmp, &len) != 0 )
535 		pnt = i;
536     }
537     return (pnt);
538 }
539 
540 static int
find_zhuyin(str)541 find_zhuyin(str)
542 register char	*str;
543 {
544 register char 	*py_zy_tmp;
545 register int	i;
546 register int	pnt ;
547 int len;
548    pnt = -1;
549    if (!isZY_EOF(((*(str+strlen(str)-2)<<8)&0xff00)|
550 				(*(str+strlen(str)-1)&0x00ff)))
551 	return( -1 );
552    for ( i = strlen(str) - 1; i >= 0; i-- ) {
553 	if ( (int)(strlen(str) - i) > PY_LEN )
554 		return( pnt );
555 	py_zy_tmp = str + i;
556 	if ( pzy_yincod(py_zy_tmp, &len) != 0 )
557 		pnt = i;
558    }
559    return (pnt);
560 }
561 
562 /* get_one_zhuyin(): get one ZhuYin from ZhuYin strings */
563 /* get_one_pinyin(): get one PinYin from PinYin strings */
564 static int
get_one_pinyin(pinzhuyin_str,one_pinzhuyin)565 get_one_pinyin(pinzhuyin_str,one_pinzhuyin)
566 register unsigned char *pinzhuyin_str;
567 register char *one_pinzhuyin;
568 {
569 register w_char  chrtmp;
570 for (; (chrtmp = (((*pinzhuyin_str<<8)&0xff00)|(*(pinzhuyin_str+1)&0x00ff)))
571 	!= PY_EOF && *pinzhuyin_str != 0;pinzhuyin_str++)
572     *one_pinzhuyin++ = *pinzhuyin_str;
573    if (chrtmp == PY_EOF)
574 	{
575 	*one_pinzhuyin++ = *pinzhuyin_str;
576 	pinzhuyin_str++;
577 	*one_pinzhuyin++ = *pinzhuyin_str;
578 	*one_pinzhuyin = 0;
579 	return(1);
580 	}
581     else  {
582 	*one_pinzhuyin = 0;
583 	return(0);
584 	}
585 }
586 
587 static int
get_one_zhuyin(pinzhuyin_str,one_pinzhuyin)588 get_one_zhuyin(pinzhuyin_str,one_pinzhuyin)
589 register unsigned char *pinzhuyin_str;
590 register char *one_pinzhuyin;
591 {
592 register w_char  chrtmp;
593 for (; !isZY_EOF(chrtmp = (((*pinzhuyin_str<<8)&0xff00)|(*(pinzhuyin_str+1)
594 	&0x00ff))) && *pinzhuyin_str != 0; pinzhuyin_str++)
595     *one_pinzhuyin++ = *pinzhuyin_str;
596     if ( isZY_EOF(chrtmp) )
597 	{
598 	*one_pinzhuyin++ = *pinzhuyin_str;
599 	pinzhuyin_str++;
600 	*one_pinzhuyin++ = *pinzhuyin_str;
601 	*one_pinzhuyin = 0;
602 	return(1);
603 	}
604     else  {
605 	*one_pinzhuyin = 0;
606 	return(0);
607 	}
608 }
609 
610 /* cwnn_is_yincod(c)	To check is "c"is a yincod.
611 	if so, return(1) otherwise return 0*/
cwnn_is_yincod(c)612 int cwnn_is_yincod(c)
613 register w_char	 c;
614 {
615 register int sheng_raw;
616 register int yun_raw;
617 
618   	if (! _cwnn_isyincod_d(c) ) return (0);
619 
620     	sheng_raw = Shengraw(c);
621     	yun_raw = Yunraw(c);
622     	if ( is_pinyin(sheng_raw, yun_raw) ) return(1);
623     	if  ( sheng_raw == X_SHENG_RAW && is_pinyin(EMPTY_SHENG_RAW, yun_raw) == 0)
624       	    return( 1 );
625 	else return(0);
626 }
627 
628 /* For a given 'yincod', creat the corresponding Pinyin or Zhuyin
629    to pzy_buf as a w_char string. If the given 'yincod' is not a yincod,
630    'yincod', followed by a NULL is created to pzy_fub.
631    Return: the lenth of pzy_buf is returned.
632    Lenth means the lenth in console but not num of character.
633 */
cwnn_yincod_pzy(pzy_buf,c,which)634 int  cwnn_yincod_pzy(pzy_buf, c, which )
635 register w_char  *pzy_buf;	/* out:    a Pinyin or Zhuyin */
636 register w_char  c;		/* input:  a yincod 	*/
637 int which;			/* option Pinyin or Zhuyin */
638 {
639 register int sheng_raw;
640 register int yun_raw;
641 register int ss;	/* for Sisheng	*/
642 register int zytmp;
643 
644   if ( ! cwnn_is_yincod(c) ) {
645 	*pzy_buf = c;
646 	*(pzy_buf + 1) = 0;
647 	return(1);
648 
649 /*	if ( ((c&0x00ff)>0xa0) && ((c&0x00ff)< 0xff) &&
650 	     ((c>>8) > 0xa0) && ((c>>8) < 0xff) )
651 		return(2);
652 	else	return(1);
653 */
654   }
655 
656   sheng_raw = Shengraw(c);
657   yun_raw = Yunraw(c);
658   ss = _cwnn_sisheng(c);
659 
660     if  (which == CWNN_PINYIN){		/* For Pinyin case */
661 	if (sheng_raw == X_SHENG_RAW && is_pinyin(sheng_raw, yun_raw) == -1 )
662 	     if ( is_pinyin(EMPTY_SHENG_RAW, yun_raw) == 0 )
663 		sheng_raw = EMPTY_SHENG_RAW;
664 	cwnn_Sstrcpy(pzy_buf, py_shengmu_tbl[sheng_raw]);
665 	if ( _cwnn_has_sisheng(c) )
666 	    cwnn_Sstrcat(pzy_buf, py_yunmu_tbl[yun_raw*5+ss]);
667 	else
668 	    cwnn_Sstrcat(pzy_buf, py_yunmu_tbl[yun_raw*5]);
669     }
670     else {		/* For Zhuyin case */
671 
672 	zytmp = zhuyin_tbl[sheng_raw * ZY_NUM_YUNMU + yun_raw];
673 	if ( is_zhuyin(sheng_raw, yun_raw) == -1 ) {
674 	     if ((zytmp & 0x0080)== 0x0080 ){
675 	       sheng_raw = (zytmp >>8) & 0x7f;
676 	       yun_raw = zytmp & 0x7f;
677 	     }
678 	     else {
679 	     if ((sheng_raw == X_SHENG_RAW) &&(is_zhuyin(EMPTY_SHENG_RAW,yun_raw)==0))
680 		sheng_raw = EMPTY_SHENG_RAW;
681 	     }
682  	}
683 	cwnn_Sstrcpy(pzy_buf, zy_shengmu_tbl[sheng_raw]);
684 	if ( yun_raw == EMPTY_YUN_RAW ) {
685 	    w_char tmp_w;
686 	    if ( _cwnn_has_sisheng(c) ) {
687 	      switch  (ss) {
688 		case 1:
689 		    tmp_w = ZY_EOF_1;
690 		    break;
691 		case 2:
692 		    tmp_w = ZY_EOF_2;
693 		    break;
694 		case 3:
695 		    tmp_w = ZY_EOF_3;
696 		    break;
697 		case 4:
698 		    tmp_w = ZY_EOF_4;
699 		    break;
700 	      }
701 	     } else {
702 		tmp_w = ZY_EOF_0;
703 	     }
704 	     wnn_Strncat(pzy_buf, &tmp_w, 1);
705 	}
706 	else {
707 	    if ( _cwnn_has_sisheng(c))
708 		  cwnn_Sstrcat(pzy_buf, zy_yunmu_tbl[yun_raw*5+ss]);
709 	    else
710 		cwnn_Sstrcat(pzy_buf, zy_yunmu_tbl[yun_raw*5]);
711 	}
712   }
713 return(wnn_Strlen(pzy_buf));
714 }
715 
716 /* Copy s2 which having yincod to s1 in which yincod are replaced by
717 the corresponding Pinyin or Zhuyin. Lenth of s2 is returned
718 */
cwnn_yincod_pzy_str(s1,s2,n,which)719 int cwnn_yincod_pzy_str(s1, s2, n, which)
720 register w_char *s1;	/* result string having Pinyin or Zhuyin */
721 register w_char *s2;	/* input string having Yincod */
722 int  n;
723 int  which;
724 {
725     w_char s2tmp[LINE_SIZE];
726     register int i, j;
727     w_char pzy_buf[10];
728     int	len, sum_len;
729 
730 	len = 0;
731 	sum_len = 0;
732     	for (i = 0; i < n;  i++)  s2tmp[i] = s2[i];
733     	for (i = 0; i < n;  i++) {
734 
735 /*	len = cwnn_yincod_pzy(pzy_buf, s2tmp[i], which);
736 	for (j = 0; j < len; j++)
737 		*s1++ = pzy_buf[j];
738 	sum_len += len;
739 */
740 /* Strlen(pzy_buf) is the num of w_char , but "len" means the width */
741 
742 	len = cwnn_yincod_pzy(pzy_buf, s2tmp[i], which);
743 	for (j = 0; j < wnn_Strlen(pzy_buf); j++)
744 	*s1++ = pzy_buf[j];
745 	sum_len += wnn_Strlen(pzy_buf);
746 	}
747 	*s1 =0;
748 	return(sum_len);
749 }
750 
751 /* cwnn_pzy_yincod(s1, s2, which):
752 After the matching in automaton, the string may be a Pinyin or a Zhuyin
753 If so, it will be replace by the coreesponding Yincod */
754 
cwnn_pzy_yincod(s1,s2,which)755 int cwnn_pzy_yincod(s1, s2, which)
756 letter *s1, *s2;
757 int which;
758 {
759   /*
760   register w_char codetmp2[PY_LEN];
761   register char *codetmp1 = {"          "};
762   */
763   w_char codetmp2_buf[PY_LEN*10+1];
764   char codetmp1_buf[PY_LEN*20+2];
765   register w_char *codetmp2 = codetmp2_buf;
766   register char *codetmp1 = codetmp1_buf;
767   register letter *lettertmp = s2, *s1tmp = s1;
768   register w_char yincod;
769   int len;
770   int conv = 0;
771   w_char save_w[2];
772   char save, tmp[6];
773 
774   save_w[0] = save_w[1] = 0;
775 	ltoScpy(codetmp2, lettertmp);
776 	if (cwnn_sStrcpy(codetmp1, codetmp2) <= 0) return(0);
777 
778 /*	if ((yincod = pzy_yincod(codetmp1)) != 0)
779 		getstr_pzy(s1, yincod, which);
780 
781 Jun 13 Zhong */
782 	for (;*lettertmp && *lettertmp != EOLTTR;) {
783 	    if ( ( yincod = pzy_yincod(codetmp1, &len)) != 0) {
784 		conv++;
785 		*s1tmp++ = (letter)yincod;
786 		save = codetmp1[len];
787 		codetmp1[len] = '\0';
788 		lettertmp += cwnn_Sstrcpy(codetmp2, codetmp1);
789 		codetmp1[len] = save;
790 		codetmp1 += len;
791 	    } else {
792 		save_w[0] = (w_char)(*lettertmp & 0xffff);
793 		*s1tmp++ = *lettertmp++;
794 		codetmp1 += cwnn_sStrcpy(tmp, save_w);
795 	    }
796 	}
797 	if (*lettertmp == EOLTTR) *s1tmp++ = *lettertmp++;
798 	if (conv) {
799 	    return(s1tmp - s1);
800 	} else {
801 	    return(0);
802 	}
803 }
804 
805 /* cwnn_py_yincod_str(), cwnn_zy_yincod_str():HUANG: for atod
806 	we get yomi as PinYin or ZhuYin strings from ascii-dictionary and
807 	translate it to YINcode
808 */
809 void
cwnn_py_yincod_str(yuyin_str,css,un_sisheng_yincod_str,yincod_str)810 cwnn_py_yincod_str(yuyin_str, css, un_sisheng_yincod_str, yincod_str)
811 register char    *yuyin_str;        /* yomi: PinYin or ZhuYin strings */
812 register char    *css;        /* get sisheng strings from PinYin strings */
813 register w_char  *un_sisheng_yincod_str; /* no-sisheng Yincod strings */
814 register w_char  *yincod_str;            /* Yincod strings with sisheng */
815 {
816 /*
817   register  char    one_yuyin[LINE_SIZE];
818   register  w_char not_yuyin[LINE_SIZE];
819 */
820   char    one_yuyin_buf[LINE_SIZE];
821   w_char    not_yuyin_buf[LINE_SIZE];
822   register  char    *one_yuyin = one_yuyin_buf;
823   register  w_char    *not_yuyin = not_yuyin_buf;
824   register  int     yin_eof;
825   register  w_char  yincod;
826   register  int     i, pst;
827   int len;
828 
829     for ( ; *yuyin_str; ) {
830 	yin_eof = get_one_pinyin(yuyin_str, one_yuyin);
831 	yuyin_str += strlen(one_yuyin);
832 	cwnn_Sstrcpy(not_yuyin,  one_yuyin);
833 	pst = find_pinyin(one_yuyin);
834 	if ( yin_eof == 1  && pst != -1 ) {
835 		for ( i = 0; i < pst; i++ ) {
836 			*yincod_str++ = not_yuyin[i];
837 			*un_sisheng_yincod_str++ = not_yuyin[i];
838 			*css++ = '5';
839 			}
840 		yincod = pzy_yincod(one_yuyin, &len);
841 		*yincod_str ++ = yincod;
842 		*un_sisheng_yincod_str++ = _cwnn_yincod_0(yincod);
843 		*css++ = (char)(_cwnn_sisheng(yincod) + 0x30);
844 	}
845 	else {
846 		for ( i = 0;  not_yuyin[i]; i++ ) {
847 			*yincod_str++ = not_yuyin[i];
848 			*un_sisheng_yincod_str++ = not_yuyin[i];
849 			*css++ = '5';
850 		}
851 	}
852     }
853 	*yincod_str = 0;
854 	*un_sisheng_yincod_str = 0;
855 	*css = 0;
856 }
857 
858 void
cwnn_zy_yincod_str(yuyin_str,css,un_sisheng_yincod_str,yincod_str)859 cwnn_zy_yincod_str(yuyin_str, css, un_sisheng_yincod_str, yincod_str)
860 register char    *yuyin_str;        /* yomi: PinYin or ZhuYin strings */
861 register char    *css;        /* get sisheng strings from PinYin strings */
862 register w_char  *un_sisheng_yincod_str; /* no-sisheng Yincod strings */
863 register w_char  *yincod_str;            /* Yincod strings with sisheng */
864 {
865 /*
866   register  char    one_yuyin[LINE_SIZE];
867   register  w_char not_yuyin[LINE_SIZE];
868 */
869   char    one_yuyin_buf[LINE_SIZE];
870   w_char    not_yuyin_buf[LINE_SIZE];
871   register  char    *one_yuyin = one_yuyin_buf;
872   register  w_char    *not_yuyin = not_yuyin_buf;
873   register  int     yin_eof;
874   register  w_char  yincod;
875   register  int     i, pst;
876   int len;
877 
878     for ( ; *yuyin_str; ) {
879 	yin_eof = get_one_zhuyin(yuyin_str, one_yuyin);
880 	yuyin_str += strlen(one_yuyin);
881 	cwnn_Sstrcpy(not_yuyin,  one_yuyin);
882 	pst = find_zhuyin(one_yuyin);
883 	if ( yin_eof == 1  && pst != -1 ) {
884 		for ( i = 0; i < pst; i++ ) {
885 			*yincod_str++ = not_yuyin[i];
886 			*un_sisheng_yincod_str++ = not_yuyin[i];
887 			*css++ = '5';
888 			}
889 		yincod = pzy_yincod(one_yuyin, &len);
890 		*yincod_str ++ = yincod;
891 		*un_sisheng_yincod_str++ = _cwnn_yincod_0(yincod);
892 		*css++ = (char)(_cwnn_sisheng(yincod) + 0x30);
893 	}
894 	else {
895 		for ( i = 0;  not_yuyin[i]; i++ ) {
896 			*yincod_str++ = not_yuyin[i];
897 			*un_sisheng_yincod_str++ = not_yuyin[i];
898 			*css++ = '5';
899 		}
900 	}
901     }
902 	*yincod_str = 0;
903 	*un_sisheng_yincod_str = 0;
904 	*css = 0;
905 }
906 
907 /* cwnn_py_str_analysis(), cp_zy_str_analysis():   HUANG: for atod
908 	we get yomi as PinYin or ZhuYin strings from ascii-dictionary
909 	and translate it to YINcode
910 */
911 void
cwnn_py_str_analysis(yuyin_str,css,un_sisheng_yincod_str,yincod_str)912 cwnn_py_str_analysis(yuyin_str, css, un_sisheng_yincod_str, yincod_str)
913 register char    *yuyin_str;        /* yomi: PinYin or ZhuYin strings */
914 register char    *css;    /* get sisheng strings from PinYin strings */
915 register w_char  *un_sisheng_yincod_str; /* no-sisheng Yincod strings */
916 register w_char  *yincod_str;       /* Yincod strings with sisheng */
917 {
918 /*
919   register  char    one_yuyin[LINE_SIZE];
920   register  w_char not_yuyin[LINE_SIZE];
921 */
922   char    one_yuyin_buf[LINE_SIZE];
923   w_char    not_yuyin_buf[LINE_SIZE];
924   register  char    *one_yuyin = one_yuyin_buf;
925   register  w_char    *not_yuyin = not_yuyin_buf;
926   register  int     yin_eof;
927   register  w_char  yincod;
928   register  int     i, pst;
929   int len;
930     for ( ; *yuyin_str; ) {
931 	yin_eof = get_one_pinyin(yuyin_str, one_yuyin);
932 	yuyin_str += strlen(one_yuyin);
933 	cwnn_Sstrcpy(not_yuyin,  one_yuyin);
934 	pst = find_pinyin(one_yuyin);
935 	if ( yin_eof == 1  && pst != -1 ) {
936 		for ( i = 0; i < pst; i++ ) {
937 			*yincod_str++ = not_yuyin[i];
938 			*un_sisheng_yincod_str++ = not_yuyin[i];
939 			*css++ = '5';
940 			}
941 		yincod = pzy_yincod(one_yuyin, &len);
942 		*yincod_str ++ = yincod;
943 		*un_sisheng_yincod_str++ = _cwnn_yincod_0(yincod);
944 		*css++ = (char)(_cwnn_sisheng(yincod) + 0x30);
945 	}
946 	else {  for ( i = 0;  not_yuyin[i]; i++ ) {
947 			*yincod_str++ = not_yuyin[i];
948 			*un_sisheng_yincod_str++ = not_yuyin[i];
949 			*css++ = '5';
950 		}
951 	}
952     }
953 	*yincod_str = 0;
954 	*un_sisheng_yincod_str = 0;
955 	*css = 0;
956 }
957 
958 void
cwnn_zy_str_analysis(yuyin_str,css,un_sisheng_yincod_str,yincod_str)959 cwnn_zy_str_analysis(yuyin_str, css, un_sisheng_yincod_str, yincod_str)
960 register char    *yuyin_str;        /* yomi: PinYin or ZhuYin strings */
961 register char    *css;     /* get sisheng strings from PinYin strings */
962 register w_char  *un_sisheng_yincod_str; /* no-sisheng Yincod strings */
963 register w_char  *yincod_str;      /* Yincod strings with sisheng */
964 {
965 /*
966   register  char    one_yuyin[LINE_SIZE];
967   register  w_char not_yuyin[LINE_SIZE];
968 */
969   char    one_yuyin_buf[LINE_SIZE];
970   w_char    not_yuyin_buf[LINE_SIZE];
971   register  char    *one_yuyin = one_yuyin_buf;
972   register  w_char    *not_yuyin = not_yuyin_buf;
973   register  int     yin_eof;
974   register  w_char  yincod;
975   register  int     i, pst;
976   int len;
977     for ( ; *yuyin_str; ) {
978 	yin_eof = get_one_zhuyin(yuyin_str, one_yuyin);
979 	yuyin_str += strlen(one_yuyin);
980 	cwnn_Sstrcpy(not_yuyin,  one_yuyin);
981 	pst = find_zhuyin(one_yuyin);
982 	if ( yin_eof == 1  && pst != -1 ) {
983 		for ( i = 0; i < pst; i++ ) {
984 			*yincod_str++ = not_yuyin[i];
985 			*un_sisheng_yincod_str++ = not_yuyin[i];
986 			*css++ = '5';
987 			}
988 		yincod = pzy_yincod(one_yuyin, &len);
989 		*yincod_str ++ = yincod;
990 		*un_sisheng_yincod_str++ = _cwnn_yincod_0(yincod);
991 		*css++ = (char)(_cwnn_sisheng(yincod) + 0x30);
992 	}
993 	else {  for ( i = 0;  not_yuyin[i]; i++ ) {
994 			*yincod_str++ = not_yuyin[i];
995 			*un_sisheng_yincod_str++ = not_yuyin[i];
996 			*css++ = '5';
997 		}
998 	}
999     }
1000 	*yincod_str = 0;
1001 	*un_sisheng_yincod_str = 0;
1002 	*css = 0;
1003 }
1004 #endif /* CHINESE */
1005