#include <stdio.h>    /* shuu_tou_saku, shuusei_kasho, setUp, getPage */
#include <string.h>   /* pageDecompose, tooLongData, manpai_ck, endOfRec */
#include <ctype.h>    /* pageWrite, getZoku, shuusei, sakujo, wdGet */
/* #include <process.h> */      /*        for MS-C && TURBO C++ */
/*            #include <stdlib.h> ; for Lattice C */

/*    #define QWJTOE  */
#define  BITS_32
/* #define BITS_16    Quick Win 版では、こちらが必要。 */

#include "macro.h"
#include "jehonfnc.h"

/*  ***************  Dictionary Maintenance  *********   */
#define  RecNb    40
#define  WdNbPg  300
#define  WdDisp   22
#define  LineLen  70

#define  USER


static void alert(int j);
static void pageDisp(int ia, int wnb);
#if defined(USER)
 static int  shuu_tou_saku(int wnb, char Ans, unsigned int *code,
		    unsigned int code0, int ppt0, int *jz, int nxs[]);
#else
 static int  shuu_tou_saku(int wnb, char Ans, unsigned int *code,
		    unsigned int code0, int ppt0);
#endif
static char shuusei_kasho(void);
static int  getPage(int ppt);
static int  pageDecompose(int jz, int nxs[]);
static void tooLongData(char *r1, char *rd, int pc);
static int  manpai_check(int j, int nxs[]);
static void ZokuDec(int pj, char r1[], int ln, int i);
static int  endOfRec(FILE *fp, int recLen);
static int  pageWrite(int wnb,int jz, int ppt, int nxs[]);
static void getZoku(char zkn[]);
static void shuusei(int in, char tsk);
static void sakujo(int in, int wnb);
static void wdGet(void);


extern   int  dic[660];
int  dicptFlag;
char DRV, jer[253], jwd[JWordLen];
char pg[RecNb][256];
char egw[WdNbPg][WordLen], jpw[WdNbPg][JWordLen], zkw[WdNbPg][ZokuLen];

#include "honyavar.h"


void jedcmain()  /*  globale variable:  jwd[],  jer[]     */
begin
   register int i;
   unsigned int code, code0;
   int j, jz, ppt, ppt0, nx, wnb, ia, iz, nxs[RecNb], cp;
   char Ans, *ptsh, jwdq[JWordLen], Ansq[256];

   while (1) {
   _  Ans = '\0';
   _  puts("\n 終わる時は、END と大文字でタイプして下さい。");
   _  wdGet();
   _  if (strcmp(jwd,"END") == 0)
   _     goto END;
   _  ppt = ptcal(jwd, &code);
   _  code0 = code;
   _  ppt0 = ppt;
   _ PgOpen:
   _  if (! ppt) {
   _  _  ppt = endOfRec(jed,256) + 1;
   _  _  dic[code] = ppt;
   _  _  ppt0 = ppt;
   _  _  dicptWrite();
   _  _  wnb = -1;
   _  _  ia = -1;
   _  }
   _  else {
   _  _  nx = getPage(ppt);  /* ************ 辞書を引く ************** */
   _  _  j = 0;
   _  _  strcpy(pg[j],jer);
   _  _  nxs[j] = nx;
   _  _  while(nx > 0 && nx < MaxNr) {
   _  _  _  j++;
   _  _  _  if (j >= RecNb - 4)
   _  _  _     alert(j);               /* alert for a full data page !! */
   _  _  _  ppt = nx;   /*  ここからは、ポインターに従って、２頁以降を引く。*/
   _  _  _  nx = getPage(ppt);
   _  _  _  strcpy(pg[j],jer);
   _  _  _  nxs[j] =nx;
   _  _  }
   _  _  jz = j;
   _  _  wnb = pageDecompose(jz,nxs);   /* *** 単語に分解する。*** */
   _  _  ia = wnb;
   _  _  strcpy(jwdq,jwd);
   _  _  ptsh = strchr(jwdq,'#');
   _  _  if (ptsh) {
   _  _  _  if (isdigit(*(ptsh + 1)))
   _  _  _    ptreplace(ptsh,2,"話");
   _  _  _  else
   _  _  _    ptreplace(ptsh,1,"話");
   _  _  }
   _  _  for (i = 0; i <= wnb; i++) {
   _  _  _  cp = strcmp(jpw[i],jwdq);
   _  _  _  if (cp > 0) {
   _  _  _  _  beeping(10);
   _  _  _  _  printf("\n 未登録語 %s は %d 番に登録して下さい。\n",jwd,i);
   _  _  _  }
   _  _  _  if (cp >= 0) {
   _  _  _  _  ia = i;
   _  _  _  _  break;
   _  _  _  }
   _  _  }
   _  }
   _  while (Ans != '6') {
   _  _  pageDisp(ia,wnb);         /* display a block of the page data */
   _  _  Ans = '\0';
   _  _  color_green;
   _  _  printf("\n\n 1 修正   2 登録　3 削除   4 同ページの次の行へ\n 5 同ページの前の行へ  6 このページはオワリ \n");
   _  _  color_white;
   _  _  *Ansq = '\0';
   _  _  while (*Ansq < '1' || *Ansq > '6')
   _  _     gets(Ansq);
   _  _  Ans = *Ansq;
   _  _  switch (Ans) {
   _  _    case '1':
   _  _    case '2':
   _  _    case '3':
#if defined(USER)
   _  _      wnb = shuu_tou_saku(wnb,Ans,&code,code0,ppt0,&jz,nxs);
#else
   _  _      wnb = shuu_tou_saku(wnb,Ans,&code,code0,ppt0);   /* 英単語の修正、登録、削除 */
#endif
   _  _      if (iz > wnb)
   _  _         iz = wnb;
   _  _      break;
   _  _    case '4':
   _  _      ia += (WdDisp + 1);
   _  _      iz = ia + WdDisp;
   _  _      if (iz > wnb)
   _  _         iz = wnb;
   _  _      break;
   _  _    case '5':
   _  _      ia -= (WdDisp + 1);
   _  _      if (ia < 0)
   _  _         ia = 0;
   _  _      iz = ia + WdDisp;
   _  _      if (iz > wnb)
   _  _         iz = wnb;
   _  _      break;
   _  _    case '6':
   _  _      if ((code == code0) && dic[code] && (dic[code] < ppt)) {
   _  _      _  ppt = dic[code];
   _  _      _  ppt = bunkatsu(ppt,jwd);
   _  _      }
   _  _      jz = pageWrite(wnb,jz,ppt0,nxs);
   _  _      if ((! dic[code]) && ppt) {
   _  _      _  dic[code] = ppt;
   _  _      _  ++dicptFlag;
   _  _      }
   _  _  }
#if defined(USER)
   _  _  if (code != code0)
   _  _     goto PgOpen;
#endif
   _  }
   }
  END:
   dicptWrite();
   fclose(jed);
   printf("\n  和英辞書管理プログラムを終了しました。\n\n");
end

static void alert(int j)      /* alert for a full data page !! */
begin                         /* global variable:  pg[][] */
   register int i;
   char *ptn, *ptq;

   printf("\n １レコードとして満杯になりかかっています！ ");
   for (i = j - 4; i <= j; i++) {
   if (strchr(pg[i],';')) {
   _  str_rchr(pg[i],':',ptn,ptq);
   _  *(++ptn) = '\0';
   }
   else
      pg[i][0] = '\0';
   printf("pg[%d] = %s \n",i,pg[i]);
   }
#if defined(USER)
   printf("\n このページから、必要度の低い単語、熟語を５，６個削除して下さい。");
#endif
   if (j >= RecNb) {
   _  printf("１レコードとして満杯です！ \n");
   _  exit(1);
   }
end

static void pageDisp(int ia, int wnb)
		 /* WdDisp 個の単語データを画面に表示する。 */
begin    /* global variables: egw[][], jpw[][], zkw[][] */
#if defined(QWJTOE)
   register int i, j;
   int  iz, iaq, line_len, item_len, excess, residue, right_space;
   char left_half[WordLen], *pty;
#else
   register int i;
   int  iz, iaq;
#endif

   iz = ia + WdDisp;
   if (iz > wnb)
      iz = wnb;
   if ((ia == -1) && (wnb == -1))
      printf("(-1)");
   else {
   _  if (ia == -1)
   _     iaq = 0;
   _  else
   _     iaq = ia;
#if defined(QWJTOE)
   _  line_len = 0;
   _  for (i = iaq; i <= iz; i++) {
   _  _  printf("(%d)",i);
   _  _  line_len += 4;
   _  _  if (line_len > LineLen) {
   _  _  _  printf("\n");
   _  _  _  line_len = 0;
   _  _  }
   _  _  item_len = strlen(jpw[i]);
   _  _  if (line_len + item_len > LineLen) {
   _  _  _  residue = ((LineLen - line_len) / 2) * 2;
   _  _  _  if (residue) {
   _  _  _  _  ptcpy(left_half,jpw[i],jpw[i] + residue);
   _  _  _  _  printf("%s\n%s;",left_half,jpw[i] + residue);
   _  _  _  _  line_len = item_len - residue + 1;
   _  _  _  }
   _  _  _  else {
   _  _  _  _  printf("\n%s;",jpw[i]);
   _  _  _  _  line_len = item_len + 1;
   _  _  _  }
   _  _  }
   _  _  else {
   _  _  _  printf("%s;",jpw[i]);
   _  _  _  line_len += (item_len + 1);
   _  _  _  if (line_len >= LineLen) {
   _  _  _  _  printf("\n");
   _  _  _  _  line_len = 0;
   _  _  _  }
   _  _  }
   _  _  item_len = strlen(egw[i]);
   _  _  if (line_len + item_len > LineLen) {
   _  _  _  residue = LineLen - line_len;
   _  _  _  if (residue) {
   _  _  _  _  excess = item_len - residue;
   _  _  _  _  if (excess > residue) {
   _  _  _  _  _  printf("\n%s;",egw[i]);
   _  _  _  _  _  line_len = item_len + 1;
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  printf("%s\n;",egw[i]);
   _  _  _  _  _  line_len = 1;
   _  _  _  _  }
   _  _  _  }
   _  _  _  else {
   _  _  _  _  printf("\n%s;",egw[i]);
   _  _  _  _  line_len = item_len + 1;
   _  _  _  }
   _  _  }
   _  _  else {  
   _  _  _  printf("%s",egw[i]);
   _  _  _  line_len += item_len;
   _  _  _  if (line_len >= LineLen) {
   _  _  _  _  printf("\n;");
   _  _  _  _  line_len = 1;
   _  _  _  }
   _  _  _  else {
   _  _  _  _  printf(";");
   _  _  _  _  ++line_len;
   _  _  _  }
   _  _  }
   _  _  item_len = strlen(zkw[i]);
   _  _  if (line_len + item_len + 5 > LineLen) {
   _  _  _  residue = LineLen - line_len;
   _  _  _  if (residue) {
   _  _  _  _  if (residue <= item_len) {
   _  _  _  _  _  ptcpy(left_half,zkw[i],zkw[i] + residue);
   _  _  _  _  _  pty = strchr(left_half,'y');
   _  _  _  _  _  if ((jpw[i][0] == '1') && pty){
   _  _  _  _  _  _  *pty = '\0';
   _  _  _  _  _  _  pty = strchr(zkw[i],'y');
   _  _  _  _  _  _  printf("%s\n%s;    ",left_half,pty);
   _  _  _  _  _  _  line_len = strlen(pty) + 5;
   _  _  _  _  _  }
   _  _  _  _  _  else {
   _  _  _  _  _  _  printf("%s\n%s;",left_half,zkw[i] + residue);
   _  _  _  _  _  _  line_len = item_len - residue + 1;
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  right_space = LineLen - line_len - item_len;
   _  _  _  _  _  excess = 5 - right_space;
   _  _  _  _  _  printf("%s;",zkw[i]);
   _  _  _  _  _  for (j = 2; j <= right_space; j++)
   _  _  _  _  _     printf(" ");
   _  _  _  _  _  printf("\n");
   _  _  _  _  _  for (j = 1; j <= excess; j++)
   _  _  _  _  _     printf(" ");
   _  _  _  _  _  line_len = excess;
   _  _  _  _  }  
   _  _  _  }
   _  _  _  else {
   _  _  _  _  printf("\n%s;    ",zkw[i]);
   _  _  _  _  line_len = item_len + 1;
   _  _  _  }
   _  _  }
   _  _  else {
   _  _  _  printf("%s;    ",zkw[i]);
   _  _  _  line_len += item_len + 5;
   _  _  _  if (line_len >= LineLen) {
   _  _  _  _  printf("\n");
   _  _  _  _  line_len = 0;
   _  _  _  }
   _  _  }
   _  }
#else
   _  for (i = iaq; i <= iz; i++) {
   _  _  printf("(%d)",i);
   _  _  printf("%s;",jpw[i]);
   _  _  color_magenta;
   _  _  printf("%c",egw[i][0]);
   _  _  color_light_blue;
   _  _  printf("%s;",egw[i] + 1);
   _  _  color_green;
   _  _  printf("%s;    ",zkw[i]);
   _  _  color_white;
   _  }
#endif
   }
end


#if defined(USER)
 static int  shuu_tou_saku(int wnb, char Ans, unsigned int *code, unsigned int code0, int ppt0, int *jz, int nxs[])
#else
 static int  shuu_tou_saku(int wnb, char Ans, unsigned int *code, unsigned int code0, int ppt0)
#endif
					      /* 日本語単語の修正、登録、削除 */
 begin        /* global variables: jwd[], egw[], jpw[], zkw[] */
   register int i;
   int  in, ppt1;
   char nbchar[100], tsk;

   in = wnb + 100;
   while ((in > wnb + 1) || (in < 0)) {
   _  printf("\n\n 修正（登録、削除）の単語（熟語）は何番ですか。\n\n");
   _  *nbchar = '\0';
   _  while (! isdigit(*nbchar))
   _     scanf("%s",nbchar);
   _  in = val(nbchar);            /* in = 修正（登録、削除）する単語の番号  */
   _  if ((in >= 0) && (in <= wnb || Ans == '2') && (in <= wnb + 1))
   _     break;
   }
   switch (Ans) {
     case '3':
	sakujo(in,wnb);   /* 単語を削除する */
	wnb--;
	break;
     case '2':
	if (wnb >= WdNbPg) {
	_  printf("このページの単語はもう満杯です !! egw[*wnb] = %s \n",egw[wnb]);
	_  exit(1);
	}
	printf("\n\n 熟語には「午後#5時」という表現が使えます。\n");
	wdGet();
	ppt1 = ptcal(jwd, code);
	if ((*code != code0) || (ppt0 != ppt1)) {
	_  color_green;
	_  printf("\n\n\n  単語 %s を登録するページが違います。\n\n\n",jwd);
	_  color_white;
#if defined(USER)
	_  beeping(25);
   /*	_  *jz = pageWrite(wnb,*jz,ppt0,nxs); *//* code0 は pt0 にすべきか？ */
   /*	_  color_yellow;  */
   /*	_  printf("\n 正しいページへジャンプします。 \n\n\n");   */
   /*	_  color_white;               */
   /*   _  break;  */
#else
	_  beeping(5);
#endif
	}
	if (in <= wnb) {
	_  for (i = wnb; i >= in; i--) {
	_  _  strcpy(jpw[i + 1],jpw[i]);
	_  _  strcpy(egw[i + 1],egw[i]);
	_  _  strcpy(zkw[i + 1],zkw[i]);
	_  }
	}
	wnb++;
	tsk = '7';
	strcpy(jpw[in],jwd);
     case '1':
	if (Ans == '1')
	   tsk = shuusei_kasho();  /* 修正箇所の問い合わせ */
	shuusei(in,tsk);
   }
   return(wnb);
end


static char shuusei_kasho(void)  /* 修正箇所の問い合わせ */
begin
   char tsk;

   tsk = '0';
   printf("修正箇所は　　");
   printf("1  日本語　　");
   color_light_blue;
   printf("2  訳語英語　　");
   color_white;
   printf("3  品詞　　4  属性　　5  全部　\n\n");
   while ((tsk < '1') || (tsk > '6'))
      tsk = getchar();
   return(tsk);
end

void dicSetUp(void)      /* タイトル表示および辞書ファイルのオープン */
begin
   char Dicfile[15];

   cls();
   color_green;
   printf("\nJapaneseEnglishJapaneseEnglishJapaneseEnglishJapaneseEnglish");
   color_white;
   printf("\n\n *** ");
   color_yellow;
   printf("和英辞書(JEDIC.JTE)メンテナンス \n");
   color_magenta;
   printf("   version 2.1 (C) Copyright by K.Shibata : '05/10/06");
   color_white;
   printf("  *** ");
   color_green;
   printf("\n\nJapaneseEnglishJapaneseEnglishJapaneseEnglishJapaneseEnglish\n\n");
   color_white;
   DRV = '\0';
 
/*   puts("\n 和英辞書が置かれているドライブは？　[A - P] \n");  
   while (tolower(DRV) < 'a' || tolower(DRV) > 'p')
   DRV = getchar();                  UNIXでは削除  */ 

/* ***************    定数格納    ******************* */
   dicptDta();
/*   Dicfile[0] = DRV;
   Dicfile[1] = '\0';
   strcat(Dicfile,":jedic");
   strcat(Dicfile,".jte");           UNIXでは削除  */

   strcpy(Dicfile,"jedic.jte");     /*  かわりに挿入  */

   jed = fopen(Dicfile,"r+");
   if (! jed) {
   _  color_green;
   _  printf("\n 辞書ファイルがオープン出来ませんでした。正しいドライブを指定しましたか？ \n");
   _  color_white;
   _  exit(1);
   }
   dicptFlag = 0;
end


static int  getPage(int ppt)
	    /* 辞書から同一キーのレコードを読み出して、jer[] にコピー。*/
begin             /*  global variable: *jed  */
   int len, nx, nxend;
   long ptl;
   char *ptc, yn, *ptq;

   nxend = endOfRec(jed,256);
   ptl = (long)(ppt - 1) * 256L;
   rewind(jed);
   if (fseek(jed,ptl,0)) {
   _  beeping(10);
   _  color_yellow;
   _  printf("辞書が見つかりません !!　正しいドライブを指定しましたか？ \n");
   _  color_white;
   _  exit(1);
   }
   fread(jer,252,1,jed);
   fscanf(jed,"%4d",&nx);
   *(jer + 251) = '\0';
   str_rchr(jer,':',ptc,ptq);
   if (ptc)
      *(ptc + 1) = '\0';
   else {
   _  ptc = strchr(jer,':');
   _  if (ptc) /* <------ dummy command      */
   _     goto OK;
   _  if (*jer && (jer != strstr(jer,"                               "))) {
   _  _  beeping(10);
   _  _  color_yellow;
   _  _  printf("辞書データに異常があります !! jer = %s \n",jer);
   _  _  color_white;
   _  _  exit(1);
   _  }
   _ OK:;
   }
   if ((nx != 0) && ((nx < 35) || (nx > nxend) || (nx > MaxNr))) {
   _  len = strlen(jer);
   _  beeping(10);
   _  color_yellow;
   _  printf("辞書のページポインターに異常があります !!  ppt = %d  nx = %d  nxend = %d  strlen(jer) = %d  jer = %s \n",ppt,nx,nxend,len,jer);
   _  yn = '\0';
   _  color_green;
   _  printf("Continue, or Abort ?  [C/A] \n");
   _  color_white;
   _  while (tolower(yn) != 'c' && tolower(yn) != 'a')
   _     yn = getchar();
   _  if (tolower(yn) == 'a')
   _      exit(1);
   }
   return(nx);
end

static int  pageDecompose(int jz, int nxs[])
  /* 辞書の頁を、日本語(jpw[]),英訳語(egw[]),属性(zkw[])に分解 */
begin          /* global variable:  pg[][]  */
   int i, j, pc, pe, pj, ln, manpai;
   char rd[256],r1[180];

   i = -1;
   manpai = 0;
   for (j = 0; j <= jz; j++) {
   _  strcpy(rd,pg[j]);
   _  pc = instrc(rd,':');
   _  while (pc) {
   _  _  if (pc >= 180)
   _  _     tooLongData(r1,rd,pc);  /* Too long data for one word!! */
   _  _  else
   _  _     left(r1,rd,pc - 1);
   _  _  while (*r1 == ' ')
   _  _     ptcut(r1,1);
   _  _  pe = instrc(r1,';');
   _  _  if (pe <= 1 || r1[0] == '\0')
   _  _     goto NXT;
   _  _  i++;
   _  _  if (pe > JWordLen) {
   _  _  _  beeping(10);
   _  _  _  printf("日本語単語（熟語）が長すぎます !! \n");
   _  _  _  color_light_blue;
   _  _  _  printf("      %s \n",r1);
   _  _  _  color_white;
   _  _  _  printf("これの長さは %d/2 文字有ります。 \n",pe);
   _  _  _  color_yellow;
   _  _  _  printf("上の熟語の一部を切り捨てます。 \n");
   _  _  _  color_white;
   _  _  _  ptcpy(jpw[i],r1,r1 + JWordLen - 7);
   _  _  _  strcat(jpw[i],".... ");
   _  _  }
   _  _  else
   _  _     left(jpw[i],r1,pe - 1);
   _  _  ln = strlen(r1);
   _  _  pj = ninstrc(pe + 1,r1,';');
   _  _  if (pj - pe - 1 >= WordLen) {
   _  _  _  beeping(10);
   _  _  _  color_green;
   _  _  _  printf("英訳語が長すぎます !! \n");
   _  _  _  color_yellow;
   _  _  _  printf("        %s \n",r1);
   _  _  _  color_white;
   _  _  _  printf("これの長さは %d 文字分あります。 \n",pj - pe - 1);
   _  _  _  printf("上の訳語の一部を切り捨てます。 \n");
   _  _  _  ptcpy(egw[i],r1 + pe,r1 + pe + WordLen - 7);
   _  _  _  strcat(egw[i],".... ");
   _  _  }
   _  _  else
   _  _     mid(r1,pe + 1,pj - pe - 1,egw[i]);
   _  _  ZokuDec(pj,r1,ln,i);
   _  _  if (i >= (WdNbPg - 12)) {
   _  _  _  manpai = manpai_check(j,nxs);
   _  _  _  if (! manpai) {
   _  _  _  _  printf("同じキーの単語が満杯になりかかっています !! \n");
   _  _  _  _  printf("limit = %d.  jpw[%d] = %s  rd = %s \n",WdNbPg,i,jpw[i],rd);
#if defined(USER)
   _  _  _  _  printf("\n このページから、必要度の低い単語、熟語を５，６個削除して下さい。");
#endif
   _  _  _  }
   _  _  _  else {
   _  _  _  _  beeping(10);
   _  _  _  _  color_magenta;
   _  _  _  _  printf("\n 辞書のデータに異常があったので、修復をしました。\n");
   _  _  _  _  color_white;
   _  _  _  _  printf("\n 一旦、このプログラムを終了して、「MS/DOS」にもどります。もう一度、「dicmain.exe」を起動し直して下さい。 \n");
   _  _  _  _  exit(1);
   _  _  _  }
   _  _  }
   _  NXT:
   _  _  ptcut(rd,pc);
   _  _  pc = instrc(rd,':');
   _  }
   }
   return(i);
end

static void tooLongData(char *r1, char *rd, int pc)
				      /* Too long data for one word!! */
begin
   int psc, psc2;

   beeping(10);
   color_yellow;
   printf("１単語のデータとして長すぎます !!  rd = %s  strlen(r1) = %d \n",rd,pc);
   printf("\n データの一部を切り捨てます。 \n");
   color_white;
   psc = instrc(rd,';');
   if (psc > 80) {          /* まず、日本語単語を短縮する。 */
   _  ptcpy(r1,rd,rd + 75);
   _  strcat(r1,".... ");
   }
   else {
   _  if (psc)
   _     ptcpy(r1,rd,rd + psc -1);
   _  else
   _     exit(1);
   }
   psc2 = instrc(rd + psc,';');
   if (psc2 > 80) {          /* 次に、英訳語を短縮する。 */
   _  ptcpy(r1 + strlen(r1),rd + psc - 1,rd + psc + 75);
   _  strcat(r1,".... ");
   }
   else {
   _  if (psc2)
   _     ptcpy(r1 + strlen(r1),rd + psc - 1,rd + psc + psc2 -1);
   _  else
   _     exit(1);
   }
   ptcpy(r1 + strlen(r1),rd + psc + psc2 -1,rd + pc - 1);
end

static int  manpai_check(int j, int nxs[])
			   /* 登録の満杯状態をチェックする。 */
begin                           /* global variable:  pg[][] */
   int  manpai;
   long ptl;
   char pgDta1[205], pgDta2[205];

   manpai = 0;
   if (j) {
   _  do {
   _  _  ptcpy(pgDta1,pg[j - 1],pg[j - 1] + 200);
   _  _  ptcpy(pgDta1,pg[j],pg[j] + 200);
   _  _  if (strcmp(pgDta1,pgDta2) == 0) {
   _  _  _  manpai = j;       /* 本当は満杯ではなかった場合 */
   _  _  _  pg[j][0] = '\0';  /* まったく同じ内容が次のページにもコピーされている。*/
   _  _  _  nxs[j] = 0;
   _  _  _  nxs[j - 1] = 0;
   _  _  }
   _  _  else
   _  _     break;
   _  } while (--j);
   _  if (manpai) {
   _  _  ptl = (long)(nxs[j - 1] - 1) * 256L;
   _  _  if (fseek(jed,ptl,0)) {
   _  _  _  printf("dictionary seek error !! \n");
   _  _  _  exit(1);
   _  _  }
   _  _  fprintf(jed,"%-252s%04d",pg[j],0);
   _  }
   }
   return(manpai);
end

static void ZokuDec(int pj, char r1[], int ln, int i)  /* zokusei bunkai */
begin      /* global variables: rom[], zkw[] */
   char yn;

   if (ln - pj >= (ZokuLen - 2)) {
   _  beeping(15);
   _  printf("属性が多過ぎます。 r1 = %s \n",r1);
   _  printf("属性の数 = %d, Limit = %d \n",ln - pj,ZokuLen);
   _  yn = '\0';
   _  printf("Continue, or Abort?  [C/A] \n");
   _  while ((toupper(yn) != 'C') && (toupper(yn) != 'A'))
   _     yn = getchar();
   _  if ((yn == 'A') || (yn == 'a'))
   _     exit(1);
   }
   right(r1,zkw[i],ln - pj);
end


static int  endOfRec(FILE *fp, int recLen)
			     /* 辞書ファイルの最後のレコード番号を返す。*/
begin
   long ptl, nl;
   int n;

   rewind(fp);
   fseek(fp,-1L,2);
   ptl = ftell(fp);
   if (ptl < 0)
      n = 0;
   else {
   _  nl = ptl / recLen;
   _  n = (int)nl + 1;
   }
#if defined(EOFDEB)
   printf("ptl = %ld  recLen = %d  nl = %ld  n = %d \n",ptl,recLen,nl,n);
#endif
   return(n);
end

static int  pageWrite(int wnb, int jz, int ppt, int nxs[])
					 /* data output to the diskette */
begin     /* global variables: ejd, egw[][],jpw[][], pg[][], zkw[][] */
   register int i, j;
   int pt0, lnr;
   long ptl;
   char rcd[256];

   j = 0;
   pt0 = ppt;
   ptl = (long)(ppt - 1) * 256L;
   rcd[0] = '\0';
   for (i = 0; i <= wnb; i++) {
   _  if (strlen(rcd) + strlen(jpw[i]) + strlen(egw[i]) + strlen(zkw[i]) >= 247) {
   _  _  strcpy(pg[j],rcd);
   _  _  rcd[0] = '\0';
   _  _  if (j == jz)
   _  _     nxs[j] = endOfRec(jed,256) + 1;
   _  _  if (j > jz)
   _  _     nxs[j] = nxs[j - 1] + 1;
   _  _  j++;
   _  }
   _  while (jpw[i][0] == ' ')
   _     cutoff(jpw[i],0,1);
   _  if (jpw[i][0] == '\0')
   _     goto NXTI;
   _  lnr = strlen(rcd);
   _  sprintf(rcd + lnr,"%s;%s;%s:",jpw[i],egw[i],zkw[i]);
   _  lnr = strlen(rcd);
   _  if (lnr >= 251) {
   _  _  printf("Too long record!! lnr = %d  rcd = %s \n",lnr,rcd);
   _  _  exit(1);
   _  }
   NXTI:;
   }
   strcpy(pg[j],rcd);
   nxs[j] = 0;
   jz = j;
   for (j = 0; j <= jz; j++) {
   _  ptl = (long)(ppt - 1) * 256L;
   _  if (fseek(jed,ptl,0)) {
   _  _  printf("dictionary seek error !! \n");
   _  _  exit(1);
   _  }
   _  fprintf(jed,"%-252s%04d",pg[j],nxs[j]);
   _  ppt = nxs[j];
   }
   if (jz > 0)
      ppt = nxs[jz - 1];
   else
      ppt = pt0;
 /*  printf("jz = %d pg[%d] = %s  nxs[%d] = %d  ppt = %d \n",jz,jz,pg[jz],jz,nxs[jz],ppt);  */
   ppt = endOfRec(jed,256);
 /*  printf("end_of_rec = %d \n",ppt);   */
   return(jz);
end

static void getZoku(char zkn[]) /* 単語の属性データをキーボードから受け取る。*/
begin
   int ct, ln, ln2;
   char *zk2w, yn[100];

   puts("属性を入力して下さい。");
   puts("数えられる名詞は、y個、y本、y冊、y匹、のように、 数え方の単位の前にyをつけて入力して下さい。");
   puts("動詞は必ず、i または jまたは kを属性として入力してください。i,j,k の意味は、下に書いてあります。");
   puts("この辞書では、単語の属性を下の記号で表します。\n");
   color_green;
   puts("a 動物、c 商業、通信、交通、d 定冠詞 (the)、e 教育、文化、芸術、f  未来、 g 国、州、地方、h 人間（名詞，代名詞）");
   puts("i 目的語を一つだけ取る他動詞、 j 自動詞、k 目的語を二つとる他動詞(give him a book のように) 、 l 動詞に連用形を要求する助動詞、 m 生理、身体、健康、スポーツ、n 数");
   color_yellow;
   puts("o 代名詞目的格、p 過去、q 疑問、r 関係代名詞、関係副詞、  s 心理、t 時、季節、u 人間（名詞，代名詞以外）、v be動詞、w 気象、天体、自然");
   puts("x 語尾に３単現または複数の 's'、y 数えられる名詞、z 複数形では使わない名詞");
   color_light_blue;
   printf("\n A 副詞句として訳す助動詞句（'have the fortune to' => 「幸いにも」など）。 時制が後続の動詞の訳語に伝ぱんする。\n");
   puts("B 場所、C 比較級、D 後続の動詞訳語に「て音便」を要求する助動詞、E there is, there are など、F and, or, but、G 現在分詞、H have および使役動詞 let, make、I 仮主語のit、J 動名詞を目的語に取る(助)動詞、K 固有名詞");
   puts("L 状態動詞('in'を'に'と訳す。live等)、M 称号（Dr. Mr. など）、N 否定、O 大文字で始まる、P 過去分詞、Q 知覚動詞('well'を'よく'と訳す。know等)、R 埋め込み単語の右の語の品詞");
   color_magenta;
   puts("T to不定詞、U 最上級、V 勧誘 (let's, please)、W 女性、 X  ふつう複数形で使われる名詞、ただし辞書には単数形で登録する、Y 未登録単語");
   color_white;
   puts("上のどれにも当てはまらない時は、単に、リターンキーを押してください。");
   puts("属性は ？");
   zkn[0] = '3';
   ct = 0;
   while(! isalpha(*zkn)) {
      gets(zkn);
      ct++;
      if (ct == 2)
	 break;
   }
   ln = strlen(zkn);
   zk2w = zkn + ln;
   *zk2w = '|';
   zk2w++;
   ++ln;
   *zk2w = '\0';
   printf("\n\n 第２属性が有れば入力して下さい。\n");
   ct = 0;
   while(! *zk2w) {
   _  gets(zk2w);
   _  ct++;
   _  if (ct >= 2)
   _	 break;
   _  if (! *zk2w) {
   _  _  beeping(10);
   _  _  color_yellow;
   _  _  printf("\n\n 第２属性は「無し」でよろしいですか？ [Y/N] \n\n");
   _  _  color_white;
   _  _  *yn = '\0';
   _  _  while (! *yn)
   _  _     gets(yn);
   _  _  if ((*yn == 'Y') || (*yn == 'y'))
   _  _     break;
   _  _  if ((*yn == 'N') || (*yn == 'n'))
   _  _     printf("\n\n 第２属性を入力して下さい。\n\n");
   _  }
   _  ln2 = strlen(zk2w);
   _  if (ln + ln2 >= ZokuLen) {
   _  _  beeping(10);
   _  _  printf("属性が長過ぎます !!  zkn = %s, 長さ = %d + %d \n",zkn,ln,ln2);
   _  _  printf("        属性の入力をやり直して下さい！！\n");
   _  _  color_yellow;
   _  _  printf("   半角 %d 文字以内 \n\n",ZokuLen - 1);
   _  _  color_white;
   _  _  *zk2w = '\0';
   _  }
   }
end

static void shuusei(int in, char tsk)    /*  辞書登録データの修正 */
begin             /*  globale variables: egw[][], jpw[][], （rom[],） zkw[][] */
   int  ln, lenLim;
   char cd, yn, jpwq[256], egwq[256];

   switch(tsk) {
   _  case '5':;
   _  case '1':
   _     jpw[in][0] = '\0';
   _     jpwq[0] = '\0';
   _     yn = '\0';
   _     lenLim = (JWordLen / 2);
   _     color_green;
   _     printf(" 日本語には、上の「#」と「>」の他に「$」(右隣の一語)と「<」(左隣の一語)が使えます。\n    日本語 =  ?    ");
   _     color_yellow;
   _     printf("全角 %d 文字以内\n\n",lenLim);
   _     color_white;
   _     while (! jpwq[0]) {
   _     _  gets(jpwq);
   _     _  ln = strlen(jpwq);
   _     _  if (ln >= JWordLen) {
   _     _  _  beeping(10);
   _     _  _  printf("日本語が長過ぎます !!  jpw[in] = %s, 長さ = %d \n",jpwq,ln);
   _     _  _  printf("        日本語の入力をやり直して下さい！！\n\n");
   _     _  _  jpwq[0] = '\0';
   _     _  }
   _     _  if (isalpha(*jpwq) && isalpha(*(jpwq + 1))) {
   _     _  _  beeping(10);
   _     _  _  printf("日本語を入力して下さい !!  jpw[in] = %s \n",jpwq);
   _     _  _  printf("        日本語の入力をやり直して下さい！！\n\n");
   _     _  _  jpwq[0] = '\0';
   _     _  }
   _     _  if (yn) {
   _     _  _  insertc(jpwq,0,yn,ln);
   _     _  _  break;
   _     _  }
   _     _  if (! jpwq[0]) {
   _     _  _  yn = getchar();
   _     _  _  if (yn == '\n')
   _     _  _     break;
   _     _  }
   _     }
   _     strcpy(jpw[in],jpwq);
   _     if (tsk == '1')
   _        goto EndANS;
   _  case '7':
   _  case '2':
   _     egw[in][0] = '\0';
   _     egwq[0] = '\0';
   _     yn = '\0';
   _     color_green;
   _     printf(" 英訳語には、上の「#」と「>」の他に「$」(右隣の一語)と「<」(左隣の一語)が使えます。\n    訳語 =  ?    ");
   _     color_yellow;
   _     printf("半角 %d 文字以内\n\n",WordLen);
   _     color_white;
   _     while (! egwq[0]) {
   _     _  gets(egwq);
   _     _  ln = strlen(egwq);
   _     _  if (ln >= WordLen) {
   _     _  _  beeping(10);
   _     _  _  printf("訳語が長過ぎます !!  egw[in] = %s, 長さ = %d \n",egwq,ln);
   _     _  _  printf("        訳語の入力をやり直して下さい！！\n\n");
   _     _  _  egwq[0] = '\0';
   _     _  }
   _     _  if (yn) {
   _     _  _  insertc(egwq,0,yn,ln);
   _     _  _  break;
   _     _  }
   _     _  if (! egwq[0]) {
   _     _  _  yn = getchar();
   _     _  _  if (yn == '\n')
   _     _  _     break;
   _     _  }
   _     }
   _     strcpy(egw[in],egwq);
   _  case '3':
   _     puts("\n 上の単語の品詞コードを下の番号の中から選んでください。\n");
   _     puts("1 名詞　 2 代名詞　 3 動詞  4 助動詞   5 形容詞   6 副詞  7 前置詞  8 冠詞  9 接続詞  X 間投詞 \n");
   _     cd = '\0';
   _     while ((cd < '0' || cd > '9') && ((! cd) || (! strchr("X?!|",cd))))
   _        cd = getchar();
   _     if (tsk == '3') {
   _     _  egw[in][0] = cd;
   _     _  goto EndANS;
   _     }
   _     else
   _        insertc(egw[in],0,cd,strlen(egw[in]));
   _     if (tsk == '2')
   _        goto EndANS;
   _  case '4':
   _     getZoku(zkw[in]);
   }
  EndANS:;
end

static void sakujo(int in, int wnb)   /* 単語を削除する */
begin                        /* global variables: egw[][],jpw[][],zkw[][] */
      register int i;

   for (i = in; i <= wnb; i++) {
   _  strcpy(egw[i],egw[i + 1]);
   _  strcpy(jpw[i],jpw[i + 1]);
   _  strcpy(zkw[i],zkw[i + 1]);
   }
end

static void wdGet(void)
   /* 登録（修正、削除）すべき英単語をキーボードから受け取って、大域変数 jwd[] に格納する。*/
begin       /*  globale variable:  jwd[]     */
   int ln;
   unsigned int  *wdptr, code;
   char wdq[256], yn[100];
   unsigned char *ptr;

   *jwd = '\0';
   *wdq = '\0';
   while (1) {
   _  color_yellow;
   _  printf("\n 登録（修正）したい日本語単語（熟語も可） = ?   ;");
   _  color_magenta;
   _  printf("全角 %d 文字以内 \n",(JWordLen - 1)/2);
   _  color_white;
   _  gets(wdq);
   _  if (! *wdq) {
   _  _  printf("\n "); /* <------------------ dummy command      */
   _  _  gets(wdq);
   _  }
   _  ln = strlen(wdq);
   _  if (ln >= JWordLen) {
   _  _  beeping(10);
   _  _  printf("日本語単語が長過ぎます !!  word = %s, 長さ = %d \n",wdq,ln);
   _  _  printf("        単語（熟語）の入力をやり直して下さい！！\n");
   _  _  color_yellow;
   _  _  printf("      全角  %d 文字以内 \n\n",(JWordLen - 1)/2);
   _  _  color_white;
   _  _  *wdq = '\0';
   _  }
   _  else
   _     if (ln >= 2) {
   _     _  if (strcmp(wdq,"END") == 0)
   _     _     break;
   _     _  else {
   _     _  _  if (isalpha(*wdq) && *jwd && (*wdq != *jwd)) {
   _     _  _  _  beeping(10);
   _     _  _  _  printf("\n\n 登録（修正）する単語は");
   _     _  _  _  color_yellow;
   _     _  _  _  printf(" %s ",wdq);
   _     _  _  _  color_white;
   _     _  _  _  printf(" でよろしいですか？ [Y/N]\n\n");
   _     _  _  _  *yn = '\0';
   _     _  _  _  while (! *yn)
   _     _  _  _     gets(yn);
   _     _  _  _  if ((*yn == 'Y') || (*yn == 'y'))
   _     _  _  _     break;
   _     _  _  _  if ((*yn == 'N') || (*yn == 'n'))
   _     _  _  _     printf("\n\n 単語を再入力して下さい。\n\n");
   _     _  _  }
   _     _  _  else {
   _     _  _  _  ptr = (unsigned char *) wdq;
   _     _  _  _  wdptr = (unsigned int *) ptr;
#if defined(BITS_32)
   _     _  _  _  code = ((((*wdptr) <<16) >> 28) | (((*wdptr) << 24) >> 20));
#endif
#if defined(BITS_16)
   _     _  _  _  code = (((*wdptr) >> 12) | (((*wdptr) << 8) >> 4));
#endif
   _     _  _  _  if ((code >= 0x814) && (code <= 0xED6))
   _     _  _  _     break;
   _     _  _  _  else {
   _     _  _  _  _  beeping(15);
   _     _  _  _  _  color_yellow;
   _     _  _  _  _  printf("\n\n 入力された単語 %s の先頭の１文字は不適切です。別の単語を再入力して下さい。\n\n",wdq);
   _     _  _  _  _  color_white;
   _     _  _  _  }
   _     _  _  }
   _     _  }
   _     }
   }
   strcpy(jwd,wdq);
end
