miau's blog?

.svnが邪魔なので

Subversion ではチェックアウトしたそれぞれのファイルに対して base ファイルを保持するみたいです。
例えば hoge.txt というファイルをチェックアウトした場合、.svn\text-base\hoge.txt.svn-base というファイルが生成されます。
こうなると何が不便って、grep した場合に base ファイルも検索結果に出てしまうので、絞込みに時間がかかってしまいます。

普段 Devas を使って grep することが多いんですが、先日せっかく Turbo C++ Explorer を導入したので、ソースをいじれないか試してみることに。




ソースいじる場合の目標は .svn 配下のファイルを検索対象から除外すること。実現方法としては、
(1) 除外ファイルの設定機能を追加
(2) 隠しファイルの除外機能を追加
のどちらかになりそう。

とりあえずコンパイルできる環境を整えよう、ということで色々やってたんですが・・・結論を言ってしまうと、ソースいじるのは諦めました。
というのも、Devas のコンパイルには

・Borland C++ Builder 6
・Boost 1.30.2
・TSonEdit

あたりが必要とのことで。

今回は
・BCB の代わりに Turbo C++ Explorer を
・Turbo C++ 対応版ということで Boost 1.34 alpha を
使うことでコンパイルできないかなー?と思ったんですが、TSonEdit が Delphi6/7 にしか対応してなくて、Turbo C++ ではコンポーネントの登録が行えないみたいです。

ソースコードを提供してもらって自分でコンパイルする手もありそうなんですが、ソースコード無償提供の条件に引っかかりそう(「販売はしないが、企業内の業務で活用するソフトに組み込んだ場合。」も有償版を利用しないとダメらしい)ので結局諦めました。


で、Devas 3.4βのソースコード眺めてみると、VCLCommon.cpp の ForEachFileInDir() を

WIN32_FIND_DATA fd;
HANDLE h= FindFirstFile(pathT.c_str(), &fd);
bool bR= true;
if (h!=INVALID_HANDLE_VALUE){
do{
if ((fd.z&FILE_ATTRIBUTE_DIRECTORY)
!=FILE_ATTRIBUTE_DIRECTORY){

if (!(fd.z&(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN)){
// なんか処理
}
}while (FindNextFile(h, &fd));
FindClose(h);

みたいに書き換えるだけで、(2) の対応は行えそう。(変更前:赤、変更後:青)
これくらいなら OllyDbg で対応できるんじゃない?

ということで、やってみた。

0049EB75 |. 52 PUSH EDX ; /pFindFileData
0049EB76 |. 8B4D E8 MOV ECX,DWORD PTR SS:[EBP-18] ; |
0049EB79 |. 51 PUSH ECX ; |FileName
0049EB7A |. E8 2FC50D00 CALL <JMP.&KERNEL32.FindFirstFileA> ; \FindFirstFileA
0049EB7F |. 8BD8 MOV EBX,EAX
0049EB81 |. C645 A3 01 MOV BYTE PTR SS:[EBP-5D],1
0049EB85 |. 83FB FF CMP EBX,-1
0049EB88 |. 0F84 D1000000 JE Devas.0049EC5F
0049EB8E |> 8B85 48FEFFFF /MOV EAX,DWORD PTR SS:[EBP-1B8]
0049EB94 |. 83E0 10 |AND EAX,10
0049EB97 |. 83F8 10 |CMP EAX,10
0049EB9A |. 0F84 A4000000 |JE Devas.0049EC44

0049EB94 A9 12000000 TEST EAX,12
0049EB99 90 NOP
0049EB9A 0F85 A4000000 JNZ Devas.0049EC44


あれ。隠しファイルの処理はうまくいってるっぽいけど、Subversion 管理のファイルに期待通りの動作をしてくれない。
よく見ると .svn が隠しフォルダになっているだけで、その配下のファイルは隠しファイルではないらしい。

ということで、ForEachSubDir() に該当する箇所もいじることに。
ちょっと悩んだけど、よく考えたら

if ((fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
if ((fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_HIDDEN)
==FILE_ATTRIBUTE_DIRECTORY
&& strcmp(fd.cFileName, ".")!=0
&& strcmp(fd.cFileName, "..")!=0){
string path2= CombineDirFile(pathDir, fd.cFileName);
if (!func(path2) || !ForEachSubDir(path2, func)){
bR= false;
break;
}
}

こう書き換えればいいだけなので、

0049E646 . 50 PUSH EAX ; /pFindFileData
0049E647 . 8B55 E8 MOV EDX,DWORD PTR SS:[EBP-18] ; |
0049E64A . 52 PUSH EDX ; |FileName
0049E64B . E8 5ECA0D00 CALL <JMP.&KERNEL32.FindFirstFileA> ; \FindFirstFileA
0049E650 . 8985 68FFFFFF MOV DWORD PTR SS:[EBP-98],EAX
0049E656 . C685 67FFFFFF >MOV BYTE PTR SS:[EBP-99],1
0049E65D . 83BD 68FFFFFF >CMP DWORD PTR SS:[EBP-98],-1
0049E664 . 0F84 74020000 JE Devas.0049E8DE
0049E66A . 66:C785 7CFFFF>MOV WORD PTR SS:[EBP-84],38
0049E673 > 8B8D 0CFEFFFF MOV ECX,DWORD PTR SS:[EBP-1F4]
0049E679 83E1 10 AND ECX,10
0049E679 83E1 12 AND ECX,12
0049E67C . 83F9 10 CMP ECX,10
0049E67F . 0F85 01020000 JNZ Devas.0049E886

こんな感じに変更。ようやく期待通りの動作をするようになりました。

パッチ作るの面倒だから、一応変更点だけ載せときます。対象バージョンは上に書いたように Devas 3.4β です。

>fc devas.exe devas.exe.org
ファイル Devas.exe と DEVAS.EXE.ORG を比較しています
0009DC7B: 12 10
0009E194: A9 83
0009E195: 12 E0
0009E196: 00 10
0009E197: 00 83
0009E198: 00 F8
0009E199: 90 10
0009E19B: 85 84



(追記)
掲示板にも要望出しておいた。のでいずれ対応してくれるかも。


(2009-11-10 追記)

Devas 3.5βでもやってみました。

>fc devas.exe devas.exe.org
ファイル Devas.exe と DEVAS.EXE.ORG を比較しています
000A7B07: 12 10
000A8020: A9 83
000A8021: 12 E0
000A8022: 00 10
000A8023: 00 83
000A8024: 00 F8
000A8025: 90 10
000A8027: 85 84
posted at 06:23:24 on 2006-11-19 by miau - Category: General No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

No comments yet

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。