⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pinyin.c

📁 ARM9-2410教学实验系统下Linux下minigui程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** $Id: pinyin.c,v 1.13 2003/09/04 03:37:34 weiym Exp $**** pinyin.c: The GB2312 pinyin module.**** Porting to MiniGUI from CCE by Zheng Xiang**** Copyright (C) 2000 by Zheng Xiang (zx@minigui.org) ** Copyright (C) 2000 ~ 2002 Wei Yongming** Copyright (C) 2003 Feynman Software.** ** Current maintainer: Wei Yongming**** Create date: 2000/11/01*//* * Copyright 1999.1 by Li ZhenChun  zhchli@163.net * * CCE - Console Chinese Environment - * Copyright (C) 1998-1999 Rui He (herui@cs.duke.edu) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//*** TODO: */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <pwd.h>#include <sys/types.h> #include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "endianrw.h"#include "hzinput.h"#include "pinyin.h"static void PinyinKeyPressed(InputModule *inmd, char ch, LPARAM lParam);static void SelectKeyPressed(InputModule *inmd, char ch, LPARAM lParam);static void CreatePyMsg(InputModule *inmd);static BOOL LoadPinyinTable (InputModule *inmd, char* pathname);static BOOL LoadUsrPhrase( InputModule *inmd, char *pathname);static BOOL LoadSysPhrase(InputModule *inmd, char *pathname);static inline u_char *GetPhrase(ChoiceItem *p);static inline u_char *GetFreq(ChoiceItem *p);static int ParsePy(InputModule *inmd, char *pybuf, PYString pinyin[]);static void FindMatchPhrase(InputModule *inmd,PYString pinyin[],int lenpy);static void FillForwardSelection(InputModule *inmd,int startpos);static void FillBackwardSelection(InputModule *inmd,int lastpos);static int EffectPyNum(PYString pinyin[],int len);static void SortOutput(InputModule *inmd);static int QueryPhrase(InputModule *inmd, u_char *key, int len);static void AdjustPhraseFreq (InputModule *inmd);static void SaveUsrPhraseToMem (InputModule *inmd,u_char *str,u_char *key,int len,int freq);static BOOL SaveUsrPhrase(InputModule *inmd, char *pathname);static BOOL SaveSysPhrase(InputModule *inmd, char *pathname);InputModule Pinyin_Module;static void get_user_phrase_file (const char* tabpath, char* file_name){    struct passwd *pwd;    if ((pwd = getpwuid (geteuid ())) != NULL) {        strcpy (file_name, pwd->pw_dir);        if (file_name [strlen (file_name) - 1] != '/')            strcat (file_name, "/");        strcat (file_name, ".usrphrase.tab");    }    else {        strcpy (file_name, tabpath);        strcat (file_name, "usrphrase.tab");    }}BOOL InitPinyinInput (const char* tabpath, InputModule *inmd){    char file_name [MAX_PATH + 1];    strcpy (file_name, tabpath);    strcat (file_name, "pinyin.map");    if (!LoadPinyinTable (inmd, file_name))        return FALSE;    strcpy (file_name, tabpath);    strcat (file_name, "sysphrase.tab");    if (!LoadSysPhrase (inmd, file_name))        return FALSE;    get_user_phrase_file (tabpath, file_name);    if (!LoadUsrPhrase (inmd, file_name))        return FALSE;    ResetPinyinInput (inmd);    return TRUE;}void PinyinInputCleanup (const char* tabpath, InputModule *inmd){    char file_name [MAX_PATH + 1];    AdjustPhraseFreq (inmd);   // lower the freq to [0,50)    strcpy (file_name, tabpath);    strcat (file_name, "sysphrase.tab");    SaveSysPhrase (inmd, file_name);    get_user_phrase_file (tabpath, file_name);    SaveUsrPhrase (inmd, file_name);}void RefreshPYInputArea (InputModule *inmd, HDC hDC, BOOL bTwoLines){  char str[100];  strcpy(str, "【拼音】");  strcat(str, inmd->iapybuf);  TextOut(hDC, 2, 2, str);  strcpy(str, inmd->iahzbuf);  if (bTwoLines)    TextOut(hDC, 2, 18, str);  else    TextOut(hDC, 150, 2, str);}void Pinyin_HZFilter(InputModule* inmd, unsigned char key, LPARAM lParam){  if ( (key>='a' && key<='z') || (key=='\''&& strlen(inmd->inbuf)) || key=='\010' || key=='\177')       PinyinKeyPressed(inmd,key,lParam);  else if (!strlen(inmd->inbuf)) {     outchar(key, lParam);     return;  }  switch(key)  {     case '=':        FillForwardSelection(inmd,inmd->endpos+1);        break;     case '-':        FillBackwardSelection(inmd,inmd->startpos-1);        break;     case '\033':  //ESCAPE        ResetPinyinInput(inmd);        break;     default:  // select some keys       if ( (key>='1' && key<='9') || key=='0' || key==' ')           SelectKeyPressed(inmd,key,lParam);       break;  }}void ResetPinyinInput(InputModule *inmd){  *(inmd->inbuf)='\0';  *(inmd->inbuftmp)='\0';  *(inmd->pybuftmp)='\0';  *(inmd->iapybuf)='\0';  *(inmd->iahzbuf)='\0';  inmd->len = 0;  inmd->lenpy = 0;  inmd->pinyinpos=0;  inmd->lenkey=0;  inmd->key[0]='\0';}static void PinyinKeyPressed(InputModule *inmd,char ch,LPARAM lParam){  /* parameter strbuf is the newly inputed pinyin, inbuf the    is the whole inputed pinyin, inbuftmp is the unselected pinyin */  char strbuf[2];  char *inbuf=inmd->inbuf;  char *pybuftmp=inmd->pybuftmp;    /* already selected Hanzi buffer */  char *inbuftmp=inmd->inbuftmp;    /* inputed pinyin buffer */  char chtmp;  int count;  strbuf[0] = ch;  strbuf[1] = '\0'; /* \010 = Ctrl+H, \177 = BackSpace */  if (ch == '\010' || ch == '\177')  // BackSpace  {      if (!strlen(inbuf)){          outchar(ch, lParam);          return;      }      else if (!strlen(inbuftmp))      {          strcpy(inbuftmp,inbuf);          *pybuftmp='\0';  // clear all the selected chars, reparse      }      else      {          inbuf[strlen(inbuf)-1] = '\0';          inbuftmp[strlen(inbuftmp)-1] = '\0';  // cut one pinyin-char off          if (!strlen(inbuf))          {              ResetPinyinInput(inmd);              return;          }      }  }  else  //other than BackSpace, ch = a-z or '  {      if (strlen(inbuf) + strlen(strbuf) + 1 < MAX_INPUT_BUF) {          strcat(inbuf,strbuf);          strcat(inbuftmp,strbuf);      }       else {          Ping ();#ifdef _DEBUG          fprintf(stderr, "buffer overrun\n");#endif      }  }  if (!strlen(pybuftmp)) inmd->pinyinpos = 0;    /* first pinyin char */   // parse the unselected pinyin(inbuftmp) input  count = ParsePy(inmd,inbuftmp,inmd->pinyin + inmd->pinyinpos);  inmd->lenpy = inmd->pinyinpos + count;    /* exclude the last i/u/v-beginning pinyin */  if (inmd->lenpy > 0)  {      chtmp = inmd->pinyin[inmd->lenpy-1][0];      if (chtmp=='i' || chtmp=='u' || chtmp=='v')      {          inbuf[strlen(inbuf)-1] = '\0';          inbuftmp[strlen(inbuftmp)-1] = '\0';          inmd->lenpy--;          return;      }  }    /* Too many chars now */  if (EffectPyNum(inmd->pinyin,inmd->lenpy) > MAX_PHRASE_LEN)  {      inbuf[strlen(inbuf)-1] = '\0';      inbuftmp[strlen(inbuftmp)-1] = '\0';      inmd->lenpy--;      return;  }  FindMatchPhrase(inmd,inmd->pinyin + inmd->pinyinpos,           inmd->lenpy-inmd->pinyinpos);  FillForwardSelection(inmd,0);  CreatePyMsg(inmd);  return;}static void SelectKeyPressed(InputModule *inmd,char ch,LPARAM lParam){  ChoiceItem *phr=inmd->sel;  char *pybuftmp=inmd->pybuftmp;    /* already selected Hanzi buffer */  char *inbuftmp=inmd->inbuftmp;    /* inputed pinyin buffer */  int i,j;  u_char *fq;  char strhz[MAX_PHRASE_LEN*2+1];  int pos,idx;  if (!inmd->len){        outchar(ch,lParam);        return;  }  if (ch == ' ') idx = 0;  else if (ch == '0') idx = 9;  else idx = (int)ch-(int)'1';  idx += inmd->startpos;  if (idx > inmd->endpos)  return;  // out of range selection!  strncpy(strhz,GetPhrase(phr+idx), MAX_PHRASE_LEN*2+1);  if (strlen(pybuftmp) + strlen(strhz) + 1 < MAX_INPUT_BUF) {      strcat(pybuftmp,strhz);  } else {      Ping ();#ifdef _DEBUG      fprintf(stderr, "buffer overrun\n");#endif  }  inmd->key[0] |= phr[idx].head->key[0] << inmd->lenkey;  for(i=1; i<=phr[idx].head->len; i++)      inmd->key[(inmd->lenkey)++ +1] = phr[idx].head->key[i];  /* pybuftmp, already selected chars */  if (strlen(pybuftmp)/2 == (size_t)EffectPyNum(inmd->pinyin,inmd->lenpy))  {      if (strlen(strhz) == strlen(pybuftmp) )      {          fq = GetFreq(phr+idx);          if (*fq < 250) (*fq)++;              /* strhz is the last phrase/char, equal, existing phrase/char                 increase its frequency */      }      else if(strlen(pybuftmp) > 2)      {          SaveUsrPhraseToMem(inmd,                    pybuftmp,inmd->key,strlen(pybuftmp)/2,1);              // not equal and pybuftmp, save the new phrase, 0 is user phrase      }      writemsg(pybuftmp, strlen(pybuftmp), lParam, 1); //1 means as the format of WORD       ResetPinyinInput(inmd);      return;//strlen(strbuf);          /* All the pinyin are translated to char/phrases!  */  }  else  // not yet, some unselected pinyin exist  {      // forward the pinyinpos pointer      for(pos = strlen(strhz)/2;  pos > 0 ; inmd->pinyinpos++)      {         ch = inmd->pinyin[inmd->pinyinpos][0];         if (ch=='i' || ch=='u' || ch=='v' || ch<'a' || ch>'z') continue;         pos--;      }      FindMatchPhrase(inmd, inmd->pinyin + inmd->pinyinpos,               inmd->lenpy - inmd->pinyinpos);      FillForwardSelection(inmd,0);      *inbuftmp = '\0';  // put the rest of the pinyin into inbuftmp      for(j = inmd->pinyinpos; j < inmd->lenpy; j++) {          if (strlen(inbuftmp) + strlen(inmd->pinyin[j]) + 1 < MAX_INPUT_BUF) {              strcat(inbuftmp, inmd->pinyin[j]);          }           else {              Ping ();#ifdef _DEBUG              fprintf(stderr, "buffer overrun\n");#endif          }      }      CreatePyMsg(inmd);      return;   }}static void CreatePyMsg(InputModule *inmd){  int i;  strncpy(inmd->iapybuf,inmd->pybuftmp, MAX_INPUT_BUF-1);  for(i=inmd->pinyinpos; i<inmd->lenpy; i++)  {      if (strlen(inmd->iapybuf)+strlen(inmd->pinyin[i])+2 >= MAX_INPUT_BUF-1) {#ifdef _DEBUG          fprintf(stderr, "buffer overrun\n");#endif      }      strcat(inmd->iapybuf,inmd->pinyin[i]);   // MAX_PY_LEN = 7      if (inmd->pinyin[i+1][0] == '\'' || inmd->pinyin[i][0] == '\'')          continue;      else          strcat(inmd->iapybuf," ");  }}static BOOL LoadPinyinTable (InputModule *inmd, char* pathname){    FILE *stream;    char str[250],strpy[15],strhz[241];    int i=0, j=0, lastpy=0, curpy;       if ( (stream = fopen (pathname, "r" )) == NULL ) {        fprintf(stderr, "IME (Pinyin): Can not open Pinyin Table to read.\n");        return FALSE;    }    while ( !feof( stream )) {        if ( fgets(str,250,stream) != NULL) {            sscanf(str,"%14s %240s",strpy,strhz);            curpy = strpy[0]-'a';            if (curpy != lastpy) j = 0;             strncpy( inmd->pytab[curpy][j].py,strpy, MAX_PY_LEN);            inmd->pytab[curpy][j].key = i+1;            lastpy = curpy;            i++,j++;        }    }    fclose(stream);      return TRUE;}static BOOL LoadUsrPhrase (InputModule *inmd, char *pathname){    FILE *stream;    UsrPhrase *kph,*tmp;    int i,j,ahead,fsize;    u_short count;    u_char len, size;    if (access (pathname, F_OK)) {        for (i = 0; i < MAX_PY_NUM; i++)            inmd->usrph[i] = NULL;        return TRUE;    }    if ((stream = fopen (pathname, "r")) == NULL ) {        fprintf (stderr, "IME (Pinyin): %s file can't be opened.\n", pathname);        return FALSE;    }    if (fseek (stream, -4, SEEK_END) == -1 ||        fread (&fsize, sizeof(int), 1, stream) != 1 ||#if MGUI_BYTEORDER == MGUI_BIG_ENDIAN        (fsize = ArchSwap32 (fsize)) == 0 ||#endif        fsize != ftell (stream) - 4)    {       fprintf (stderr, "IME (Pinyin): %s is not a valid pinyin phrase file.\n", pathname);       fclose (stream);       return FALSE;    }    fseek (stream, 0, SEEK_SET);    for(i = 1; i < MAX_PY_NUM; i++) {       inmd->usrph[i] = NULL;       fread (&count, sizeof(count), 1, stream);#if MGUI_BYTEORDER == MGUI_BIG_ENDIAN       count = ArchSwap16 (count);#endif       if (count == 0) continue;       for(j = 0; j < count; j++)       {          fread(&len,sizeof(len),1,stream);          fread(&size,sizeof(size),1,stream);                    if ((kph = (UsrPhrase *)malloc(6+len+1+(2*len+1)*size)) == NULL) {                fprintf (stderr, "IME (Pinyin): No enough memory.\n");                fclose (stream);                return FALSE;          }          kph->len = len;          kph->count = size;          kph->next = NULL;          fread (kph->key, sizeof(char), len+1, stream);          fread (kph->key + len + 1, 2*len+1, size, stream);          ahead = kph->key[1];          ahead |= (kph->key[0] & 0x01) << 8;         if (inmd->usrph[ahead] == NULL)             inmd->usrph[ahead] = kph;         else         {            tmp = inmd->usrph[ahead];            while (tmp->next != NULL)                 tmp = tmp->next;            tmp->next = kph;         }      }   }   fclose(stream);   return TRUE;}// Load the system and user phrase library// the phrase file can be combined just by cat a >> bstatic BOOL LoadSysPhrase (InputModule *inmd, char *pathname){    FILE *stream;    Phrase *kph;    SysPhrase *sysph;    char *p;    int i,j;    if ( (stream = fopen(pathname , "r" )) == NULL ) {        fprintf (stderr, "IME (Pinyin): %s file can't open\n", pathname);        return FALSE;    }    if (fseek (stream, -4, SEEK_END) == -1 ||      !(inmd->sys_size = MGUI_ReadLE32FP (stream)) ||      inmd->sys_size != ftell (stream)-4)   // error!!    {        fprintf (stderr, "IME (Pinyin): %s is not a valid pinyin phrase file.\n",                 pathname);        fclose (stream);        return FALSE;    }     fseek (stream, 0, SEEK_SET);    if ((p = malloc(inmd->sys_size)) == NULL) {        fprintf (stderr, "IME (Pinyin): No enough memory.\n");        fclose (stream);        return FALSE;    }    if (fread (p, inmd->sys_size, 1, stream) != 1) {        fprintf (stderr, "IME (Pinyin): Loading system phrase error.\n");        fclose (stream);        free (p);        return FALSE;    }       for(i = 1; i < MAX_PY_NUM; i++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -