NTEmacs23.2 Shift_JISパッチ
GNU Emacs 23.2.1 (i386-mingw-nt6.0.6002)
テキストファイルをアップロードできないので直接貼りつけ。
いわゆるShift_JISで0x5cで終わっている文字列(「XXX表」とか)がファイル名/
フォルダ名になっているとdiredで見れない問題とか、
コマンドラインをjapanese-shift-jisで吐いてるはずなのになぜかへんな
エスケープが入ってファイルが見つからないとかいわれる、
とかといった現象が解消します。
(今さらかよ、という気もしますが。emacsだっせーとかいわないように。)
テストも何もしてないので申し訳ないんですが適用は自己責任でお願いします。
(自分もビクビクしながら使ってます。)
あときれいなパッチでもないのでそのへんも許してください。
ベースは
http://sourceforge.jp/projects/gnupack/
のソース(オリジナル
+Emacs-23.1.92-IME+a.patch+Emacs-23.1.92-IME_ReConversion.patch)
です。
パッチ内の「^L」は実際はコントロールコードが入ってます。
適当に編集してください。
まず本体(src)のほう。
diff -ur emacs-23.2.orig/src/buffer.c emacs-23.2/src/buffer.c --- emacs-23.2.orig/src/buffer.c 2010-04-04 07:26:12.000000000 +0900 +++ emacs-23.2/src/buffer.c 2010-10-16 22:19:43.065400000 +0900 @@ -189,6 +189,19 @@ error ("No buffer named %s", SDATA (spec)); error ("Invalid buffer argument"); } + +/* patch20101016 */ +#ifdef WINDOWSNT +#include <mbstring.h> +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + ^L DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0, doc: /* Return non-nil if OBJECT is a buffer which has not been killed. @@ -5379,7 +5392,10 @@ /* Maybe this should really use some standard subroutine whose definition is filename syntax dependent. */ len = strlen (pwd); +/* patch20101016 if (!(IS_DIRECTORY_SEP (pwd[len - 1]))) +*/ + if (!(IS_DIRECTORY_SEP (LAST_CHAR(pwd, len)))) { /* Grow buffer to add directory separator and ''. */ pwd = (char *) realloc (pwd, len + 2); diff -ur emacs-23.2.orig/src/w32.c emacs-23.2/src/w32.c --- emacs-23.2.orig/src/w32.c 2010-10-14 01:36:32.399000000 +0900 +++ emacs-23.2/src/w32.c 2010-10-16 22:26:30.218800000 +0900 @@ -159,6 +159,18 @@ extern int w32_num_mouse_buttons; +/* patch20101016 */ +#ifdef WINDOWSNT +#include <mbstring.h> +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + ^L /* Initialization states. @@ -304,8 +316,6 @@ LPFILETIME lpKernelTime, LPFILETIME lpUserTime); - - /* ** A utility function ** */ static BOOL is_windows_9x () @@ -1352,7 +1362,10 @@ { if (IS_DIRECTORY_SEP (*name) && --slashes == 0) break; +/* patch20101016 name++; +*/ + name = STRINC(name); } while ( *name ); if (IS_DIRECTORY_SEP (name[0])) @@ -2175,7 +2188,13 @@ { if (IS_DIRECTORY_SEP (*name) && --slashes == 0) break; +/* patch20101016 *str++ = *name++; +*/ + { + const char *namex = STRINC(name); + while (namex != name) *str++ = *name++; + } } while ( *name ); @@ -2411,8 +2430,12 @@ strcpy (filename, dir_pathname); ln = strlen (filename) - 1; +/* patch20101016 if (!IS_DIRECTORY_SEP (filename[ln])) strcat (filename, "\\"); +*/ + if (!IS_DIRECTORY_SEP (LAST_CHAR(filename, ln + 1))) + strcat (filename, "\\"); strcat (filename, "*"); dir_find_handle = FindFirstFile (filename, &dir_find_data); @@ -2517,7 +2540,10 @@ /* WNetEnumResource returns \\resource\share...skip forward to "share". */ ptr = ((LPNETRESOURCE) buffer)->lpRemoteName; ptr += 2; +/* patch20101016 while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++; +*/ + while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr = STRINC(ptr); ptr++; strncpy (readbuf, ptr, size); @@ -2578,6 +2604,7 @@ n_slashes = 2; strncpy (share, path, MAX_PATH); /* Truncate to just server and share name. */ +/* patch20101016 for (i = 2; i < MAX_PATH; i++) { if (IS_DIRECTORY_SEP (share[i]) && ++n_slashes > 3) @@ -2586,6 +2613,15 @@ break; } } +*/ + for (i = 2; i < MAX_PATH; i += (char*)STRINC(share + i) - (share + i)) + { + if (IS_DIRECTORY_SEP (share[i]) && ++n_slashes > 3) + { + share[i] = ''; + break; + } + } resource.dwType = RESOURCETYPE_DISK; resource.lpLocalName = NULL; @@ -3191,9 +3227,17 @@ const char *s; char *p; +/* patch20101016 for (s = fname + 2, p = machine; *s && !IS_DIRECTORY_SEP (*s); s++, p++) *p = *s; +*/ + for (s = fname + 2, p = machine; + *s && !IS_DIRECTORY_SEP (*s);) + { + const char *sx = STRINC(s); + while (sx != s) *p = *s; + } *p = ''; mp = machine; } @@ -3334,7 +3378,11 @@ } else if (rootdir) { +/* patch20101016 if (!IS_DIRECTORY_SEP (name[len-1])) +*/ + strcat (name, "\\"); + if (!IS_DIRECTORY_SEP (LAST_CHAR(name, len))) strcat (name, "\\"); if (GetDriveType (name) < 2) { @@ -3350,15 +3398,23 @@ } else { +/* patch20101016 if (IS_DIRECTORY_SEP (name[len-1])) name[len - 1] = 0; +*/ + if (IS_DIRECTORY_SEP (LAST_CHAR(name, len))) + name[len - 1] = 0; /* (This is hacky, but helps when doing file completions on network drives.) Optimize by using information available from active readdir if possible. */ len = strlen (dir_pathname); +/* patch20101016 if (IS_DIRECTORY_SEP (dir_pathname[len-1])) len--; +*/ + if (IS_DIRECTORY_SEP (LAST_CHAR(dir_pathname, len))) + len--; if (dir_find_handle != INVALID_HANDLE_VALUE && strnicmp (name, dir_pathname, len) == 0 && IS_DIRECTORY_SEP (name[len]) diff -ur emacs-23.2.orig/src/w32proc.c emacs-23.2/src/w32proc.c --- emacs-23.2.orig/src/w32proc.c 2010-04-04 07:26:11.000000000 +0900 +++ emacs-23.2/src/w32proc.c 2010-10-17 04:46:29.630600000 +0900 @@ -71,6 +71,19 @@ + ((DWORD)(var) - (section)->VirtualAddress) \ + (filedata).file_base)) + +/* patch20101016 */ +#ifdef WINDOWSNT +#include <mbstring.h> +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + /* Control whether spawnve quotes arguments as necessary to ensure correct parsing by child process. Because not all uses of spawnve are careful about constructing argv arrays, we make this behavior @@ -906,7 +919,10 @@ if (*p == 0) need_quotes = 1; +/* patch20101016 for ( ; *p; p++) +*/ + for ( ; *p; p = STRINC(p)) { if (escape_char == '"' && *p == '\\') /* If it's a Cygwin app, \ needs to be escaped. */ @@ -958,7 +974,10 @@ if (do_quoting) { +/* patch20101016 for ( ; *p; p++) +*/ + for ( ; *p; p = STRINC(p)) if ((strchr (sepchars, *p) != NULL) || *p == '"') need_quotes = 1; } @@ -986,7 +1005,10 @@ *parg++ = *p++; } #else +/* patch20101016 for ( ; *p; p++) +*/ + for ( ; *p; ) { if (*p == '"') { @@ -1001,12 +1023,20 @@ } else if (escape_char == '"' && *p == '\\') *parg++ = '\\'; +/* patch20101016 *parg++ = *p; +*/ if (*p == escape_char && escape_char != '"') escape_char_run++; else escape_char_run = 0; +/* patch20101016 */ + { + char *px = STRINC(p); + while (px != p) *parg++ = *p++; + } +/* patch20101016 */ } /* double escape chars before enclosing quote */ while (escape_char_run > 0)
付属ツール(lib-src)のほう。
こっちは使ってないのでさらに人柱の覚悟が必要です。
diff -ur emacs-23.2.orig/lib-src/emacsclient.c emacs-23.2/lib-src/emacsclient.c --- emacs-23.2.orig/lib-src/emacsclient.c 2010-04-04 07:26:07.000000000 +0900 +++ emacs-23.2/lib-src/emacsclient.c 2010-10-16 22:57:30.106400000 +0900 @@ -228,6 +228,17 @@ #endif +/* patch20101016 */ +#ifdef WINDOWSNT +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + /* Return the current working directory. Returns NULL on errors. Any other returned value must be freed with free. This is used only when get_current_dir_name is not defined on the system. */ diff -ur emacs-23.2.orig/lib-src/make-docfile.c emacs-23.2/lib-src/make-docfile.c --- emacs-23.2.orig/lib-src/make-docfile.c 2010-04-04 07:26:08.000000000 +0900 +++ emacs-23.2/lib-src/make-docfile.c 2010-10-16 22:58:56.724000000 +0900 @@ -87,6 +87,17 @@ /* Name this program was invoked with. */ char *progname; +/* patch20101016 */ +#ifdef WINDOWSNT +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + /* Print error message. `s1' is printf control string, `s2' is arg for it. */ /* VARARGS1 */ @@ -192,10 +203,17 @@ { char *tmp; +/* patch20101016 for (tmp = filename; *tmp; tmp++) { if (IS_DIRECTORY_SEP(*tmp)) filename = tmp + 1; + } +*/ + for (tmp = filename; *tmp; tmp = STRINC(tmp)) + { + if (IS_DIRECTORY_SEP(*tmp)) + filename = tmp + 1; } putc (037, outfile); diff -ur emacs-23.2.orig/lib-src/movemail.c emacs-23.2/lib-src/movemail.c --- emacs-23.2.orig/lib-src/movemail.c 2010-04-04 07:26:13.000000000 +0900 +++ emacs-23.2/lib-src/movemail.c 2010-10-16 23:00:12.774000000 +0900 @@ -166,6 +166,17 @@ /* Nonzero means this is name of a lock file to delete on fatal error. */ char *delete_lockname; +/* patch20101016 */ +#ifdef WINDOWSNT +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + int main (argc, argv) int argc; @@ -301,8 +312,12 @@ tempname = (char *) xmalloc (strlen (inname) + strlen ("EXXXXXX") + 1); strcpy (tempname, inname); p = tempname + strlen (tempname); +/* patch20101016 while (p != tempname && !IS_DIRECTORY_SEP (p[-1])) p--; +*/ + while (p != tempname && !IS_DIRECTORY_SEP (*STRDEC(tempname, p))) + p = STRDEC(tempname, p); *p = 0; strcpy (p, "EXXXXXX"); mktemp (tempname); diff -ur emacs-23.2.orig/lib-src/ntlib.c emacs-23.2/lib-src/ntlib.c --- emacs-23.2.orig/lib-src/ntlib.c 2010-04-04 07:26:05.000000000 +0900 +++ emacs-23.2/lib-src/ntlib.c 2010-10-16 23:03:26.840000000 +0900 @@ -32,6 +32,18 @@ #include "ntlib.h" +/* patch20101016 */ +#ifdef WINDOWSNT +#include <mbstring.h> +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *_mbsdec((buf), (buf) + (len))) +#define STRINC(p) _mbsinc(p) +#define STRDEC(start, p) _mbsdec(start, p) +#else +#define LAST_CHAR(buf,len) ((len) < 1 ? '' : *((buf) + (len) - 1)) +#define STRINC(p) p + 1 +#define STRDEC(start, p) p - 1 +#endif + #define MAXPATHLEN _MAX_PATH /* Emulate sleep...we could have done this with a define, but that @@ -327,8 +339,12 @@ } else { +/* patch20101016 if (IS_DIRECTORY_SEP (name[len-1])) name[len - 1] = 0; +*/ + if (IS_DIRECTORY_SEP (LAST_CHAR(name, len))) + name[len - 1] = 0; fh = FindFirstFile (name, &wfd); if (fh == INVALID_HANDLE_VALUE)
cvsのSJISパッチを思い出す強引さ。
本当はutf-8パッチを作りたいんですが、仕様的に悩んでます。
WindowsのCreateProcessAが妙なことをするから実質japanese-shift-jisか
utf-16しか受け付けられないし。
coding-system-for-writeがコマンドラインのエンコーディングに使われるのが
Windows上ではちょっと困る感じ。
windows-argument-coding-systemとか別につくったほうがきれいにいくのかも。
7件のコメント
コメントは受け付けていません。
はじめまして。自分もこの問題に悩んでいたところ、こちらのサイトを見つけました。
大変貴重な情報ありがとうございます。
ところでこのバグレポートあるいはパッチは、本家GNU Emacsにご報告されているのでしょうか??
(非常に重要な内容だと思いましたので。。。)
すみません。気後れしていて現状は特にどこかに報告などはしていません。
こんなんじゃいけないとは思ってるんですが…
w32proc.c、力不足で修正入れてもらえませんでした。
お久しぶりです。でも最新のEmacsではこの問題はもう発生しないですよね。別のアプローチで解決されたんですかね。
+ while (sx != s) *p = *s;
は
+ while (sx != s) *p++ = *s++;
の間違いではありませんか。UNC パスでファイルが開けなくなりました。
ありがとうございます。おはずかしい。
‘\0’ が ” になっていたりとかもおかしいですね… すみません。