[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:00379] Re: 日本語文字コード(UTF8) 環境での動作について



 しらいです。

In Message-Id <20050414142634.25680806.26933@nifty.ne.jp>
        =?ISO-2022-JP?B?GyRCSXBEZyEhMGw7MBsoQg==?= <HCD02054@nifty.ne.jp>さんwrites:
> >実用上支障があるというのは判るんですが、そもそも設定と実態が異なるような状況
> >を生み出したのはユーザ自身なので、ある程度の支障は容認して貰えないでしょうか
> >ね。
> 
>  あ、いや、それは勿論その通りで。
>  と言うか、この時点まででも adhoc な対応と仰られながらも、 patch を作成した頂
> いたり、色々とお手を煩わせることになってしまって、申し訳なく思っております。

 まぁこちらも本気でこれは無理だと思ったら対処しないので、何
らかの対処法が見えそうだからこそ色々試行錯誤してみている訳で。
この件も一応 patch 作り直してみたので試してみて下さい。

 結論から言うと、一旦 UTF-8 だと思い込んで処理してしまった
filename を元に戻すのは無理でした。UTF-8 が間違いなのだとし
たら、一体何が正しいのか判断する術がないからです。
 なので、明示的に FNAMEKCODE を改めて設定し直すという処理を
ユーザがしてくれるなら対処可能です。.fd2rc で UTF-8 を指定し
てあっても、command line option で EUC-JP に上書き指定してや
れば起動可能になります。

 ただ、この patch の弊害として稼働中に FNAMEKCODE を変更す
ると起動時と同じようなことが起こり得るという症状が起きるでし
ょう。
 FNAMEKCODE=UTF-8 の設定で UTF-8 な directory にいる時に、
カスタマイザ等で FNAMEKCODE=EUC-JP に設定してしまうと、同様
に current directory が不正な文字扱いとなって異常終了します。
 んー悩ましいところですね。


>  ただ、そういった、謂わば「ユーザーの我儘」をどう処理するか?ってことに関して
> は、一重に作者さんの「ポリシー」に依るものだと思います。

 んー、policy とゆーか単に食指が動くかどうかだけのような気
もしますけどね。
 どんなに切望されても、手間がかかるばかりで全然やりがいのな
いニーズだったりしたら手は出さないと思います。その辺りが pro-
prietary との違いかな。


> >> 3.ディレクトリ移動3(内蔵シェル使用)
> >>  EXECUTE_SH にて、内蔵シェルを起動し、以下のコマンドを実行
> >> 
> >>  $ cd <日本語ディレクトリ名> 
> >>
> >上と合わせてこの件も見直しておきます。詳細は後日ということで。
> 
>  宜しくお願い致します。

 こっちの件は cd が builtin だからいけない訳ですね。外部コ
マンドと違って builtin は中で漢字コード変換しますから、既に
変換済の引数を渡すとこうなってしまう訳です。
 なので、filename を引数に取る builtin に関しては、既定漢字
コードが定められていた際には builtin に渡す前に内部コードに
逆変換しておく必要があります。
 まぁそういう枠組は、既定漢字コード機能を実装するまでには用
意しておきましょうか。


 では patch。4/6 patch は忘れて 2.06c に直接適用して下さい。

-------- Cut Here --------
diff -u ../old/FD-2.06c/custom.c ./custom.c
--- ../old/FD-2.06c/custom.c	Wed Feb 23 00:00:00 2005
+++ ./custom.c	Thu Apr 14 15:50:07 2005
@@ -88,6 +88,12 @@
 #ifndef	_NOORIGSHELL
 extern int dumbshell;
 #endif
+extern char fullpath[];
+extern char *origpath;
+extern char *progpath;
+#if	!defined (_NOKANJICONV) || !defined (_NODOSDRIVE)
+extern char *unitblpath;
+#endif
 #ifndef	_NOCUSTOMIZE
 extern int curcolumns;
 extern int subwindow;
@@ -186,10 +192,26 @@
 #define	T_KNAM		16
 #define	T_OCTAL		17
 
+#ifndef	_NOKANJICONV
+typedef struct _pathtable {
+	VOID_P path;
+	char buf[MAXPATHLEN];
+	int lang;
+	int flags;
+} pathtable;
+
+#define	P_ISARRAY	0001
+#define	P_STABLE	0002
+#endif	/* !_NOKANJICONV */
+
 #if	FD >= 2
 static int NEAR atooctal __P_((char *));
 #endif
 static VOID NEAR _evalenv __P_((int));
+#ifndef	_NOKANJICONV
+static char *NEAR pathlang __P_((pathtable *, int));
+static VOID NEAR pathconv __P_((pathtable *));
+#endif
 #ifndef	_NOCUSTOMIZE
 static int NEAR custputs __P_((char *));
 static char *NEAR strcatalloc __P_((char *, char *));
@@ -389,6 +411,18 @@
 };
 #define	ENVLISTSIZ	((int)(sizeof(envlist) / sizeof(envtable)))
 
+#ifndef	_NOKANJICONV
+static pathtable pathlist[] = {
+	{fullpath, "", NOCNV, P_ISARRAY},
+	{&origpath, "", NOCNV, P_STABLE},
+	{&progpath, "", NOCNV, P_STABLE},
+# if	!defined (_NOKANJICONV) || !defined (_NODOSDRIVE)
+	{&unitblpath, "", NOCNV, P_STABLE},
+# endif
+};
+#define	PATHLISTSIZ	((int)(sizeof(pathlist) / sizeof(pathtable)))
+#endif	/* !_NOKANJICONV */
+
 #ifndef	_NOCUSTOMIZE
 # ifdef	_USEDOSEMU
 static CONST devinfo mediadescr[] = {
@@ -561,12 +595,96 @@
 	}
 }
 
+#ifndef	_NOKANJICONV
+static char *NEAR pathlang(pp, stable)
+pathtable *pp;
+int stable;
+{
+	char *path;
+
+	if (pp -> flags & P_ISARRAY) path = (char *)(pp -> path);
+	else path = *((char **)(pp -> path));
+	if (!path) return(NULL);
+
+	if (!stable) /*EMPTY*/;
+	else if (pp -> lang == NOCNV) stable = 0;
+	else if (!(pp -> flags & P_STABLE) && strcmp(path, pp -> buf))
+		stable = 0;
+
+	if (!stable && (pp -> lang = getkcode(path)) == NOCNV)
+		pp -> lang = DEFCODE;
+
+	return(path);
+}
+
+static VOID NEAR pathconv(pp)
+pathtable *pp;
+{
+	char *path, buf[MAXPATHLEN];
+	int lang;
+
+	lang = pp -> lang;
+	if (!(path = pathlang(pp, 0))) return;
+	if (lang != pp -> lang) {
+		kanjiconv(buf, path, MAXPATHLEN - 1, DEFCODE, lang, L_FNAME);
+		if (pp -> flags & P_ISARRAY)
+			kanjiconv(path, buf,
+				MAXPATHLEN - 1, pp -> lang, DEFCODE, L_FNAME);
+		else {
+			path = newkanjiconv(buf, pp -> lang, DEFCODE, L_FNAME);
+			if (path == buf) path = strdup2(buf);
+			free(*((char **)(pp -> path)));
+			*((char **)(pp -> path)) = path;
+		}
+		if (kanjierrno) pp -> lang = DEFCODE;
+	}
+	strcpy(pp -> buf, path);
+}
+#endif	/* !_NOKANJICONV */
+
 VOID evalenv(VOID_A)
 {
+#if	!defined (_NOKANJICONV) && !defined (_NOSPLITWIN)
+# ifndef	_NOARCHIVE
+	pathtable archlist[MAXWINDOWS];
+# endif
+	pathtable fulllist[MAXWINDOWS];
+#endif	/* !_NOKANJICONV && !_NOSPLITWIN */
 	int i, duperrno;
 
 	duperrno = errno;
+
+#ifndef	_NOKANJICONV
+	for (i = 0; i < PATHLISTSIZ; i++) VOID_C pathlang(&(pathlist[i]), 1);
+
+# ifndef	_NOSPLITWIN
+	for (i = 0; i < MAXWINDOWS; i++) {
+#  ifndef	_NOARCHIVE
+		archlist[i].path = &(winvar[i].v_archivedir);
+		archlist[i].flags = 0;
+		VOID_C pathlang(&(archlist[i]), 1);
+#  endif
+		fulllist[i].path = &(winvar[i].v_fullpath);
+		fulllist[i].flags = 0;
+		VOID_C pathlang(&(fulllist[i]), 1);
+	}
+# endif	/* !_NOSPLITWIN */
+#endif	/* !_NOKANJICONV */
+
 	for (i = 0; i < ENVLISTSIZ; i++) _evalenv(i);
+
+#ifndef	_NOKANJICONV
+	for (i = 0; i < PATHLISTSIZ; i++) pathconv(&(pathlist[i]));
+# ifndef	_NOSPLITWIN
+	for (i = 0; i < MAXWINDOWS; i++) {
+#  ifndef	_NOARCHIVE
+		pathconv(&(archlist[i]));
+#  endif
+		pathconv(&(fulllist[i]));
+	}
+# endif	/* !_NOSPLITWIN */
+#endif	/* !_NOKANJICONV */
+
 	errno = duperrno;
 }
 
diff -u ../old/FD-2.06c/kanji.c ./kanji.c
--- ../old/FD-2.06c/kanji.c	Wed Feb 23 00:00:00 2005
+++ ./kanji.c	Thu Apr 14 14:43:38 2005
@@ -344,6 +344,22 @@
 	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,	/* 0x70 */
 	0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,    0
 };
+static u_char j2sjtable3[128] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 */
+	   0, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5,	/* 0x20 */
+	0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
+	0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5,	/* 0x30 */
+	0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd,
+	0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5,	/* 0x40 */
+	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
+	0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5,	/* 0x50 */
+	0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd,
+	0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5,	/* 0x60 */
+	0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed,
+	0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,	/* 0x70 */
+	0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,    0
+};
 #endif	/* !_NOKANJICONV || (FD && _USEDOSEMU && CODEEUC) */
 #ifndef	_NOKANJICONV
 static u_int nftblnum = 0;
@@ -585,7 +601,10 @@
 			if (w >= convtable[i].start
 			&& w < convtable[i].start + convtable[i].range)
 				break;
-		if (i >= CNVTBLSIZ) w = SJ_UDEF;
+		if (i >= CNVTBLSIZ) {
+			w = SJ_UDEF;
+			kanjierrno = SJIS;
+		}
 		else {
 			w -= convtable[i].start;
 			w += convtable[i].cnv;
@@ -595,7 +614,10 @@
 	}
 	j1 = sj2jtable1[s1];
 	j2 = sj2jtable2[s2];
-	if (s2 >= 0x9f) j1++;
+	if (!j1 || !j2) {
+		kanjierrno = SJIS;
+	}
+	else if (s2 >= 0x9f) j1++;
 	buf[0] = j1;
 	buf[1] = j2;
 }
@@ -611,8 +633,12 @@
 	j2 = s[1] & 0x7f;
 
 	s1 = j2sjtable1[j1];
-	s2 = (j1 & 1) ? j2sjtable2[j2] : (j2 + 0x7e);
-	w = (((u_int)s1 << 8) | s2);
+	s2 = (j1 & 1) ? j2sjtable2[j2] : j2sjtable3[j2];
+	if (!s1 || !s2) {
+		w = SJ_UDEF;
+		kanjierrno = JIS7;
+	}
+	else w = (((u_int)s1 << 8) | s2);
 
 	for (i = 0; i < CNVTBLSIZ; i++)
 	if (w >= convtable[i].cnv
@@ -850,7 +876,10 @@
 			return(0xff00 | (wc - 0x8260 + 0x21));
 		if (wc >= 0x8281 && wc <= 0x829a)
 			return(0xff00 | (wc - 0x8281 + 0x41));
-		if (wc < MINKANJI || wc > MAXKANJI) return(r);
+		if (wc < MINKANJI || wc > MAXKANJI) {
+			kanjierrno = SJIS;
+			return(r);
+		}
 		wc = unifysjis(wc, 0);
 	}
 	else {
@@ -871,7 +900,10 @@
 			default:
 				break;
 		}
-		if (wc < MINUNICODE || wc > MAXUNICODE) return(r);
+		if (wc < MINUNICODE || wc > MAXUNICODE) {
+			kanjierrno = UTF8;
+			return(r);
+		}
 	}
 
 	if (unicodebuffer && !unitblbuf) readunitable(0);
@@ -945,9 +977,11 @@
 
 	if (encode) {
 		if (ofs < unitblent) r = getword(cp, 0);
+		else kanjierrno = SJIS;
 	}
 	else {
 		if (ofs > min && ofs < max) r = getword(cp, 2);
+		else kanjierrno = UTF8;
 	}
 
 	return(r);
@@ -1489,12 +1523,16 @@
 
 	w = s[(*ptrp)++];
 	if (w < 0x80);
-	else if ((w & 0xe0) == 0xc0 && (s[(*ptrp)++] & 0xc0) == 0x80)
+	else if ((w & 0xe0) == 0xc0 && (s[*ptrp] & 0xc0) == 0x80)
 		w = ((w & 0x1f) << 6) | (s[(*ptrp)++] & 0x3f);
-	else {
+	else if ((w & 0xf0) == 0xe0 && (s[*ptrp] & 0xc0) == 0x80
+	&& (s[*ptrp + 1] & 0xc0) == 0x80) {
 		w = ((w & 0x0f) << 6) | (s[(*ptrp)++] & 0x3f);
 		w = (w << 6) | (s[(*ptrp)++] & 0x3f);
 	}
+	else {
+		kanjierrno = UTF8;
+	}
 	return(w);
 }
 
@@ -1763,6 +1801,8 @@
 char *buf, *s;
 int max, in, out, *lenp, io;
 {
+	kanjierrno = 0;
+
 	if (in == out || in == NOCNV || out == NOCNV) return(s);
 	switch (out) {
 # ifdef	CODEEUC
@@ -1852,6 +1892,8 @@
 /*NOTREACHED*/
 			break;
 	}
+	if (io == L_FNAME && kanjierrno) return(s);
+
 	return(buf);
 }
 
diff -u ../old/FD-2.06c/kctype.h ./kctype.h
--- ../old/FD-2.06c/kctype.h	Wed Feb 23 00:00:00 2005
+++ ./kctype.h	Thu Apr 14 14:45:00 2005
@@ -259,6 +259,12 @@
 #define	_NOKANJIFCONV
 #endif
 
+#if	!defined (_NOKANJICONV) || (defined (FD) && !defined (_NODOSDRIVE))
+K_EXTERN int kanjierrno K_INIT(0);
+#endif
+#ifndef	_NOKANJIFCONV
+K_EXTERN int defaultkcode K_INIT(NOCNV);
+#endif
 #ifndef	_NOKANJICONV
 K_EXTERN int inputkcode K_INIT(NOCNV);
 #endif
-------- Cut Here --------

                                               しらい たかし