1 /**************************************************************************
2 * X J D F R O N T E N D *
3 * Common Frontend Routines for client & stand-alone vers. *
4 * Japanese-English Dictionary program (X11 version) *
5 * Author: Jim Breen *
6 ***************************************************************************/
7 /* This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <stdlib.h>
27 #include <signal.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include "xjdic.h"
31
32 /* Paul Burchard supplied a patch to provide BSD compatibility for xjdic
33 (it uses the appropriate BSD ioctls in place of the SVR4 stuff). In
34 order to enable this, people should compile with the option
35 -D__STRICT_BSD___ . */
36
37 #ifdef __STRICT_BSD__
38 #include <sgtty.h>
39 #else
40 #ifdef __POSIX__
41 #if !defined(__DragonFly__) && !defined(__FreeBSD__)
42 #include <sys/termios.h>
43 #else
44 #include <termios.h>
45 #endif
46 #else
47 #include <termio.h>
48 #endif
49 #endif
50
51 #define WINSIZE_IOCTL_AVAILABLE
52
53
54
55 static enum
56 {
57 IOCTL_ORIG,
58 IOCTL_RAW
59 } myi_status = IOCTL_ORIG;
60
61 #ifdef __STRICT_BSD__
62 static struct sgttyb orig,new;
63 #elif defined(__POSIX__)
64 static struct termios orig,new;
65 #else
66 static struct termio orig,new;
67 #endif
68
69 extern unsigned char CBname[100];
70 extern unsigned char Dnamet[10][100],XJDXnamet[10][100];
71 extern unsigned char *dicbufft[10];
72 extern unsigned long diclent[10], indkent[10],indptrt[10];
73 extern int NoDics,CurrDic;
74 int thisdic = 0;
75 int gdicnos[10],gdicmax=0,GDmode=FALSE,gdiclen;
76
77 FILE *fe, *fex, *fclip, *fopen();
78
79 #ifdef XJDCLSERV
80 extern int portno;
81 extern unsigned char host[];
82 #endif
83
84 #ifdef XJDDIC
85 extern unsigned long dichits[10],dicmiss[10];
86 extern unsigned long indhits[10],indmiss[10];
87 extern unsigned long vbkills;
88 #endif
89
90 char DicDir[100];
91 int xfilelen;
92
93 pid_t pid;
94 int sig=SIGTSTP;
95 int ShiftJIS = FALSE,NoSJIS=FALSE;
96 unsigned char instr[256],radkanj[250][2];
97 int radnos[250];
98 unsigned char kanatab[NRKANA*2][7];
99 int Omode = 0,Smode = 0,Dmode = 0,AKanaMode;
100 int DRow,DCol,MaxY=MAXLINES,MaxX=MAXCOLS-1,KFlushRes,nok;
101 unsigned long hittab[NOHITS];
102 int verblen,DispHit,ksp,hitind,FirstKanj = 0,prieng = FALSE,Extopen=FALSE,NoSkip;
103 int extlen,extjdxlen;
104 unsigned char kmodes[2][10] = {"ON","OFF"};
105 unsigned char kmodes_r[2][10] = {"OFF","ON"};
106 unsigned long chline,chpos,it;
107 unsigned char strfilt[10],tempout[80];
108 unsigned char KSname[50] = {"kanjstroke"};
109 unsigned char RKname[50] = {"radkfile"};
110 unsigned char Rname[50] = {"radicals.tm"};
111 unsigned char ROMname[60] = {"romkana.cnv"};
112 unsigned char EXTJDXname[80] = {"edictext.xjdx"};
113 unsigned char EXTname[80] = {"edictext"};
114 unsigned char Vname[60] = {"vconj"};
115 unsigned char ENVname[100];
116 unsigned char cl_rcfile[100];
117 unsigned char Clip_File[100] = {"clipboard"};
118 unsigned char GPL_File[100] = {"gnu_licence"};
119 unsigned char KDNSlist[50];
120 int jiver = 14; /*The last time the index structure changed was Version1.4*/
121 unsigned char sver[] = {SVER};
122 unsigned char fbuff[512],KLine[KFBUFFSIZE],karray[KANJARRAYSIZE][5];
123 unsigned char LogLine[200];
124 unsigned char ksch[50],ktarg[50];
125 /* The following Help table has "~" to force spaces */
126 unsigned char Help[40][81] = {
127 "\n~~~~~~~~~~~~~~~~~~XJDIC USAGE SUMMARY ",
128 "At the SEARCH KEY prompt respond with a string of ascii, kana and/or ",
129 "kanji to look up in the current dictionary (prefix with @ or # to invoke ",
130 "conversion of romaji to hiragana or katakana)",
131 "~~~~~~~~~~~~~~~~~~SINGLE CHARACTER COMMANDS",
132 "~~\\ enter Kanji Dictionary mode~~~? ~~get this Help display",
133 "~~_ select dictionary files ~~~~~~=/^ cycle up/down dictionary files",
134 "~~\' set/clear one-off filter~~~~~~; activate/deactivate general filters",
135 "~~/ toggle kanji_within_compound~~- toggle long kanji display on/off",
136 "~~$ set global dictionaries ~~~~~~% toggle global search mode on/off",
137 "~~] display Dictionary Extension ~: toggle verb deinflection on/off",
138 "~~+ toggle priority English keys~~| toggle unedited display mode on/off",
139 "~~[ toggle exact_match on/off~~~~~& toggle kana input mode on/off",
140 "~~{ switch to clipboard input ~~~~} toggle reverse video of matches",
141 "~~* report page-buffer stats ~~~~~Ctrl-D to exit",
142 "~~! display gnu licence~~~~~~~~~~~Ctrl-Z to suspend",
143 "~~~~~~Kanji Dictionary mode - prompt is KANJI LOOKUP TYPE:. Responses:",
144 "~~a single kanji or a kana reading (default)",
145 "~~j followed by the 4-digit hexadecimal JIS code for a kanji",
146 "~~j followed by k and the 4-digit KUTEN code for a kanji",
147 "~~~~~~~(precede code with `h' for JIS X 0212 kanji.)",
148 "~~j followed by s and the 4-digit hexadecimal Shift-JIS code for a kanji",
149 "~~m followed by an (English) kanji meaning",
150 "~~c followed by an index code such as Nnnn (Nelson), Bnn (Bushu), etc",
151 "~~r initiates a display of all radicals and their numbers",
152 "~~l switches the program into the Radical Lookup mode",
153 "$$$"
154 };
155 unsigned char RVon[] = {0x1b,'[','7','m',0};
156 unsigned char RVoff[] = {0x1b,'[','m',0};
157 int nofilts=FALSE,filton[NOFILT],filtact[NOFILT],filttype[NOFILT],filtcoden[NOFILT];
158 unsigned char filtnames[NOFILT][50],filtcodes[NOFILT][10][10];
159 unsigned char testline[1025],SingleFilter[50];
160 unsigned char vdicf[VMAX][7],vinfl[VMAX][21],vcomms[41][50];
161 int strf,Jverb = TRUE,SFFlag=FALSE,vcommno[VMAX];
162 int ROmode = 1,EMmode = 1,KLmode = 1,KImode = 1,KLRmode,KLcount;
163 unsigned char vline[250],vstr[13];
164 unsigned char RadK1[300],RadK2[300],*RKanj1,*RKanj2,*RKSet[10];
165 unsigned char RKTarg[21];
166 int rmax,NoSets=0,NoRads,RKStart[300],RKCnt[300];
167 unsigned char ops[3],kstrokes[7000];
168 int kstrokelim,kstroketype;
169 int clipmode=FALSE;
170 unsigned char clipstring1[51];
171 unsigned char clipstring2[51]={"XXXX"};
172 int RVACTIVE = TRUE;
173
174 int DicNum;
175 long DicLoc;
176
177 /*====== Prototypes========================================================*/
178
179 FILE *xfopen(char *file_name, char *file_mode, int *xfilelen);
180 int getcharxx();
181 void RadDisp();
182 void RadBuild();
183 int FindRad(unsigned char char1, unsigned char char2);
184 void DoLOOKUP();
185 void RadLoad();
186 void KSLoad();
187 void xjdserver (int type, int dic_no, long index_posn, int sch_str_len,
188 unsigned char *sch_str, int *sch_resp, long *res_index,
189 int *hit_posn, int *res_len, unsigned char *res_str,
190 long *dic_loc );
191 void OneShot();
192 void RadSet();
193 void Verbtoggle();
194 void FiltSet();
195 void xjdicrc();
196 void DoRADICALS();
197 int Vlookup();
198 void AppKanji(unsigned char c1,unsigned char c2);
199 void Verbinit();
200 void KOut(unsigned char *sout);
201 void LoadKana();
202 void DoRomaji(unsigned char kc);
203 int kanaconv(int rpos, int rlen);
204 void togglemode();
205 void engpritoggle();
206 void altdic(int dicincr);
207 void DoKANJI();
208 void DoJIS();
209 int addhit(long spot);
210 void GetEUC(unsigned char *eucline);
211 void cbreakon();
212 void cbreakoff();
213 void ioctlorig();
214 void ioctlraw();
215 void Lookup();
216 void Lookup2();
217 void DicSet();
218 void sjis2jis(int *p1,int *p2);/* Ken Lunde's routine */
219 void jis2sjis(unsigned char *p1,unsigned char *p2);/* Ken Lunde's routine */
220 int stringcomp(unsigned char *s1, unsigned char *s2);
221 void FixSJIS(unsigned char *jline);
222 void GetKBStr(unsigned char *prompt);
223 void ExtFileDisp();
224 void SeekErr(int iores);
225 void KOutc(int c);
226 void KLookup();
227 int KFlush(unsigned char *msg);
228 int KEOS (unsigned char *msg);
229 void NewWinSize();
230 int kcmp (unsigned char *t1, unsigned char *t2);
231 unsigned char *DicName(int dn);
232 /*====== end of prototypes==================================================*/
233
234
235 /* ==== ioctl routines supplied by Cameron Blackwood=======================*/
236 /* ==== BSD compatibility hacked in by Paul Burchard ==============*/
237 /* These routines are to disable/re-enable "cbreak", when I want to
238 switch in & out of canonical input processing. Mostly xjdic does
239 not use canonical input, as I want to react immediately to most
240 key-presses */
241
ioctlraw()242 void ioctlraw()
243 {
244 if (myi_status == IOCTL_ORIG)
245 {
246 #ifdef __STRICT_BSD__
247 ioctl(0, TIOCGETP, &orig); ioctl(0, TIOCGETP, &new);
248 new.sg_flags |= CBREAK; new.sg_flags &= ~ECHO;
249 ioctl(0, TIOCSETP, &new);
250 #elif defined(__POSIX__)
251 tcgetattr(0, &orig); tcgetattr(0, &new);
252 new.c_lflag &= ~ICANON; new.c_lflag &= ~ISIG; new.c_lflag &= ~ECHO;
253 new.c_lflag &= ~IXON; new.c_cc[VMIN] = 1;
254 new.c_cc[4] = 1; new.c_cc[5] = 0; tcsetattr(0, TCSANOW, &new);
255 #else
256 ioctl(0, TCGETA, &orig); ioctl(0, TCGETA, &new);
257 new.c_lflag &= ~ICANON; new.c_lflag &= ~ISIG; new.c_lflag &= ~ECHO;
258 new.c_lflag &= ~IXON;
259 new.c_cc[4] = 1; new.c_cc[5] = 0; ioctl(0, TCSETA, &new);
260 #endif
261 myi_status=IOCTL_RAW;
262 }
263 else return;
264 }
265
ioctlorig()266 void ioctlorig()
267 {
268 #ifdef __STRICT_BSD__
269 ioctl(0, TIOCSETP, &orig);
270 #elif defined(__POSIX__)
271 tcsetattr(0, TCSANOW, &orig);
272 #else
273 ioctl(0, TCSETA, &orig);
274 #endif
275 myi_status = IOCTL_ORIG;
276 }
277
278
cbreakoff()279 void cbreakoff()
280 {
281 ioctlorig();
282 /*system("stty -cbreak echo");*/
283 }
284
cbreakon()285 void cbreakon()
286 {
287 ioctlraw();
288 /*system("stty cbreak -echo");*/
289 }
290
getcharxx()291 int getcharxx()
292 {
293 if (clipmode)
294 {
295 return('n');
296 }
297 else
298 {
299 return(getchar());
300 }
301 }
302 /*====GetWinSize==== Hank Cohen's routine for getting the (new) window size==*/
303 /*
304 * (The following was supplied by Hank Cohen)
305 * We would like to use the Berkeley winsize structure to determine
306 * the number of lines and columns in the window. If that's not
307 * available we can use termcap.
308 * If using termcap, you will need to compile with "-lcurses -ltermcap".
309 */
310 char termcap_buf[1024];
GetWinSize()311 void GetWinSize()
312 {
313 char *term_name;
314
315 #ifdef WINSIZE_IOCTL_AVAILABLE
316 struct winsize window;
317
318 signal(SIGWINCH, NewWinSize);
319 ioctl(0,TIOCGWINSZ,&window);
320 MaxX = window.ws_col;
321 MaxX--;
322 MaxY = window.ws_row;
323 #else /* Use termcap */
324 if ((term_name = getenv("TERM")) == 0){
325 fprintf(stderr,"No TERM in environment!\n");
326 } else if (tgetent(termcap_buf, term_name) != 1) {
327 fprintf(stderr,"No termcap entry for %s!\n", term_name);
328 } else {
329 MaxX = tgetnum("co");
330 MaxY = tgetnum("li");
331 }
332 #endif /* termcap */
333 }
NewWinSize()334 void NewWinSize()
335 {
336 struct winsize window;
337 ioctl(0,TIOCGWINSZ,&window);
338 MaxX = window.ws_col;
339 MaxX--;
340 MaxY = window.ws_row;
341 }
342
343 /*=====KSLoad===Load file of kanji/stroke data==========================*/
KSLoad()344 void KSLoad()
345 {
346 int i,j,k,lno;
347 FILE *fk,*fopen();
348
349 fk = xfopen(KSname,"r",&xfilelen);
350 lno=0;
351 while(!feof(fk))
352 {
353 fgets(testline,9,fk);
354 if(feof(fk)) break;
355 testline[3] = 0;
356 lno++;
357 i = ((testline[0] & 0x7f)-0x30)*94 + ((testline[1] & 0x7f) - 0x21);
358 if ((i < 0) || (i > 6999))
359 {
360 printf("Bad kanji in %s at line %d (%s)\n",KSname,lno,testline);
361 i = 6999;
362 }
363 kstrokes[i] = testline[2]-'0';
364 }
365 fclose(fk);
366 }
367
368 /*=====RadLoad===Load file of Radical Data==============================*/
RadLoad()369 void RadLoad()
370 {
371 int i,j,k;
372 FILE *fk,*fopen();
373
374 fk = xfopen(RKname,"r", &xfilelen);
375 k = xfilelen/2;
376 RKanj1 = malloc(k*sizeof(char));
377 if (RKanj1==NULL)
378 {
379 printf("malloc failed for radical tables!\n");
380 exit(1);
381 }
382 RKanj2 = malloc(k*sizeof(char));
383 if (RKanj2==NULL)
384 {
385 printf("malloc failed for radical tables!\n");
386 exit(1);
387 }
388 i = -1;
389 j = 0;
390 rmax = 0;
391 while(!feof(fk))
392 {
393 fgets(testline,199,fk);
394 if(feof(fk)) break;
395 if (testline[0] == '$')
396 {
397 i++;
398 RadK1[i] = testline[2];
399 RadK2[i] = testline[3];
400 RKStart[i] = j;
401 RKCnt[i] = 0;
402 if (i != 0)
403 {
404 if (RKCnt[i-1] > rmax) rmax = RKCnt[i-1];
405 }
406 }
407 else
408 {
409 for (k = 0; k < strlen(testline); k++)
410 {
411 if (testline[k] < 127) continue;
412 RKanj1[j] = testline[k];
413 RKanj2[j] = testline[k+1];
414 RKCnt[i]++;
415 j++;
416 k++;
417 }
418 }
419 }
420 fclose(fk);
421 NoRads = i;
422 for (i=0; i<10;i++)
423 {
424 RKSet[i] = malloc(2*rmax+1);
425 if (RKSet[i] == NULL)
426 {
427 printf("malloc() failed for Radical set(s)!\n");
428 }
429 }
430 }
431 /*=====DoRomaji==collect search key from keyboard. Convert to kana.======*/
432 /* Code originally from JDIC */
DoRomaji(unsigned char kc)433 void DoRomaji(unsigned char kc)
434 {
435 int is;
436 unsigned char c;
437
438 /* collect the search string */
439 Smode = 1;
440 if(kc == '#') Smode = 2;
441 is = 0;
442 ksp = 0;
443 c = 0;
444 ktarg[0] = 0;
445 printf("\r \r%sROMAJI ENTRY:%s ",RVon,RVoff);
446 while (c != 0x0a) /* loop until Enter is pressed */
447 {
448 c = getcharxx();
449
450 if ((c == 0x8)||(c == 0x7f)) /* backspace */
451 {
452 if (is != ksp) /* kana mode - back over a romaji */
453 {
454 ksch[is-1] = '\0';
455 is--;
456 sprintf(tempout,"\r \r%sROMAJI ENTRY:%s %s%s",RVon,RVoff,ktarg,ksch+ksp);
457 KOut(tempout);
458 continue;
459 }
460 else
461 {
462 if (strlen(ktarg) != 0) /* kana mode - back over a kana */
463 {
464 ktarg[strlen(ktarg)-2] = '\0';
465 sprintf(tempout,"\r \r%sROMAJI ENTRY:%s %s%s",RVon,RVoff,ktarg,ksch+ksp);
466 KOut(tempout);
467 continue;
468 }
469 }
470 }
471 if (c > 32) /* ordinary character - store and display */
472 {
473 ksch[is] = c | 0x20;
474 ksch[is+1] = '\0';
475 is++;
476 sprintf(tempout,"\r \r%sROMAJI ENTRY:%s %s%s",RVon,RVoff,ktarg,ksch+ksp);
477 KOut(tempout);
478 }
479 if (ksp != is)
480 {
481
482 /* the input string so far is now parsed for romaji -> kana conversions.
483 function "kanaconv" is used for the various sub-strings */
484
485 /* if there is an "nn", "nm" or "mm", convert to first to "q" to force it to be
486 converted to a kana "n" */
487 if ((ksch[ksp] == 'n')&&(ksch[ksp+1] == 'n')) ksch[ksp] = 'q';
488 if ((ksch[ksp] == 'm')&&(ksch[ksp+1] == 'm')) ksch[ksp] = 'q';
489 if ((ksch[ksp] == 'n')&&(ksch[ksp+1] == 'm')) ksch[ksp] = 'q';
490 /* if there is "nx", where "x" is not a vowel or a "y", force the "n". */
491 if (((ksch[ksp] == 'n')||(ksch[ksp] == 'm'))&&(ksch[ksp+1] != 0))
492 {
493 c = ksch[ksp+1];
494 if((c!='y')&&(c!='a')&&(c!='e')&&(c!='i')&&(c!='o')&&(c!='u')&&(c!='\''))
495 {
496 ksch[ksp] = 'q';
497 }
498 }
499 if(kanaconv(ksp,1)) /* match on a,e,i,o,u,q or - ? */
500 {
501 continue;
502 }
503 if(ksch[ksp] == '\'')
504 {
505 ksp++;
506 continue;
507 }
508 if (ksch[ksp] == ksch[ksp+1]) /* double consonant - force small
509 "tsu" */
510 {
511 ksch[ksp] = '*';
512 kanaconv(ksp,1);
513 continue;
514 }
515 if(kanaconv(ksp,2)) /* match on two letter syllable */
516 {
517 continue;
518 }
519 if(kanaconv(ksp,3)) /*match on 3 letter syllable */
520 {
521 continue;
522 }
523 if(kanaconv(ksp,4)) /*match on 4 letter syllable */
524 {
525 continue;
526 }
527 } /* end of rom->kana */
528 } /* end of while loop */
529 if (ksch[ksp] =='n') /*flush out a trailing "n"*/
530 {
531 ksch[ksp] = 'q';
532 kanaconv(ksp,1);
533 }
534
535 strcpy(instr,ktarg);
536 }
537
538 /*========kanaconv==convert romaji to kana==============================*/
539 /* More code from JDIC */
kanaconv(int rpos,int rlen)540 int kanaconv(int rpos, int rlen)
541 {
542 /* rpos and rlen are the start and length of the romaji characters in
543 array ksch. Smode specifies hira or kata. If found, the kana is
544 appended to ktarg and TRUE returned. */
545
546 int koff,ki;
547 unsigned char targ[50];
548
549 koff = (Smode-1)*NRKANA;
550 for(ki = 0; ki < rlen; ki++)
551 {
552 targ[ki] = ksch[rpos+ki];
553 }
554 targ[rlen] = 0;
555 for (ki = koff; ki < koff+NRKANA; ki+=2)
556 {
557 if (strlen(targ) != strlen(kanatab[ki])) continue;
558 if (stringcomp(targ,kanatab[ki]) != 0) continue;
559 strcat(ktarg,kanatab[ki+1]);
560 ksp = ksp+rlen;
561 sprintf(tempout,"\r \r%sROMAJI ENTRY:%s %s%s",RVon,RVoff,ktarg,ksch+ksp);
562 KOut(tempout);
563 return (TRUE);
564 }
565 return(FALSE);
566 }
567
568 /* ==== LoadKana=== Load the romaji to kana conversion file============*/
LoadKana()569 void LoadKana()
570 {
571 int i,ih,mode;
572 FILE *fp,*fopen();
573 unsigned char LKin[80],*ptr;
574
575 for (i = 0; i < NRKANA*2; i++) strcpy(kanatab[i]," ");
576 fp = xfopen(ROMname,"r", &xfilelen);
577 mode = 0;
578 while (!feof(fp))
579 {
580 fgets(LKin,79,fp);
581 if (feof(fp))break;
582 /*LKin[strlen(LKin)-1] = '\0';*/
583 if(LKin[0] == '#')continue;
584 if((LKin[0] == '$')&&((LKin[1]|0x20) == 'h'))
585 {
586 mode = 0;
587 ih = 0;
588 continue;
589 }
590 if((LKin[0] == '$')&&((LKin[1]|0x20) == 'k'))
591 {
592 mode = 1;
593 ih = 0;
594 continue;
595 }
596 ptr = (unsigned char *)strtok(LKin," \t");
597 if ( ptr != NULL ) strcpy(kanatab[mode*NRKANA+ih*2+1],ptr);
598 ptr = (unsigned char *)strtok(NULL," \t\r\n");
599 if ( ptr != NULL ) strcpy(kanatab[mode*NRKANA+ih*2],ptr);
600 ih++;
601 if(ih == NRKANA)
602 {
603 printf("Too many romaji table entries!");
604 exit(1);
605 }
606 }
607 fclose(fp);
608 }
609 /*======jis2sjis (from Ken Lunde) =====================================*/
jis2sjis(unsigned char * p1,unsigned char * p2)610 void jis2sjis(unsigned char *p1,unsigned char *p2) /* courtesy of Ken Lunde */
611 {
612 register unsigned char c1 = *p1;
613 register unsigned char c2 = *p2;
614 register int rowOffset = c1 < 95 ? 112 : 176;
615 register int cellOffset = c1 % 2 ? 31 + (c2 > 95) : 126;
616
617 *p1 = ((c1 + 1) >> 1) + rowOffset;
618 *p2 = c2 + cellOffset;
619 }
620
621 /*====KEOS===End of screen processing for KFlush==================*/
KEOS(unsigned char * msg)622 int KEOS (unsigned char *msg)
623 {
624 unsigned char ck;
625
626 if (DRow < MaxY-2) return(TRUE);
627 DRow = 0;
628 if (strlen(msg) == 0) return (TRUE);
629 printf("%s\n",msg);
630 ck = getcharxx();
631 if ((ck == 'n')||(ck == 'N')) return (FALSE);
632 if ((ck == 'y')||(ck == 'Y')) return (TRUE);
633 if ((ck != 0xa) && (ck != 0xd)) ungetc(ck,stdin);
634 return (FALSE);
635 }
636 /*====KFlush==== Output a line, folding if necessary===============*/
637 /* This is now the main screen output routine. An array "KLine"
638 is built up of text to be output. KFlush() sends it to the screen,
639 folding the line at white-space if it is about to hit the RHS.
640 It also tests for end of screen, and prompts for continuation,
641 using the KEOS(). Returns TRUE for continue, and FALSE for
642 stopping.
643 Called with the prompt measseage. */
644
KFlush(unsigned char * msg)645 int KFlush(unsigned char *msg)
646 {
647 unsigned char *kptr,ktemp[80];
648 int retf,it,j;
649
650 if (strlen(KLine) == 0) return (TRUE);
651 kptr = (unsigned char *)strtok(KLine," ");
652 while (kptr != NULL)
653 {
654 strcpy(ktemp,kptr);
655 if (ktemp[0] == '\t')
656 {
657 it = DCol % 10;
658 if (it != 0)
659 {
660 DCol = DCol+10-it;
661 if (DCol <= MaxX-1)
662 {
663 for (j = 0;j < 10-it;j++) KOut(" ");
664 }
665 }
666 strcpy(ktemp,ktemp+1);
667 }
668 it = strlen(ktemp);
669 if (DCol+it < MaxX)
670 {
671 DCol = DCol+it+1;
672 }
673 else
674 {
675 KOut("\n");
676 DRow++;
677 DCol=it+1;
678 retf = KEOS(msg);
679 if (!retf) return (FALSE);
680 }
681 KOut(ktemp);
682 if (DCol <= MAXCOLS) KOut(" ");
683 kptr = (unsigned char *)strtok(NULL," ");
684 }
685 KOut("\n");
686 DRow++;
687 retf = KEOS(msg);
688 DCol = 0;
689 if (!retf) return (FALSE);
690 return (TRUE);
691 }
692 /*====KOutc===add a character to KLine=============================*/
KOutc(int c)693 void KOutc(int c)
694 {
695 unsigned char tmp[2];
696 tmp[0] = c;
697 tmp[1] = 0;
698 strcat(KLine,tmp);
699 return;
700 }
701
702 /*=====KOut===output kana/kanji according to selected mode===========*/
703 /* Mostly called from KFlush. Outputs the parameter string, in the
704 specified JIS mode. */
KOut(unsigned char * sout)705 void KOut(unsigned char *sout)
706 {
707 int i;
708 unsigned char c1,c2;
709
710 for (i = 0; i < strlen(sout); i++)
711 {
712 c1 = sout[i]; c2 = sout[i+1];
713 if (c1 < 127)
714 {
715 if (c1 == '~') c1 = ' ';
716 printf("%c",c1);
717 continue;
718 }
719 switch(Omode)
720 {
721 case 0 : /* JIS (default) */
722 if (c1 == 0x8f)
723 {
724 printf("%c$(D%c%c%c(B",0x1b,c2&0x7f,sout[i+2]&0x7f,0x1b);
725 i+=2;
726 break;
727 }
728 printf("%c$B%c%c%c(B",0x1b,c1&0x7f,c2&0x7f,0x1b);
729 i++;
730 break;
731
732 case 1 : /* EUC (internal format) */
733 if (c1 == 0x8f)
734 {
735 printf("%c%c%c",c1,c2,sout[i+2]);
736 i+=2;
737 break;
738 }
739 printf("%c%c",c1,c2);
740 i++;
741 break;
742
743 case 2 : /* Shift-JIS */
744 c1 -= 128; c2 -= 128;
745 jis2sjis(&c1,&c2);
746 printf("%c%c",c1,c2);
747 i++;
748 break;
749 }
750 }
751 }
752
753 /*======function to test if this entry has already been displayed=====*/
addhit(long spot)754 int addhit(long spot)
755 {
756 int i;
757
758 if (spot == 0) return(TRUE);
759
760 for (i=0;i<=hitind;i++)
761 {
762 if(hittab[i] == spot) return(FALSE);
763 }
764 if(hitind < NOHITS) hitind++;
765 hittab[hitind] = spot;
766 return(TRUE);
767 }
768
769 /*====GetEUC - ensures that any JIS in the string is EUC ============*/
770 /* Based on the GetEUC in JREADER, this routine examines
771 the string "instr" and converts any JIS or SJIS to EUC.
772 The result is placed in the specified string. */
773
GetEUC(unsigned char * eucline)774 void GetEUC(unsigned char *eucline)
775 {
776 int i,j,SI,J212,J212sw;
777
778 J212 = FALSE;
779 eucline[0] = '\0';
780 chline = 0;
781 chpos = 0;
782 SI = FALSE;
783 ShiftJIS = FALSE;
784 j = 0;
785 for (i = 0; i < strlen(instr); i++)
786 {
787 if((instr[i]==0x1b)&&(instr[i+1]=='$')&&(instr[i+2]=='(')&&(instr[i+3]=='D'))
788 {
789 SI = TRUE;
790 J212 = TRUE;
791 J212sw = 0;
792 NoSJIS = TRUE;
793 i+=3;
794 continue;
795 }
796 if((instr[i]==0x1b)&&(instr[i+1]=='$')&&(instr[i+2]=='B'))
797 {
798 SI = TRUE;
799 J212 = FALSE;
800 i+=2;
801 continue;
802 }
803 if((instr[i]==0x1b)&&(instr[i+1]=='$')&&(instr[i+2]=='@'))
804 {
805 SI = TRUE;
806 J212 = FALSE;
807 i+=2;
808 continue;
809 }
810 if((instr[i]==0x1b)&&(instr[i+1]=='(')&&(instr[i+2]=='J'))
811 {
812 SI = FALSE;
813 J212 = FALSE;
814 i+=2;
815 continue;
816 }
817 if((instr[i]==0x1b)&&(instr[i+1]=='(')&&(instr[i+2]=='B'))
818 {
819 SI = FALSE;
820 J212 = FALSE;
821 i+=2;
822 continue;
823 }
824 if (instr[i] == '\0')break;
825 if (SI)
826 {
827 if (J212 && (J212sw == 0)) eucline[j++] = 0x8f;
828 eucline[j] = instr[i] | 0x80;
829 J212sw = (J212sw+1) % 2;
830 }
831 else
832 {
833 eucline[j] = instr[i];
834 }
835 j++;
836 eucline[j] = '\0';
837 }
838 /* fix up SHIFT-JIS, if present */
839 if (!NoSJIS) FixSJIS(eucline);
840 }
841
842 /*====FixSJIS=== convert any SJIS to EUC in a string==================*/
FixSJIS(unsigned char * jline)843 void FixSJIS(unsigned char *jline)
844 {
845 int i,p1,p2,ShiftJIS;
846
847 ShiftJIS = FALSE;
848 for (i = 0; i < strlen(jline); i++)
849 {
850 p1 = jline[i];
851 if (p1 < 127)continue;
852 p2 = jline[i+1];
853 if ((p1 >= 129) && (p1 <= 159)) ShiftJIS = TRUE;
854 if (((p1 >= 224) && (p1 <= 239))&& ((p2 >= 64) && (p2 <= 158))) ShiftJIS = TRUE;
855 if (ShiftJIS)
856 {
857 sjis2jis (&p1,&p2);
858 p1 += 128;
859 p2 += 128;
860 jline[i] = p1;
861 jline[i+1] = p2;
862
863 }
864 i++;
865 }
866 }
867
868 /*===sjis2jis - convert ShiftJIS to JIS ===========================*/
869
sjis2jis(int * p1,int * p2)870 void sjis2jis (int *p1,int *p2) /* Ken Lunde's routine */
871 {
872 register unsigned char c1 = *p1;
873 register unsigned char c2 = *p2;
874 register int adjust = c2 < 159;
875 register int rowOffset = c1 < 160 ? 112 : 176;
876 register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
877
878 *p1 = ((c1 - rowOffset) << 1) - adjust;
879 *p2 -= cellOffset;
880 }
881
882 /*====ExtFileDisp===Display from EDICTEXT file=======================*/
883
ExtFileDisp()884 void ExtFileDisp()
885 {
886
887 unsigned extrec[2],seekoff,iores,hi,lo,mid,ejdxtest[2];
888 unsigned char Ssch[20];
889 int bsres,i;
890
891 printf("%sExtension Key:%s ",RVon,RVoff);
892
893 GetKBStr("Extension Key:");
894 if(fbuff[0] < 128)
895 {
896 printf("\nThe extension file has Kanji & Kana keys\n");
897 return;
898 }
899 if(!Extopen)
900 {
901 fe = xfopen(EXTname,"rb", &extlen);
902 fex = xfopen(EXTJDXname,"rb", &extjdxlen);
903 Extopen = TRUE;
904 extlen++;
905 fread(ejdxtest,sizeof(long),1,fex);
906 if (ejdxtest[0] != (extlen+jiver))
907 {
908 printf("\nEDICT Extension file & Index Mismatch! %ld %ld\n",ejdxtest[0],extlen+jiver);
909 exit(1);
910 }
911 }
912
913 lo = 0;
914 hi = (extjdxlen/(2*sizeof(long)))-1;
915 while(TRUE)
916 {
917 mid = (lo+hi)/2;
918 seekoff = mid;
919 seekoff *= (2*sizeof(long));
920 seekoff+=sizeof(long);
921 if((iores = fseek(fex,seekoff,SEEK_SET)) != 0)SeekErr(iores);
922 iores = fread(&extrec,sizeof(long),2,fex);
923 seekoff = extrec[0];
924 if((iores = fseek(fe,seekoff,SEEK_SET)) != 0)SeekErr(iores);
925 iores = fread(&Ssch,sizeof(char),19,fe);
926 Ssch[19] = 0;
927 i = 0;
928 bsres = 0;
929 for (i = 0; Ssch[i] != 0 ;i++)
930 {
931 if (Ssch[i] < 128) break;
932 if (fbuff[i] < 128) break;
933 if (fbuff[i] < Ssch[i])
934 {
935 bsres = -1;
936 break;
937 }
938 if (fbuff[i] > Ssch[i])
939 {
940 bsres = 1;
941 break;
942 }
943 }
944 if ((bsres != 0) && ((lo + hi) == 0)) break;
945 if(bsres < 0)
946 {
947 if (mid == 0) break;
948 hi = mid-1;
949 }
950 else
951 {
952 lo = mid+1;
953 }
954 if (bsres == 0) break;
955 if (lo > hi) break;
956 if (hi < 0) break;
957 }
958 if (bsres == 0)
959 {
960 printf("\n%sDictionary Extension Display%s\n",RVon,RVoff);
961 seekoff = extrec[1];
962 if((iores = fseek(fe,seekoff,SEEK_SET)) != 0)SeekErr(iores);
963 strcpy (KLine," <");
964 DRow = 0;
965 DCol = 0;
966 while(!feof(fe))
967 {
968 fgets(LogLine,199,fe);
969 if (feof(fe)) break;
970 if ((LogLine[0] == '<') && (LogLine[1] > 128)) break;
971 for (i = strlen(LogLine); i >= 0; i--)
972 {
973 if (LogLine[i] < 0x20) LogLine[i] = 0;
974 }
975 strcat(KLine,LogLine);
976 if (!KFlush("Continue displaying extension information? (y/n)")) break;
977 DCol = 0;
978 strcpy (KLine," ");
979 }
980 return;
981 }
982 if (bsres != 0)
983 {
984 printf("\nNot found in Extension file!\n");
985 return;
986 }
987 }
988 /*====kcmp === comparison routine for qsort for kanji table==========*/
kcmp(unsigned char * t1,unsigned char * t2)989 int kcmp (unsigned char *t1, unsigned char *t2)
990 {
991 int i,cmp;
992 for (i=0;i<4;i++)
993 {
994 cmp = t1[i] - t2[i];
995 if (cmp == 0) continue;
996 return(cmp);
997 }
998 return(0);
999 }
1000
1001 /*==== Verbinit===Load & initialize verb inflection details==========*/
Verbinit()1002 void Verbinit()
1003 {
1004 unsigned char tempstr[512],*vptr;
1005 int vmode,i;
1006 FILE *fi,*fopen();
1007
1008 for (i = 0;i< VMAX;i++)
1009 {
1010 vdicf[i][0] = 0;
1011 vinfl[i][0] = 0;
1012 vcommno[i] = 40;
1013 }
1014 for (i = 0;i<40;i++)
1015 {
1016 vcomms[i][0] = 0;
1017 }
1018 vmode = 1;
1019 strcpy(vcomms[40],"Unknown type");
1020 verblen = 0;
1021 fi = xfopen(Vname,"r", &xfilelen);
1022 while(TRUE)
1023 {
1024 fgets(tempstr,511,fi);
1025 if(feof(fi))break;
1026 if (tempstr[0] == '#')continue;
1027 if (tempstr[0] == '$')
1028 {
1029 vmode = 2;
1030 continue;
1031 }
1032
1033 switch (vmode) {
1034 case 1 :
1035 vptr = (unsigned char *)strtok(tempstr," \t\n\r");
1036 i = atoi(vptr);
1037 if ((i < 0) || (i > 39)) break;
1038 vptr = (unsigned char *)strtok(NULL,"\t\n\r");
1039 strcpy(vcomms[i],vptr);
1040 break;
1041 case 2 :
1042 vptr = (unsigned char *)strtok(tempstr," \t\n\r");
1043 strcpy(vinfl[verblen],vptr);
1044 vptr = (unsigned char *)strtok(NULL," \t\n\r");
1045 strcpy(vdicf[verblen],vptr);
1046 vptr = (unsigned char *)strtok(NULL," \t\n\r");
1047 i = atoi(vptr);
1048 if ((i >= 0)&&(i <= 40)) vcommno[verblen] = i;
1049 verblen++;
1050 if (verblen==VMAX)
1051 {
1052 printf("Verb data overflow. Ignoring following entries\n");
1053 verblen--;
1054 fclose(fi);
1055 return;
1056 }
1057 break;
1058 }
1059 }
1060 verblen--;
1061 fclose(fi);
1062 }
1063
1064 /*=== append a kana/kanji to the verb display line================*/
AppKanji(unsigned char c1,unsigned char c2)1065 void AppKanji(unsigned char c1,unsigned char c2)
1066 {
1067 unsigned char ops[3];
1068
1069 ops[0] = c1;
1070 ops[1] = c2;
1071 ops[2] = 0;
1072 strcat(vline,ops);
1073 }
1074
1075 /*=======Vlookup== look up plain form verb in dictionary=============*/
Vlookup()1076 int Vlookup()
1077 {
1078
1079 int xjresp,roff,rlen;
1080 unsigned char repstr[512];
1081 long respos;
1082 int hit,schix;
1083 unsigned char khi,klo,cc,ops[4];
1084 long it;
1085
1086 DicNum = CurrDic;
1087 khi = 0;
1088 klo = 0;
1089 vline[0] = 0;
1090 xjdserver (XJ_FIND, DicNum,it, strlen(vstr), vstr,
1091 &xjresp, &respos, &roff, &rlen, repstr, &DicLoc);
1092 if (xjresp != XJ_OK) return (FALSE);
1093 it = respos;
1094 while (xjresp == XJ_OK)
1095 {
1096 if (roff != 0)
1097 {
1098 it++;
1099 xjdserver (XJ_ENTRY, DicNum, it, strlen(vstr), vstr,
1100 &xjresp, &respos, &roff, &rlen, repstr, &DicLoc);
1101 continue;
1102 }
1103 schix = 0;
1104 /* now work forwards, displaying the line */
1105 hit = FALSE;
1106 /* If the first word has already been displayed, skip it.
1107 Otherwise, put braces around the first word (kanji) */
1108 while (TRUE)
1109 {
1110 cc = repstr[schix];
1111 if (cc < 32) break;
1112 /* put a () around the yomikata in an ascii or Kanji search */
1113 if (cc=='[')
1114 {
1115 AppKanji(0xa1,0xcA); /* EUC ( */
1116 schix++;
1117 continue;
1118 }
1119 if (cc==']')
1120 {
1121 AppKanji(0xA1,0xCB); /* EUC ) */
1122 schix++;
1123 continue;
1124 }
1125 if (cc < 128) /* non-Japanese, display it
1126 (fix up the "/") */
1127 {
1128 ops[0]= cc;
1129 ops[1] = '\0';
1130 if (ops[0] == '/')
1131 {
1132 if (hit)
1133 {
1134 ops[0] = ',';
1135 ops[1] = ' ';
1136 ops[2] = '\0';
1137 }
1138 else
1139 {
1140 hit = TRUE;
1141 ops[0] = '\0';
1142 }
1143 }
1144 strcat(vline,ops);
1145 }
1146 else
1147 {
1148 if (cc == 0x8f)
1149 {
1150 AppKanji(cc,0);
1151 schix++;
1152 continue;
1153 }
1154 if (khi == 0)
1155 {
1156 khi = cc;
1157 }
1158 else
1159 {
1160 klo = cc;
1161 AppKanji(khi,klo);
1162 khi = 0;
1163 klo = 0;
1164 }
1165 }
1166 schix++;
1167 }
1168 if(strlen(vline) > 0) break;
1169 }
1170 if(strlen(vline) <=1) return(FALSE);
1171 return(TRUE);
1172 }
1173 /*=========== slencal - calculate the actual search string length ===*/
1174 /* This routine exists to sort out the actual length of the search
1175 string when there is a mix of 2 and 3-byte EUC characters */
1176
slencal(int noch,unsigned char * targ)1177 int slencal (int noch, unsigned char *targ)
1178 {
1179 int i,j;
1180
1181 if (targ[0] < 127) return(noch+1);
1182 i = 0;
1183 j = 0;
1184 while(i <= noch)
1185 {
1186 if (targ[j] == 0x8f) j++;
1187 i++;
1188 j+=2;
1189 }
1190 return(j);
1191 }
1192
1193 /*=========== Lookup - global frontend to dictionary search ========*/
Lookup()1194 void Lookup()
1195 {
1196 int gi,dicsav,gdiclenbest;
1197 unsigned char retsave[KFBUFFSIZE],rethdr[5];
1198
1199 retsave[0] = 0;
1200 gdiclen = 0;
1201 gdiclenbest = 0;
1202 if ((!GDmode) || (Dmode == 1))
1203 {
1204 Lookup2();
1205 return;
1206 }
1207 if (gdicmax == 0)
1208 {
1209 printf("\nNo global dictionaries specified - disabling!\n");
1210 GDmode = FALSE;
1211 Lookup2();
1212 return;
1213 }
1214 dicsav = CurrDic;
1215 for (gi=0;gi<=gdicmax;gi++)
1216 {
1217 CurrDic = gdicnos[gi];
1218 Lookup2();
1219 if ((gdiclen > gdiclenbest) || ((strlen(KLine) > strlen(retsave)) && (gdiclen == gdiclenbest)))
1220 {
1221 strcpy(retsave,KLine);
1222 strcpy(rethdr,"[X] ");
1223 rethdr[1] = '0'+gdicnos[gi];
1224 gdiclenbest = gdiclen;
1225 }
1226 }
1227 strcpy(KLine,rethdr);
1228 strcat(KLine,retsave);
1229 KFlush("");
1230 CurrDic = dicsav;
1231 }
1232
1233
1234
1235 /*=========== Lookup2 - carry out dictionary search ================*/
Lookup2()1236 void Lookup2()
1237 {
1238 /*
1239
1240 Carries out a search for matches with the string "fbuff" in the specified
1241 dictionary. It matches the full string, then progressively shortens it.
1242
1243 */
1244 int schix,schiy,schiz,j,dind,hit,skip,brace,engrv;
1245 int EngFirst;
1246 int slk,slen,slenx,i,srchlen,srchlenok;
1247 unsigned int khi,klo,cc;
1248 unsigned long zz,bshit[20];
1249 unsigned char *kptr,*kptr2, k1,k2,kanj1,kanj2,kanj3;
1250 int FiltOK;
1251 unsigned char vlast[11],temp[11],ops[80];
1252 int vi,vok,KDNSflag,KDskip,KTest;
1253 int xjresp,roff,rlen;
1254 unsigned char repstr[512];
1255 unsigned long respos;
1256
1257 vlast[0] = 0;
1258 KLcount = 0;
1259 DRow = 3;
1260
1261 if (!GDmode && (Dmode == 0)&&Jverb&&(fbuff[0] > 0xa8) && (fbuff[2] < 0xa5) && (fbuff[4] < 0xa5))
1262 {
1263 /* possible inflected verb or adjective, so look up the verb table
1264 for a matching plain form, and serch the dictionary for it */
1265
1266 vstr[0] = fbuff[0];
1267 vstr[1] = fbuff[1];
1268 vstr[2] = 0;
1269 for(i=0;i<11;i++) temp[i] = fbuff[i];
1270
1271 for (vi = 0;vi <= verblen;vi++)
1272 {
1273 vok = TRUE;
1274 vstr[2] = 0;
1275 for (i = 0;i < strlen(vinfl[vi]);i++)
1276 {
1277 if (fbuff[2+i] != vinfl[vi][i])
1278 {
1279 vok = FALSE;
1280 break;
1281 }
1282 }
1283 if (!vok) continue;
1284 strcat(vstr,vdicf[vi]);
1285
1286 if(strcmp(vstr,temp) == 0) continue;
1287 if (strcmp(vstr,vlast) == 0)continue;
1288 if (Vlookup())
1289 {
1290 strcpy(vlast,vstr);
1291 printf(" Possible inflected verb or adjective: (%s)\n",vcomms[vcommno[vi]]);
1292 strcpy(KLine,vline);
1293 DCol = 0;
1294 KFlush("");
1295
1296 printf("Continue with this search (y/n)\n");
1297 cc = getcharxx();
1298 if ((cc == 'n')||(cc == 'N')) return;
1299 if ((cc != 'y')&&(cc != 'Y'))
1300 {
1301 ungetc(cc,stdin);
1302 return;
1303 }
1304 DRow = 1;
1305 }
1306 }
1307 }
1308 /* do a binary search through the index table looking for a match */
1309 KLine[0] = 0;
1310 DCol = 0;
1311 nok = 0;
1312 DispHit = FALSE;
1313 khi = 0;
1314 klo = 0;
1315 DicNum = CurrDic;
1316 if(Dmode !=0) DicNum = 0;
1317 if (fbuff[strlen(fbuff)-1] < 32) fbuff[strlen(fbuff)-1] = 0;
1318 for (slenx = 1; slenx < 20; slenx++)
1319 {
1320 if (slencal(slenx-1,fbuff) >= strlen(fbuff)) break;
1321 }
1322 Smode = 0;
1323 if ((fbuff[0] == 0xa4)||(fbuff[0] == 0xa5))
1324 {
1325 Smode = 1;
1326 for (i = 0; i < strlen(fbuff); i+=2)
1327 {
1328 if (fbuff[i] > 0xa5)
1329 {
1330 Smode = 0;
1331 break;
1332 }
1333 }
1334 }
1335 srchlenok = 0;
1336 for ( slen = 0; slen <slenx; slen++)
1337 {
1338 srchlen = slencal(slen,fbuff);
1339 xjdserver (XJ_FIND, DicNum, zz, srchlen, fbuff,
1340 &xjresp, &respos, &roff, &rlen, repstr, &DicLoc);
1341 /* printf("F: Returning: %d %ld %d %d %s\n",xjresp,respos,roff,rlen,repstr); */
1342 if (xjresp == XJ_OK)
1343 {
1344 bshit[slen] = respos;
1345 srchlenok = srchlen;
1346 continue;
1347 }
1348 else
1349 {
1350 break;
1351 }
1352 }
1353 if (slen == 0)
1354 {
1355 if (!GDmode) printf("No Match Found\n");
1356 return;
1357 }
1358 if (EMmode == 0)
1359 {
1360 if (srchlenok != strlen(fbuff))
1361 {
1362 printf("No Match Found (Exact Test)\n");
1363 return;
1364 }
1365 if (((fbuff[0] <127) && isalnum(repstr[roff+srchlenok]))
1366 ||((fbuff[0] >=0xa4) && (repstr[roff+srchlenok] > 127)))
1367 {
1368 printf("No Match Found (Exact Test)\n");
1369 return;
1370 }
1371 }
1372 hitind = 0;
1373 hittab[0] = -1;
1374 gdiclen = slen*2;
1375 /* loop for each possible string length */
1376 for (dind = slen-1; dind >= 0 ; dind--)
1377 {
1378 /* this is the display loop - usually one line per entry */
1379 it = bshit[dind];
1380 while (TRUE) /* display as long as there are matches*/
1381 {
1382 srchlen = slencal(dind,fbuff);
1383 xjdserver (XJ_ENTRY, DicNum, it, srchlen,
1384 fbuff, &xjresp, &respos, &roff, &rlen, repstr, &DicLoc);
1385 /* printf("E: Returning: %d %ld %d %d %ld %s\n",xjresp,respos,roff,rlen,DicLoc,repstr); */
1386 if (xjresp != XJ_OK) break;
1387 schix = 0;
1388 schiy = roff;
1389 /* make copy of line for filter testing */
1390 slk=0;
1391 for(schiz=0;repstr[schiz]>=0x20;schiz++)
1392 {
1393 testline[schiz] = repstr[schiz];
1394 if(testline[schiz]=='/')slk++;
1395 }
1396 testline[schiz] = '\0';
1397 kanj1 = testline[0];
1398 kanj2 = testline[1];
1399 FiltOK = TRUE;
1400 /* now if filters are active, check the line for a match */
1401 if((Dmode == 0)&& nofilts && (!GDmode))
1402 {
1403 if(nofilts>0)
1404 {
1405 for (i=0;i<NOFILT;i++)
1406 {
1407 if(!filtact[i]||!filton[i])continue;
1408 if(filttype[i] == 0)
1409 {
1410 FiltOK = FALSE;
1411 for(j=0;j<filtcoden[i];j++)
1412 {
1413 if(strstr(testline,filtcodes[i][j]) != NULL)
1414 {
1415 FiltOK = TRUE;
1416 break;
1417 }
1418 }
1419 if(FiltOK)break;
1420 }
1421 if((filttype[i] == 1)||((filttype[i] == 2)&&(slk <= 2)))
1422 {
1423 FiltOK = TRUE;
1424 for(j=0;j<filtcoden[i];j++)
1425 {
1426 if(strstr(testline,filtcodes[i][j]) != NULL)
1427 {
1428 FiltOK = FALSE;
1429 break;
1430 }
1431 }
1432 if(!FiltOK) break;
1433 }
1434 }
1435 }
1436 }
1437 if(strf && (Dmode ==1))
1438 {
1439 FiltOK = FALSE;
1440 if (strstr(testline,strfilt) != NULL) FiltOK = TRUE;
1441 }
1442 if ((Dmode == 0) && SFFlag && FiltOK)
1443 {
1444 FiltOK = FALSE;
1445 kptr = strstr(testline,SingleFilter);
1446 if ((kptr != NULL) && (SingleFilter[0] < 128))
1447 {
1448 FiltOK = TRUE;
1449 }
1450 else
1451 {
1452 while (TRUE)
1453 {
1454 if (kptr == NULL) break;
1455 if ((strlen(testline) - strlen(kptr)) % 2 == 0)
1456 {
1457 FiltOK = TRUE;
1458 break;
1459 }
1460 else
1461 {
1462 kptr2 = kptr;
1463 kptr = strstr(kptr2+1,SingleFilter);
1464 }
1465 }
1466 }
1467 }
1468 if ((EMmode == 0) && (((fbuff[0] <127) && isalnum(repstr[roff+srchlenok]))
1469 ||((fbuff[0] >=0xa4) && (repstr[roff+srchlenok] > 127))))
1470 {
1471 FiltOK = FALSE;
1472 }
1473 KFlushRes = TRUE;
1474 /* now work forwards, displaying the line */
1475 KTest = TRUE;
1476 if (((fbuff[0] > 0xa5) || (fbuff[0] == 0x8f)) && (roff != 0)) KTest = FALSE;
1477 if ((Dmode == 0) && GDmode) KTest = TRUE;
1478 if (roff != 0) gdiclen--;
1479 if (FiltOK && addhit(DicLoc) && (!FirstKanj || (FirstKanj && KTest)))
1480 {
1481 DispHit = TRUE;
1482 if ((Dmode == 0) &&(ROmode == 0))
1483 {
1484 /* We are in "raw output mode, so just splat out the EDICT line.
1485 Note that this block does its own "end-of display" processing */
1486 for(schiz=0;repstr[schiz]>=0x20;schiz++)
1487 {
1488 KLine[schiz] = repstr[schiz];
1489 }
1490 KLine[schiz] = '\0';
1491 KFlushRes = KFlush("Continue displaying matches? (y/n)");
1492 it++;
1493 if (!KFlushRes) return;
1494 continue;
1495 }
1496 engrv = FALSE;
1497 EngFirst = TRUE;
1498 if((Dmode == 0) || ((Dmode ==1)&&(KLRmode == 0))) KLine[0] = 0;
1499 if (Dmode == 0)
1500 {
1501 if (fbuff[0] == SPTAG)
1502 {
1503 sprintf(ops,"%d: ",dind);
1504 strcpy(KLine,ops);
1505 }
1506 else
1507 {
1508 sprintf(ops,"%d: ",dind+1);
1509 strcpy(KLine,ops);
1510 }
1511 DCol = 0;
1512 }
1513 strcat(KLine," ");
1514 if (Dmode == 1)
1515 {
1516 ops[0] = 0xa1; ops[1] = 0xda;
1517 kanj1 = repstr[0];
1518 kanj2 = repstr[1];
1519 kanj3 = repstr[2];
1520 ops[2] = repstr[0];
1521 ops[3] = repstr[1];
1522 ops[4] = repstr[2];
1523 ops[5] = 0;
1524 if (ops[2] != 0x8f) ops[4] = 0;
1525 instr[0] = 0xa1; instr[1] = 0xdb; instr[2] = 0;
1526 strcat (ops,instr);
1527 if (KLRmode == 0)
1528 {
1529 if (ops[2] == 0x8f)
1530 {
1531 sprintf (instr,"%s 1-%x%x [1-%d]",ops,kanj2&0x7f,kanj3&0x7f,((kanj2&0x7f)-0x20)*100+(kanj3&0x7f)-0x20);
1532 schix+=8;
1533
1534 }
1535 else
1536 {
1537 k1 = kanj1 & 0x7f;
1538 k2 = kanj2 & 0x7f;
1539 jis2sjis(&k1,&k2);
1540 sprintf (instr,"%s %x%x [%d:%x%x]",ops,kanj1&0x7f,kanj2&0x7f,((kanj1&0x7f)-0x20)*100+(kanj2&0x7f)-0x20,k1,k2);
1541 schix+=7;
1542 }
1543 strcat(KLine,instr);
1544 }
1545 else
1546 {
1547 KLine[0] = 0;
1548 karray[nok][2] = kanj1;
1549 karray[nok][3] = kanj2;
1550 karray[nok][4] = kanj3;
1551 kptr = strstr(testline,"S");
1552 if (kptr == NULL)
1553 {
1554 karray[nok][0] = 0;
1555 }
1556 else
1557 {
1558 karray[nok][0] = atoi(kptr+1);
1559 }
1560 kptr = strstr(testline,"B");
1561 if (kptr == NULL)
1562 {
1563 karray[nok][1] = 0;
1564 }
1565 else
1566 {
1567 karray[nok][1] = atoi(kptr+1);
1568 }
1569 KLcount++;
1570 if (nok < KANJARRAYSIZE) nok++;
1571 continue;
1572 }
1573 }
1574 while ((cc = repstr[schix]) != 0x0a)
1575 {
1576 if (cc == 0x0d) break;
1577 if (RVACTIVE && (schix == roff)) strcat (KLine,RVon);
1578 if (RVACTIVE && (schix == roff+srchlen)) strcat (KLine,RVoff);
1579 if ((Dmode == 0) && (cc == '['))
1580 {
1581 ops[0] = 0xa1; ops[1] = 0xca; ops[2] = 0; /* JIS ( */
1582 strcat(KLine,ops);
1583 schix++;
1584 continue;
1585 }
1586 if ((Dmode == 0) && (cc == ']'))
1587 {
1588 ops[0] = 0xa1; ops[1] = 0xcb; ops[2] = 0; /* JIS ( */
1589 strcat(KLine,ops);
1590 schix++;
1591 continue;
1592 }
1593 if (cc < 128) /* non-Japanese, display it (fix up the EDICT "/") */
1594 {
1595 ops[0]= cc;
1596 ops[1] = '\0';
1597 if (cc == SPTAG)
1598 {
1599 if (prieng)
1600 {
1601 strcat (KLine,RVon);
1602 engrv = TRUE;
1603 }
1604 schix++;
1605 continue;
1606 }
1607 if (!isalnum(cc) && engrv)
1608 {
1609 engrv = FALSE;
1610 strcat (KLine,RVoff);
1611 }
1612 if ((Dmode == 1) && (cc == '}')) /* { */
1613 {
1614 ops[0] = ';';
1615 if ((repstr[schix+2] == 0x0a) && (ops[0] == ';')) ops[0] = '\0';
1616 }
1617 if ((Dmode == 1) && (cc == '{'))
1618 {
1619 schix++;
1620 continue;
1621 }
1622 if ((Dmode == 0) && (ops[0] == '/'))
1623 {
1624 if (!EngFirst)
1625 {
1626 ops[0] = ';';
1627 ops[1] = ' ';
1628 ops[2] = 0;
1629 }
1630 else
1631 {
1632 EngFirst = FALSE;
1633 ops[0] = 0;
1634 }
1635 }
1636 if ((repstr[schix+1] == 0x0a) && (ops[0] == ';')) ops[0] = '\0';
1637 if ((repstr[schix+1] == 0x0d) && (ops[0] == ';')) ops[0] = '\0';
1638 strcat(KLine,ops);
1639 }
1640 else /* kana or kanji */
1641 {
1642 if (cc == 0x8f)
1643 {
1644 KOutc(0x8f);
1645 schix++;
1646 continue;
1647 }
1648 if (khi == 0)
1649 {
1650 khi = cc;
1651 }
1652 else
1653 {
1654 klo = cc;
1655 KOutc(khi);
1656 KOutc(klo);
1657 khi = 0;
1658 }
1659 }
1660 schix++;
1661 } /* end of line display loop */
1662 if (GDmode && (Dmode == 0)) return; /* early return from global*/
1663 if (Dmode == 0) KFlushRes = KFlush("Continue displaying matches? (y/n)");
1664 if ((Dmode == 1)&&(KLRmode == 0)) KFlushRes = KFlush("Continue displaying matches? (y/n)");
1665 } /* of "once-per-line" test */
1666 it++;
1667 if ((Dmode == 0)||((Dmode ==1)&&(KLRmode == 0)))
1668 {
1669 if (!KFlushRes) return;
1670 }
1671 } /* end of the "while it matches loop */
1672 if (!DispHit) printf("No display for this key (filtered or non-initial kanji)\n");
1673 if ((Dmode == 1)&&(KLRmode == 1))
1674 {
1675 if (nok >= KANJARRAYSIZE) printf("\nWarning! Kanji table overflow!\n");
1676 if (nok == 0) return;
1677 qsort(&karray,nok,sizeof(karray[0]),kcmp);
1678 for (i = 0; i < nok; i++)
1679 {
1680 if ((i != 0) && (karray[i][2] == karray[i-1][2]) && (karray[i][3] == karray[i-1][3]) && (karray[i][4] == karray[i-1][4])) continue;
1681 KOutc(karray[i][2]);
1682 KOutc(karray[i][3]);
1683 if (karray[i][2] == 0x8f) KOutc(karray[i][4]);
1684 KOutc(' ');
1685 }
1686 KFlushRes = KFlush("Continue displaying kanji (y/n)");
1687 }
1688 if ((Dmode != 0) || (dind == 0)) return;
1689 if (EMmode == 0) return;
1690 printf("End of %d character matches. Continue for shorter matches? (y/n)\n\r",dind+1);
1691 ops[0] = getcharxx();
1692 DRow = 1;
1693 fflush(stdin);
1694 if ((ops[0] == 'y')||(ops[0] == 'Y')) continue;
1695 if ((ops[0] != 'n')&&(ops[0] != 'N'))
1696 {
1697 if ((ops[0] != 0x0a) && (ops[0] != 0x0d)) ungetc(ops[0],stdin);
1698 }
1699 break;
1700 } /* end of the dind loop */
1701 } /* end of lookup */
1702
1703 /*======RadSet=== set up Radicals for bushu search=================*/
RadSet()1704 void RadSet()
1705 {
1706 int i,errf;
1707 unsigned char rstr[20];
1708 FILE *fpr, *fopen();
1709
1710 fpr = xfopen(Rname,"r", &xfilelen);
1711 i = 0;
1712 while(TRUE)
1713 {
1714 errf = (fgets(rstr,19,fpr) == NULL);
1715 if (feof(fpr)||errf) break;
1716 while(rstr[strlen(rstr)-1] < 0x20) rstr[strlen(rstr)-1] = 0;
1717 if (rstr[3] == '0') continue;
1718 radkanj[i][0] = rstr[0];
1719 radkanj[i][1] = rstr[1];
1720 if (rstr[3] == '(')
1721 {
1722 radnos[i] = atoi(rstr+4);
1723 }
1724 else
1725 {
1726 radnos[i] = atoi(rstr+3);
1727 }
1728 i++;
1729 }
1730 fclose(fpr);
1731 return;
1732 }
1733 /*=====DispLic======display GPL ==============================*/
DispLic()1734 void DispLic()
1735 {
1736 FILE *flic,*fopen();
1737
1738 flic = xfopen(GPL_File,"r", &xfilelen);
1739 DRow = 1;
1740 DCol = 0;
1741 while (!feof(flic))
1742 {
1743 fgets(KLine,81,flic);
1744 if (feof(flic))
1745 {
1746 KFlush("");
1747 return;
1748 }
1749 KLine[strlen(KLine)-1] = 0;
1750 if(!KFlush("Continue Licence Display? (y/n)")) return;
1751 }
1752 }
1753 /*=====DoRADICALS===display Theresa's Radical File================*/
1754
DoRADICALS()1755 void DoRADICALS()
1756 {
1757
1758 int errf,j;
1759 unsigned char rstr[20];
1760 FILE *fpr, *fopen();
1761
1762 fpr = xfopen(Rname,"r", &xfilelen);
1763 printf("\n RADICAL DISPLAY \n");
1764 DRow = 3;
1765 DCol = 0;
1766 KLine[0] = 0;
1767 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
1768 j = 0;
1769 while(TRUE)
1770 {
1771 errf = (fgets(rstr,19,fpr) == NULL);
1772 if (feof(fpr)||errf)
1773 {
1774 KFlush("");
1775 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
1776 return;
1777 }
1778 while(rstr[strlen(rstr)-1] < 0x20) rstr[strlen(rstr)-1] = 0;
1779 if ((rstr[strlen(rstr)-2] == ' ')&&(rstr[strlen(rstr)-1] == '0'))
1780 {
1781 KFlushRes = KFlush("Continue displaying radicals? (y/n)");
1782 if (!KFlushRes) return;
1783 strcpy(KLine," ");
1784 KFlushRes = KFlush("Continue displaying radicals? (y/n)");
1785 if (!KFlushRes) return;
1786 rstr[2] = 0;
1787 sprintf(tempout,"%s Stroke Radicals ",rstr);
1788 strcpy(KLine,tempout);
1789 KFlushRes = KFlush("Continue displaying radicals? (y/n)");
1790 if (!KFlushRes) return;
1791 strcpy(KLine," ");
1792 KFlushRes = KFlush("Continue displaying radicals? (y/n)");
1793 if (!KFlushRes) return;
1794 continue;
1795 }
1796 strcat(KLine,"\t");
1797 KOutc(rstr[0]);
1798 KOutc(rstr[1]);
1799 KOutc(0xa1);
1800 KOutc(0xa1);
1801 sprintf(tempout,"%s ",rstr+3);
1802 strcat(KLine,tempout);
1803 }
1804 KFlush("");
1805 }
1806
1807 /*=========KLookup=== Special front-end to Lookup for Kanji searches==========*/
KLookup()1808 void KLookup()
1809 {
1810 if (KLmode == 0) /* Long display mode, just pass on call */
1811 {
1812 KLRmode = 0;
1813 Lookup();
1814 return;
1815 } /* Short display mode - see how many there */
1816 KLRmode = 1;
1817 Lookup();
1818 if (KLcount == 1) /* only one - force long display */
1819 {
1820 KLRmode = 0;
1821 Lookup();
1822 }
1823 return;
1824 }
1825
1826 /*=========DoJIS === JIS kanji lookup==========================================*/
1827
DoJIS()1828 void DoJIS()
1829 {
1830 int i,ktf,sjf,hojof,i1,i2;
1831 unsigned char cj;
1832
1833 ktf = FALSE;
1834 sjf = FALSE;
1835 hojof = FALSE;
1836 cbreakoff();
1837 scanf("%s",instr);
1838 cbreakon();
1839 fflush(stdin);
1840 cj = instr[0];
1841 if ((cj == '-') || (cj == 'k') || (cj == 'K'))
1842 {
1843 ktf = TRUE;
1844 strcpy(instr,instr+1);
1845 }
1846 else if ((cj == 's')||(cj == 'S'))
1847 {
1848 sjf = TRUE;
1849 strcpy(instr,instr+1);
1850 }
1851 cj = instr[0];
1852 if ((cj == 'h') || (cj == 'H'))
1853 {
1854 hojof = TRUE;
1855 strcpy(instr,instr+1);
1856 }
1857 if (ktf)
1858 {
1859 for (i = 0;i <4; i++)
1860 {
1861 if ((instr[i] >= '0') && (instr[i] <= '9'))instr[i] = instr[i] - '0';
1862 }
1863 instr[0] = (instr[0]*10+instr[1]+0x20) | 0x80;
1864 instr[1] = (instr[2]*10+instr[3]+0x20) | 0x80;
1865 instr[2] = 0;
1866 }
1867 else
1868 {
1869 for (i = 0;i <4; i++)
1870 {
1871 if ((instr[i] >= '0') && (instr[i] <= '9'))instr[i] = instr[i] - '0';
1872 if ((instr[i] >= 'a') && (instr[i] <= 'f'))instr[i] = instr[i]-'a'+0x0a;
1873 if ((instr[i] >= 'A') && (instr[i] <= 'F'))instr[i] = instr[i]-'A'+0x0a;
1874 }
1875 if(sjf)
1876 {
1877 i1 = (instr[0] << 4) + instr[1];
1878 i2 = (instr[2] << 4) + instr[3];
1879 sjis2jis(&i1,&i2);
1880 instr[0] = i1 | 0x80;
1881 instr[1] = i2 | 0x80;
1882 instr[2] = 0;
1883 }
1884 else
1885 {
1886 instr[0] = ((instr[0] << 4) + instr[1]) | 0x80;
1887 instr[1] = ((instr[2] << 4) + instr[3]) | 0x80;
1888 instr[2] = 0;
1889 }
1890 }
1891 Dmode =1;
1892 fbuff[0] = 0; fbuff[1] = 0;
1893 if (hojof) fbuff[0] = 0x8f;
1894 strcat(fbuff,instr);
1895 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
1896 KLookup();
1897 instr[0] = 0;
1898 }
1899
1900 /*===== GetKBStr=== Collect ASCII or JIS string from keyboard=========*/
1901
GetKBStr(unsigned char * prompt)1902 void GetKBStr(unsigned char *prompt)
1903 {
1904 int ShowIt,escf,bit8,i;
1905 unsigned char c;
1906
1907 escf = FALSE;
1908 bit8 = FALSE;
1909 c='x'; /*keep lint happy*/
1910 ShowIt = FALSE;
1911
1912 for (i = 0; (c != 0xd) && (c != 0xa); i++)
1913 {
1914 instr[i+1] = 0;
1915 c = getcharxx();
1916 if (!bit8 && !escf && ((c == '@') || (c == '#')))
1917 {
1918 DoRomaji(c);
1919 break;
1920 }
1921 if (c == 0x1b) escf = TRUE;
1922 if (c > 0x7f) bit8 = TRUE;
1923 if ((c == 0x7f) || (c == 8))
1924 {
1925 if(bit8) i--;
1926 if( i > 0) instr[--i] = 0;
1927 i--;
1928 strcpy(fbuff,instr);
1929 if (!NoSJIS) FixSJIS(fbuff);
1930 printf("\r \r");
1931 printf("%s%s%s ",RVon,prompt,RVoff);
1932 KOut(fbuff);
1933 continue;
1934 }
1935 instr[i] = c;
1936 if (!escf)
1937 {
1938 if (!bit8)
1939 {
1940 printf("\r \r");
1941 printf("%s%s%s %s",RVon,prompt,RVoff,instr);
1942 }
1943 else
1944 {
1945 strcpy(fbuff,instr);
1946 if ((strlen(fbuff) % 2) > 0) fbuff[strlen(fbuff)-1] = 0;
1947 printf("\r \r");
1948 printf("%s%s%s ",RVon,prompt,RVoff);
1949 if (!NoSJIS) FixSJIS(fbuff);
1950 KOut(fbuff);
1951 }
1952 }
1953 if ((instr[i] == 'B')&&(instr[i-1] == '(')&&(instr[i-2] == 0x1b))
1954 {
1955 ShowIt = TRUE;
1956 break;
1957 }
1958 }
1959 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
1960 fflush(stdin);
1961 GetEUC(fbuff);
1962 if ( fbuff[strlen(fbuff)-1] < 0x20) fbuff[strlen(fbuff)-1] = 0;
1963 if (ShowIt)
1964 {
1965 printf("\r \r");
1966 printf("%s%s%s ",RVon,prompt,RVoff);
1967 KOut(fbuff);
1968 }
1969 printf("\n\r");
1970 }
1971
1972 /*===== OneShot === Collect and set single filter=============*/
1973
OneShot()1974 void OneShot()
1975 {
1976 printf("\nFilter inactivated. Enter new filter, or press return\n\n");
1977 printf("%sFILTER:%s ",RVon,RVoff);
1978 SFFlag = FALSE;
1979
1980 GetKBStr("FILTER:");
1981 strcpy(SingleFilter,fbuff);
1982 if (strlen(fbuff) >= 2)
1983 {
1984 SFFlag = TRUE;
1985 printf("Filter set to: ");
1986 KOut(fbuff);
1987 printf("\n");
1988 }
1989 else
1990 {
1991 printf("No filter set\n");
1992 }
1993 }
1994
1995 /*====FindRad=== finds the spot in the table for a radical==========*/
FindRad(unsigned char char1,unsigned char char2)1996 int FindRad(unsigned char char1, unsigned char char2)
1997 {
1998 int i,j,k,Found;
1999
2000 Found = FALSE;
2001 for (i = 0; i < NoRads; i++)
2002 {
2003 if ((char1 == RadK1[i]) && (char2 == RadK2[i]))
2004 {
2005 Found = TRUE;
2006 break;
2007 }
2008 }
2009 if (!Found) return(-1);
2010 return(i);
2011 }
2012 /*===RadBuild==Extracts the kanji that meet the multi-radical selection===*/
RadBuild()2013 void RadBuild()
2014 {
2015 /* RKTarg will contain the string of target "radicals"
2016 The RKSet tables are progressively loaded with the kanji that
2017 meet the radical criteria */
2018
2019 int stest,jtest,i,j,k,l,m,n,lind,hitcount;
2020
2021 /* the first radical has all its kanji loaded (which meet any stroke count test) */
2022 i = FindRad((unsigned char)RKTarg[0],(unsigned char)RKTarg[1]);
2023 if (i < 0)
2024 {
2025 printf("Invalid Radical!\n");
2026 RKTarg[0] = 0;
2027 return;
2028 }
2029 k = 0;
2030 hitcount = 0;
2031 for (j = RKStart[i]; j < RKStart[i]+RKCnt[i]; j++)
2032 {
2033 if (kstrokelim > 0)
2034 {
2035 n = ((RKanj1[j] & 0x7f)-0x30)*94 + ((RKanj2[j] & 0x7f) - 0x21);
2036 if ((kstroketype == 0) && (kstrokelim != kstrokes[n])) continue;
2037 if ((kstroketype == 1) && (kstrokelim > kstrokes[n])) continue;
2038 if ((kstroketype == 2) && (kstrokelim < kstrokes[n])) continue;
2039 }
2040 RKSet[0][k] = RKanj1[j];
2041 RKSet[0][k+1] = RKanj2[j];
2042 RKSet[0][k+2] = 0;
2043 hitcount++;
2044 k+=2;
2045 }
2046 ops[0] = RKTarg[0]; ops[1] = RKTarg[1]; ops[2] = 0;
2047 printf("Target Radicals: 0 ");
2048 KOut(ops);
2049 printf(" (%d) ",hitcount);
2050 NoSets = 1;
2051 if (strlen(RKTarg) <= 2)
2052 {
2053 printf("\n");
2054 return;
2055 }
2056 /* The second and subsequent radicals only have their matching kanji loaded
2057 if they are a member of the previous set */
2058
2059 for (l=2; l< strlen(RKTarg); l+=2)
2060 {
2061 lind = (l/2)-1;
2062 i = FindRad((unsigned char)RKTarg[l],(unsigned char)RKTarg[l+1]);
2063 ops[0] = RKTarg[l]; ops[1] = RKTarg[l+1]; ops[2] = 0;
2064 printf(" %d ",NoSets);
2065 KOut(ops);
2066 if (i < 0)
2067 {
2068 printf("\nInvalid Radical!\n");
2069 RKTarg[l] = 0;
2070 return;
2071 }
2072 k = 0;
2073 RKSet[lind+1][k] = 0;
2074 jtest = RKStart[i]+RKCnt[i];
2075 for (j = RKStart[i]; j < jtest; j++)
2076 {
2077 for (n = 0; RKSet[lind][n] != 0; n+=2)
2078 {
2079 if ((RKSet[lind][n] == RKanj1[j]) && (RKSet[lind][n+1] == RKanj2[j]))
2080 {
2081 RKSet[lind+1][k] = RKanj1[j];
2082 RKSet[lind+1][k+1] = RKanj2[j];
2083 RKSet[lind+1][k+2] = 0;
2084 k+=2;
2085 break;
2086 }
2087 }
2088 }
2089 NoSets++;
2090 printf(" (%d) ",strlen(RKSet[NoSets-1])/2);
2091 }
2092 printf("\n");
2093 }
2094
2095 /*=====RadDisp===Display Radical Data==============================*/
RadDisp()2096 void RadDisp()
2097 {
2098 FILE *fk,*fopen();
2099 int j,k,l,n;
2100 unsigned char *ptr;
2101
2102 fk = xfopen(RKname,"r", &xfilelen);
2103 j = 0;
2104 printf("RADICAL TABLE FOR USE WITH THE XJDIC RADICAL LOOKUP FUNCTION\n");
2105 DRow = 0;
2106 DCol = 0;
2107 k = 99;
2108 KLine[0] = 0;
2109 while(!feof(fk))
2110 {
2111 fgets(testline,199,fk);
2112 if(feof(fk)) break;
2113 if (testline[0] != '$') continue;
2114 ptr = strtok(testline+4," ");
2115 l = atoi(ptr);
2116 if (l != k)
2117 {
2118 k = l;
2119 for (n = 0; n < strlen(ptr); n++)
2120 {
2121 if (ptr[n] < 32) break;
2122 KOutc(0xa3); KOutc(ptr[n] | 0x80);
2123 }
2124 KOutc(' ');
2125 }
2126 KOutc(testline[2]); KOutc(testline[3]); KOutc(' ');
2127 }
2128 fclose(fk);
2129 KFlush("");
2130 }
2131 /*===KanjRad=== Display which "radicals" are used to imdex this kanji=====*/
KanjRad()2132 void KanjRad()
2133 {
2134 int i,j;
2135
2136 printf("%sWhich Kanji:%s",RVon,RVoff);
2137 GetKBStr("Which Kanji:");
2138 if (fbuff[0] < 127) return;
2139 strcpy(KLine,"Kanji: ");
2140 KOutc(fbuff[0]);
2141 KOutc(fbuff[1]);
2142 strcat(KLine," Elements: ");
2143 DRow = 0;
2144 DCol = 0;
2145 for (i = 0; i < NoRads; i++)
2146 {
2147 for (j = RKStart[i]; j < RKStart[i]+RKCnt[i]; j++)
2148 {
2149 if ((fbuff[0] == RKanj1[j]) && (fbuff[1] == RKanj2[j]))
2150 {
2151 KOutc(RadK1[i]);
2152 KOutc(RadK2[i]);
2153 KOutc(' ');
2154 }
2155 }
2156 }
2157 KFlush("");
2158 }
2159 /*====RadKDisp=====display selected kanji============================*/
RadKDisp()2160 void RadKDisp()
2161 {
2162 int i;
2163
2164 if (RKTarg[0] == 0) return;
2165 if (NoSets == 0) return;
2166 printf("Selected Kanji: ");
2167 for (i = 0; i < strlen(RKSet[NoSets-1]); i+=2)
2168 {
2169 ops[0] = RKSet[NoSets-1][i]; ops[1] = RKSet[NoSets-1][i+1]; ops[2] = 0;
2170 KOut(ops);
2171 printf(" ");
2172 }
2173 printf("\n");
2174 }
2175 /*====DoLOOKUP=====driver routine for the multi-radical lookup=======*/
DoLOOKUP()2176 void DoLOOKUP()
2177 {
2178 int i;
2179
2180 printf("\nRadical Lookup Mode\n");
2181 RKTarg[0] = 0;
2182 while(TRUE)
2183 {
2184 printf("%sLookup Code:%s",RVon,RVoff);
2185 GetKBStr("Lookup Code:");
2186 if (fbuff[0] > 127)
2187 {
2188 ops[0] = fbuff[0]; ops[1] = fbuff[1]; ops[2] = 0;
2189 if (strlen(RKTarg) == 20)
2190 {
2191 printf("\nToo many radicals!\n");
2192 continue;
2193 }
2194 strcat(RKTarg,ops);
2195 RadBuild();
2196 if(NoSets == 0) continue;
2197 if (strlen(RKSet[NoSets-1]) == 0) continue;
2198 if (strlen(RKSet[NoSets-1]) <=RADLOOKLIM) RadKDisp();
2199 continue;
2200 }
2201 if ((fbuff[0] | 0x20) == 'r')
2202 {
2203 RadDisp();
2204 continue;
2205 }
2206 if ((fbuff[0] | 0x20) == 'v')
2207 {
2208 KanjRad();
2209 continue;
2210 }
2211 if ((fbuff[0] | 0x20) == 'x')
2212 {
2213 instr[0] = 0;
2214 fflush(stdin);
2215 return;
2216 }
2217 if ((fbuff[0] | 0x20) == 'c')
2218 {
2219 RKTarg[0] = 0;
2220 kstrokelim = 0;
2221 printf("Cleared\n");
2222 continue;
2223 }
2224 if ((fbuff[0] | 0x20) == 's')
2225 {
2226 kstroketype = 0;
2227 i = 1;
2228 testline[0] = 0;
2229 if (fbuff[1] == '+')
2230 {
2231 kstroketype = 1;
2232 strcat(testline," >= ");
2233 i = 2;
2234 }
2235 if (fbuff[1] == '-')
2236 {
2237 kstroketype = 2;
2238 strcat(testline," <= ");
2239 i = 2;
2240 }
2241 kstrokelim = atoi(fbuff+i);
2242 if (kstrokelim == 0)
2243 {
2244 printf("Stroke-count cleared\n");
2245 }
2246 else
2247 {
2248 printf("Stroke-count set to %s%d\n",testline,kstrokelim);
2249 }
2250 if (strlen(RKTarg) > 0) RadBuild();
2251 if (NoSets <= 0) continue;
2252 if (strlen(RKSet[NoSets-1]) <=RADLOOKLIM) RadKDisp();
2253 continue;
2254 }
2255 if ((fbuff[0] | 0x20) == 'd')
2256 {
2257 i = fbuff[1]-'0';
2258 if (i >= strlen(RKTarg)/2)
2259 {
2260 printf("Out of Range!\n");
2261 continue;
2262 }
2263 strcpy(RKTarg+i*2,RKTarg+i*2+2);
2264 if(strlen(RKTarg) > 0) RadBuild();
2265 if (strlen(RKSet[NoSets-1]) <=RADLOOKLIM) RadKDisp();
2266 continue;
2267 }
2268
2269 if ((fbuff[0] | 0x20) == 'l') RadKDisp();
2270 }
2271 }
2272
2273 /*===== DoKANJI === Kanji single lookup ======================*/
DoKANJI()2274 void DoKANJI()
2275 {
2276
2277 GetKBStr("KANJI/KANA:");
2278 Dmode =1;
2279 KLookup();
2280 instr[0] = 0;
2281 }
2282 /*===EMtoggle==alternate between match display modes===============*/
EMtoggle()2283 void EMtoggle()
2284 {
2285 EMmode = (EMmode+1) % 2;
2286 printf("Exact Match Display Mode: %s\n",kmodes[EMmode]);
2287 }
2288 /*===togglekana==alternate between kana input modes===============*/
togglekana()2289 void togglekana()
2290 {
2291 KImode = (KImode+1) % 2;
2292 printf("Kana Default Input Mode: %s\n",kmodes[KImode]);
2293 }
2294 /*===togglekanji==alternate between kanji display modes===============*/
togglekanji()2295 void togglekanji()
2296 {
2297 KLmode = (KLmode+1) % 2;
2298 printf("Long Kanji Display Mode: %s\n",kmodes[KLmode]);
2299 }
2300 /*===toggleraw===alternate between raw/edited output modes===============*/
toggleraw()2301 void toggleraw()
2302 {
2303 ROmode = (ROmode+1) % 2;
2304 printf("Unedited Output Mode: %s\n",kmodes[ROmode]);
2305 }
2306 /*===RVtoggle===alternate between reverse video modes===============*/
RVtoggle()2307 void RVtoggle()
2308 {
2309 RVACTIVE = (RVACTIVE +1) % 2;
2310 printf("Reverse Video Match Display Mode: %s\n",kmodes_r[RVACTIVE ]);
2311 }
2312 /*===togglemode===alternate between kanji compound modes===============*/
togglemode()2313 void togglemode()
2314 {
2315 FirstKanj = (FirstKanj+1) % 2;
2316 printf("Display All Kanji Mode: %s\n",kmodes[FirstKanj]);
2317 }
2318
2319 /*=====engpritoggle=====alternate between English priorities=======*/
engpritoggle()2320 void engpritoggle()
2321 {
2322 if(prieng == FALSE)
2323 {
2324 prieng = TRUE;
2325 printf("English search will now only select priority keys\n");
2326 return;
2327 }
2328 prieng = FALSE;
2329 printf("English search will now select all keys\n");
2330 }
2331
2332 /*=====seldic=====select dictionary file =====================*/
seldic()2333 void seldic()
2334 {
2335 int i;
2336 char c;
2337
2338 if (NoDics == 1)
2339 {
2340 printf("No alternative dictionary active!\n");
2341 return;
2342 }
2343 for (i = 1; i <= NoDics; i++)
2344 {
2345 printf("Dictionary: %d [%s]\n",i,DicName(i));
2346 }
2347 printf ("Select a dictionary file (1-%d)\n",NoDics);
2348 c = getcharxx();
2349 if ((c == 0x1b)||(c == 0xa)||(c == 0xd)) return;
2350 i = c-'0';
2351 if ((i <0)||(i >NoDics))
2352 {
2353 printf("INVALID!\n");
2354 return;
2355 }
2356 CurrDic = i;
2357 printf("Active Dictionary is now #%d (%s)\n",CurrDic,DicName(CurrDic));
2358 }
2359
2360 /*=====BuffStats=====report on page buffer stats=====================*/
BuffStats()2361 void BuffStats()
2362 {
2363 int i;
2364
2365 #ifdef XJDDIC
2366 printf("DEMAND-PAGING STATISTICS:\n\n");
2367 printf("Dic Hits: ");
2368 for (i=0;i<=NoDics;i++) printf("\t%ld ",dichits[i]);
2369 printf("\n");
2370 printf("Dic Miss: ");
2371 for (i=0;i<=NoDics;i++) printf("\t%ld ",dicmiss[i]);
2372 printf("\n");
2373 printf("Ind Hits: ");
2374 for (i=0;i<=NoDics;i++) printf("\t%ld ",indhits[i]);
2375 printf("\n");
2376 printf("Ind Miss: ");
2377 for (i=0;i<=NoDics;i++) printf("\t%ld ",indmiss[i]);
2378 printf("\n");
2379 printf("Buffer overwrites: \t%ld\n",vbkills);
2380 #else
2381 printf("CLIENT! NO BUFFER STATISTICS\n");
2382 #endif
2383 }
2384 /*=====altdic=====rotate around dictionaries=======*/
altdic(int dicincr)2385 void altdic(int dicincr)
2386 {
2387 if (NoDics == 1)
2388 {
2389 printf("No alternative dictionary active!\n");
2390 return;
2391 }
2392 CurrDic = CurrDic + dicincr;
2393 if (CurrDic == NoDics+1) CurrDic = 1;
2394 if (CurrDic == 0) CurrDic = NoDics;
2395 printf("Switching to dictionary: %d [%s]\n",CurrDic,DicName(CurrDic));
2396 }
2397 /*====GDicSet====== initialize the global dictionary list===============*/
GDicSet()2398 void GDicSet()
2399 {
2400 char gdtemp[100],*gdp;
2401
2402 if (NoDics == 1)
2403 {
2404 printf("No alternative dictionary active!\n");
2405 return;
2406 }
2407
2408 gdicmax = 0;
2409 printf("\nEnter the list of dictionary numbers for the global search\n");
2410 printf("%sDictionary Numbers:%s",RVon,RVoff);
2411 GetKBStr("Dictionary Numbers:");
2412 strcpy(gdtemp,fbuff);
2413 gdp = strtok(gdtemp," ,\t");
2414 while(gdp!=NULL)
2415 {
2416 gdicnos[gdicmax] = atoi(gdp);
2417 gdp = strtok(NULL," ,\t");
2418 gdicmax++;
2419 if (gdicmax > 9)
2420 {
2421 printf("Too many dictionary numbers!\n");
2422 gdicmax--;
2423 break;
2424 }
2425 if (gdicnos[gdicmax-1] > NoDics)
2426 {
2427 printf("Illegal Dictionary number!\n");
2428 gdicmax--;
2429 }
2430 }
2431 gdicmax--;
2432 if (gdicmax <1)
2433 {
2434 printf("Warning! Insufficient dictionaries set!\n");
2435 }
2436 }
2437
2438 /*====GDictoggle=== alternate between single & global dics==============*/
GDictoggle()2439 void GDictoggle()
2440 {
2441 int gi;
2442
2443 if (GDmode)
2444 {
2445 GDmode = FALSE;
2446 printf("Global dictionary searching is now OFF\n");
2447 }
2448 else
2449 {
2450 if (gdicmax <1)
2451 {
2452 printf("Insufficient dictionaries set!\n");
2453 return;
2454 }
2455 GDmode = TRUE;
2456 printf("Global dictionary searching is now ON [");
2457 for (gi=0;gi<=gdicmax;gi++)
2458 {
2459 printf("%d",gdicnos[gi]);
2460 if (gi != gdicmax) printf(" ");
2461 }
2462 printf("]\n");
2463 }
2464 }
2465 /*====Verbtoggle=== alternate between deinflection on/off===============*/
Verbtoggle()2466 void Verbtoggle()
2467 {
2468 if (Jverb)
2469 {
2470 Jverb = FALSE;
2471 printf("Verb deinflection is now OFF\n");
2472 }
2473 else
2474 {
2475 Jverb = TRUE;
2476 printf("Verb deinflection is now ON\n");
2477 }
2478 }
2479 /*=== FiltSet=== turn filters on & off==============================*/
FiltSet()2480 void FiltSet()
2481 {
2482 unsigned char c,fff[10];
2483 int anyfilt,j,k;
2484
2485 anyfilt = FALSE;
2486 printf("%sFilter Setting%s\n",RVon,RVoff);
2487 for(j = 0;j < NOFILT;j++)
2488 {
2489 if(!filtact[j])continue;
2490 anyfilt = TRUE;
2491 strcpy(fff,"OFF");
2492 if(filton[j])strcpy(fff,"ON ");
2493 printf("No: %d Type: %d Status: %s Name: %s\n",j,filttype[j],fff,filtnames[j]);
2494 }
2495 if (!anyfilt)
2496 {
2497 printf("No filters are loaded!\n");
2498 return;
2499 }
2500 printf("Modify which Filter?\n");
2501 c = getcharxx();
2502 if ((c == 0x1b)||(c == 0xa)||(c == 0xd)) return;
2503 k = c-'0';
2504 if ((k <0)||(k >NOFILT))
2505 {
2506 printf("INVALID!\n");
2507 return;
2508 }
2509 if (!filtact[k])
2510 {
2511 printf("Filter %c is not active!\n",c);
2512 return;
2513 }
2514 printf("Filter %c OFF (0) or ON (1)\n",c);
2515 c = getcharxx();
2516 if ((c != '0') && (c != '1'))return;
2517 if(c == '0')
2518 {
2519 filton[k] = FALSE;
2520 printf("Filter %d Turned OFF\n",k);
2521 }
2522 if(c == '1')
2523 {
2524 filton[k] = TRUE;
2525 printf("Filter %d Turned ON\n",k);
2526 }
2527 nofilts = FALSE;
2528 for(j = 0;j < NOFILT;j++)if(filton[j])nofilts=TRUE;
2529 return;
2530 }
2531
2532 /* M A I N */
2533
main(argc,argv)2534 main(argc,argv)
2535 int argc;
2536 char **argv;
2537
2538 {
2539 int i,j,ip,cmdmode,bit8,escf;
2540 unsigned char *dicenv,strtmp[50];
2541 unsigned char c;
2542 unsigned char xap[50];
2543 unsigned char kbprompt[99];
2544 unsigned char kbprompt2[99];
2545
2546 printf("XJDIC Version %s (Japanese Dictionary) Copyright J.W.Breen 1998.\n",sver);
2547 #ifdef XJDDIC
2548 printf(" Stand-alone mode\n");
2549 #else
2550 printf(" Client mode\n");
2551 #endif
2552
2553 for (i=0;i<NOFILT;i++)
2554 {
2555 filtact[i] = FALSE;
2556 filton[i] = FALSE;
2557 }
2558 dicenv = (unsigned char *)getenv("XJDIC");
2559 if (!dicenv) dicenv = (unsigned char *)DEFAULT_DICDIR;
2560 if (strlen(dicenv) <= 2)
2561 {
2562 dicenv = (unsigned char *)getcwd(ENVname,sizeof(ENVname));
2563 if (dicenv == NULL)
2564 {
2565 printf("Cannot extract working directory!\n");
2566 exit(1);
2567 }
2568 }
2569 else
2570 {
2571 strcpy (ENVname,dicenv);
2572 }
2573 #ifdef XJDDIC
2574 strcpy (Dnamet[1],"edict");
2575 strcpy (Dnamet[0], "kanjidic");
2576 strcpy (XJDXnamet[1], "edict.xjdx");
2577 strcpy (XJDXnamet[0], "kanjidic.xjdx");
2578 NoDics = 1;
2579 CurrDic = 1;
2580 #endif
2581 cl_rcfile[0] = 0;
2582 /* process command-line options*/
2583 if (argc > 1)
2584 {
2585 for (i = 1; i < argc; i++)
2586 {
2587 strcpy(xap,argv[i]);
2588 if ((xap[0] == '-') && (xap[1] == 'c'))
2589 {
2590 if(xap[2] != 0)
2591 {
2592 strcpy(strtmp,xap+2);
2593 }
2594 else
2595 {
2596 i++;
2597 strcpy(xap,argv[i]);
2598 strcpy (strtmp,xap);
2599 }
2600 strcpy (cl_rcfile,strtmp);
2601 printf ("Using control-file: %s\n",cl_rcfile);
2602 }
2603 if ((xap[0] == '-') && (xap[1] == 'j'))
2604 {
2605 if(xap[2] != 0)
2606 {
2607 strcpy(strtmp,xap+2);
2608 }
2609 else
2610 {
2611 i++;
2612 strcpy(xap,argv[i]);
2613 strcpy (strtmp,xap);
2614 }
2615 if (strtmp[0] == 'j')
2616 {
2617 Omode = 0;
2618 printf("Output mode set to JIS\n");
2619 }
2620 if (strtmp[0] == 's')
2621 {
2622 Omode = 2;
2623 printf("Output mode set to Shift-JIS\n");
2624 }
2625 if (strtmp[0] == 'e')
2626 {
2627 Omode = 1;
2628 printf("Output mode set to EUC\n");
2629 }
2630 continue;
2631 }
2632 #ifdef XJDCLSERV
2633 if ((xap[0] == '-') && (xap[1] == 'S'))
2634 {
2635 if(xap[2] != 0)
2636 {
2637 strcpy(host,xap+2);
2638 }
2639 else
2640 {
2641 i++;
2642 strcpy(xap,argv[i]);
2643 strcpy(host,xap);
2644 }
2645 printf("Command-line request to use server: %s\n",host);
2646 continue;
2647 }
2648 if ((xap[0] == '-') && (xap[1] == 'P'))
2649 {
2650 if(xap[2] != 0)
2651 {
2652 portno = atoi(xap+2);
2653 }
2654 else
2655 {
2656 i++;
2657 strcpy(xap,argv[i]);
2658 portno = atoi(xap);
2659 }
2660 printf("Command-line request to use port: %d\n",portno);
2661 continue;
2662 }
2663 #endif
2664 #ifdef XJDDIC
2665 if ((xap[0] == '-') && (xap[1] == 'C'))
2666 {
2667 if(xap[2] != 0)
2668 {
2669 strcpy(strtmp,xap+2);
2670 }
2671 else
2672 {
2673 i++;
2674 strcpy(xap,argv[i]);
2675 strcpy (strtmp,xap);
2676 }
2677 strcpy (Clip_File,strtmp);
2678 printf ("Using clipboard-file: %s\n",Clip_File);
2679 }
2680 if ((xap[0] == '-') && (xap[1] == 'd'))
2681 {
2682 if (thisdic == 0)
2683 {
2684 thisdic = 1;
2685 }
2686 else
2687 {
2688 thisdic++;
2689 NoDics++;
2690 }
2691 if(xap[2] != 0)
2692 {
2693 strcpy(strtmp,xap+2);
2694 }
2695 else
2696 {
2697 i++;
2698 strcpy(xap,argv[i]);
2699 strcpy (strtmp,xap);
2700 }
2701 strcpy (Dnamet[thisdic],strtmp);
2702 strcpy (XJDXnamet[thisdic],strtmp);
2703 strcat (XJDXnamet[thisdic],".xjdx");
2704 printf("Command-line request to use dictionary files (%d): %s and %s\n",
2705 thisdic,Dnamet[thisdic],XJDXnamet[thisdic]);
2706 continue;
2707 }
2708 if ((xap[0] == '-') && (xap[1] == 'k'))
2709 {
2710 if(xap[2] != 0)
2711 {
2712 strcpy(strtmp,xap+2);
2713 }
2714 else
2715 {
2716 i++;
2717 strcpy(xap,argv[i]);
2718 strcpy (strtmp,xap);
2719 }
2720 strcpy (Dnamet[0],strtmp);
2721 strcpy (XJDXnamet[0],strtmp);
2722 strcat (XJDXnamet[0],".xjdx");
2723 printf("Command-line request to use kanji dictionary files: %s and %s\n",Dnamet[0],XJDXnamet[0]);
2724 continue;
2725 }
2726 #endif
2727 if ((xap[0] == '-') && (xap[1] == 'V'))
2728 {
2729 RVACTIVE = FALSE;
2730 printf("Reverse-video match display disabled\n");
2731 }
2732 if ((xap[0] == '-') && (xap[1] == 'E'))
2733 {
2734 NoSJIS = TRUE;
2735 printf("EUC (No Shift-JIS) operation enforced\n");
2736 }
2737 if ((xap[0] == '-') && (xap[1] == 'v'))
2738 {
2739 Jverb = FALSE;
2740 printf("Verb deinflection turned OFF\n");
2741 }
2742 if ((xap[0] == '-') && (xap[1] == 'h'))
2743 {
2744 printf("\nUSAGE: xjdic <options>\n\nwhere options are:\n\n");
2745 printf(" -h this information\n");
2746 printf(" -c control-file\n");
2747 #ifdef XJDCLSERV
2748 printf(" -P port-no\n");
2749 printf(" -S server\n");
2750 #else
2751 printf(" -d dictionary file_path\n");
2752 printf(" -k kanji-dictionary file_path\n");
2753 #endif
2754 printf(" -v disable verb function\n");
2755 printf(" -j x (where x is Output code: e = EUC, s = Shift-JIS, j = JIS)\n");
2756 printf(" -V disable reverse video display\n");
2757 printf(" -C clipboard-file\n");
2758 printf("\nSee xjdic23.inf for full information\n");
2759 exit(0);
2760 }
2761 }
2762 }
2763 xjdicrc();
2764 #ifdef XJDDIC
2765 printf ("Loading Dictionary and Index files. Please wait...\n");
2766 #endif
2767 Verbinit();
2768 DicSet ();
2769 RadSet();
2770 RadLoad();
2771 KSLoad();
2772 LoadKana();
2773 togglemode();
2774 togglekanji();
2775 cbreakon();
2776 printf("\n(Enter ? for a summary of operating instructions)\n");
2777
2778 /*
2779 From here on, the code loops endlessly, reading commands
2780 from the keyboard. This code decodes any kana/kanji/romaji
2781 itself, rather than using the "GetKBStr" function, as it has
2782 to sort out special commands as well.
2783 */
2784 while (TRUE)
2785 {
2786 GetWinSize(); /* Just in case the screen has changed */
2787 sprintf(kbprompt,"%sXJDIC [%d:%s] SEARCH KEY:%s ",RVon,CurrDic,DicName(CurrDic),RVoff);
2788 sprintf(kbprompt2,"XJDIC [%d:%s] SEARCH KEY: ",CurrDic,DicName(CurrDic));
2789 if (GDmode)
2790 {
2791 sprintf(kbprompt,"%sXJDIC [GLOBAL] SEARCH KEY:%s ",RVon,RVoff);
2792 sprintf(kbprompt2,"XJDIC [GLOBAL] SEARCH KEY: ");
2793 }
2794 printf("\n\r%s",kbprompt);
2795 c = 0;
2796 cmdmode = FALSE;
2797 strf = FALSE;
2798 escf = FALSE;
2799 bit8 = FALSE;
2800 AKanaMode = FALSE;
2801 if (KImode == 0) AKanaMode = TRUE;
2802 for (i = 0; (c != 0xd) && (c != 0xa); i++)
2803 {
2804 instr[i+1] = 0;
2805 if (clipmode) break;
2806 c = getcharxx();
2807 if (c == 0x1b)
2808 {
2809 escf = TRUE;
2810 AKanaMode = FALSE;
2811 }
2812 if (c > 0x7f)
2813 {
2814 bit8 = TRUE;
2815 AKanaMode = FALSE;
2816 }
2817 if (!bit8 && !escf && (c == 0x04)) /* Simulate ^D */
2818 {
2819 cbreakoff();
2820 exit(0);
2821 }
2822 if (!bit8 && !escf && (c == 0x1a)) /* Simulate ^Z */
2823 {
2824 cbreakoff();
2825 printf("\nSuspending XJDIC. Type `fg' to resume.\n");
2826 pid = getpid();
2827 kill(pid,sig);
2828 cbreakon();
2829 break;
2830 }
2831 /* Romaji Input */
2832 if (!bit8 && !escf && ((c == '@') || (c == '#')))
2833 {
2834 DoRomaji(c);
2835 break;
2836 }
2837 /* On-line Help Summmary */
2838 if ((c == '?') && (!escf) && (!bit8))
2839 {
2840 DRow = 0;
2841 for (ip = 0; strcmp(Help[ip],"$$$")!=0;ip++)
2842 {
2843 strcpy(KLine,Help[ip]);
2844 if(!KFlush("Continue Help Display? (y/n)")) break;
2845 }
2846 break;
2847 }
2848 /* Turn on cmd mode for special characters */
2849 if ((!escf) && (!bit8) && (strchr("!{}$%*&^=/-:\'+\\;][|_",c) != NULL))
2850 {
2851 cmdmode = TRUE;
2852 break;
2853 }
2854 /* backspace or rubout - shrink i/p buffer and redisplay */
2855 if ((c == 0x7f) || (c == 8))
2856 {
2857 if(bit8) i--;
2858 if( i > 0) instr[--i] = 0;
2859 i--;
2860 strcpy(fbuff,instr);
2861 if (!NoSJIS) FixSJIS(fbuff);
2862 printf("\r \r");
2863 printf("%s",kbprompt);
2864 KOut(fbuff);
2865 continue;
2866 }
2867 /* Actually an input character */
2868 instr[i] = c;
2869 if (AKanaMode)
2870 {
2871 if ((c == 'l') || (c == 'L'))
2872 {
2873 AKanaMode = FALSE;
2874 GetKBStr(kbprompt2);
2875 break;
2876 }
2877 if (c < 128)
2878 {
2879 ungetc(c,stdin);
2880 DoRomaji('@');
2881 break;
2882 }
2883 }
2884 if (!escf)
2885 {
2886 if (!bit8)
2887 {
2888 printf("\r \r");
2889 printf("%s%s",kbprompt,instr);
2890 }
2891 else
2892 {
2893 strcpy(fbuff,instr);
2894 if ((strlen(fbuff) % 2) > 0) fbuff[strlen(fbuff)-1] = 0;
2895 printf("\r \r");
2896 printf("%s",kbprompt);
2897 if (!NoSJIS) FixSJIS(fbuff);
2898 KOut(fbuff);
2899 }
2900 }
2901 /* JIS ShiftOUT, so terminate input */
2902 if ((instr[i] == 'B')&&(instr[i-1] == '(')&&(instr[i-2] == 0x1b)) break;
2903 }
2904 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
2905 /* "bye" is the end of the run */
2906 if ((instr[2] == 'e')&&(instr[1] == 'y')&&(instr[0] == 'b'))
2907 {
2908 cbreakoff();
2909 exit(0);
2910 }
2911 /* sort out the special commands */
2912 if(cmdmode)
2913 {
2914 if (c == '{') /* } to balance {} */
2915 {
2916 printf("\r \r");
2917 printf("Now in Clipboard Mode\n");
2918 clipmode = TRUE;
2919 continue;
2920 }
2921 if (c == '}') /* matching { */
2922 {
2923 printf("\r \r");
2924 RVtoggle();
2925 continue;
2926 }
2927 if (c == '/')
2928 {
2929 printf("\r \r");
2930 togglemode();
2931 continue;
2932 }
2933 if (c == '!')
2934 {
2935 printf("\r \r");
2936 DispLic();
2937 continue;
2938 }
2939 if (c == '|')
2940 {
2941 printf("\r \r");
2942 toggleraw();
2943 continue;
2944 }
2945 if (c == '+')
2946 {
2947 printf("\r \r");
2948 engpritoggle();
2949 continue;
2950 }
2951 if (c == '&')
2952 {
2953 printf("\r \r");
2954 togglekana();
2955 continue;
2956 }
2957 if (c == '-')
2958 {
2959 printf("\r \r");
2960 togglekanji();
2961 continue;
2962 }
2963 if (c == ']')
2964 {
2965 printf("\r \r");
2966 ExtFileDisp();
2967 continue;
2968 }
2969 if (c == '=')
2970 {
2971 printf("\r \r");
2972 altdic(+1);
2973 continue;
2974 }
2975 if (c == '^')
2976 {
2977 printf("\r \r");
2978 altdic(-1);
2979 continue;
2980 }
2981 if (c == '_')
2982 {
2983 printf("\r \r");
2984 seldic();
2985 continue;
2986 }
2987 if (c == '\'')
2988 {
2989 printf("\r \r");
2990 OneShot();
2991 continue;
2992 }
2993 if (c == ';')
2994 {
2995 printf("\r \r");
2996 FiltSet();
2997 continue;
2998 }
2999 if (c == ':')
3000 {
3001 printf("\r \r");
3002 Verbtoggle();
3003 continue;
3004 }
3005 if (c == '[')
3006 {
3007 printf("\r \r");
3008 EMtoggle();
3009 continue;
3010 }
3011 if (c == '$')
3012 {
3013 printf("\r \r");
3014 GDicSet();
3015 continue;
3016 }
3017 if (c == '%')
3018 {
3019 printf("\r \r");
3020 GDictoggle();
3021 continue;
3022 }
3023 if (c == '*')
3024 {
3025 #ifdef DEMAND_PAGING
3026 printf("\r \r");
3027 BuffStats();
3028 #else
3029 printf("\nNo statistics in this mode!\n");
3030 #endif
3031 continue;
3032 }
3033 /* none of the above, so it must be a Kanji search */
3034 printf("\r \r");
3035 printf("%sKANJI LOOKUP TYPE:%s ",RVon,RVoff);
3036 c = getcharxx();
3037
3038 switch (c)
3039 {
3040 case 'c' : /* a KANJIDIC Index Code */
3041 case 'C' :
3042
3043 printf("\r \r");
3044 printf("%sINDEX CODE:%s",RVon,RVoff);
3045 GetKBStr("INDEX CODE:");
3046 fflush(stdin);
3047 Dmode =1;
3048 strcat(fbuff," ");
3049 /* For bushu or classical radical, ask for stroke count */
3050 if (((fbuff[0] | 0x20) == 'b')||((fbuff[0] | 0x20) == 'c'))
3051 {
3052 if (fbuff[1] >= 0xb0) /* test for "bKANJI" */
3053 {
3054 for (i=0;i<250;i++)
3055 {
3056 if((fbuff[1] != radkanj[i][0]) || (fbuff[2] != radkanj[i][1])) continue;
3057 sprintf(strtmp,"%d",radnos[i]);
3058 strcpy(fbuff+1,strtmp);
3059 strcat(fbuff," ");
3060 printf("Bushu: %s\n",strtmp);
3061 break;
3062 }
3063 if (i == 250)
3064 {
3065 printf("Invalid Bushu. Assuming B1 \n");
3066 strcpy(fbuff,"B1 ");
3067 }
3068 }
3069 printf("\r \r");
3070 printf("%sSTROKE COUNT (0 selects all):%s",RVon,RVoff);
3071 cbreakoff();
3072 fgets(instr,3,stdin);
3073 i = atoi(instr);
3074 sprintf(strfilt,"S%d",i);
3075 cbreakon();
3076 fflush(stdin);
3077 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
3078 strf = TRUE;
3079 if (atoi(strfilt+1) == 0) strf = FALSE;
3080 }
3081 KLookup();
3082 instr[0] = 0;
3083 break;
3084 case 'm' : /* "meaning" */
3085 case 'M' :
3086 printf("\r \r");
3087 printf("%sMEANING:%s",RVon,RVoff);
3088 cbreakoff();
3089 scanf("%s",instr);
3090 cbreakon();
3091 fflush(stdin);
3092 Dmode =1;
3093 strcpy(fbuff,instr);
3094 fseek(stdin,0L,SEEK_END); /*kill any leftovers*/
3095 KLookup();
3096 instr[0] = 0;
3097 break;
3098 case 'j' : /* JIS code */
3099 case 'J' :
3100 printf("\r \r");
3101 printf("%sJIS CODE:%s",RVon,RVoff);
3102 DoJIS();
3103 break;
3104 case 'r' :
3105 case 'R' :
3106 DoRADICALS();
3107 break;
3108 case 'l' :
3109 case 'L' :
3110 DoLOOKUP();
3111 break;
3112 case 'k' :
3113 case 'K' :
3114 DoKANJI();
3115 break;
3116 default :
3117 ungetc(c,stdin);
3118 DoKANJI();
3119 break;
3120 }
3121 }
3122 if (clipmode)
3123 {
3124 while(TRUE)
3125 {
3126 sleep(2);
3127 fclip = fopen(Clip_File,"r");
3128 if (fclip == NULL)
3129 {
3130 printf("\nNo Clipboard file! (returning to normal mode.)\n");
3131 strcpy(clipstring1,"XXXX");
3132 strcpy(clipstring2,"XXXX");
3133 clipmode = FALSE;
3134 break;
3135 }
3136 fgets(clipstring1,50,fclip);
3137 fclose(fclip);
3138 if (clipstring1[strlen(clipstring1)-1] < 32) clipstring1[strlen(clipstring1)-1] = 0;
3139 if (strcmp(clipstring1,"quit") == 0)
3140 {
3141 clipmode = FALSE;
3142 printf("\nLeaving Clipboard mode\n");
3143 break;
3144 }
3145 if (strcmp(clipstring1,clipstring2) == 0)
3146 {
3147 continue;
3148 }
3149 else
3150 {
3151 strcpy(clipstring2,clipstring1);
3152 strcpy(instr,clipstring1);
3153 break;
3154 }
3155 }
3156 }
3157 if(strlen(instr) < 2) continue;
3158 GetEUC(fbuff);
3159 if (escf) KOut(fbuff);
3160 sprintf(tempout,"\nSearching for: %s%s%s\n",RVon,fbuff,RVoff);
3161 KOut(tempout);
3162 Dmode = 0;
3163 if (prieng && (fbuff[0] < 128)) /* if priority English key only */
3164 {
3165 j = strlen(fbuff);
3166 fbuff[j+1] = 0;
3167 for (i=0 ; i < j ; i++) fbuff[i+1] = fbuff[i];
3168 fbuff[0] = SPTAG;
3169 }
3170 Lookup();
3171 }
3172 }
3173