変更点は以下の5点です。 * 16行表示 LINES16を#defineしてコンパイルすると16行表示になります。 * ヘルプの運指表示修正 UNIX上で使う場合、cursesが日本語に対応していないと、 ヘルプの運指表示中に同じ数字が複数表示されることがあります。 1の上に2が上書きされる時などに、表示が変わらないことがあるようです。 パッチではrefresh()を追加しています。 * termios対応 最近のUNIXでもコンパイルできるように、 デフォルトでsgttyではなくtermiosを使うように変更しています。 * ひらがな辞書ファイル(sub.dic)不使用オプション(-ns)の追加 ひらがな辞書ファイル(sub.dic)を使用しないようにするオプション(-ns)を 追加しています。 * 例文練習時に長い文字列を入力するとバッファオーバフローする問題の修正 例文練習時に長い文字列を入力すると、バッファオーバフローが発生して 動作がおかしくなる問題を修正しています。 --- orig/tutr2.c 1997-11-25 08:20:00.000000000 +0900 +++ tutr2.c 2006-07-08 21:41:41.000000000 +0900 @@ -13,11 +13,15 @@ # include # include # include +# ifdef USE_OLD_TTY /* #ifdef BSD */ # include # ifdef LINUX # include -#endif +# endif +# else +# include +# endif #endif #ifndef TRUE @@ -59,8 +63,12 @@ unsigned char c; # define SEPARATOR '/' +#ifdef NEED_TIME_T_TYPEDEF typedef long time_t; #endif +#endif + +#define BUFSIZE BUFSIZ #define ORGFILE "org.dic" #define SUBFILE "sub.dic" @@ -80,30 +88,65 @@ typedef long time_t; #define Y_SUB 1 #define X_SUB 0 +#ifdef LINES16 +#define Y_LIST 2 +#else #define Y_LIST 3 +#endif #define X_LIST 0 +#ifdef LINES16 +#define Y_TEXT 4 +#else #define Y_TEXT 5 +#endif #define X_TEXT 0 +#ifdef LINES16 +#define Y_FRAME 6 +#else #define Y_FRAME 8 +#endif #define X_FRAME 4 +#ifdef LINES16 +#define Y_IN 12 +#else #define Y_IN 18 +#endif #define X_IN 0 +#ifdef LINES16 +#define Y_RAP1 13 +#else #define Y_RAP1 20 +#endif #define X_RAP1 0 +#ifdef LINES16 +#define Y_RAP2 14 +#else #define Y_RAP2 21 +#endif #define X_RAP2 0 +#ifdef LINES16 +#define Y_RAP3 15 +#else #define Y_RAP3 22 +#endif #define X_RAP3 0 #define Y_USED Y_RAP2 #define X_USED 45 +#ifdef LINES16 +#define Y_NU (Y_FRAME + 0) +#define Y_UP (Y_FRAME + 0) +#define Y_MD (Y_FRAME + 2) +#define Y_LW (Y_FRAME + 4) +#else #define Y_NU (Y_FRAME + 1) #define Y_UP (Y_FRAME + 3) #define Y_MD (Y_FRAME + 5) #define Y_LW (Y_FRAME + 7) +#endif #define X_L1 (X_FRAME -0 + 2) #define X_L2 (X_FRAME -0 + 7) @@ -121,9 +164,11 @@ typedef long time_t; char *frame[] = { +#ifndef LINES16 "--------------------- ------ ------ ---------------------", "| | | | | | | | | | | | | |", "===================== ====== ====== =====================", +#endif "| | | | | | | | | | | | | |", "--------------------- ------ ------ ---------------------", "| | | | | | | | | | | | | |", @@ -339,6 +384,7 @@ int option = 0; #define ONLYWORD 0x0080 #define ONLYRANDOM 0x0100 #define ALLSAMECOUNT 0x0200 +#define NOSUB 0x0400 unsigned char spc[] = " "; unsigned char first[] = "亜"; @@ -444,6 +490,7 @@ clrtoeol() unsigned char getch2() { +#ifdef USE_OLD_TTY struct sgttyb tty_mode, org_mode; unsigned char c; @@ -465,6 +512,30 @@ getch2() ioctl(0, TIOCSETP, (char *) &org_mode); return c; +#else + struct termios tty_mode, org_mode; + unsigned char c; + + if (tcgetattr(0, &tty_mode) < 0) { + return EOF; + } + + org_mode = tty_mode; + + tty_mode.c_lflag &= ~(ECHO | ICANON); + tty_mode.c_cc[VMIN] = 1; /* 1 byte at a time, no timer */ + tty_mode.c_cc[VTIME] = 0; + + if (tcsetattr(0, TCSAFLUSH, &tty_mode) < 0) { + return EOF; + } + + c = getchar(); + + tcsetattr(0, TCSAFLUSH, &org_mode); + + return c; +#endif } #endif @@ -573,6 +644,11 @@ int pos_f; } } } + /* 1の上に2が上書きされる場合等、 + cursesが片方のバイトしか更新しないので + 画面上で変わらないことがあるため、refresh()を入れる + */ + refresh(); } unsigned char @@ -1048,17 +1124,17 @@ end_help: } unsigned char /* CR or ESC or in terminate */ -read_console(buf, terminate, tbuf, help_buf, guide_func, echo) +read_console(buf, bufsize, terminate, tbuf, help_buf, guide_func, echo) unsigned char *buf, *terminate, *help_buf; long *tbuf; void (*guide_func)(); -int echo; +int echo, bufsize; { long t; unsigned char c, *p, *org_buf = buf; int count; static - int kflag[100]; + int kflag[BUFSIZE]; move(Y_IN, X_IN); refresh(); @@ -1180,6 +1256,9 @@ goin_help: continue; } + if (buf - org_buf + 1 >= bufsize) { + continue; + } if (echo || !(option & NOECHO)) { addch(c); } @@ -1356,7 +1435,7 @@ get_new_console() move(Y_SUB, X_SUB); addstr("  例文練習:改行のみ入力   終了:ESC"); - while (read_console(buffer, "", NULL, NULL, NULL, TRUE) != ESC) { + while (read_console(buffer, sizeof(buffer), "", NULL, NULL, NULL, TRUE) != ESC) { if (!strlen(buffer)) { ret = CR; goto exit_1; @@ -1666,7 +1745,7 @@ check(buf1, buf2) unsigned char *buf1, *buf2; { static - unsigned char buf12[80], buf22[80], guide[80]; + unsigned char buf12[BUFSIZE], buf22[BUFSIZE], guide[BUFSIZE]; unsigned char c, *p, *p1, *p2, *perr = NULL, *bp1, *bp2; int diff; @@ -2154,7 +2233,7 @@ char buf[20]; } lineno_pos = 0; -move(3, 0); +move(Y_LIST, 0); addstr("Setting lineno. "); sprintf(buf, "average_offset = %d ", average_offset); addstr(buf); @@ -2325,7 +2404,7 @@ void (*guide_func)(); int echo; { static - unsigned char buffer[80], buffer2[80]; + unsigned char buffer[BUFSIZE], buffer2[BUFSIZE]; long i; int j, k, size, prev_no; KANA_T far *prev_p; @@ -2334,12 +2413,13 @@ int echo; buffer[0] = buffer2[0] = '\0'; size = new_count - start_pos; + /*refresh();*/ disp_raps(buffer, buffer2, i = 0, flag); j = 0; for ( ; ; ) { -move(3, 0); clrtoeol(); -move(4, 0); clrtoeol(); +move(Y_LIST, 0); clrtoeol(); +move(Y_LIST+1, 0); clrtoeol(); get_ave(); @@ -2375,7 +2455,7 @@ move(4, 0); clrtoeol(); } else { i = 0; for ( ; ; ) { - if (i || (random() % 3)) { + if ((option & NOSUB) || i || (random() % 3)) { if (size > LINE_SIZE) { check_next_char(start_pos, size, flag); } @@ -2403,7 +2483,7 @@ move(4, 0); clrtoeol(); help_pos = 0; for ( ; ; ) { - if ((c = read_console(buffer2, terminate, &i, buffer, guide_func, echo)) != CR) { + if ((c = read_console(buffer2, sizeof(buffer2), terminate, &i, buffer, guide_func, echo)) != CR) { ret = c; goto exit_1; } @@ -2823,6 +2903,10 @@ unsigned char *argv[]; option |= NOECHO; (*argc)--; (*argp)++; + } else if (!strcmp(argv[*argp], "-ns")) { + option |= NOSUB; + (*argc)--; + (*argp)++; } else if (!strcmp(argv[*argp], "-ow")) { option |= ONLYWORD; (*argc)--;