lrstolfm: improve tool to allow extraction of contained resources into files (the last param must be @)

git-svn-id: trunk@43113 -
This commit is contained in:
paul 2013-10-06 05:19:16 +00:00
parent fc5eae905d
commit 09c6722b45

View File

@ -37,32 +37,35 @@ program lrstolfm;
uses uses
Classes, SysUtils, LResources, FileUtil; Classes, SysUtils, LResources, FileUtil;
function FindResourceInLRS(const ResourceName: string; List: TStrings): integer; procedure FindResourceInLRS(List: TStrings; var ResourceName: string; var Index: Integer; out ResType: String);
const const
Pattern = 'LazarusResources.Add('''; Pattern = 'LazarusResources.Add(''';
var var
Line: string; Line,
s: String; ResName: String;
begin begin
Result:=0; while (Index < List.Count) do
while (Result<List.Count) do begin begin
Line:=List[Result]; Line := List[Index];
if (length(Line)>length(Pattern)) if (Length(Line) > Length(Pattern)) and
and ((strlcomp(PChar(Line),Pattern,length(Pattern)))=0) then begin (Pos(Pattern, Line) = 1) then
if (ResourceName='') then begin
exit; Delete(Line, 1, Length(Pattern));
s:=Pattern+ResourceName+''','; ResName := Copy(Line, 1, Pos(''',''', Line) - 1);
if (strlcomp(PChar(Line),PChar(s),length(s))=0) then if (ResourceName <> '') and (ResName <> ResourceName) then
exit; Continue;
ResourceName := ResName;
Delete(Line, 1, Length(ResName) + 3);
ResType := Copy(Line, 1, Pos(''',[', Line) - 1);
Exit;
end; end;
inc(Result); Inc(Index);
end; end;
Result:=-1; Index := -1;
end; end;
function ExtractResource(HeaderIndex: integer; LRS: TStrings): TMemoryStream; function ExtractResource(LRS: TStrings; var Index: integer): TMemoryStream;
var var
i: LongInt;
p: Integer; p: Integer;
Line: string; Line: string;
StartPos: LongInt; StartPos: LongInt;
@ -70,19 +73,23 @@ var
c: Char; c: Char;
begin begin
Result:=TMemoryStream.Create; Result:=TMemoryStream.Create;
i:=HeaderIndex+1; inc(Index);
while (i<LRS.Count) do begin while (Index < LRS.Count) do
Line:=LRS[i]; begin
Line := LRS[Index];
if (Line<>'') and (Line[1]=']') then exit;// found the end of this resource if (Line<>'') and (Line[1]=']') then exit;// found the end of this resource
p:=1; p := 1;
while (p<=length(Line)) do begin while (p <= length(Line)) do
begin
case Line[p] of case Line[p] of
'''': '''':
// string constant // string constant
begin begin
inc(p); inc(p);
while p<=length(Line) do begin while p<=length(Line) do
if Line[p]<>'''' then begin begin
if Line[p]<>'''' then
begin
// read normal characters // read normal characters
StartPos:=p; StartPos:=p;
while (p<=length(Line)) and (Line[p]<>'''') do inc(p); while (p<=length(Line)) and (Line[p]<>'''') do inc(p);
@ -114,52 +121,75 @@ begin
inc(p); inc(p);
end; end;
end; end;
inc(i); inc(Index);
end; end;
end; end;
var var
LRSFilename: String; LRSFilename, ResText,
ResourceName: String; ResourceName, ResourceType: String;
LRS: TStringList;
ResourceHeader: LongInt; ResourceHeader: LongInt;
ObjResource: TMemoryStream; LRS: TStringList;
TextResource: TMemoryStream; ObjResource, TextResource: TMemoryStream;
LFMText: string; FileStream: TFileStream;
begin begin
if (ParamCount<1) or (ParamCount>2) then begin if (ParamCount < 1) or (ParamCount > 2) then
writeln('Usage: ',ExtractFileName(ParamStr(0)) begin
,' resourcefilename [resourcename]'); WriteLn('Usage: ', ExtractFileName(ParamStr(0)), ' resourcefilename [resourcename]');
exit; Exit;
end; end;
LRSFilename:=ParamStr(1); LRSFilename := ParamStr(1);
ResourceName:=''; ResourceName := '';
if ParamCount>=2 then if ParamCount >= 2 then
ResourceName:=ParamStr(2); ResourceName := ParamStr(2);
LRS:=TStringList.Create; LRS := TStringList.Create;
LRS.LoadFromFile(LRSFilename); LRS.LoadFromFile(LRSFilename);
ResourceHeader := 0;
// find resource
ResourceHeader:=FindResourceInLRS(ResourceName,LRS);
if ResourceHeader<0 then
raise Exception.Create('resource not found: '+ResourceName);
// convert lrs format to binary format if ResourceName = '@' then
ObjResource:=ExtractResource(ResourceHeader,LRS); begin
while True do
begin
// find resource
ResourceName := '';
FindResourceInLRS(LRS, ResourceName, ResourceHeader, ResourceType);
if ResourceHeader < 0 then
break;
ObjResource := ExtractResource(LRS, ResourceHeader);
ObjResource.Position := 0;
FileStream := TFileStream.Create(ResourceName + '.' + ResourceType, fmCreate);
try
FileStream.CopyFrom(ObjResource, ObjResource.Size);
finally
FileStream.Free;
end;
ObjResource.Free;
end;
end
else
begin
// find resource
FindResourceInLRS(LRS, ResourceName, ResourceHeader, ResourceType);
if ResourceHeader < 0 then
raise Exception.Create('Resource not found: ' + ResourceName);
// convert binary format to lfm format // convert lrs format to binary format
TextResource:=TMemoryStream.Create; ObjResource := ExtractResource(LRS, ResourceHeader);
ObjResource.Position:=0; ObjResource.Position := 0;
LRSObjectBinaryToText(ObjResource,TextResource);
// write to stdout // convert binary format to lfm format
TextResource.Position:=0; TextResource := TMemoryStream.Create;
SetLength(LFMText,TextResource.Size); LRSObjectBinaryToText(ObjResource, TextResource);
TextResource.Read(LFMText[1],length(LFMText));
write(LFMText);
TextResource.Free; // write to stdout
ObjResource.Free; TextResource.Position := 0;
SetLength(ResText, TextResource.Size);
TextResource.Read(ResText[1], Length(ResText));
Write(ResText);
TextResource.Free;
ObjResource.Free;
end;
LRS.Free; LRS.Free;
end. end.