#include <stdio.h>   /*  **************  katuyou.c  ************** */
#include <string.h>  /* past, past_be, nega, sinko */
#include <ctype.h>   /* mokuteki_kaku, hikaku */
/*  #include <jctype.h>       for MS-C && TURBO C++ */
/* #include <mbctype.h>     for Visual C++ ver. 4.0 */
/* #include <process.h>  */

#include "macro.h"

#include "jehonfnc.h"

static int  irreg_file_ck(char mdq[], int pp_flag, char pstq[], char *pt1, int v_pos, char *ptsp, int lnq, char md[]);
static int  past_be(char md[], char mdq[], char *pt1, char *ptsp, int v_pos, int lnq);

#include "honyavar.h"

void past(char md[], int i, int pp_flag)
				/* 英訳語を過去形または過去分詞形にする。*/
begin      /* global variables : wc, cz[][]  */
   int   v_pos, b_pos, H_pos, axv_pos, conj_pos, ln, lnq, j, irg = 0, pstv = 0;
   unsigned int  spcnt;
   char  hseq[10], mdq[WordLen], pstq[WordLen];
   char  *pt1, *pt2, *ptsp;

   if (md == strstr(md," （"))
      goto END;
   *pstq = '\0';
   if ((! strchr(md,'(')) || strstr(md,"(x)") || strstr(md,"(s)") || (pp_flag == 2) ) {
   _  v_pos = 0;  /* 上で (x) だけでなく (s) も加えた。 2004.03.10 */
   _  b_pos = 0;  /*  2005.06.09 */
   _  H_pos = 0;  /*  2005.06.09 */
   _  pt2 = strchr(md,'(');
   _  if (pt2 && (*(pt2 + 1) != 'x') && (pt2 != strstr(pt2,"(s)"))) {
   _  _  strcpy(mdq,pt2 + 1);
   _  _  pt1 = strchr(mdq,')');
   _  _  if (pt1)
   _  _     *pt1 = '\0';
   _  _  ptcpy(pstq,md,pt2 - 1);
   _  _  str_rchr(pstq,' ',ptsp,pt1);
   _  _  if (ptsp)
   _  _     ptptcut(pstq,ptsp);
   _  }
   _  else {
   _  _  pt1 = strchr(cz[wc + i],'|');
   _  _  if (pt1)
   _  _     pt1 = strchr(pt1 + 1,'(');
   _  _  if (pt1 && (! strchr(pt1 + 2,'('))) {
	/* md[] が複数の単語からなる熟語で、その要素の品詞列が第２属性に記述されている場合 */
   _  _  _  ++pt1;
   _  _  _  pt2 = strchr(pt1 + 1,')');
   _  _  _  ptcpy(hseq,pt1,pt2);
   _  _  _  spcnt = 1;
   _  _  _  ptsp = strchr(md,' ');
   _  _  _  while (ptsp) {
   _  _  _  _  ++spcnt;
   _  _  _  _  ptsp = strchr(ptsp + 1,' ');
   _  _  _  }  /* (636) で後ろの「6」が複数の語からなる場合に対応した。2002.07.28 */
   _  _  _  if ( (spcnt == strlen(hseq)) || (strcmp(hseq,"636") == 0) ) {
   _  _  _  _  axv_pos = instrc(hseq,'4');
   _  _  _  _  if ((isdigit(*pt1) && (! axv_pos)) || strchr("vHX&",*pt1)) {
   _  _  _  _  _  v_pos = instrc(hseq,'3'); /* 上の '&' を加えた。2005.04.18 */
   _  _  _  _  _  b_pos = instrc(hseq,'v');
   _  _  _  _  _  H_pos = instrc(hseq,'H');
   _  _  _  _  _  if ( (! v_pos) || ((b_pos > 0) && (v_pos > b_pos)) )
   _  _  _  _  _     v_pos = b_pos;  /* 上の第２条件を加えた。 2005.06.09 */
   _  _  _  _  _  if ( (! v_pos) || ((H_pos > 0) && (v_pos > H_pos)) )
   _  _  _  _  _     v_pos = H_pos;  /* 上の第２条件を加えた。 2005.06.09 */
   _  _  _  _  _  if (v_pos) {
   _  _  _  _  _  _  --v_pos;
   _  _  _  _  _  _  if (v_pos < 1) {
   _  _  _  _  _  _  _  wdcpy(mdq,md);
   _  _  _  _  _  _  _  v_pos = 0;
   _  _  _  _  _  _  }
   _  _  _  _  _  _  else {
   _  _  _  _  _  _  _  ptsp = md;
   _  _  _  _  _  _  _  for (j = 1; j <= v_pos; j++)
   _  _  _  _  _  _  _     ptsp = strchr(ptsp + 1,' ');
   _  _  _  _  _  _  _  wdcpy(mdq,ptsp + 1);
   _  _  _  _  _  _  }
   _  _  _  _  _  }
   _  _  _  _  _  else {
   _  _  _  _  _  _  if ((! strchr(hseq,'v')) && (! strchr(hseq,'H')) && (! strchr(hseq,'X')))
   _  _  _  _  _  _     pstv = 1;
   _  _  _  _  _  _  else
   _  _  _  _  _  _     wdcpy(mdq,md);
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  if (axv_pos) {
   _  _  _  _  _  _  pstv = 1;
   _  _  _  _  _  _  if (md == strstr(md,"don't ")) /* 否定形の場合を加えた。*/
   _  _  _  _  _  _    ptreplace(md,5,"didn't (don't)"); /* 2004.01.21 */
   _  _  _  _  _  _  else {
   _  _  _  _  _  _  _  if (md == strstr(md,"do "))
   _  _  _  _  _  _  _    ptreplace(md,2,"did (do)");
   _  _  _  _  _  _  _  else {
   _  _  _  _  _  _  _  _  if (md == strstr(md,"can't "))
   _  _  _  _  _  _  _  _     ptreplace(md,5,"couldn't (can't)");
   _  _  _  _  _  _  _  _  else {
   _  _  _  _  _  _  _  _  _  if (md == strstr(md,"can "))
   _  _  _  _  _  _  _  _  _     ptreplace(md,3,"could (can)");
   _  _  _  _  _  _  _  _  }
   _  _  _  _  _  _  _  }
   _  _  _  _  _  _  }
   _  _  _  _  _  }
   _  _  _  _  _  else
   _  _  _  _  _     wdcpy(mdq,md);
   _  _  _  _  }
   _  _  _  }
   _  _  _  else   /* 動詞句の一部分に熟語が取り込まれている場合 */
   _  _  _     wdcpy(mdq,md);
   _  _  }
   _  _  else
   _  _     wdcpy(mdq,md);
   _  }
   _  if (! pstv) {
   _  _ START:;  /* 動詞が２つ以上有る場合に対応した。2002.08.18 */
   _  _  ln = strlen(md);
   _  _  lnq = strlen(mdq);
   _  _  irg = irreg_file_ck(mdq,pp_flag,pstq,pt1,v_pos,ptsp,lnq,md);
	 /* 不規則動詞活用変化表 "irregul.jte"により過去形を求める。*/
   _  _  if (! irg)
   _  _     irg = past_be(md,mdq,pt1,ptsp,v_pos,lnq); /* be動詞現在形(am,is,are)を過去形にする。*/
   _  _  if (! irg) {
   _  _  _  if (! strstr("burst,cast,cut,hit,put,read,become,come,cost,plead,run,set,shed,thrust",mdq)) {
			       /* 原型、過去、過去分詞が同じ形ではない動詞 */
   _  _  _  _  if ((lnq >= 3) && strchr("prt",*(mdq + lnq - 1)) && isVowel(*(mdq + lnq - 2)) && (! isVowel(*(mdq + lnq - 3))) ) {
   _  _  _  _  _  if ( (lnq == 3) || (! isVowel(*(mdq + lnq - 4))) ) {
   _  _  _  _  _  _  if ((*(mdq + lnq - 1) != 'r') || (strcmp(mdq + lnq - 2,"ir") == 0) || (strcmp(mdq + lnq - 3,"fer") == 0)) {
				 /* 末尾の子音をだぶらせる場合 */
   _  _  _  _  _  _  _  *(mdq + lnq) = *(mdq + lnq - 1);
   _  _  _  _  _  _  _  *(mdq + lnq + 1) = '\0';
   _  _  _  _  _  _  }
   _  _  _  _  _  }
   _  _  _  _  _  else {
   _  _  _  _  _  _  if ( (strcmp(mdq + lnq - 3,"mit") == 0) && (*(mdq + lnq - 4) != 'i') ) {
   _  _  _  _  _  _  _  *(mdq + lnq) = 't';
   _  _  _  _  _  _  _  *(mdq + lnq + 1) = '\0'; /* commit, omit => committed, omitted  2005.04.10 */
   _  _  _  _  _  _  }
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  if ((*(mdq + lnq - 1) == 'y') && (! isVowel(*(mdq + lnq - 2)))) {
   _  _  _  _  _  _  if (strcmp(mdq,"marry") == 0)
   _  _  _  _  _  _     strcpy(mdq,"got marri");
   _  _  _  _  _  _  else
   _  _  _  _  _  _     *(mdq + lnq - 1) = 'i';
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  _  if (*(mdq + lnq - 1) == 'e')
   _  _  _  _     strcat(mdq,"d");
   _  _  _  _  else
   _  _  _  _     strcat(mdq,"ed");
   _  _  _  }
   _  _  _  strcat(mdq," (");
   _  _  _  if (v_pos) {      /* 動詞の位置(v_pos)が熟語の先頭ではない場合 */
   _  _  _  _  ptinsert(ptsp + 1 + lnq,")");
   _  _  _  _  ptinsert(ptsp + 1,mdq); /* バグを訂正した。pt1 => ptsp 2002.07.27 */
   _  _  _  }
   _  _  _  else {
   _  _  _  _  if (ln == lnq)
   _  _  _  _     strcat(md,")");
   _  _  _  _  else
   _  _  _  _     ptinsert(md + lnq,")");
   _  _  _  _  ptinsert(md,mdq);
   _  _  _  }
   _  _  }
   _  _  if (*hseq && strstr(hseq + v_pos + 1,"93")) { /* 動詞が２つ以上有る場合に対応した。*/
   _  _  _  conj_pos = instrc(hseq + v_pos + 1,'9');   /* 2002.08.18 */
   _  _  _  while (*(hseq + v_pos + conj_pos + 1) != '3') {
   _  _  _  _  conj_pos = instrc(hseq + v_pos + conj_pos + 1,'9');
   _  _  _  _  if (! conj_pos)
   _  _  _  _     goto END;
   _  _  _  }
   _  _  _  v_pos += conj_pos;
   _  _  _  if (v_pos) {
   _  _  _  _  ptsp = md; /* md[] には既に過去形括弧の前後に空白が１つずつ有る。 */
   _  _  _  _  for (j = 0; j <= (v_pos + 1); j++)
   _  _  _  _     ptsp = strchr(ptsp + 1,' '); /* ３番目以降の動詞で有れば */ 
   _  _  _  _  wdcpy(mdq,ptsp + 1);            /* さらに偶数を加算する必要がある。*/
   _  _  _  _  goto START;
   _  _  _  }
   _  _  _  else
   _  _  _     goto END;
   _  _  }
   _  _  if (! strchr(cz[wc + i],'p'))
   _  _     ptinsert(cz[wc + i],"p");
   _  }
   }
  END:;
end

static int irreg_file_ck(char mdq[], int pp_flag, char pstq[], char *pt1, int v_pos, char *ptsp, int lnq, char md[])
         /* 不規則動詞活用変化表 "irregul.jte"により過去形を求める。*/
begin      /* global variable :  DRV  */
   int   irg = 0;
   char  Irregfile[15], irdata[55], org[20], pst[20], pple[20];
   char  *ptn, *ogpt, *pt_space, *ptcom, *ptpar, *ptpar2;
   FILE  *irreg;

/*    Irregfile[0] = DRV; */  /* 一般動詞の過去、過去分詞型の可能性を調べる。*/
/*    Irregfile[1] = '\0';  */  /* 不規則動詞活用変化表 "irregul.jte"を引く。*/
/*    strcat(Irregfile,":irregul.jte");  */

   strcpy(Irregfile,"irregul.jte");   /* UNIX */

   irreg = fopen(Irregfile,"r");
   while (fgets(irdata,53,irreg))  {
   _  ptn = strchr(irdata,';');
   _  if (ptn)
   _     *ptn = '\0';
   _  ogpt = strchr(irdata,',');
   _  if (ogpt)
   _     ptcpy(org,irdata,ogpt);     /* org[] は動詞の原形 */
   _  if (strcmp(org,mdq) == 0) {
   _  _  ptcom = strchr(ogpt + 2,',');
   _  _  if (ptcom) {
   _  _  _  strcat(mdq,")");
   _  _  _  if (pp_flag == 1) {        /* pst[] は過去形 */
   _  _  _  _  ptcpy(pst,ogpt + 1,ptcom++);
   _  _  _  _  strcat(pst," (");
   _  _  _  _  ptinsert(mdq,pst);
   _  _  _  }
   _  _  _  else {
   _  _  _  _  strcpy(pple,++ptcom);  /* pple[] は過去分詞形 */
   _  _  _  _  if (strcmp(pstq,pple)) {
		   /* 過去分詞形が既に有る過去形と異なる場合のみ修正する。*/
   _  _  _  _  _  strcat(pple," (");
   _  _  _  _  _  ptinsert(mdq,pple);
   _  _  _  _  }
   _  _  _  _  else
   _  _  _  _     *mdq = '\0';
   _  _  _  }
   _  _  _  irg = 1;
   _  _  _  if (*mdq) {
   _  _  _  _  if (pt1) {
   _  _  _  _  _  if (v_pos >= 1)
   _  _  _  _  _     ptreplace(ptsp + 1,lnq,mdq);
   _  _  _  _  _  else {
   _  _  _  _  _  _  if ( (*(md + lnq) == ' ') || (*(md + lnq) == '\0') )
   _  _  _  _  _        ptreplace(md,lnq,mdq);
   _  _  _  _  _  _  else {             /* lnq の値が予想に反している場合。2002.11.03. */
   _  _  _  _  _  _  _  pt_space = strchr(md + lnq + 1,' ');
   _  _  _  _  _  _  _  if (pt_space) {
   _  _  _  _  _  _  _  _  ptptcut(md,pt_space - 1);
   _  _  _  _  _  _  _  _  ptinsert(md,mdq);
   _  _  _  _  _  _  _  }
   _  _  _  _  _  _  _  else {
   _  _  _  _  _  _  _  _  ptpar = strchr(md + 5,')');
   _  _  _  _  _  _  _  _  if ( ptpar && (! *(ptpar + 1)) )
   _  _  _  _  _  _  _  _     strcpy(md,mdq);
   _  _  _  _  _  _  _  _  else {
   _  _  _  _  _  _  _  _  _  printf("\n 活用エラー！  md[] = %s, lnq = %d, md + lnq = %s \n",md,lnq,md + lnq);
   _  _  _  _  _  _  _  _  _  exit(1);
   _  _  _  _  _  _  _  _  }
   _  _  _  _  _  _  _  }
   _  _  _  _  _  _  }
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  pt1 = strchr(md,' ');
   _  _  _  _  _  if (pt1)
   _  _  _  _  _     strcat(mdq,pt1);
   _  _  _  _  _  strcpy(md,mdq);
   _  _  _  _  }
   _  _  _  }
   _  _  _  break;
   _  _  }
   _  _  else {
   _  _  _  beeping(15);
   _  _  _  color_yellow;
   _  _  _  printf("\n 不規則動詞表のデータに不備が有ります。\n");
   _  _  _  printf("      %s \n\n",irdata);
   _  _  _  color_white;
   _  _  _  exit(1);
   _  _  }
   _  }
   }
   ptpar = strstr(md,") (");
   if (ptpar) {
   _  ptpar2 = strchr(ptpar + 3,')');
   _  if (ptpar2) {
   _  _  if (*(ptpar2 + 1))
   _  _     ptptcut(ptpar + 1,ptpar2);
   _  _  else
   _  _     *(ptpar + 1) = '\0';
   _  }
   _  else {
   _  _  beeping(10);
   _  _  printf("\n\n 閉じ括弧が抜けています。 md = %s \n",md);
   _  _  exit(1);
   _  }
   }
   fclose(irreg);
   return(irg);
end


static int  past_be(char md[], char mdq[], char *pt1, char *ptsp, int v_pos, int lnq)
			/* be動詞現在形(am,is,are)を過去形にする。*/
begin
   int  irg = 0;

   if (strstr("am,is(x)",mdq)) {
   _  irg = 1;
   _  strcpy(mdq,"was");
   }
   else {
   _  if (strcmp(mdq,"are") == 0) {
   _  _  irg = 1;
   _  _  strcpy(mdq,"were");
   _  }
   }
   if (irg) {
   _  if (pt1) {
   _  _  if (v_pos)
   _  _     ptreplace(ptsp + 1,lnq,mdq);
   _  _  else
   _  _     ptreplace(md,lnq,mdq);
   _  }
   _  else
   _     strcpy(md,mdq);
   }
   return(irg);
end


void nega(char md[])   /* 否定形を作る */
begin   /* global variable:  */
   char *ptv;

   if (strcmp(md,"3be") == 0)
      strcat(md," not");
   else {
   _  if (md == strstr(md,"3be "))
   _     ptinsert(md + 4,"not ");
   _  else {
   _  _  ptv = strstr(md," be ");
   _  _  if (ptv)
   _  _     ptinsert(ptv + 4,"not ");
   _  _  else {
   _  _  _  ptv = strstr(md,"(be) ");
   _  _  _  if (ptv)
   _  _  _     ptinsert(ptv + 5,"not ");
   _  _  _  else {
   _  _  _  _  ptv = strstr(md,"were (be)");
   _  _  _  _  if ( ptv && (*(ptv + 9) == '\0') )
   _  _  _  _     strcpy(ptv + 9," not");
   _   _  _ }
   _  _  }
   _  }
   }
end

void sinko(char md[])  /* 動詞の進行形を作る。*/
begin
   int  lnq, sumi = 0;
   char mdq[WordLen], ings[SentLen], verb_tailq[4];

   wdcpy(mdq,md + 1);
   sprintf(ings,"ing(%s)",mdq);
   *verb_tailq = '\0';
   if (strcmp(mdq,"be") == 0) {
   _  ptinsert(md + 3,"ing (be)");
   _  sumi = 1;
   }
   else {
   _  if (strcmp(mdq,"lie") == 0) {
   _  _  strcpy(md + 1,"lying(lie)");
   _  _  sumi = 1;
   _  }
   _  else {
   _  _  if (strcmp(mdq,"die") == 0) {
   _  _  _  strcpy(md + 1,"dying(die)");
   _  _  _  sumi = 1;
   _  _  }
   _  }
   }
   if (! sumi) {
   _  lnq = strlen(mdq);
   _  if (lnq > 2)
   _     wdcpy(verb_tailq,mdq + lnq - 3);
   _  if ( (strcmp(verb_tailq,"run") == 0) || (strcmp(verb_tailq,"win") == 0) ) {
   _  _  ptinsert(md + 1 + lnq,"n");   /* run => running, win => winning */
   _  _  ++lnq;                        /* 2004.02.14 */
   _  }
   _  else {
   _  _  wdcpy(verb_tailq,mdq + lnq - 2);
   _  _  if (strcmp(verb_tailq,"im") == 0) {
   _  _  _  ptinsert(md + 1 + lnq,"m");   /* swim => swimming */
   _  _  _  ++lnq;
   _  _  }
   _  _  else {
   _  _  _  if ((lnq <= 4) && ((strcmp(verb_tailq,"it") == 0) || (strcmp(verb_tailq,"et") == 0)) && (! isVowel(*(mdq + lnq - 3)))) {
   _  _  _  _  ptinsert(md + 1 + lnq,"t");    /* hit => hitting,  get => getting */
   _  _  _  _  ++lnq;
   _  _  _  }
   _  _  _  else {
   _  _  _  _  if ( *verb_tailq && (strcmp(verb_tailq,"ut") == 0) && (! isVowel(*(verb_tailq - 1))) ) {
   _  _  _  _  _  ptinsert(md + 1 + lnq,"t");    /* cut => cutting,  put => putting */
   _  _  _  _  _  ++lnq;
   _  _  _  _  }
   _  _  _  _  else {
   _  _  _  _  _  if ((*(verb_tailq + 1) == 'e') && (! isVowel(*(verb_tailq)))) {
   _  _  _  _  _  _   ptcut(md + 1 + lnq - 1,1);  /* take => taking */
   _  _  _  _  _  _   --lnq;
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  }
   _  _  }
   _  }
   _  ptinsert(md + 1 + lnq,ings);
   _  sumi = 1;
   }
end

void mokuteki_kaku(char daimeishi[]) /* 代名詞を目的格に変化させる。*/
begin
   register int  i;
   static char const shukaku[6][5] = {"I","we","you","he","she","they"};
   static char const shoyuukaku[6][6] = {"my","our","your","his","her","their"};
   static char const mokt_kaku[6][5] = {"me","us","you","him","her","them"};
   
   for (i = 0; i <= 5; i++) {
   _  if (strcmp(daimeishi,shukaku[i]) == 0) {
   _  _  strcpy(daimeishi,mokt_kaku[i]);
   _  _  break;
   _  }
   _  else {
   _  _  if (strcmp(daimeishi,shoyuukaku[i]) == 0) {
   _  _  _  strcpy(daimeishi,mokt_kaku[i]);
   _  _  _  break;
   _  _  }
   _  }
   }
end

void hikaku(char adj[]) /* 形容詞や副詞を比較級にする。*/
begin
   unsigned int  ln;
   
   ln = strlen(adj);
   if (ln >= 7)
      ptinsert(adj,"more ");
   else {
   _  if ((strcmp(adj,"good") == 0) || (strcmp(adj,"well") == 0))
   _     strcpy(adj,"better");  /* 2000.11.24 && 12.09 補強した。*/
   _  else {
   _  _  if (strcmp(adj,"bad") == 0)  /* 2000.12.10 追加した。*/
   _  _     strcpy(adj,"worse");
   _  _  else {
   _  _  _  if (strcmp(adj,"big") == 0)
   _  _  _     strcat(adj,"ger");
   _  _  _  else {
   _  _  _  _  if (*(adj + ln - 1) == 'e')
   _  _  _  _     strcat(adj,"r");
   _  _  _  _  else {
   _  _  _  _  _  if (*(adj + ln - 1) == 'y')
   _  _  _  _  _     strcpy(adj + ln - 1,"ier");
   _  _  _  _  _  else
   _  _  _  _  _     strcat(adj,"er");
   _  _  _  _  }
   _  _  _  }
   _  _  }
   _  }
   }
end


void most(char adj[]) /* 形容詞や副詞を最上級にする。*/
begin                   /* 2000.11.23 */
   unsigned int  ln;
   
   ln = strlen(adj);
   if (ln >= 7)
      ptinsert(adj,"most ");
   else {
   _  if ( (ln == 6) && (strcmp(adj + 3,"ern") == 0) )
   _     ptinsert(adj,"most "); /* modern の case に対応した。2004.07.04 */
   _  else {
   _  _  if ((strcmp(adj,"good") == 0) || (strcmp(adj,"well") == 0))
   _  _     strcpy(adj,"best");
   _  _  else {
   _  _  _  if (strcmp(adj,"bad") == 0)  /* 2000.12.10 追加した。*/
   _  _  _     strcpy(adj,"worst");
   _  _  _  else {
   _  _  _  _  if (strcmp(adj,"big") == 0)
   _  _  _  _     strcat(adj,"gest");
   _  _  _  _  else {
   _  _  _  _  _  if (*(adj + ln - 1) == 'e')
   _  _  _  _  _     strcat(adj,"st");
   _  _  _  _  _  else {
   _  _  _  _  _  _  if (*(adj + ln - 1) == 'y')
   _  _  _  _  _  _     strcpy(adj + ln - 1,"iest");
   _  _  _  _  _  _  else
   _  _  _  _  _  _     strcat(adj,"est");
   _  _  _  _  _  }
   _  _  _  _  }
   _  _  _  }
   _  _  }
   _  }
   }
end
