Back to index

im-sdk  12.3.91
codetable.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <locale.h>
00003 
00004 #include "ime.h"
00005 #include "codetable.h"
00006 
00007 #define WILD_MATCH          0      /* exact match */
00008 #define WILD_PREFIX         1      /* no match, but maybe if go deeper */
00009 #define WILD_UNMATCH        2      /* complete mismatch */
00010 
00011 #define SC_FAIL                    0
00012 #define SC_OK               1
00013 
00014 #define WILDCHAR_MATCHSINGLE       '?'
00015 #define WILDCHAR_MATCHANY   '*'
00016 
00017 #define       MAX_CANDIDATES_NUM   16
00018 #define MAX_CANDIDATE_CHAR_NUM     64
00019 #define MAX_INPUT_KEY_NUM   32
00020 
00021 /* CodeTable Search Context */
00022 typedef struct _HZSearchContext {
00023 
00024        int depth;                                /* the current depth in the DFS traversal */
00025 
00026        char prefix[MAX_INPUT_KEY_NUM+1];         /* the prefix traced codes */
00027        char wildpattern[MAX_INPUT_KEY_NUM+1];           /* the wildchar pattern codes */
00028        char repcode[MAX_INPUT_KEY_NUM+1];        /* the tracing codes */
00029        tableNode *tNstack[MAX_INPUT_KEY_NUM+1];  /* the tableNode stack */
00030        short int tNnumSb[MAX_INPUT_KEY_NUM+1];          /* number of sibling tableNode */
00031 
00032 } HZSearchContext;
00033 
00034 /*********************** Load Codetable File ***********************/
00035 
00036 /*
00037  * LoadCodeTableHeader -- load the input table header from codetable binary file
00038  */
00039 int LoadCodeTableHeader (file_name, hztbl)
00040 char *file_name;
00041 CodeTableStruct *hztbl;
00042 {
00043        FILE *ifile;
00044        char ctFlag[256];
00045        int  ver, i;
00046 
00047        DEBUG_printf("LoadCodeTableHeader ====\n");
00048 
00049        /* read table from file to memory buffer  */
00050        ifile = fopen (file_name, "r");
00051        if (! ifile) {
00052               fprintf(stderr, "Unable to open the input table file \"%s\"\n",file_name);
00053               return(-1);
00054        }
00055 
00056        /* Read CodeTable File Flag */
00057        if (fread (ctFlag, strlen(CODETABLE_FLAG), 1, ifile) != 1) {
00058               fprintf (stderr, "Codetable File read Error:%s\n", file_name);
00059               fclose(ifile);
00060               return(-1);
00061        }
00062 
00063        if (strncmp (ctFlag, CODETABLE_FLAG, strlen(CODETABLE_FLAG)) != 0) {
00064               fprintf (stderr, "File is not in CodeTable format\n");
00065               fclose(ifile);
00066               return(-1);
00067        }
00068 
00069        /* Read CodeTable Version Flag */
00070        if (fread ((char *)(&ver), sizeof (int), 1, ifile) != 1)  {
00071               fprintf (stderr, "Codetable File read Error:%s\n", file_name);
00072               fclose(ifile);
00073               return(-1);
00074        }
00075 
00076        if (ver != CODETABLE_VERSION) {
00077               fprintf (stderr, "File is not in correct Version Number\n");
00078               fclose(ifile);
00079               return(-1);
00080        }
00081 
00082        if (fread((char *)hztbl, sizeof(CodeTableStruct), 1, ifile) != 1) {
00083               fprintf(stderr, "Error in loading input table for %s\n", file_name);
00084               fclose(ifile);
00085               return(-1);
00086        }
00087 
00088        fclose (ifile);
00089        return(0);
00090 }
00091 
00092 /*
00093  * LoadCodeTable -- load the input table from codetable binary file
00094  */
00095 int LoadCodeTable (file_name, hztbl)
00096 char *file_name;
00097 CodeTableStruct *hztbl;
00098 {
00099        FILE *ifile;
00100        char ctFlag[256];
00101        int  ver, i;
00102 
00103        ifile = fopen (file_name, "r");
00104        if (! ifile) {
00105               printf("Unable to open the input table file \"%s\"\n",file_name);
00106               return(-1);
00107        }
00108 
00109        /* Read CodeTable File Flag */
00110        if (fread (ctFlag, strlen(CODETABLE_FLAG), 1, ifile) != 1) {
00111               fprintf (stderr, "Codetable File read Error:%s\n", file_name);
00112               fclose (ifile);
00113               return(-1);
00114        }
00115 
00116        if (strncmp (ctFlag, CODETABLE_FLAG, strlen(CODETABLE_FLAG)) != 0) {
00117               fprintf (stderr, "File is not in CodeTable format\n");
00118               fclose (ifile);
00119               return(-1);
00120        }
00121 
00122        /* Read CodeTable Version Flag */
00123        if (fread ((char *)(&ver), sizeof (int), 1, ifile) != 1)  {
00124               fprintf (stderr, "Codetable File read Error:%s\n", file_name);
00125               fclose (ifile);
00126               return(-1);
00127        }
00128 
00129        if (ver != CODETABLE_VERSION) {
00130               fprintf (stderr, "File is not in correct Version Number\n");
00131               fclose (ifile);
00132               return(-1);
00133        }
00134 
00135        if (fread((char *)hztbl, sizeof(CodeTableStruct), 1, ifile) == 0) {
00136               printf( "Error in loading input table for %s\n", file_name);
00137               fclose (ifile);
00138               return(-1);
00139        }
00140 
00141        /* malloc memory for codetable information */
00142        hztbl->nodeList = (tableNode *)calloc(hztbl->sizeNodeList,sizeof(tableNode));
00143        hztbl->hzList = (unsigned char *)calloc(hztbl->sizeHZList, sizeof(unsigned char));
00144        hztbl->keyprompt = (keyPrompt *)calloc(MAX_USEDCODES_NUM, sizeof(keyPrompt));
00145        hztbl->functionkey = (functionKey *)calloc(MAX_FUNCTIONKEY_NUM, sizeof(functionKey));
00146        if ((! hztbl->hzList) || (! hztbl->nodeList) ||
00147            (! hztbl->keyprompt) || (! hztbl->functionkey)) {
00148               printf( "No memory to load input table for %s\n", file_name);
00149               fclose (ifile);
00150               return(-1);
00151        }
00152 
00153        if ((fread ((char *)(hztbl->nodeList), sizeof(tableNode),
00154                 (int)hztbl->sizeNodeList, ifile) != hztbl->sizeNodeList) ||
00155            (fread ((char *)hztbl->hzList, sizeof(unsigned char),
00156                 (int)(hztbl->sizeHZList), ifile) != hztbl->sizeHZList))
00157        {
00158               printf( "Error in loading input table for %s\n", file_name);
00159               fclose (ifile);
00160               return(-1);
00161        }
00162        
00163        if (GETBIT(hztbl->bSectionsFlag, KEYPROMPT_SECTION)) {
00164               if (fread((char *)(&(hztbl->keyprompt[0])), MAX_USEDCODES_NUM, 
00165                      sizeof(keyPrompt), ifile) != sizeof(keyPrompt))
00166               {
00167                      printf( "Error in loading input table for %s\n", file_name);
00168                      fclose (ifile);
00169                      return(-1);
00170               }
00171        }
00172 
00173        if (GETBIT(hztbl->bSectionsFlag, FUNCTIONKEY_SECTION)) {
00174               if (fread((char *)(&(hztbl->functionkey[0])), MAX_FUNCTIONKEY_NUM, 
00175                      sizeof(functionKey), ifile) != sizeof(functionKey))
00176               {
00177                      printf( "Error in loading input table for %s\n", file_name);
00178                      fclose (ifile);
00179                      return(-1);
00180               }
00181        }
00182 
00183        for (i=0; i<MAX_USEDCODES_NUM; i++) {
00184               if (hztbl->keyprompt[i].prompt[0] == 0) {
00185                      hztbl->keyprompt[i].prompt[0] = i;
00186                      hztbl->keyprompt[i].prompt[1] = 0;
00187               }
00188        }
00189 
00190        fclose (ifile);
00191        return(0);
00192 }
00193 
00194 /*
00195  * UnloadCodeTable -- unload the input table, free the memory
00196  */
00197 void UnloadCodeTable(hztbl)
00198 CodeTableStruct *hztbl;
00199 {
00200        if (! hztbl) return;
00201 
00202         if (hztbl->nodeList)  free ((char *)(hztbl->nodeList));
00203         if (hztbl->hzList)  free ((char *)(hztbl->hzList));
00204         if (hztbl->keyprompt)  free ((char *)(hztbl->keyprompt));
00205         if (hztbl->functionkey)  free ((char *)(hztbl->functionkey));
00206 }
00207 
00208 int Is_WildcharMatchAny_Key(hztbl, key)
00209 CodeTableStruct *hztbl;
00210 int key;
00211 {
00212        if ( index(hztbl->UsedCodes, WILDCHAR_MATCHANY) )
00213               return(0);
00214 
00215        return(key == WILDCHAR_MATCHANY);
00216 
00217 }
00218 
00219 int Is_WildcharMatchSingle_Key(hztbl, key)
00220 CodeTableStruct *hztbl;
00221 int key;
00222 {
00223        if ( index(hztbl->WildChar, key) )
00224               return(1);
00225 
00226        if ( index(hztbl->UsedCodes, WILDCHAR_MATCHSINGLE) )
00227               return(0);
00228 
00229        return(key == WILDCHAR_MATCHSINGLE);
00230 }
00231 
00232 int Is_Wildchar_Key(hztbl, key)
00233 CodeTableStruct *hztbl;
00234 int key;
00235 {
00236        int ret;
00237 
00238        ret = ( Is_WildcharMatchSingle_Key(hztbl, key) || Is_WildcharMatchAny_Key(hztbl, key) );
00239        return(ret);
00240 }
00241 
00242 /*********************** Wild Char Matching ***********************/
00243 
00244 /*
00245  * WildcardMatch() returns 3 values.  WILD_MATCH is for an exact match.
00246  * WILD_PREFIX means the current traversal path (from "top" to the current
00247  * node) matches a prefix of the wildcard pattern, which might suggest a
00248  * possible match if the traversal goes deeper.  WILD_UNMATCH is a total
00249  * mismatch, in which case the traversal should stop go any deeper.
00250  */
00251 
00252 #define car(s)              (*(s))
00253 #define cdr(s)              ((s)+1)
00254 #define empty(s)     (!(*(s)))
00255 
00256 /*
00257  * recursively WildcharMatch string (with no wildcard) against pattern (possibly with wildcard)
00258  */
00259 static int WildcharMatch(hztbl, string, pattern)
00260 CodeTableStruct *hztbl;
00261 char *string;
00262 char *pattern;
00263 {
00264        if (empty(pattern))
00265               return (empty(string) ? WILD_MATCH : WILD_UNMATCH);
00266        else if (Is_WildcharMatchAny_Key(hztbl, car(pattern))) {
00267               int x = WildcharMatch(hztbl, string, cdr(pattern));
00268               if (x == WILD_UNMATCH)
00269                      return (WildcharMatch(hztbl, cdr(string), pattern));
00270               else
00271                      return x;
00272        } 
00273        else if (empty(string))
00274               return WILD_PREFIX;
00275        else if (Is_WildcharMatchSingle_Key(hztbl, car(pattern)) || car(pattern) == car(string))
00276               return WildcharMatch(hztbl, cdr(string), cdr(pattern));
00277        else
00278               return WILD_UNMATCH;
00279 }
00280 
00281 /*********************** Traversal in Codetable Node ***********************/
00282 
00283 /*
00284  * Search in the trie for the given suffix in the input sequent
00285  * that contains wildcard(s).  The "top" node matches the longest
00286  * prefix in the input sequent that contains no wildcard.
00287  * The traversal is a Deep-First-Search starting from "top".
00288  * But it visits the node before visiting any child under the node.
00289  *
00290  */
00291 
00292 /*
00293  * Move to next sibling, if no more sibling, move up to parent's sibling
00294  */
00295 static int Get_NextNode(pSC)
00296 HZSearchContext *pSC;
00297 {
00298        while (pSC->tNnumSb[pSC->depth] == 0) 
00299        {
00300               /* no more sibling, go up */
00301               if (pSC->depth == 0) {
00302                      /* now at the topmost; we've tried everything! */
00303                      pSC->tNstack[0] = NULL;
00304                      return(SC_FAIL);
00305               } else {
00306                      pSC->depth--;
00307                      pSC->repcode[pSC->depth] = '\0';
00308               }
00309        }
00310 
00311        /* go to sibling node */
00312        pSC->tNnumSb[pSC->depth]-- ;
00313        pSC->tNstack[pSC->depth]++ ; 
00314        pSC->repcode[pSC->depth-1] = pSC->tNstack[pSC->depth]->key;
00315        return(SC_OK);
00316 }
00317 
00318 int is_valid_candidate(unsigned char *hzptr, int hzlen, int dict_encode, int output_encode)
00319 {
00320        int ret;
00321 
00322        if (dict_encode == output_encode)
00323               return(1);
00324 
00325        if (dict_encode == ENCODE_UTF8) {
00326               char *ip, *op, buffer[512];
00327               int ileft, oleft;
00328               
00329               ip = (char *)hzptr;
00330               ileft = hzlen;
00331               op = buffer;
00332               oleft = 512;
00333               memset(buffer, 0, 512);
00334               ret = Convert_UTF8_To_Native(output_encode, ip, ileft, &op, &oleft);
00335               DEBUG_printf("ctim: Convert UTF-8 to native, ret: %d\n", ret);
00336               if (ret == -1) {
00337                      return(0);
00338               } else {
00339                      if(buffer[0] && is_valid_encode_string(output_encode, buffer, strlen(buffer)) == 0)
00340                             return(1);
00341                      else
00342                             return(0);
00343               }
00344        }
00345 
00346        if (dict_encode == ENCODE_GB18030) {
00347               if (output_encode == ENCODE_GB2312 || output_encode == ENCODE_GBK) {
00348                      /* need check whether valid candidate*/
00349                      ret = is_valid_encode_string(output_encode, hzptr, hzlen);
00350                      if (ret == -1) return(0);
00351               }
00352               return (1);
00353        }
00354               
00355        if (dict_encode == ENCODE_GBK) {
00356               if (output_encode == ENCODE_GB2312) {
00357                      /* need check whether valid candidate*/
00358                      ret = is_valid_encode_string(output_encode, hzptr, hzlen);
00359                      if (ret == -1) return(0);
00360               }
00361               return (1);
00362        }
00363        
00364        return (1);
00365 }
00366 
00367 int normal_search(hztbl, pSC, outbuf, attrbuf, pos, num)
00368 CodeTableStruct *hztbl;
00369 HZSearchContext *pSC;
00370 unsigned char **outbuf;
00371 unsigned char **attrbuf;
00372 int pos;
00373 int num;
00374 {
00375        tableNode *tnptr;
00376        unsigned char *hzptr, tmpbuf[MAX_CANDIDATE_CHAR_NUM];
00377        int outptr, i, j, hzlen, len;
00378        int num_matched = 0; /* pointer that how many items match the conditions */
00379        int num_selected = 0;       /* pointer that how many items be selected */
00380        char dict_encode, output_encode;
00381 
00382        dict_encode = hztbl->Encode;
00383        output_encode = hztbl->Output_Encode;
00384 
00385        DEBUG_printf("dict_encode:%d, output_encode:%d\n", dict_encode, output_encode);
00386        /* traversal all the subnodes of pSC->tNstack[0] */
00387        while (1) 
00388        {
00389               tnptr = pSC->tNstack[pSC->depth];
00390 
00391               /* check if any HZ choices on this node */
00392               if (tnptr->num_HZchoice > 0) 
00393               {
00394                      /* if any HZ choices on this node,then check if match search conditions */
00395 /*
00396                      DEBUG_printf("repcode:%s  \t%d\n", pSC->repcode, tnptr->num_HZchoice);
00397 */
00398 
00399                      /* get HZ choices */
00400                      hzptr = hztbl->hzList + tnptr->pos_HZidx;
00401                      for (i=0; i<tnptr->num_HZchoice; i++) 
00402                      {
00403                             if (*hzptr == HZ_PHRASE_TAG) {
00404                                    hzlen = *(hzptr + 1);
00405                                    hzptr += 2;
00406                             } else {
00407                                    hzlen = get_char_len_by_encodeid(hztbl->Encode, hzptr);
00408                             }
00409 
00410                             if (is_valid_candidate(hzptr, hzlen, dict_encode, output_encode)) {
00411                                    num_matched ++;
00412 
00413                                    outptr = 0; 
00414                                    if (num_matched > pos) {
00415                                           DEBUG_printf("pos:%d, matched:%d\n", pos, num_matched);
00416                                           len = hzlen;
00417                                           if (len>MAX_CANDIDATE_CHAR_NUM) 
00418                                                  len = MAX_CANDIDATE_CHAR_NUM;
00419                                           for (j=0; j< len; j++)
00420                                                  tmpbuf[outptr++] = *(hzptr+j);
00421                                           tmpbuf[outptr++] = '\0';
00422                                    }
00423        
00424                                    if (outptr > 0) {
00425                                           strncpy((char *)outbuf[num_selected], tmpbuf, MAX_CANDIDATE_CHAR_NUM);
00426                                           snprintf((char *)attrbuf[num_selected], MAX_CANDIDATE_CHAR_NUM, "%s%s", 
00427                                                  pSC->prefix, pSC->repcode); 
00428                                           num_selected ++;
00429                                    }
00430                                    if (num_selected >= num) return (num);
00431                             }
00432 
00433                             hzptr += hzlen;
00434                      }
00435               }
00436 
00437               if (!(hztbl->nKeyByKeyMode))
00438                      return (num_selected);
00439 
00440               /* if have any addition input key, move down */
00441               if (tnptr->num_NextKeys > 0) {
00442                      tableNode *new_tnptr = &(hztbl->nodeList[tnptr->pos_NextKey]);
00443 
00444                      pSC->depth++ ;
00445                      pSC->tNnumSb[pSC->depth] = tnptr->num_NextKeys - 1;
00446                      pSC->tNstack[pSC->depth] = new_tnptr;
00447                      pSC->repcode[pSC->depth-1] = new_tnptr->key;
00448                      continue;
00449               }
00450 
00451               /* No more additional key, hence no match for this node. */
00452               /* Don't go down, move forward */
00453               if ( Get_NextNode(pSC) == SC_FAIL )
00454                      return (num_selected);
00455        }
00456 
00457 }
00458 
00459 int wildchar_search(hztbl, pSC, outbuf, attrbuf, pos, num)
00460 CodeTableStruct *hztbl;
00461 HZSearchContext *pSC;
00462 unsigned char **outbuf;
00463 unsigned char **attrbuf;
00464 int pos;
00465 int num;
00466 {
00467        tableNode *tnptr;
00468        unsigned char *hzptr, tmpbuf[MAX_CANDIDATE_CHAR_NUM];
00469        int outptr, i, j, hzlen, len;
00470        int num_matched = 0;    /* pointer that how many items match the conditions */
00471        int num_selected = 0;   /* pointer that how many items be selected */
00472        int bMatched;
00473 
00474        char dict_encode, output_encode;
00475 
00476        dict_encode = hztbl->Encode;
00477        output_encode = hztbl->Output_Encode;
00478 
00479        DEBUG_printf("wildpattern:%s\n", pSC->wildpattern);
00480 
00481        /* traversal all the subodes of pSC->tNstack[0] */
00482        while (1) 
00483        {
00484               tnptr = pSC->tNstack[pSC->depth];
00485 
00486               /* check if any HZ choices on this node */
00487               bMatched = 0xff;
00488               if (tnptr->num_HZchoice > 0) {
00489                      DEBUG_printf("repcode:%s  ", pSC->repcode);
00490 
00491                      /* if any HZ choices on this node, then check match search conditions */
00492                      bMatched = WildcharMatch(hztbl, pSC->repcode, pSC->wildpattern);
00493               }
00494 
00495               if (bMatched == WILD_MATCH) 
00496               {
00497                      /* if any HZ choices on this node,then check if match search conditions */
00498 
00499                      DEBUG_printf("repcode:%s  \t%d\n", pSC->repcode, tnptr->num_HZchoice);
00500 
00501                      /* get HZ choices */
00502                      hzptr = hztbl->hzList + tnptr->pos_HZidx;
00503                      for (i=0; i<tnptr->num_HZchoice; i++) {
00504                             if (*hzptr == HZ_PHRASE_TAG) {
00505                                    hzlen = *(hzptr + 1);
00506                                    hzptr += 2;
00507                             } else {
00508                                    hzlen = get_char_len_by_encodeid(hztbl->Encode, hzptr);
00509                             }
00510 
00511                             if (is_valid_candidate(hzptr, hzlen, dict_encode, output_encode)) {
00512                                    num_matched ++;
00513 
00514                                    outptr = 0; 
00515                                    if (num_matched > pos) {
00516                                           len = hzlen;
00517                                           if (len>MAX_CANDIDATE_CHAR_NUM) 
00518                                                  len = MAX_CANDIDATE_CHAR_NUM;
00519                                           for (j=0; j< len; j++)
00520                                                  tmpbuf[outptr++] = *(hzptr+j);
00521                                           tmpbuf[outptr++] = '\0';
00522                                    }
00523        
00524                                    if (outptr > 0) {
00525                                           strncpy((char *)outbuf[num_selected], tmpbuf, MAX_CANDIDATE_CHAR_NUM);
00526                                           snprintf((char *)attrbuf[num_selected], MAX_CANDIDATE_CHAR_NUM, "%s%s", 
00527                                                  pSC->prefix, pSC->repcode); 
00528                                           num_selected ++;
00529                                    }
00530                                    if (num_selected >= num) return (num);
00531                             }
00532 
00533                             hzptr += hzlen;
00534                      }
00535               } else if (bMatched == WILD_UNMATCH) {
00536                      /* need not to go down */
00537                      if ( Get_NextNode(pSC) == SC_FAIL )
00538                             return (num_selected);
00539                      continue;
00540               }
00541 
00542               /* if have any addition input key, move down */
00543               if (tnptr->num_NextKeys > 0) {
00544                      tableNode *new_tnptr = &(hztbl->nodeList[tnptr->pos_NextKey]);
00545 
00546                      pSC->depth++ ;
00547                      pSC->tNnumSb[pSC->depth] = tnptr->num_NextKeys - 1;
00548                      pSC->tNstack[pSC->depth] = new_tnptr;
00549                      pSC->repcode[pSC->depth-1] = new_tnptr->key;
00550                      continue;
00551               }
00552 
00553               /* No more additional key, hence no match for this node. */
00554               /* Don't go down, move forward */
00555               if ( Get_NextNode(pSC) == SC_FAIL )
00556                      return (num_selected);
00557        }
00558 }
00559 
00560 int codetable_search(hztbl, inbuf, outbuf, attrbuf, pos, num)
00561 CodeTableStruct *hztbl;
00562 char *inbuf;
00563 unsigned char **outbuf;
00564 unsigned char **attrbuf;
00565 int pos;
00566 int num;
00567 {
00568        HZSearchContext search_context, *pSC;
00569        char tmp_inbuf[MAX_INPUT_KEY_NUM+1];
00570 
00571        int matched, i, j, len;
00572        tableNode *tnptr, *tCurTNptr;
00573        int search_num;
00574        
00575        memset(tmp_inbuf, 0, MAX_INPUT_KEY_NUM+1);
00576        for (i = 0; i < strlen(inbuf); i++) {
00577               if (i >= MAX_INPUT_KEY_NUM) break;
00578               tmp_inbuf[i] = tolower(inbuf[i]);
00579        }
00580 
00581        inbuf = tmp_inbuf;
00582 
00583        /* search maxinum matched top node that not include wildchar */
00584        tCurTNptr = &(hztbl->nodeList[0]);
00585        i = 0;
00586        while (i < strlen(inbuf))
00587        {
00588               if (   (Is_WildcharMatchSingle_Key(hztbl, inbuf[i])) || 
00589                      (Is_WildcharMatchAny_Key(hztbl, inbuf[i])) )
00590                      break;
00591 
00592               matched = 0;
00593               j = 0;
00594               tnptr = &(hztbl->nodeList[tCurTNptr->pos_NextKey]);
00595               while (j < tCurTNptr->num_NextKeys)
00596               {
00597                      if (inbuf[i] == tnptr->key) {
00598                             matched = 1;
00599                             break;
00600                      }
00601                      tnptr ++;
00602                      j ++;
00603               }
00604               if (matched == 0)
00605                      return(0);
00606 
00607               tCurTNptr = tnptr;
00608               i++;
00609        }
00610 
00611        /* set search context */
00612        pSC = &search_context;
00613        pSC->depth = 0;
00614        pSC->tNnumSb[0] = 0;
00615        pSC->tNstack[0] = tCurTNptr;
00616        memset(pSC->repcode, 0, MAX_INPUT_KEY_NUM+1);
00617        memset(pSC->prefix, 0, MAX_INPUT_KEY_NUM+1);
00618        memset(pSC->wildpattern, 0, MAX_INPUT_KEY_NUM+1);
00619 
00620        if (i>0) {
00621               len = MAX_INPUT_KEY_NUM+1>i ? i : MAX_INPUT_KEY_NUM+1;  
00622               strncpy(pSC->prefix, inbuf, len);
00623        }
00624 
00625        search_num = num > MAX_CANDIDATES_NUM ? MAX_CANDIDATES_NUM : num;
00626        if (i == strlen(inbuf)) {
00627               /* no wildchar,  begin normal mode search */
00628               num = normal_search(hztbl, pSC, outbuf, attrbuf, pos, search_num);
00629        } else {
00630               /* have any wildchar, begin wildchar mode search */
00631               strncpy(pSC->wildpattern, inbuf+i, MAX_INPUT_KEY_NUM+1);
00632               num = wildchar_search(hztbl, pSC, outbuf, attrbuf, pos, search_num);
00633        }
00634        return(num);
00635 }
00636