[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 メーリングリストの案内