home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2004 March
/
CMCD0304.ISO
/
Software
/
Freeware
/
Programare
/
nullsoft
/
nsis20.exe
/
Contrib
/
VPatch
/
Source
/
GenPat
/
GenPat2.dpr
next >
Wrap
Text File
|
2003-12-27
|
7KB
|
227 lines
program GenPat2;
{
VPatch 2 - Patch Generator
===============================
(c) 2001-2003 Van de Sande Productions
This is the main program unit for the commandline version. It implements
commandline options (like /b=) and displays help if no options are given.
What's new
----------
2.1 20031219 Koen Added error checking, handling, shouldn't
crash when invalid arguments, returns
exit codes now.
2.0 20030811 Koen Initial documentation
}
{$APPTYPE CONSOLE}
uses
PatchGenerator in 'PatchGenerator.pas',
VDSP_CRC in 'VDSP_CRC.pas',
Sysutils,
TreeCode in 'TreeCode.pas';
type
TEventHandler = class
procedure PrintDebug(S: String);
end;
procedure TEventhandler.PrintDebug(S: String);
begin
WriteLn(S);
end;
{$DEFINE READCONFIG} //try to read genpat.ini?
{.$DEFINE AUTOWAIT} //have /wait command line switch on by default?
//useful when debugging
var
Config: TextFile;
T1,T2: TDateTime;
d, i: Integer;
S,Key: String;
SourceFile, TargetFile, PatchFile: String;
ShowDebug, ShowHelp: Boolean;
PG: TPatchGenerator;
EV: TEventHandler;
begin
EV:=TEventHandler.Create;
PG:=TPatchGenerator.Create;
PG.StartBlockSize:=64;
WriteLn('GenPat v2.1');
WriteLn('===========');
WriteLn;
WriteLn('(c) 2001-2003 Van de Sande Productions');
WriteLn('Website: http://www.tibed.net/vpatch');
WriteLn('E-mail: koen@tibed.net');
WriteLn;
ShowDebug:=FindCmdLineSwitch('debug',['/'],True);
if ShowDebug then
DebugEvent:=EV.PrintDebug;
{$IFDEF READCONFIG}
if FileExists('genpat.ini') then begin
AssignFile(Config,'genpat.ini');
Reset(Config);
while not eof(Config) do begin
ReadLn(Config,S);
d:=Pos('=',S);
if not (d=0) then begin
Key:=LowerCase(Copy(S,1,d-1));
S:=Copy(S,d+1,Length(S));
if CompareStr(Key,'startblocksize')=0 then PG.StartBlockSize:=StrToInt(S);
end;
end;
CloseFile(Config);
end;
{$ENDIF}
i:=0;
for d:=1 to ParamCount do begin
if CompareStr(LowerCase(Copy(ParamStr(d),1,3)),'/b=')=0 then begin
PG.StartBlockSize:=StrToInt(Copy(ParamStr(d),4,10));
end else begin
// not a parameter?
if not (ParamStr(d)[1] = '/') then begin
if i = 2 then begin
PatchFile:=ParamStr(d);
Inc(i);
end;
if i = 1 then begin
TargetFile:=ParamStr(d);
Inc(i);
end;
if i = 0 then begin
SourceFile:=ParamStr(d);
Inc(i);
end;
end;
end;
end;
ShowHelp:=False;
if(CompareStr(PatchFile,'')=0) then ShowHelp:=True;
if SourceFile = '' then ShowHelp:=True;
if TargetFile = '' then ShowHelp:=True;
if ShowHelp then begin
WriteLn('This program will take (sourcefile) as input and create a (patchfile).');
WriteLn('With this patchfile, you can convert a (sourcefile) into (targetfile).');
WriteLn;
WriteLn('Command line info:');
WriteLn(' GENPAT (sourcefile) (targetfile) (patchfile)');
WriteLn;
WriteLn('Command line options (you do not need them):');
WriteLn('/B=(BlockSize) Set blocksize (def=64), multiple of 2');
WriteLn('/NOEQUALERROR Exit code becomes 0 instead of 10 when');
WriteLn(' two files with equal CRC are encountered');
WriteLn(' (patch file will remain unchanged)');
WriteLn('/DEBUG Show runtime debug information');
WriteLn;
WriteLn('Note: filenames should never start with / character!');
WriteLn;
WriteLn('Possible exit codes:');
WriteLn(' 0 Success');
WriteLn(' 1 Arguments missing');
WriteLn(' 2 Source file not found');
WriteLn(' 3 Target file not found');
WriteLn(' 4 Unknown error while reading existing patch file');
WriteLn(' 5 Unknown error while generating patch');
WriteLn(' 6 Unknown error while writing patch file to disk');
WriteLn(' 10 CRC of source and target file are equal (impossible with /NOEQUALERROR)');
WriteLn(' 11 Not enough memory for source file');
WriteLn(' 12 Not enough memory for target file');
PG.Free;
ExitCode:=1;
Exit;
end;
// stop if file error, result shown above
if not FileExists(SourceFile) then begin
WriteLn('Error: Source file not found');
PG.Free;
ExitCode:=2;
Exit;
end;
if not FileExists(TargetFile) then begin
WriteLn('Error: Target file not found');
PG.Free;
ExitCode:=3;
Exit;
end;
if FileExists(PatchFile) then begin
WriteLn('Using existing file to include patches in: '+PatchFile);
try
PG.LoadFromFile(PatchFile);
except
on E: Exception do begin
WriteLn('Error: Reading existing patch file failed');
WriteLn('Error message: ', E.ClassName, ': ', E.Message);
PG.Free;
ExitCode:=4;
Exit;
end;
end;
end;
WriteLn('Source (original) file: ', SourceFile);
WriteLn('Target (newer) file: ', TargetFile);
T1:=Now;
// create patch file, with error handling
try
i:=PG.CreatePatch(SourceFile,TargetFile);
except
on E: Exception do begin
WriteLn('Error: Generating patch failed');
WriteLn('Error message: ', E.ClassName, ': ', E.Message);
PG.Free;
ExitCode:=5;
Exit;
end;
end;
if(i < 0) then begin
if(i = -1) then begin
if not FindCmdLineSwitch('noequalerror',['/'],True) then
WriteLn('Error: CRC of source and target file are equal');
end;
if(i = -2) then WriteLn('Error: Not enough memory for source file');
if(i = -3) then WriteLn('Error: Not enough memory for target file');
ExitCode:=9 - i;
if(i = -1) and (FindCmdLineSwitch('noequalerror',['/'],True)) then begin
WriteLn('Equal CRCs ignored (no patch will be written and exit code is 0)');
ExitCode:=0;
end;
end else begin
WriteLn('Patch body size: '+IntToStr(i));
try
PG.WriteToFile(PatchFile);
except
on E: Exception do begin
WriteLn('Error: Writing patch to file ' + PatchFile + ' failed');
WriteLn('Error message: ', E.ClassName, ': ', E.Message);
PG.Free;
ExitCode:=6;
Exit;
end;
end;
T2:=Now;
Write('Time taken for generation: ');
WriteLn(FloatToStr((T2-T1)*24*60*60),'s');
WriteLn;
ExitCode:=0;
end;
PG.Free;
end.