|
でるもんた・いいじま さんの助言をもとに、文末に掲載の検証用の DLL とマクロで
いろいろテストを
行っているのですが、実行結果から「秀丸独自コード」の挙動を確認したところ、実
際にこれを正規表現 DLL などで
処理するうえでどのように対処したらよいのか分からない点がございます。
1. Shift-JIS で二重定義された文字についてです。例えば、記号の「≒」( U+2252
) は、Shift-JIS 上は
0x81E0 と 0x8790 で二重に定義されているのですが、マクロの文字列リテラル
として直接 @"≒" と
した場合は「秀丸独自コード」は 0x81E0 のほうを踏襲して 81 E0 となります。
一方、char 関数を
使って char( 0x8790 ) と書いた場合には記述通りに 87 90 となります。
しかし、両方とも Unicode にすると同じ U+2252 になって、これを元の「秀丸
独自コード」に戻す時には
どちらだったのか分からなくなっています。この 2 つを明確に区別する必要が
ある場合はどうすれば
よいのでしょうか。
2. 制御文字 \x1A で始まる一部の Shift-JIS 文字列についてです。例えば、制御
コード交じりの半角カナの
「\x1Aツチ\x0F」を「秀丸独自コード」にすると、1A C2 C1 0F となります。一方、
ハングルの「쇂」( U+C1C2 ) の
「秀丸独自コード」も同じく 1A C2 C1 0F となります。
当然、この 2 つは明確に区別されなければならないのですが、一度「秀丸独自
コード」にしてしまうと全く
区別がつかなくなってしまいます。この場合はどのように対処すればよいのでし
ょうか。
なお、秀丸エディタの検索ダイアログでは HmJre.dll および hmonig.dll とも
に、パターン「쇂」が本文の
「\x1Aツチ\x0F」にマッチしたり、逆にパターン「\x1Aツチ\x0F」が「쇂」に
マッチするようなことはありませんでした。
これらの DLL ではいったいどうやって 1A C2 C1 0F の元の文字列を判別してい
るのか知りたいです。
// -------------------------------- HexDump.dll ----------------------------
----
// Visual Studio 2019 にて C17 としてビルド。
// ここでは size_t の加算や乗算での整数オーバーフロー対策はしていません。
// メモリリーク防止のため、マクロ上で freedll する前に Clear() 関数を実行す
る必要があります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
wchar_t * hexString = ( (wchar_t *) NULL ) ;
wchar_t emptyHexString[ 1 ] = { L'\0' } ;
wchar_t * WINAPI getHexString( void ) ;
void WINAPI setHexString( void * , size_t ) ;
void WINAPI clearHexString( void ) ;
wchar_t * WINAPI getHexString() {
return ( ( (wchar_t *) NULL ) == hexString ) ? emptyHexString : hexString ;
}
void WINAPI setHexString(
void * byteData
, size_t byteDataLength
) {
clearHexString() ;
if ( NULL == byteData ) { return ; }
size_t hexDigitWidth = ( (size_t) 2 ) ;
size_t hexSpaceWitdh = ( (size_t) 1 ) ;
size_t hexItemWidth = ( hexDigitWidth + hexSpaceWitdh ) ;
hexString = ( (wchar_t *) malloc(
( ( byteDataLength * hexItemWidth ) + ( (size_t) 1 ) )
* sizeof( wchar_t )
) ) ;
unsigned char * byteDataStart = ( (unsigned char *) byteData ) ;
wchar_t * hexStringPtr = hexString ;
for ( size_t byteDataOffset = ( (size_t) 0 ) ; byteDataOffset < byteData
Length ; byteDataOffset ++ ) {
swprintf_s(
hexStringPtr
, hexDigitWidth + ( (size_t) 1 )
, L"%0*hhX"
, (int) hexDigitWidth
, * ( byteDataStart + byteDataOffset )
) ;
hexStringPtr += hexDigitWidth ;
( * hexStringPtr ) = L' ' ;
hexStringPtr += hexSpaceWitdh ;
}
( * hexStringPtr ) = L'\0' ;
}
void WINAPI clearHexString() {
if ( ( (wchar_t *) NULL ) != hexString ) {
free( (void *) hexString ) ;
hexString = ( (wchar_t *) NULL ) ;
}
}
BOOL WINAPI DllMain( HINSTANCE , DWORD , LPVOID ) ;
__declspec( dllexport ) void __cdecl STARTUNIMACRO ( void ) ;
__declspec( dllexport ) INT_PTR __cdecl ExecuteAscii( char * ) ;
__declspec( dllexport ) INT_PTR __cdecl ExecuteUnicode( WCHAR * ) ;
__declspec( dllexport ) WCHAR * __cdecl GetResult() ;
__declspec( dllexport ) INT_PTR __cdecl Clear() ;
BOOL WINAPI DllMain(
HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpReserved
) {
switch ( fdwReason ) {
case DLL_PROCESS_ATTACH : break ;
case DLL_PROCESS_DETACH : break ;
case DLL_THREAD_ATTACH : break ;
case DLL_THREAD_DETACH : break ;
}
return TRUE ;
}
__declspec( dllexport ) void __cdecl STARTUNIMACRO () {}
__declspec( dllexport ) INT_PTR __cdecl ExecuteAscii(
char * inputString
) {
setHexString(
(void *) inputString
, ( strlen( (const char *) (void *) inputString ) + ( (size_t)
1 ) )
* sizeof( char )
) ;
return (INT_PTR) TRUE ;
}
__declspec( dllexport ) INT_PTR __cdecl ExecuteUnicode(
WCHAR * inputString
) {
setHexString(
(void *) inputString
, ( wcslen( (const wchar_t *) (void *) inputString ) + ( (size
_t) 1 ) )
* sizeof( wchar_t )
) ;
return (INT_PTR) TRUE ;
}
__declspec( dllexport ) WCHAR * __cdecl GetResult() {
return (WCHAR *) (void *) getHexString() ;
}
__declspec( dllexport ) INT_PTR __cdecl Clear() {
clearHexString() ;
return (INT_PTR) TRUE ;
}
// -------------------------------- Test.mac --------------------------------
#defaultCompatibleMode = setcompatiblemode(
0x00000003
| 0x0000000C
| 0x00000200
| 0x00020000
| 0x00080000
| 0x00400000
| 0x00800000
| 0x04000000
| 0x08000000
) ;
disablehistory
0x00000001
| 0x00000002
| 0x00000004
| 0x00000008
| 0x00000010
| 0x00000020
| 0x00000040
;
disablebreak ;
#defaultTopY = screentopy ; #defaultLeftX = screenleftx ; disabledraw ; disa
bleinvert ;
#hexDump = loaddll( currentmacrodirectory + @"\HexDump.dll" ) ;
#stringCount = 0 ;
$title[ #stringCount ] = @"ASCII 範囲" ;
$string[ #stringCount ] = @"abcd"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Shift-JIS 範囲" ;
$string[ #stringCount ] = @"あいうえ"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Unicode 半角" ;
$string[ #stringCount ] = @"ĹĻĽĿ"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Unicode 全角" ;
$string[ #stringCount ] = @"ᾨᾩᾪᾫ"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"サロゲートペア" ;
$string[ #stringCount ] = @"𝟞𒈅"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"合字" ;
$string[ #stringCount ] = @"👩🏼‍👨🏽&
#8205;👦🏼‍👧🏽"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"混合" ;
$string[ #stringCount ] = @"aᾨĹあ𝟞"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Shift-JIS の重複定義 1" ;
$string[ #stringCount ] = char( 0x81E0 ) + char( 0xED40 )
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Shift-JIS の重複定義 2" ;
$string[ #stringCount ] = char( 0x8790 ) + char( 0xFA5C )
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Shift-JIS の重複定義 3" ;
$string[ #stringCount ] = @"≒\"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"不正サロゲート" ;
$string[ #stringCount ] = "\U0000DFDE" + @"a" + "\U0000D835" + @"b" + "\
U0000DFDE\U0000D835" ;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Null 文字" ;
$string[ #stringCount ] = @"ab" + "\U00000000" + @"cd"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"秀丸独自コードと重複 1" ;
$string[ #stringCount ] = @"쇂쇂"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"秀丸独自コードと重複 2" ;
$string[ #stringCount ] = "\x1A" + @"ツチ" + "\x0F\x1A" + @"ツチ" + "\x0F"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Unicode 未使用" ;
$string[ #stringCount ] = "\U00314000\U00314001\U00314002\U00314003"
;
#stringCount = #stringCount + 1 ;
$title[ #stringCount ] = @"Unicode 範囲外" ;
$string[ #stringCount ] = "\U00500000\U01000000\U10000000\U80000000"
;
#stringCount = #stringCount + 1 ;
#stringIndex = 0 ;
while ( #stringIndex < #stringCount ) {
call WriteLine @"[" + $title[ #stringIndex ] + @"]" ;
call WriteLine @"String = " + $string[ #stringIndex ]
;
#result = dllfuncw( #hexDump , @"ExecuteUnicode" , $string[ #stri
ngIndex ] ) ;
call WriteLine @"Unicode = " + dllfuncstrw( #hexDump , @"GetResult"
) ;
#result = dllfunc( #hexDump , @"ExecuteAscii" , $string[ #stri
ngIndex ] ) ;
call WriteLine @"Ascii = " + dllfuncstrw( #hexDump , @"GetResult"
) ;
call WriteLine @"" ;
#stringIndex = #stringIndex + 1 ;
}
#result = dllfuncw( #hexDump , @"Clear" ) ; freedll #hexDump ;
refreshoutline ;
enableinvert ; enabledraw #defaultTopY , #defaultLeftX ;
enablebreak ;
setcompatiblemode #defaultCompatibleMode ;
endmacro ;
WriteLine :
insert $$1 ;
insert "\U0000000A" ;
return ;
// -------------------------------- 実行結果 --------------------------------
[ASCII 範囲]
String = abcd
Unicode = 61 00 62 00 63 00 64 00 00 00
Ascii = 61 62 63 64 00
[Shift-JIS 範囲]
String = あいうえ
Unicode = 42 30 44 30 46 30 48 30 00 00
Ascii = 82 A0 82 A2 82 A4 82 A6 00
[Unicode 半角]
String = ĹĻĽĿ
Unicode = 39 01 3B 01 3D 01 3F 01 00 00
Ascii = 1A B9 81 04 1A BB 81 04 1A BD 81 04 1A BF 81 04 00
[Unicode 全角]
String = ᾨᾩᾪᾫ
Unicode = A8 1F A9 1F AA 1F AB 1F 00 00
Ascii = 1A A8 9F 0D 1A A9 9F 0D 1A AA 9F 0D 1A AB 9F 0D 00
[サロゲートペア]
String = 𝟞𒈅
Unicode = 35 D8 DE DF 08 D8 05 DE 00 00
Ascii = 1A B5 D8 06 1A DE DF 07 1A 88 D8 06 1A 85 DE 06 00
[合字]
String = 👩🏼‍👨🏽‍👦ㇿ
6;‍👧🏽
Unicode = 3D D8 69 DC 3C D8 FC DF 0D 20 3D D8 68 DC 3C D8 FD DF 0D 20 3D D8
66 DC 3C D8 FC DF 0D 20 3D D8 67 DC 3C D8 FD DF 00 00
Ascii = 1A BD D8 06 1A E9 DC 06 1A BC D8 06 1A FC DF 07 1A 8D A0 04 1A BD
D8 06 1A E8 DC 06 1A BC D8 06 1A FD DF 07 1A 8D A0 04 1A BD D8 06 1A E6 DC 0
6 1A BC D8 06 1A FC DF 07 1A 8D A0 04 1A BD D8 06 1A E7 DC 06 1A BC D8 06 1A
FD DF 07 00
[混合]
String = aᾨĹあ𝟞
Unicode = 61 00 A8 1F 39 01 42 30 35 D8 DE DF 00 00
Ascii = 61 1A A8 9F 0D 1A B9 81 04 82 A0 1A B5 D8 06 1A DE DF 07 00
[Shift-JIS の重複定義 1]
String = ≒\
Unicode = 52 22 8A 7E 00 00
Ascii = 81 E0 ED 40 00
[Shift-JIS の重複定義 2]
String = ≒\
Unicode = 52 22 8A 7E 00 00
Ascii = 87 90 FA 5C 00
[Shift-JIS の重複定義 3]
String = ≒\
Unicode = 52 22 8A 7E 00 00
Ascii = 81 E0 FA 5C 00
[不正サロゲート]
String = �ab�
Unicode = DE DF 61 00 35 D8 62 00 DE DF 35 D8 00 00
Ascii = 1A DE DF 07 61 1A B5 D8 06 62 1A DE DF 07 1A B5 D8 06 00
[Null 文字]
String = abcd
Unicode = 61 00 62 00 63 00 64 00 00 00
Ascii = 61 62 63 64 00
[秀丸独自コードと重複 1]
String = 쇂쇂
Unicode = C2 C1 C2 C1 00 00
Ascii = 1A C2 C1 0F 1A C2 C1 0F 00
[秀丸独自コードと重複 2]
String = ツチツチ
Unicode = 1A 00 82 FF 81 FF 0F 00 1A 00 82 FF 81 FF 0F 00 00 00
Ascii = 1A C2 C1 0F 1A C2 C1 0F 00
[Unicode 未使用]
String = ��������
Unicode = 10 DC 00 DC 10 DC 01 DC 10 DC 02 DC 10 DC 03 DC 00 00
Ascii = 1A 90 DC 06 1A 80 DC 06 1A 90 DC 06 1A 81 DC 06 1A 90 DC 06 1A 82
DC 06 1A 90 DC 06 1A 83 DC 06 00
[Unicode 範囲外]
String = 􀀀￀�￀�￀�
Unicode = C0 DB 00 DC C0 FF 00 DC C0 FF 00 DC C0 FF 00 DC 00 00
Ascii = 1A C0 DB 07 1A 80 DC 06 1A C0 FF 07 1A 80 DC 06 1A C0 FF 07 1A 80
DC 06 1A C0 FF 07 1A 80 DC 06 00
|
|