仕様変更で、差分ファイル作成ツールを刷新しようと考えてます。そこで、まず二フォルダ間の差分ファイルを取得するモジュールを作りました。速度は Holy Knights Ver.2.13(X'mas Edition) と HolyKnights Ver.2.10 の差分ファイルを出力するのに 0.4 秒強ぐらいで、十分許容範囲でしょう。他の方のモジュールに依存しまくりなんで、どうかとも思いますが、一応スクリプトを公開しときます。
// 二フォルダ間の差分ファイルを調べるモジュール
// kernel32.as、dirlist2代替モジュール、CRC32取得モジュールに依存する
#ifndef modDifflist
#include "kernel32.as"
#include "dirlist2.hsp"
#include "crc32.hsp"
#module modDifflist
#uselib "shlwapi"
#cfunc PathMatchSpec "PathMatchSpecA" sptr, sptr
// difflist NewFolder, OldFolder, ExcludeFileList, Mode
//
// DiffListBuf : 結果を格納する変数
// NewFolder : 比較する新しいフォルダ
// OldFolder : 比較する古いフォルダ
// FileMask : 検索するファイルのワイルドカード
// GetMode : 検索するファイルの取得モード
// ExcludeFileList : 差分ファイルから除外するファイルのリスト
// DiffMode : 差分ファイルを調べるモード
//
// FileMask は NewFolder 内のファイルを検索するときのファイルマスク。
// ワイルドカードで指定する。("*.*"など)
//
// GetMode は dirlist 命令で使う取得モード。
// サブフォルダも検索するときはそれと 8 の和。
//
// ExcludeFileListは、差分ファイルから除外するファイルをワイルドカードで指定したものを改行で区切ったリスト。
//
// DiffModeは以下の値の組み合わせ
// $0001 : 差分ファイルに入れる条件に「新しいファイル」を付け加える
// $0002 : 差分ファイルに入れる条件に「異なるサイズ」を付け加える
// $0004 : 差分ファイルに入れる条件に「新しい更新日時」を付け加える
// $0008 : 差分ファイルに入れる条件に「異なる更新日時」を付け加える
// $0010 : 差分ファイルに入れる条件に「異なるファイル内容」を付け加える
// これらの選択された条件のうち一つでも当てはまれば差分ファイルに入る
#define global difflist( %1, %2, %3, %4 = "*.*", %5 = 9, %6 = "", %7 = $0013 ) _difflist %1, %2, %3, %4, %5, %6, %7
#deffunc _difflist var DiffListBuf, str NewFolder, str OldFolder, str FileMask, int GetMode, str _ExcludeFileList, int DiffMode
StartDir = dir_cur
//改行で区切られた除外リストを配列変数に変換
ExcludeFileList = _ExcludeFileList
notesel ExcludeFileList
sdim ExcludeFile, 260, notemax
noteunsel
idx = 0
repeat length( ExcludeFile )
getstr ExcludeFile.cnt, ExcludeFileList, idx
idx += strsize
loop
chdir NewFolder
dirlist2 NewFolderFileList, FileMask, GetMode
nFiles = stat
nDiffFile = 0
//結果格納文字列変数
DiffListBufSz = 65536
sdim DiffListBuf, DiffListBufSz
DiffListBufIdx = 0
idx = 0
repeat nFiles
getstr buf, NewFolderFileList, idx
if strsize == 0 : break
idx += strsize
//除外リストに当てはまるか
ExcludeFlag = 0
repeat length( ExcludeFile )
if PathMatchSpec( buf, ExcludeFile.cnt ) : ExcludeFlag = 1 : continue
loop
if ExcludeFlag : continue
//ファイルが異なっているかチェック
FileName = NewFolder + "\\" + buf, OldFolder + "\\" + buf
repeat 2
exist FileName.cnt
FileSz.cnt = strsize
loop
//古いフォルダーに当該ファイルが存在しなかったら、差分ファイルへ入れる
if ( DiffMode & 1 ) & FileSz.1 == -1 : gosub *AddToList : continue
//ファイルサイズが異なっていたら、差分ファイルへ入れる
if ( DiffMode >> 1 & 1 ) & FileSz.0 != FileSz.1 : gosub *AddToList : continue
//更新日時
if DiffMode >> 2 & 3 {
ddim FileTime, 2
repeat 2
CreateFile FileName.cnt, 0, 0, 0, 3, 0, 0
hFile = stat
GetFileTime hFile, 0, 0, varptr( FileTime ) + 8 * cnt
CloseHandle hFile
loop
CompareFileTime varptr( FileTime ), varptr( FileTime ) + 8
//新しいファイルの更新日時が古いファイルのそれより新しかったら、差分ファイルへ入れる
if DiffMode >> 2 & 1 {
if stat == 1 : gosub *AddToList : continue
}
//新しいファイルの更新日時が古いファイルのそれと異なっていたら、差分ファイルへ入れる
if DiffMode >> 3 & 1 {
if stat != 0 : gosub *AddToList : continue
}
}
//ファイルの内容(CRC32)が異なっていたら、差分ファイルへ入れる
if DiffMode >> 4 & 1 {
repeat 2
FileCrc = 0
if FileSz.cnt > 0 {
sdim FileBuf, FileSz.cnt
bload FileName.cnt, FileBuf
FileCrc.cnt = GetCrc32( FileBuf, FileSz.cnt, 0 )
}
loop
if FileCrc.0 != FileCrc.1 : gosub *AddToList : continue
}
loop
return nDiffFile
*AddToList
//ファイルが異なっていると判断できたので、リストに追加
if DiffListIdx + 260 >= DiffListBufSz : DiffListBufSz += 65536 : memexpand DiffListBuf, DiffListBufSz
poke DiffListBuf, DiffListBufIdx, buf + "\n"
DiffListBufIdx += strsize
nDiffFile ++
return
#global
#endif
dirlist2.hsp はModule/修正版dirlist2 - HSP開発wikiのモジュールを自分の使いやすいように直したものです。具体的には以下のように改造しました。
noteget を getstr で代用するなどして高速化dirlist2h や、 dirlist2r を消して、引数を dirlist と同じものに
このように、全然 hspext と互換性のない dirlist2 に改造しました。
「 crc32.hsp 」はつーさのくーかん | 「HSPが遅い」って書いたのは......にある CRC32 取得モジュール。これについて、使用していいか今まで確認していないまま使用してしまっていました。問い合わせると、使用していいとのことでした。確認せずに使用したしまったこと、お詫びします。