[FreeBSD-users-jp 96346] Re: FreeBSD-11.2 の ja_JP.eucJP 環境
Kouichi Hirabayashi
kh @ mogami.com
2018年 11月 7日 (水) 08:42:50 UTC
> NetBSD のように、sh のコマンドライン編集機能をデフォルトで off
> にするだけでもいいかなと思います。
これが最善ではないかと思います。
> 平林さんの /bin/sh の parser.h が問題だという話は全く無関係に
> 思いますし
これは、NO_HISTORY による回避法を見てわかりました。元の libedit
より先に sh のコードを直そうとすると、parser.h の CTLESC などで
問題が起きるのですが、先に libedit を直してみると、sh は元のまま
で済むようです。
例えば、/usr/src/lib/libedit を下記のように書き換えて、EUC-JP
の 2 バイト文字を連続して読み、文字幅の計算を正しい値にすれば、
/lib/libedit.so.7 を置き換えるだけで回避できるようです。
--- chartype.c.orig 2018-06-22 08:02:22.000000000 +0900
+++ chartype.c 2018-11-07 10:51:04.903723000 +0900
@@ -45,6 +45,8 @@
#define CT_BUFSIZ ((size_t)1024)
#ifdef WIDECHAR
+int ct_flags; // copy of el_flags
+
protected int
ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
{
@@ -182,6 +184,13 @@
protected size_t
ct_enc_width(Char c)
{
+ if (ct_flags & CHARSET_IS_eucJ) { // EUC-JP
+ if (c < 0x100)
+ return 1;
+ else if (c < 0x10000)
+ return 2;
+ }
+ else if (ct_flags & CHARSET_IS_UTF8) { // UTF-8
/* UTF-8 encoding specific values */
if (c < 0x80)
return 1;
@@ -191,8 +200,10 @@
return 3;
else if (c < 0x110000)
return 4;
- else
- return 0; /* not a valid codepoint */
+ }
+ else if (c < 0x100)
+ return 1;
+ return 0; /* not a valid codepoint */
}
protected ssize_t
--- el.c.orig 2018-06-22 08:02:22.000000000 +0900
+++ el.c 2018-11-07 10:51:04.911493000 +0900
@@ -74,6 +74,7 @@
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr)
{
+ extern int ct_flags; // chartype.c
EditLine *el = el_malloc(sizeof(*el));
if (el == NULL)
@@ -102,6 +103,9 @@
if (setlocale(LC_CTYPE, NULL) != NULL){
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
+ else if (strcmp(nl_langinfo(CODESET), "eucJP") == 0)
+ el->el_flags |= CHARSET_IS_eucJ;
+ ct_flags = el->el_flags;
}
if (terminal_init(el) == -1) {
--- el.h.orig 2018-06-22 08:02:22.000000000 +0900
+++ el.h 2018-11-07 10:51:04.916863000 +0900
@@ -57,6 +57,7 @@
#define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
#define CHARSET_IS_UTF8 0x10
+#define CHARSET_IS_eucJ 0x20
#define NARROW_HISTORY 0x40
typedef unsigned char el_action_t; /* Index to command array */
--- read.c.orig 2018-06-22 08:02:22.000000000 +0900
+++ read.c 2018-11-07 10:51:04.926098000 +0900
@@ -343,6 +343,40 @@
*cp = L'\0';
return 0;
}
+ if (el->el_flags & CHARSET_IS_eucJ) {
+ static int eucst = 0;
+ int c = cbuf[cbp] & 0xff;
+
+ ++cbp;
+ if (eucst == 0) { // first byte
+ if (c & 0x80) { // KANJI, KANA
+ if (((c < 0xa1) || (0xf4 < c)) && (c != 0x8e))
+ --cbp; // non JIS code
+ else
+ eucst = 1;
+ goto again;
+ }
+ else // ASCII
+ ct_mbrtowc(cp, cbuf, cbp);
+ }
+ else { // second byte
+ eucst = 0;
+ if (!(c & 0x80)) { // ASCII
+ // ignore first byte
+ cbuf[cbp - 2] = cbuf[cbp - 1];
+ --cbp;
+ ct_mbrtowc(cp, cbuf, cbp);
+ }
+ else if ((c < 0xa1) || (0xfe < c)) {
+ // ignore non JIS code
+ cbp = 0;
+ goto again;
+ }
+ else // KANJI second byte
+ ct_mbrtowc(cp, cbuf, cbp);
+ }
+ return 1;
+ }
for (;;) {
--
平林 浩一
freebsd-users-jp メーリングリストの案内