Converter: convert Windows WideString syntax (#xxx) to UTF8 in LFM files. Issue #23116

git-svn-id: trunk@41962 -
This commit is contained in:
juha 2013-07-01 23:33:50 +00:00
parent 86818186ba
commit 2667dcf7f4
2 changed files with 93 additions and 19 deletions

View File

@ -34,7 +34,7 @@ interface
uses uses
// FCL+LCL // FCL+LCL
Classes, SysUtils, Math, LCLProc, Forms, Controls, Grids, LResources, LConvEncoding, Classes, SysUtils, Math, LCLProc, Forms, Controls, Grids, LResources, LConvEncoding,
Graphics, Dialogs, Buttons, StdCtrls, ExtCtrls, contnrs, FileUtil, Graphics, Dialogs, Buttons, StdCtrls, ExtCtrls, contnrs, FileUtil, LCLType,
// components // components
SynHighlighterLFM, SynEdit, SynEditMiscClasses, LFMTrees, SynHighlighterLFM, SynEdit, SynEditMiscClasses, LFMTrees,
// codetools // codetools
@ -56,6 +56,7 @@ type
private private
fSettings: TConvertSettings; fSettings: TConvertSettings;
fOrigFormat: TLRSStreamOriginalFormat; fOrigFormat: TLRSStreamOriginalFormat;
function FixWideString(aInStream, aOutStream: TMemoryStream): TModalResult;
function GetLFMFilename(const DfmFilename: string; KeepCase: boolean): string; function GetLFMFilename(const DfmFilename: string; KeepCase: boolean): string;
public public
constructor Create; constructor Create;
@ -134,6 +135,8 @@ type
implementation implementation
uses strutils;
{$R *.lfm} {$R *.lfm}
function IsMissingType(LFMError: TLFMError): boolean; function IsMissingType(LFMError: TLFMError): boolean;
@ -186,15 +189,79 @@ begin
Result:=''; Result:='';
end; end;
function TDFMConverter.FixWideString(aInStream, aOutStream: TMemoryStream): TModalResult;
// Convert Windows WideString syntax (#xxx) to UTF8
function UnicodeNumber(const InS: string; Ind: integer): string;
// Convert the number to UTF8
var
c: Integer;
begin
c := StrToInt(copy(InS, Ind, 3));
if c > 255 then
Result := UnicodeToUTF8(c)
else
Result := SysToUTF8(chr(c)); // or use a function in lconvencoding.
end;
function CollectString(const InS: string; var Ind: integer): string;
// Collect a string composed of quoted strings and unicode numbers like #xxx
var
InQuote: Boolean;
ch: Char;
begin
Result:='';
InQuote:=False;
repeat
ch:=InS[Ind];
if ch in [#13,#10] then Break;
if ch = '''' then
InQuote:=not InQuote
else if InQuote then
Result:=Result+ch
else if ch = '#' then begin
Result:=Result+UnicodeNumber(InS, Ind+1);
Inc(Ind, 3);
end
else
Break;
Inc(Ind);
until False;
Result:=QuotedStr(Result);
end;
var
InS, OutS: string;
i: Integer;
begin
Result:=mrOk;
OutS:='';
aInStream.Position:=0;
SetLength(InS, aInStream.Size);
aInStream.Read(InS[1],length(InS));
i := 1;
while i < Length(InS) do begin
if InS[i] in ['''', '#'] then
OutS:=OutS+CollectString(InS, i)
else begin
OutS:=OutS+InS[i];
Inc(i);
end;
end;
// Write data to a new stream.
aOutStream.Write(OutS[1], Length(OutS));
end;
function TDFMConverter.ConvertDfmToLfm(const aFilename: string): TModalResult; function TDFMConverter.ConvertDfmToLfm(const aFilename: string): TModalResult;
var var
DFMStream, LFMStream: TMemoryStream; DFMStream, LFMStream, Utf8LFMStream: TMemoryStream;
begin begin
Result:=mrOk; Result:=mrOk;
DFMStream:=TMemoryStream.Create; DFMStream:=TMemoryStream.Create;
LFMStream:=TMemoryStream.Create; LFMStream:=TMemoryStream.Create;
Utf8LFMStream:=TMemoryStream.Create;
try try
// Note: The file is copied from DFM file earlier. // Note: The file is copied from DFM file earlier. Load it.
try try
DFMStream.LoadFromFile(UTF8ToSys(aFilename)); DFMStream.LoadFromFile(UTF8ToSys(aFilename));
except except
@ -208,8 +275,9 @@ begin
end; end;
end; end;
fOrigFormat:=TestFormStreamFormat(DFMStream); fOrigFormat:=TestFormStreamFormat(DFMStream);
// converting dfm file, without renaming unit -> keep case...
try try
FormDataToText(DFMStream,LFMStream); FormDataToText(DFMStream, LFMStream, fOrigFormat);
except except
on E: Exception do begin on E: Exception do begin
Result:=QuestionDlg(lisFormatError, Result:=QuestionDlg(lisFormatError,
@ -220,9 +288,11 @@ begin
exit; exit;
end; end;
end; end;
// converting dfm file, without renaming unit -> keep case... // Convert Windows WideString syntax (#xxx) to UTF8
FixWideString(LFMStream, Utf8LFMStream);
// Save the converted file.
try try
LFMStream.SaveToFile(UTF8ToSys(aFilename)); Utf8LFMStream.SaveToFile(UTF8ToSys(aFilename));
except except
on E: Exception do begin on E: Exception do begin
Result:=MessageDlg(lisCodeToolsDefsWriteError, Result:=MessageDlg(lisCodeToolsDefsWriteError,
@ -234,6 +304,7 @@ begin
end; end;
end; end;
finally finally
Utf8LFMStream.Free;
LFMSTream.Free; LFMSTream.Free;
DFMStream.Free; DFMStream.Free;
end; end;

View File

@ -528,7 +528,8 @@ procedure LRSObjectResToText(Input, Output: TStream;
var OriginalFormat: TLRSStreamOriginalFormat); var OriginalFormat: TLRSStreamOriginalFormat);
function TestFormStreamFormat(Stream: TStream): TLRSStreamOriginalFormat; function TestFormStreamFormat(Stream: TStream): TLRSStreamOriginalFormat;
procedure FormDataToText(FormStream, TextStream: TStream); procedure FormDataToText(FormStream, TextStream: TStream;
aFormat: TLRSStreamOriginalFormat = sofUnknown);
procedure DefineRectProperty(Filer: TFiler; const Name: string; procedure DefineRectProperty(Filer: TFiler; const Name: string;
ARect, DefaultRect: PRect); ARect, DefaultRect: PRect);
@ -3028,21 +3029,23 @@ begin
LRSObjectBinaryToText(Input, Output); LRSObjectBinaryToText(Input, Output);
end; end;
procedure FormDataToText(FormStream, TextStream: TStream); procedure FormDataToText(FormStream, TextStream: TStream; aFormat: TLRSStreamOriginalFormat);
begin begin
case TestFormStreamFormat(FormStream) of if aFormat = sofUnknown then
sofBinary: aFormat := TestFormStreamFormat(FormStream);
LRSObjectResourceToText(FormStream, TextStream); case aFormat of
sofBinary:
LRSObjectResourceToText(FormStream, TextStream);
sofText: sofText:
begin begin
if TextStream is TMemoryStream then if TextStream is TMemoryStream then
TMemoryStream(TextStream).SetSize(TextStream.Position+FormStream.Size); TMemoryStream(TextStream).SetSize(TextStream.Position+FormStream.Size);
TextStream.CopyFrom(FormStream,FormStream.Size); TextStream.CopyFrom(FormStream,FormStream.Size);
end; end;
else else
raise Exception.Create(rsInvalidFormObjectStream); raise Exception.Create(rsInvalidFormObjectStream);
end; end;
end; end;