Back to index

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