|
でるもんた・いいじまです。
うーむ。ここは初心者ユーザーさんも利用する hidemaru.2 なので、できればこうい
う内部構造の話は turukame.3 に移りたいところですが、往年の fj.* と違ってここ
には、スレッドの続きを別の会議室に引っ越す機能がありません。どうしたものか…
☆ ☆ ☆
というわけで、Unicodeがらみのところだけコメントします。
> BOOL WINAPI Jre2Compile( LPJRE2 lpjre , LPSTR lpszRe ) ;
> でのパターン文字列値 lpszRe や、検索実行時の
> BOOL WINAPI Jre2GetMatchInfo( LPJRE2 lpjre , LPSTR lpszStr ) ;
> または
> BOOL WINAPI Jre2GetMatchInfo_HmJre( LPJRE2 lpjre , LPSTR lpszStr , int x
>End ) ;
> での検索対象文字列値 lpszStr には UTF-16LE にエンコードした
> バイトシーケンスの先頭ポインターを渡すのか、
> またその場合 BOM は必要なのか、
結論からいえば「最初に指定したコードページでのANSI文字列」のはずです。型名が
LPWSTRではなくLPSTRになっています。
当たり前の事実の再確認になりますが、手元のMinGW-w64だと、winnt.hに次のような
記述があります。
typedef char CHAR;
typedef wchar_t WCHAR;
typedef WCHAR *NWPSTR,*LPWSTR,*PWSTR;
typedef CHAR *NPSTR,*LPSTR,*PSTR;
#ついでに余談ですが、UTF-32用にこんな記述もありますね…初めて知りました。
# #if _WIN32_WINNT >= 0x0600 || /* 略 */
# /* 略 */
# typedef unsigned long UCSCHAR;
# #define UCSCHAR_INVALID_CHARACTER (0xffffffff)
# #define MIN_UCSCHAR (0)
# #define MAX_UCSCHAR (0x0010ffff)
# /* 略 */
# #endif
☆ ☆ ☆
で、こちらもご承知かと思いますが、さらに歴史的背景の確認を。
このAPIが最初に設計されたのはWindows3.1時代のjre.dllです。
その時代はまだUnicodeの方向性自体が揺れていた時期で、漢字統合(Han Unificati
on)反対論が世の中を席巻していたり、おとなり韓国が「ハングル大移動」を敢行し
たりで、Unicodeはとてもじゃないがまだ実用にならない、という時代でした。
そのあとWindowsNTがOSの内部コードとしてUTF16-LEを採用し、Windows95が32bitア
プリ用のAPIとしてNTのものをそのまま採用したことで一気にUTF-16への敷居が低く
なり、そして1996年にUnicodeの規格にサロゲートペアが盛り込まれたことでやっと
問題解決の光が見えてきた、という状況です。
そして最終的に、WindowsXP(2003年)からは一般家庭用のWindowsOSでも NantokaKa
ntokaW() というAPI群が気軽に使えるようになって現在に至ります。
☆ ☆ ☆
> これがもし、
> http://htom.in.coocan.jp/macro/macro_dll.html#N4.6
> https://help.maruo.co.jp/hmjre/html/0008_API_MACRO.html#about_unicode
> に出てくる、Shift-JIS を拡張した「秀丸独自コード」であった場合には、
残念ながらその通りであろうと予想します。
> これを onig.dll などで受け取れる UTF-8 などの「真正」の
> Unicode バイトシーケンスに変換する手段がどこにも見当たらない
サイトー企画さんとしては公式には非公開のままにする予定、というコメントが以前
vscode-life さんとの対話中にありましたが、自作のDLLでちょっと実験してみれば
独自コードとUTF-16(もしかしたらUTF-32かも)との換算方法は解読可能です。
そのためにはまず、自作DLLから STARTUNIMACRO という関数を export します。
とりあえず turukame.3:10332 が良いまとめになっていますので、そこからスレッド
を遡ってみてください。
そのうえで、こんな関数を作ってみてください。
- - - - キリトリセン - - - -
#define MAX_INPUTLEN 10000 // テキトーに決め打ちでいい
static char result[MAX_INPUTLEN*3 + 1];
__dllspec(dllexport) __cdecl char* HexDumpA(unsigned char* pInput) {
size_t len = strlen(pInput);
if ( len > MAX_INPUTLEN ) {
// 今時の言語ならcastせずとも %zu と %zX が使えるはずだけどね
sprintf(result, "Error: too long (%llu = 0x%llX bytes).",
(unsigned long long)len, (unsigned long long)len );
return result;
}
// ----コード省略----
// pInputの中身を適宜の方法で16進ダンプして、result[] に書き込む
// ----/コード省略----
return result;
}
- - - - キリトリセン - - - -
要は、秀丸マクロから
$s = dllfuncstr(#hMyDLL, "HexDumpA", "abc123");
のように呼び出したら $s に "61 62 63 31 32 33" のような文字列(私ならスペー
ス区切りにしますが、必ずしもそうしなくていいです)が返ってくるように HexDump
A() を実装してください。
それを踏まえて、
// $u="簡漢,ハングル,(青いハート)"
$u = unichar(0x7B80)+unichar(0x6C49)+','+unichar(0xD55C)+unichar(0xAE00)+','
+unichar(0x1F499);
$s = dllfuncstr(#hMyDLL, "HexDumpA", $u);
message "HexDumpA('" + $u + "') => '" + $s +'.";
のように色々と試してみてください。
> ラッパー DLL に iconv などの文字コードコンバーターを
> 実装する必要があるのかどうか
自前で実装する必要はありません。Jre2SetCodePage() でコードページの情報をクラ
イアントからもらっているので、秀丸独自エンコードの部分とコードページ準拠の部
分とに切り分けて、後者を MultiByteToWideChar() に渡すだけでUTF-16に変換でき
るはずです。
#というか、逆にMultiByteToWideChar() を使わないで
#迂闊に独自実装してしまうと、将来的にいろいろ
#爆弾を抱え込むことになりかねません。
さらにいうと、その後のUTF-8への変換すらも自前で用意する必要はなくて、WideCha
rToMultiByte() でコードページ65001に変換してやればそれで終わりのはずです。
#ただしこちらは、どこまで古いOSが対応しているのか未確認です。
> いずれも、完成品としての HmJre.dll や hmonig.dll の
> API リファレンスは公開されているが、第三者が
> 互換 DLL を作成するのを支援することを目的とした、
> あくまで秀丸エディタ主体の正規表現 DLL 呼び出しの
> 方法が公開されていないため、
確かにこれはその通りですが、これもサイトー企画さんとしては「将来に渡って永久
に仕様を縛ってしまうことになりかねないので、公認つきでの情報公開はしたくな
い」という見解だと思います。
なので、すべてのAPIを形だけでも実装するしかないと思います。とはいえ、「少な
くともAPIではあいまい検索指定の指示を受け付けない」と決め打ちするのであれば、
pythonか何かのスクリプトでダミーの関数を量産してもいいような気がしますが。
|
|