Back to index

im-sdk  12.3.91
ParsePreedit.c
Go to the documentation of this file.
00001 /*
00002 Copyright 1990-2001 Sun Microsystems, Inc. All Rights Reserved.
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a
00005 copy of this software and associated documentation files (the
00006 "Software"), to deal in the Software without restriction, including
00007 without limitation the rights to use, copy, modify, merge, publish,
00008 distribute, sublicense, and/or sell copies of the Software, and to
00009 permit persons to whom the Software is furnished to do so, subject to
00010 the following conditions: The above copyright notice and this
00011 permission notice shall be included in all copies or substantial
00012 portions of the Software.
00013 
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00016 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00017 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00018 IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
00019 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
00020 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
00021 THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
00022 ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
00023 
00024 
00025 Except as contained in this notice, the names of The Open Group and/or
00026 Sun Microsystems, Inc. shall not be used in advertising or otherwise to
00027 promote the sale, use or other dealings in this Software without prior
00028 written authorization from The Open Group and/or Sun Microsystems,
00029 Inc., as applicable.
00030 
00031 
00032 X Window System is a trademark of The Open Group
00033 
00034 OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
00035 logo, LBX, X Window System, and Xinerama are trademarks of the Open
00036 Group. All other trademarks and registered trademarks mentioned herein
00037 are the property of their respective owners. No right, title or
00038 interest in or to any trademark, service mark, logo or trade name of
00039 Sun Microsystems, Inc. or its licensors is granted.
00040 
00041 */
00042 /*
00043 **  This File was modified to process [#] and [$] for compatiable with ShuangPin.
00044 **  [#] and [$] was added automatically during edition and Sp2Qp conversion.
00045 **  [#] and [$]'s ASCII code are 0x23 and 0x24.
00046 **  # and $ was still reserved even in DecompPeIntArray.
00047 **  PeIntArray was changed !!
00048 **  Principle of Input String:  [a ~ z] [#] [$] ['], there was no connected [#][$][']
00049 **  If it is [#] or [$], just add it. If it is ['], it will affect [SPACE]!!
00050 */
00051 #include "PYIM.h"
00052 
00053 VOID    DecompPeIntArray(JINT *pnOutPreedit, CHAR* szDspPreedit);
00054 JINT    MakeOPE(JINT nHalfMatchLen, JINT nIUVetc, JINT nYJCode);
00055 VOID    ParseRawInputStr(char* szPreedit, int* pnOutPreedit);
00056 JINT    GetNextUnit(char* szPreedit, JINT nPos, char* szNextUnit);
00057 JINT    MatchUnitByYinjie(char* szNextUnit);
00058 VOID    GetFirst9Yj(JINT* pnPrsYj, JINT* pnF9Yj, JINT* pnLen, JINT* pnMatchMode);
00059  
00060 /*
00061 **  Decompose pnOutPreedit Array to a szString.
00062 */
00063 VOID DecompPeIntArray(JINT *pnOutPreedit, CHAR* szDspPreedit)
00064 {
00065        JINT    i, j, tmp;
00066        JINT    nHalfMatchLen, nIUVetc, nYJCode;
00067        CHAR    szHalfMatch[7];
00068        
00069        i   = 0;
00070        tmp = 1;
00071 
00072        for (i = 0; i < 256; i++)
00073               szDspPreedit[i] = '\0';
00074               
00075        for (i = 0; pnOutPreedit[i] != 0; )
00076        {
00077               tmp = pnOutPreedit[i];
00078               nYJCode = tmp & 0x01FF;
00079               nIUVetc = (tmp >> 9) & 0x07;
00080               nHalfMatchLen = (tmp >> 12) & 0x0F;
00081               
00082               if (nIUVetc != 0)
00083               {
00084                      if (nIUVetc == 6)                        /* [$] */
00085                      {
00086                             strcat (szDspPreedit, "$");
00087                             i++;
00088                      }
00089                      else if (nIUVetc == 5)                   /* [#] */
00090                      {
00091                             strcat (szDspPreedit, "#");
00092                             i++;
00093                      }
00094                      else if (nIUVetc == 4)                   /* ['] */
00095                      {
00096                             strcat (szDspPreedit, "\'");
00097                             i++;
00098                      }
00099                      else                                      /* [i u v] */
00100                      {
00101                             /*
00102                             **  Add a space before [iuv] except that this is 
00103                             **  the first CHAR in Preedit string or a ['ivu]
00104                             **  ahead it.
00105                             **  MakeOPE(0, 1, 0) is 0000 001 000000000 = 0x0200 [i]
00106                             **  MakeOPE(0, 2, 0) is 0000 010 000000000 = 0x0400 [u]
00107                             **  MakeOPE(0, 3, 0) is 0000 011 000000000 = 0x0600 [v]
00108                             **  MakeOPE(0, 4, 0) is 0000 100 000000000 = 0x0800 [']
00109                             **
00110                             **  [#] and [$] don't affect [SPACE]
00111                             **
00112                             **  MakeOPE(0, 5, 0) is 0000 101 000000000 = 0x0A00 [#]
00113                             **  MakeOPE(0, 6, 0) is 0000 110 000000000 = 0x0C00 [$]
00114                             */
00115                             if ( (i > 0) && (pnOutPreedit[i-1] != 0x0200)    \
00116                                          && (pnOutPreedit[i-1] != 0x0400)    \
00117                                          && (pnOutPreedit[i-1] != 0x0600)    \
00118                                          && (pnOutPreedit[i-1] != 0x0800) )
00119                                    strcat (szDspPreedit, " ");
00120                             
00121                             if (nIUVetc == 1)
00122                                    strcat (szDspPreedit, "i");
00123                             else  if (nIUVetc == 2)
00124                                    strcat (szDspPreedit, "u");
00125                             else  if (nIUVetc == 3)
00126                                    strcat (szDspPreedit, "v");
00127                             i++;
00128                      }
00129               }
00130               
00131               else if ((nIUVetc == 0) && (nHalfMatchLen == 6))
00132               {
00133                      /*
00134                      ** A valid Yinjie code. Add a SPACE before
00135                      ** Yinjie string expect that there is a ['] ahead or it is the first.
00136                      ** MakeOPE(0, 4, 0) is 0000 100 000000000 = 0x0800
00137                      */
00138                      if ((i > 0) && (pnOutPreedit[i-1] != 0x0800))
00139                             strcat (szDspPreedit, " ");
00140                      
00141                      if (nYJCode >= 450)
00142                             strcat (szDspPreedit, SHENGMUSTR[nYJCode - 450]);
00143                      else if (nYJCode < 450)
00144                             strcat (szDspPreedit, YINJIESTR_CSZ[nYJCode]);
00145                             
00146                      i++;
00147               }
00148               
00149               else if ((nHalfMatchLen > 0) && (nHalfMatchLen < 6) && (nIUVetc == 0))
00150               {
00151                      for (j = 0; j < nHalfMatchLen; j++)
00152                             szHalfMatch[j] = (char)pnOutPreedit[i + j + 1];
00153                      szHalfMatch[j] = '\0';
00154                      if ((i > 0) && (pnOutPreedit[i-1] != 0x0800))
00155                             strcat (szDspPreedit, " ");
00156                      strcat (szDspPreedit, szHalfMatch);
00157                      i += (j + 1);
00158               }
00159               else
00160               {
00161                      i++;
00162                      fprintf (stderr, "Error in DecompPeIntArray()\n");
00163               }
00164        }
00165        
00166 }
00167 
00168 
00169 JINT MakeOPE(JINT nHalfMatchLen, JINT nIUVetc, JINT nYJCode)
00170 {
00171        return (nYJCode + (nIUVetc << 9) + (nHalfMatchLen << 12));
00172 }
00173 
00174 
00175 /*
00176 **  [#] and [$] Support is added!   MXL, 98-02-22
00177 **
00178 **  szPreedit[] contains only [a]~[z] and [']. No other chars included.
00179 **  pnOutPreedit points to a array that contains the parsed result in the
00180 **  following format:
00181 **      |  4Bits   |  3Bits   |       9Bits        |
00182 **      ===========++++++++++++=====================
00183 **      4Bits: nHalfMatchLen ==> Indicates that the following integer is
00184 **             HalfMatched Pinyin string. 0x61[a] ~ 0x7A[z].
00185 **             Min is 1, Max is 5.  If it is 7, indicates 9Bits is YJCode.
00186 **      3Bits: 000 ==> Default
00187 **             001 ==> [i]
00188 **             010 ==> [u]
00189 **             011 ==> [v]
00190 **             100 ==> [']     4
00191 **             101 ==> [#]     5
00192 **             110 ==> [$]     6
00193 **      9Bits: 0 ~ 511  Yinjie Code or Shengmu code
00194 **             Same as notes before function MatchUnitByYinjie().
00195 */
00196 VOID ParseRawInputStr(char* szPreedit, int* pnOutPreedit)
00197 {
00198        CHAR    szNextUnit[10];
00199        JINT    nPELen;
00200        JINT    nCurOff, nOPEOff, nRef, nPy;
00201        JINT    nMatchFlag,  nMatchSMLen,  nMatchYMLenFit,  nMatchYMLenMax,  nMatchYinjie;
00202        JINT    nMatchFlag2, nMatchSMLen2, nMatchYMLenFit2, nMatchYMLenMax2, nMatchYinjie2;
00203        JINT    i, j, tmp, tmp1, tmp2;
00204        CHAR    cEnd, cNext;
00205        
00206        JINT    nHalfMatchLen, nIUVetc, nYJCode;
00207 
00208        nHalfMatchLen = nIUVetc = nYJCode = 0;
00209        nCurOff       = 0;
00210        nRef = nPy = 0;
00211        nOPEOff    = 0;
00212        
00213        nPELen = (int)strlen(szPreedit);
00214        
00215        while (nPELen > nCurOff)
00216        {
00217               for (i = 0; i < 10; i++)
00218                      szNextUnit[i] = '\0';
00219               
00220               tmp  = GetNextUnit(szPreedit, nCurOff, szNextUnit);
00221               nRef = (tmp >> 8) & 0x00FF;
00222               nPy  = tmp & 0x00FF;
00223 
00224               if (nRef == 1)           /* a ['] */
00225               {
00226                      pnOutPreedit[nOPEOff] = MakeOPE (0, 4, 0);
00227                      nOPEOff ++;
00228                      nCurOff ++;
00229               }
00230               else if (nRef == 2)      /* a [#] */
00231               {
00232                      pnOutPreedit[nOPEOff] = MakeOPE (0, 5, 0);
00233                      nOPEOff ++;
00234                      nCurOff ++;
00235               }
00236               else if (nRef == 3)      /* a [$] */
00237               {
00238                      pnOutPreedit[nOPEOff] = MakeOPE (0, 6, 0);
00239                      nOPEOff ++;
00240                      nCurOff ++;
00241               }
00242               
00243               if (nPy == 0)
00244               {
00245 #ifdef _DEBUG
00246                      fprintf (stderr, "ParseRawInputStr() was exited from [nPy == 0]\n");
00247 #endif
00248                      nCurOff = nPELen;    /* break;  OR: nCurOff = nPELen; */
00249               }
00250               else                        /* nPy > 0 */
00251               {
00252                      tmp = MatchUnitByYinjie (szNextUnit);
00253                      nMatchYMLenFit = (tmp >> 16) & 0x07;
00254                      nMatchFlag = (tmp >> 13) & 0x07;
00255                      nMatchSMLen = (tmp >> 12) & 0x01;
00256                      nMatchYMLenMax = (tmp >> 9) & 0x07;
00257                      nMatchYinjie = tmp & 0x01FF;
00258                      
00259                      tmp1 = nCurOff + nMatchSMLen + nMatchYMLenMax + 1;
00260                      
00261                      if (nMatchFlag == 1)
00262                      {
00263                             /* The first Char is [i][u][v] */
00264                             if (szNextUnit[0] == 'i')
00265                                    tmp = 1;
00266                             else if (szNextUnit[0] == 'u')
00267                                    tmp = 2;
00268                             else if (szNextUnit[0] == 'v')
00269                                    tmp = 3;
00270                                    
00271                             pnOutPreedit[nOPEOff] = MakeOPE(0, tmp, 0);
00272                             nOPEOff ++;
00273                             nCurOff ++;
00274                      }
00275                      /*
00276                      **   A Bug Fixed: ORG: zhonw => zhon w // NEW: zhonw => zh o n w
00277                      **   97-10-5
00278                      */
00279                      else if ( (nMatchFlag == 2) && (tmp1 == nPELen) )
00280                      {
00281                             nHalfMatchLen = nMatchSMLen + 1 + nMatchYMLenMax;
00282                             pnOutPreedit[nOPEOff] = MakeOPE (nHalfMatchLen, 0, 0);
00283                             nOPEOff ++;
00284                             for (j = 0; j < (nMatchSMLen + nMatchYMLenMax + 1); j++ )
00285                             {
00286                                    pnOutPreedit[nOPEOff] = (int)szNextUnit[j];
00287                                    nOPEOff ++;
00288                                    nCurOff ++;
00289                             }
00290                      }
00291                      else if (nMatchFlag == 0)
00292                      {
00293                             cEnd = szPreedit[nCurOff + nMatchSMLen + nMatchYMLenFit];
00294                             cNext = szPreedit[nCurOff + nMatchSMLen + 1 + nMatchYMLenFit];
00295                             
00296                             /*
00297                             ** G[aeou]  //  N[aeiouv]  //  R[aeiou]
00298                             */
00299                             if( ((cEnd == 'g') && ((cNext == 'a') || (cNext == 'e') ||     \
00300                                                  (cNext == 'o') || (cNext == 'u') ))       \
00301                              || ((cEnd == 'n') && ((cNext == 'a') || (cNext == 'e') ||     \
00302                                                    (cNext == 'i') || (cNext == 'o') ||     \
00303                                                    (cNext == 'u') || (cNext == 'v') ))     \
00304                              || ((cEnd == 'r') && ((cNext == 'a') || (cNext == 'e') ||     \
00305                                                    (cNext == 'i') || (cNext == 'o') ||     \
00306                                                    (cNext == 'u') )) )
00307                             {
00308                                    for (i = 0; i < (nMatchSMLen + nMatchYMLenFit); i++)
00309                                           szNextUnit[i] = szPreedit[nCurOff + i];
00310                                    for (i = (nMatchSMLen + nMatchYMLenFit); i < 7; i++)
00311                                           szNextUnit[i] = '\0';
00312                                    
00313                                    tmp2 = MatchUnitByYinjie (szNextUnit);
00314                                    nMatchYMLenFit2 = (tmp2 >> 16) & 0x07;
00315                                    nMatchFlag2 = (tmp2 >> 13) & 0x07;
00316                                    nMatchSMLen2 = (tmp2 >> 12) & 0x01;
00317                                    nMatchYMLenMax2 = (tmp2 >> 9) & 0x07;
00318                                    nMatchYinjie2 = tmp2 & 0x01FF;
00319                                    
00320                                    /*
00321                                    ** The following condition may be adjusted to get more
00322                                    ** precision and general. Thus, following syntax is equal.
00323                                    ** eran <==> er'an  ana <==> an'a  IS IT BEST????
00324                                    */
00325                                    if (nMatchFlag2 == 0)
00326                                    {
00327                                           nMatchYinjie = nMatchYinjie2;
00328                                           nMatchSMLen = nMatchSMLen2;
00329                                           nMatchYMLenFit = nMatchYMLenFit2;
00330                                    }
00331                             }
00332                             
00333                             pnOutPreedit[nOPEOff] = MakeOPE (6, 0, nMatchYinjie);
00334                             nOPEOff ++;
00335                             nCurOff += (nMatchSMLen + 1 + nMatchYMLenFit);
00336                      }
00337                      else
00338                      {
00339                             /* nMatchFlag = 3, or 2 in middle */
00340                             /* Setting nHalfMatchLen to 6 to avoid MakeOPE(0, 0, 0) */
00341                             
00342                             pnOutPreedit[nOPEOff] = MakeOPE (6, 0, nMatchYinjie);
00343                             nOPEOff ++;
00344                             nCurOff += (nMatchSMLen + 1 + nMatchYMLenFit);
00345                      }
00346               }
00347                      
00348        } /* End of While() */
00349        pnOutPreedit[nOPEOff] = 0;
00350 }
00351 
00352 
00353 /*
00354 **  szPreedit[] consisted of [a]~[z] ['] [#] and [\0]
00355 **  nOff indicates the start offset to get next unit
00356 **  szNextUnit points to the buffer to store next unit
00357 **  The return JINT indicates the chars have been read from szPreedit.
00358 **                  | Hi 8Bits  | Low 8Bits  |
00359 **                  =============-------------
00360 **                  Hi8   =: 0000 0001  ==> a ['] in the front of szPreedit[nOff]
00361 **                        =: 0000 0010  ==> a [#] in the front of szPreedit[nOff]
00362 **                        =: 0000 0011  ==> a [$] in the front of szPreedit[nOff]
00363 **                  -: 00000xxx  ==> 0-1-2-3-4-5-6 Length of this unit[a]~[z]
00364 */
00365 
00366 JINT GetNextUnit(char* szPreedit, JINT nOff, char* szNextUnit)
00367 {
00368        JINT    nRef, nPy;
00369        JINT    i;
00370 
00371        nRef = nPy = 0;
00372        i = nOff;
00373        
00374        /* Skip ['] at position szPreedit[nOff] */
00375        if (szPreedit[i] == '\'')
00376        {
00377               nRef = 1;
00378               i++;
00379        }
00380        else if (szPreedit[i] == '#')
00381        {
00382               nRef = 2;
00383               i++;
00384        }
00385        else if (szPreedit[i] == '$')
00386        {
00387               nRef = 3;
00388               i++;
00389        }
00390               
00391        while( (szPreedit[i] != '\0') && (szPreedit[i] != '\'') && 
00392                (szPreedit[i] != '#') && (szPreedit[i] != '$') && (nPy <= 6) )
00393        {
00394               szNextUnit[nPy] = szPreedit[i];
00395               i++;
00396               nPy++;
00397        }
00398        if (nPy == 7)
00399               nPy = 6;
00400        
00401        return ((nRef << 8) + nPy);
00402 }
00403 
00404 
00405 /*
00406 **  Lookup the SHENGMUSTR[] and YINJIESTR_CSZ[] to determine the max longest YINJIE
00407 **  which match szNextUnit from header. return the value which indicate
00408 **  the YINJIE. 
00409 **  RETURN JINT     Range 0~414:   YINJIESTR_CSZ[return]
00410 **                  Range > 450:   SHENGMUSTR[return - 450]
00411 **                        Notes:   return-450 don't contains ['a' 'e' 'm' 'n' 'o']
00412 **
00413 **                  |<= High ......................  Low =>|
00414 **                  |  3Bits  |  1Bit  |  3Bits  |  9Bits  |
00415 **                   0 - 8   9Bits:  0~414  & 450 + Shengmu
00416 **                                   0x01FF indicates invalid.
00417 **                   9 - 11  3Bits:  1-2-3-4  Length of Matched Yunmu chars
00418 **                  12       1Bit:   0-1 Length of Shengmu, 1 => [ch][sh][zh]  
00419 **                  13 - 15  4Bits:  000  ==> Full Matched
00420 **                                   001  ==> Invalid Char [i][u][v]
00421 **                                   010  ==> Half Matched. ex, "zho".  Length is 3
00422 **                                   011  ==> Match ShengMu only
00423 **
00424 **  Question:       How about if the first CHAR in szNextUnit is [i][u][v]?
00425 **                  How to convert [u] and [v] automatically?
00426 **                  How to process half match question? for example, "zho"?
00427 */
00428 
00429 /*
00430 **                  How to make this function match to mode "mohu pinyin"?
00431 **                              include:  l/n, n/ng/, f/h,  zh ch sh/ z c s
00432 **                  NO, MOHU is only considered during "YinjieToHzstr".
00433 */
00434 JINT MatchUnitByYinjie(char* szNextUnit)
00435 {
00436        JINT   i, j;
00437        CHAR   cFirstCh;
00438        JINT   nShengmuLen, nFromYJStr, nToYJStr, nShengmuIndex;       
00439        JINT   nMatchYinjie, nMatchYMLenFit, nMatchSMLen, nMatchFlag, nMatchYMLenMax;
00440        JINT   tmp;
00441        
00442        cFirstCh = szNextUnit[0];
00443        
00444        nMatchYinjie = nMatchYMLenFit = nMatchYMLenMax = nMatchSMLen = nMatchFlag = 0;
00445        
00446        if ((cFirstCh == 'i') || (cFirstCh == 'u') || (cFirstCh == 'v'))
00447        {
00448               nMatchSMLen       = 0;              /* Indicates 1 */
00449               nMatchYMLenFit    = 0;
00450               nMatchYMLenMax    = 0;
00451               nMatchFlag        = 1;         /* Invalid Char [i][u][v] */
00452               nMatchYinjie      = 0x1FF;     /* Invalid Shenmu */
00453        }
00454        else if ((cFirstCh >= 'a') && (cFirstCh <= 'z'))
00455        {
00456               nMatchSMLen       = 0;
00457               nMatchYMLenMax    = 0;
00458               nMatchYMLenFit    = 0;
00459               
00460               if ((cFirstCh == 'c') && (szNextUnit[1] == 'h'))
00461               {
00462                      nFromYJStr    = INDEXSMTOYINJIE[3];
00463                      nToYJStr      = INDEXSMTOYINJIE[4];
00464                      nMatchSMLen   = 1;
00465                      nShengmuIndex = 3;   /* [ch], same as INDEXMAGIC[(int)('i' - 'a')] */
00466               }
00467               else if ((cFirstCh == 's') && (szNextUnit[1] == 'h'))
00468               {
00469                      nFromYJStr    = INDEXSMTOYINJIE[19];
00470                      nToYJStr      = INDEXSMTOYINJIE[20];
00471                      nMatchSMLen   = 1;
00472                      nShengmuIndex = 19;  /* [sh], same as INDEXMAGIC[(int)('u' - 'a')] */
00473               }
00474               else if ((cFirstCh == 'z') && (szNextUnit[1] == 'h'))
00475               {
00476                      nFromYJStr    = 395; /*INDEXSMTOYINJIE[25]; */
00477                      nToYJStr      = 415; /*INDEXSMTOYINJIE[26]; */
00478                      nMatchSMLen   = 1;
00479                      nShengmuIndex = 25;   /* [zh], same as INDEXMAGIC[(int)('v' - 'a')] */
00480               }
00481               else
00482               {
00483                      nFromYJStr    = INDEXSMTOYINJIE[ INDEXMAGIC[(int)(cFirstCh - 'a')] ];
00484                      nToYJStr      = INDEXSMTOYINJIE[ INDEXMAGIC[(int)(cFirstCh - 'a')] + 1];
00485                      nMatchSMLen   = 0;
00486                      nShengmuIndex = INDEXMAGIC[(int)(cFirstCh - 'a')];
00487               }
00488               
00489               nShengmuLen  = nMatchSMLen + 1;
00490 
00491               nMatchYinjie = 450 + nShengmuIndex;
00492               nMatchFlag   = 3;                         /* Match ShengMu Only */
00493 
00494               for (i = nFromYJStr; i < nToYJStr; i++)
00495               {
00496                      for (j = nShengmuLen; ((szNextUnit[j] == YINJIESTR_CSZ[i][j]) && (YINJIESTR_CSZ[i][j] != '\0')); )
00497                      {
00498                             j += 1;
00499                      /* Null Loop Here. It is Right */
00500                      }
00501                      
00502                      /*
00503                      ** [cu] => [cuan],  [su] => [suan],  [zu] => [zuan] ??
00504                      ** Get the Max Matchment Length among YINJIESTR_CSZ[i],
00505                      ** where, [i] is between nFromYJStr and nToYJStr.
00506                      ** Example, [su] and [suan] is both valid Yinjie, but [sua] is invalid.
00507                      ** How to process if user input only [sua]?
00508                      */
00509                      /*
00510                      ** !!!!NOTE!!!! The following condition cannot be changed to
00511                      ** !!!!NOTE!!!! ((j - nShengmuLen) >= nMatchYMLenMax)  ...... 
00512                      */
00513                      if ( ((j - nShengmuLen) > nMatchYMLenMax) && ((j - nShengmuLen) > 0) )
00514                      {
00515                             nMatchYMLenMax = j - nShengmuLen;
00516                             if (YINJIESTR_CSZ[i][j] != '\0')
00517                             {
00518                                    nMatchFlag = 2;              /* Half Matchment. [cua] */
00519                             }
00520                             else
00521                             {
00522                                    nMatchYinjie   = i;
00523                                    nMatchFlag     = 0;      /* Full Matchment */
00524                                    nMatchYMLenFit = nMatchYMLenMax;
00525                             }
00526                      }
00527               }
00528        }
00529        else
00530               nMatchYinjie = nMatchYMLenFit = nMatchYMLenMax = nMatchSMLen = nMatchFlag = 0;
00531 
00532        tmp = nMatchYinjie + (nMatchYMLenMax << 9) + (nMatchSMLen << 12) + (nMatchFlag << 13) + (nMatchYMLenFit << 16);
00533        
00534        return (tmp);
00535 }
00536 
00537 
00538 /*
00539 **  This function is defined for LookupSysCiku(). The MAX length of SysCiku
00540 **  is 9 Hanzies.
00541 **  If nIUVetc is ['], add 0x0001 0000   (0001)
00542 **  If nIUVetc is [#], add 0x0002 0000   (0010)
00543 **  If nIUVetc is [$], add 0x0003 0000   (0011)
00544 */
00545 VOID GetFirst9Yj(JINT* pnPrsYj, JINT* pnF9Yj, JINT* pnLen, JINT* pnMatchMode)
00546 {
00547        JINT    i, nTmp1, nTmp2;
00548        JINT    nHalfMatchLen, nIUVetc, nYjcode;
00549        
00550        for(i = 0; i < 9; i++)
00551               pnF9Yj[i] = 0;
00552 
00553        *pnMatchMode = LU_MATCH_WIDELY;
00554        *pnLen       = 0;
00555        
00556        for (i = 0; (pnPrsYj[i] != 0) && ((*pnLen) < 9); )
00557        {
00558               nTmp1   = pnPrsYj[i];
00559               nTmp2   = pnPrsYj[i + 1];
00560 
00561               nYjcode       = nTmp1 & 0x01FF;
00562               nIUVetc       = (nTmp1 >> 9) & 0x07;
00563               nHalfMatchLen = (nTmp1 >> 12) & 0x0F;
00564               
00565               if ((nIUVetc == 0) && (nHalfMatchLen == 6))
00566               {
00567                      pnF9Yj[*pnLen] = nYjcode;
00568                      (*pnLen)++;
00569                      i++;
00570               }
00571               else if ((nIUVetc == 4) || (nIUVetc == 5) || (nIUVetc == 6))           /* ['][#][$] */
00572               {
00573                      i++;
00574                      nYjcode       = nTmp2 & 0x01FF;
00575                      nIUVetc       = (nTmp2 >> 9) & 0x07;
00576                      nHalfMatchLen = (nTmp2 >> 12) & 0x0F;
00577                      
00578                      if ((nIUVetc == 0) && (nHalfMatchLen == 6))
00579                      {
00580                             pnF9Yj[*pnLen]  = nYjcode + ((nIUVetc - 3) << 16);
00581                             (*pnLen)++;
00582                             i ++;
00583                      }
00584                      else
00585                      {
00586                             *pnMatchMode = LU_MATCH_STRICT;
00587                             break;
00588                      }
00589               }
00590               else
00591               {
00592                      *pnMatchMode = LU_MATCH_STRICT;
00593                      break;
00594               }
00595        }
00596 
00597        if (*pnMatchMode == LU_MATCH_WIDELY)
00598        {
00599               nTmp1   = pnPrsYj[i];
00600 
00601               nYjcode       = nTmp1 & 0x01FF;
00602               nIUVetc       = (nTmp1 >> 9) & 0x07;
00603               nHalfMatchLen = (nTmp1 >> 12) & 0x0F;
00604        
00605               if (nTmp1 == 0)
00606                      *pnMatchMode = LU_MATCH_WIDELY;
00607               else if ((nTmp1 != 0) && ((nIUVetc != 0) || (nHalfMatchLen != 6)))
00608                      *pnMatchMode = LU_MATCH_STRICT;
00609        }
00610 }
00611 
00612