/*//////////////////////////////////////////////////////////////////////// Copyright (c) 1993 Electrotechnical Laboratry (ETL) Permission to use, copy, modify, and distribute this material for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies, and that the name of ETL not be used in advertising or publicity pertaining to this material without the specific, prior written permission of an authorized representative of ETL. ETL MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. ///////////////////////////////////////////////////////////////////////// Content-Type: program/C; charset=US-ASCII Program: onewWnn (Wnn kanakan interface) Author: Yutaka Sato Description: History: 931104 extracted from onewlib.c ///////////////////////////////////////////////////////////////////////*/ int KanakanExists; #define STATIC static #define VERSION Onew_version() #include #include #include #include "onew.h" #include "Wnn_euc.h" char *WNN_DICLISTP[]={"$ONEW_WNN_DICLIST","$ONEW_DICLIST",WNN_DICLIST,0}; char *WNN_DICDIRSP[]={"$ONEW_WNN_DICFORM","$ONEW_DICFORM",WNN_DICDIRS,0}; char *strtok(); static ONEWopen_dic(); static onew_setevf(); static wchar_strcpy(), wchar_strlen(); STATIC kana_cands(); /* * define DO_SIGMASK if you wish to avoid errorneous interruption possibly * caused by the application during communication with JSERVER. */ #ifdef DO_SIGMASK #include #define SIGMASKS (sigmask(SIGALRM)|sigmask(SIGIO)) #define SIGMASKON(omask) (omask = sigblock(SIGMASKS)) #define SIGMASKOFF(omask) sigsetmask(omask) #else #define SIGMASKON(omask) #define SIGMASKOFF(omask) #endif /*######################################################################* * Wnn STARTUP * *######################################################################*/ typedef struct bunjoho BUN_JOHO; BUN_JOHO *jd_open_in(); BUN_JOHO *BunJohos[64]; #define BjP BunJohos[BjX] static int BunJohoX; static int NoOfBunsetu; #define S_KANALEN 2000 /* jd_open() */ #define S_KLISTLEN 500 /* jd_open() */ #define S_KANJILEN 2000 /* jd_open(),jd_recove(),jd_tanconv() */ #define MAX_ALTS 500 /* jd_next() */ #define ALT_KANJILEN 5000 /* jd_next() */ static WnnInit(){ int omask; Pathname hostname; char *jshost, *user; Pathname diclist,dname,dicname; char *dl, *dp; int diclisti; int pri; BUN_JOHO *BJ; if(BunJohoX) return BunJohoX; jshost = getenv("JSERVER"); if( jshost == 0 ){ gethostname(hostname,sizeof(hostname)); jshost = hostname; } if( !ONEW_SHOWDIC ) onew_notify_kkinit("%s ** JSERVER(%s)",VERSION,jshost); user = getenv("USER"); BJ = jd_open_in(S_KANALEN,S_KLISTLEN,S_KANJILEN,jshost,user,0); if(BJ == 0){ Onew_putmsg(1,"%s ** JSERVER(%s)%s",VERSION,jshost, ONEW_msg_connectfail); ONEW_BEEP(2); return 0; } BunJohos[++BunJohoX] = BJ; for( diclisti = 0; dl = WNN_DICLISTP[diclisti]; diclisti++ ){ Onew_env_substitute(dl,diclist); if( strchr(diclist,'$') == 0 ) break; } SIGMASKON(omask); for( dp=strtok(diclist," \t\n"); dp; dp=strtok(0," \t\n") ){ pri = 1; sscanf(dp,"%[^=]=%d",dname,&pri); Onew_env_substitute(dname,dicname); if( ONEWopen_dic(dicname,pri) < 0 ) ONEW_BEEP(2); } SIGMASKOFF(omask); onew_setevf(); return BunJohoX; } static ONEWopen_dic(dicname,pri) char *dicname; { Pathname dicform,dicdir,frqdir,dicpath,frqpath; char *dicf; int dicformi; if( strchr(dicname,'/') ){ strcpy(dicpath,dicname); strcpy(frqpath,""); if( jd_dicadd(dicname,"",pri,0) != -1 ) goto opened; }else for(dicformi=0; dicf = WNN_DICDIRSP[dicformi]; dicformi++){ Onew_env_substitute(dicf,dicform); *dicdir = *frqdir = 0; sscanf(dicform,"%[^;];%s",dicdir,frqdir); if( strchr(dicdir,'%') == 0 ) continue; sprintf(dicpath,dicdir,dicname,"",""); sprintf(frqpath,frqdir,dicname,"",""); if( *dicpath == 0 ) continue; if( jd_dicadd(dicpath,frqpath,pri,0) != -1 ) goto opened; if( ONEW_SHOWDIC ) printf("#wnn:%s;%s%s\n",dicpath,frqpath,ONEW_msg_dicfail); } Onew_putmsg(1,"%s;%s%s",dicpath,frqpath,ONEW_msg_dicfail); return -1; opened: if( ONEW_SHOWDIC ) printf("wnn:%s%s%s\n",dicpath,*frqpath?";":"",*frqpath?frqpath:""); return 0; } static onew_setevf() { int n,w0,w1,w2,w3,w4; char *env; if( env = getenv("ONEW_WNN_EVF") ) if( jd_getevf(&n,&w0,&w1,&w2,&w3,&w4) == 0 ){ sscanf(env,"%d %d %d %d %d %d %d",&n,&w0,&w1,&w2,&w3,&w4); jd_setevf(n,w0,w1,w2,w3,w4); Onew_putmsg_retain(1," ONEW_WNN_EVF='%d %d %d %d %d %d'", n,w0,w1,w2,w3,w4); } } static ONEWkanakan_ready(){ return WnnInit() != 0; } static ONEWkanakan(com,str) Uchar *str; { int comch; int BjX; char yomibuf[S_KANALEN]; BjX = WnnInit(); if( BjX == 0 ) return 0; clr_keyinQ(); Onew_setupYomistr(com,str,yomibuf); ToServerString(yomibuf,BjP->kana_buf); comch = kana_cands(BjX); return comch; } static int henkan_sareta; static ONEWkanakan_freqsave(){ if( !henkan_sareta ) return 0; henkan_sareta = 0; if( 0 < BunJohoX ){ if(jd_freqsv() != 0){ Onew_putmsg(1,ONEW_msg_cantsavehind); ONEW_BEEP(2); return -1; } /*Onew_putmsg_sys(1," WNN | Frequency information saved.");*/ } return 0; } static kanakan_end(){ if( 0 < BunJohoX ){ BunJohoX = 0; if(jd_close() != 0){ Onew_putmsg(1,">> wnn lib close err"); ONEW_BEEP(2); } } } extern Uchar *ToLocalString(); STATIC wchar* YomiString(BjX,i,out) wchar *out; { int len; *out = 0; len = BjP->klist[i].jl + BjP->klist[i].fl; ToLocalString(out,&BjP->kana_buf[BjP->klist[i].s_ichi],len); } STATIC char* BunsetsuString(BjX,i,out) char *out; { struct kouho_entry *kep; Uchar *sp; kep = &BjP->klist[i]; sp = ToLocalString(out,kep->k_data,wchar_strlen(kep->k_data)); ToLocalString(sp,&BjP->kana_buf[kep->s_ichi+kep->jl],kep->fl); return out; } /* * DISPLAY kanji_buff WITH WORD CURSOR * */ static disp_kanji_buf(BjX,cur_bi,so) { int i,col; Uchar left[S_KANALEN],current[S_KANALEN],right[S_KANALEN]; left[0] = 0; for(i = 0; i < cur_bi && i < NoOfBunsetu; i++) BunsetsuString(BjX,i,&left[strlen(left)]); current[0] = 0; if( i == cur_bi ) BunsetsuString(BjX,i,current); right[0] = 0; for(i++; i < NoOfBunsetu; i++) BunsetsuString(BjX,i,&right[strlen(right)]); Onew_dispKanakanBuf(so,left,current,right); } static wchar* ONEWkanakan_kouho(alts,i,kouho,len) struct jikouhojoho *alts; wchar *kouho; { struct jikouho_entry *jkep; jkep = alts->jlist; ToLocalString(kouho,jkep[i].k_data,wchar_strlen(jkep[i].k_data)); return kouho; } static int ONEWbunsetu_next(BjX,index,inc) { int i; wchar yomi[1000]; Uchar *cp; i = index; if( index == 0 && inc == -1 ) i = NoOfBunsetu - 1; else for( ;; ){ i += inc; if( i < 0 ) { i = 0; break; } if( i >= NoOfBunsetu ) { i = NoOfBunsetu - 1; break; } if( i == index ) break; YomiString(BjX,i,yomi); for(cp = (Uchar*)yomi; *cp; cp++) if( *cp & 0x80 ) goto OUT; } OUT: return i; } /*######################################################################* * KANJI_BUFFER EDITOR * *######################################################################*/ static OW_CurrentSerial; static OW_CurrentDic_no; STATIC kana_cands(BjX) { struct kouho_entry *kep; int bunsetux,altx,candn; struct jikouhojoho altcand; struct jikouho_entry altcands[MAX_ALTS],*jkep; wchar altklist[ALT_KANJILEN]; char comch; NoOfBunsetu = jd_begin(BjP->kanji_buf,BjP->kanji_buf_size); for(bunsetux = ONEWbunsetu_next(BjX,-1,1); bunsetux < NoOfBunsetu; ){ if( NoOfBunsetu <= 0 ){ Onew_putmsg(1,"ERROR: jserver dead ? (BunsetuNo==0)"); ONEW_BEEP(2); BunJohoX = 0; return 0x7F; } if(NoOfBunsetu <= bunsetux) bunsetux = NoOfBunsetu-1; if(bunsetux < 0) bunsetux = NoOfBunsetu-1; kep = &BjP->klist[bunsetux]; altcand.jlist = altcands; altcand.jlist_size = MAX_ALTS; altcand.kanji_buf = altklist; altcand.kanji_buf_size = ALT_KANJILEN; candn = jd_next(bunsetux,&altcand); altx = 0; for(;;){ OW_CurrentDic_no = kep->jishono; OW_CurrentSerial = kep->serial; onew_put_kanakanmode(); disp_kanji_buf(BjX,bunsetux,1); comch = OnewGetchar(); { int rcode; rcode = Onew_kanakancom(BjX,comch,&bunsetux,NoOfBunsetu, ONEWkanakan_kouho,&altx,candn,&altcand); switch( rcode ){ case ONEW_CONT: break; case ONEW_LOOP: goto Loop; case ONEW_EXIT: goto Exit; } } if(candn <= altx) altx = 0; if(altx < 0) altx = candn - 1; jkep = &altcand.jlist[altx]; kep->jishono = jkep->jishono; kep->serial = jkep->serial; if( strcmp((char*)kep->k_data,(char*)jkep->k_data) ){ kep->fl = (kep->jl + kep->fl) - jkep->jl; kep->jl = jkep->jl; wchar_strcpy(kep->k_data,jkep->k_data); if( (bunsetux+1) < NoOfBunsetu ){ int inbun; inbun = jd_reconv(bunsetux+1, &kep->k_data[wchar_strlen(kep->k_data)+1], S_KANJILEN); NoOfBunsetu = bunsetux+1 + inbun; } } } Loop:; } Exit: /* 940124 This caller must be BEFORE jd_end() !? */ disp_kanji_buf(BjX,1000,0); if( jd_end() != 0 ){ Onew_putmsg(1,ONEW_msg_cantsavehind);; ONEW_BEEP(1); } henkan_sareta++; return comch; } static ONEWbunsetu_expand(BjX,i) { struct kouho_entry *kep; int inbun,wleng; wchar *kbp; kep = &BjP->klist[i]; wleng = kep->jl + kep->fl; kbp = BjP->kana_buf; if( kbp[kep->s_ichi+wleng] ){ inbun = jd_tanconv(i,wleng+1,kep->k_data,S_KANJILEN); if(0 < inbun) NoOfBunsetu = i + inbun; } } static ONEWbunsetu_shrink(BjX,i) { struct kouho_entry *kep; int inbun,wleng; kep = &BjP->klist[i]; wleng = kep->jl + kep->fl; if(1 < wleng ){ inbun = jd_tanconv(i,wleng-1,kep->k_data,S_KANJILEN); if(0 < inbun) NoOfBunsetu = i + inbun; } } static ONEWbunsetu_delete(BjX,dbunsetu) { struct kouho_entry *kep; wchar *kbp; int i,wleng; kbp = BjP->kana_buf; kep = &BjP->klist[dbunsetu]; wleng = kep->jl + kep->fl; for(i = kep->s_ichi; kbp[i + wleng]; i++) kbp[i] = kbp[i + wleng]; kbp[i] = 0; for(i = dbunsetu; i < NoOfBunsetu; i++){ kep = &BjP->klist[i]; kep[0] = kep[1]; kep->s_ichi -= wleng; } NoOfBunsetu--; } static add_alts(BjX,alts) struct jikouhojoho *alts; { struct kouho_entry *kep; wchar *kbp; FILE *fp; char command[1024],exp[1024],result[2048]; kbp = BjP->kana_buf; kep = &BjP->klist[0]; ToLocalString(exp,kbp,wchar_strlen(kbp)); strcpy(exp,"AHO"); sprintf(command,"sh -c \"echo '%s' | bc\"",exp); if( fp = popen(command,"r") ){ fgets(result,sizeof(result),fp); pclose(fp); strcpy((char *)alts->kanji_buf,result); kep->jl = strlen(exp); kep->fl = 0; }else sprintf((char *)alts->kanji_buf,"Fail popen(%s)",command); } static ONEWexternal_henkan(BjX,alts){ add_alts(BjX,alts); } static wchar_strcpy(dst,src) wchar *dst,*src; { register wchar *d,*s; d = dst; s = src; while( *d++ = *s++ ); } static wchar_strlen(wstr) wchar *wstr; { int len; wchar *wcp; len = 0; for(wcp = wstr; *wcp; wcp++) len++; return len; } static get_dicno(name,dicno) char *name; { int ndic,dici,udic; struct dicinfo *di; struct dicinfo dicinfo[64]; char dicnames[4096]; char *dname; ndic = jd_dicinfo(dicinfo,64,dicnames,4096); for( dici = 0; dici < ndic; dici++ ){ di = &dicinfo[dici]; if( dname = (char*)strrchr(di->file_name,'/') ) dname++; else dname = di->file_name; if( strcmp(name,"USERDIC1") == 0 ){ if( jd_udp(di->dic_no) & 1 ){ strcpy(name,dname); return di->dic_no; } }else if( *name != 0 ){ if( strcmp(name,dname) == 0 ) return di->dic_no; }else{ if( dicno == di->dic_no ){ strcpy(name,dname); return di->dic_no; } } } return -1; } static change_udic(name) char *name; { int dicno; if( 0 <= (dicno = get_dicno(name,0)) ){ if( jd_udchg(dicno) == 0 ) return dicno; Onew_putmsg(1,"UD (%s) CHANGE FAILED",name); }else Onew_putmsg(1,"UD (%s) NOT FOUND",name); return -1; } /* * DICTIONARY MANAGEMENT */ static ONEWjisyo_touroku(touroku,hinshi,eyomi,ekanji) char *hinshi; Uchar *eyomi,*ekanji; { wchar yomi[256],kanji[2048]; char dicname[1024]; int rcode; ToServerString(eyomi,yomi); ToServerString(ekanji,kanji); if( touroku ){ int udic; strcpy(dicname,"USERDIC1"); if( (udic = change_udic(dicname)) < 0 ){ Onew_putmsg(1,"FAILED: cannot open user dictionary[%s]", dicname); return -1; } if( (rcode = jd_wreg(kanji,yomi,1<<(int)hinshi)) < 0 ){ Onew_putmsg(1,"(%s) %s",dicname,ONEW_msg_tourokuERROR); ONEW_BEEP(2); }else Onew_putmsg(1,"(%s) %s",dicname,ONEW_msg_tourokuOK); }else{ dicname[0] = 0; get_dicno(dicname,OW_CurrentDic_no); change_udic(dicname); if( 0 <= (rcode = jd_wdel(OW_CurrentSerial,yomi)) ) Onew_putmsg(1,"%s (%s:%d) %s %s",ONEW_msg_massyouOK, dicname,OW_CurrentSerial,eyomi,ekanji); else{ Onew_putmsg(1,"%s (%s:%d) %s %s",ONEW_msg_cantdelete, dicname,OW_CurrentSerial,eyomi,ekanji); ONEW_BEEP(2); } } return rcode; } static ONEWjisyo_hinshi(hinship) Hinshi **hinship; { *hinship = WNN_HINSHI; return 1; } RegisterKanakan(ONEW_WnnKanakan); Uchar * ToLocalString(dst,src,wlen) Uchar *dst; wchar *src; { int si,di,wc; di = 0; for(si = 0; si < wlen; si++){ wc = src[si]; if( wc & 0xFF00) dst[di++] = (wc >> 8) & 0xFF; if( wc & 0xFF ) dst[di++] = wc & 0xFF; } dst[di] = 0; return &dst[di]; } ToServerString(str,wp) Uchar *str; wchar *wp; { Uchar *s; for(s = str; s[0]; ){ if(s[0] & 0x80){ if(s[1] == 0) break; *wp++ = (s[0] << 8) | s[1]; s += 2; }else{ *wp++ = s[0]; s += 1; } } *wp = 0; }