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