IDE: removed broken .lrt file format support, we generate LRJ files instead now (in format identical to FPC emitted .rsj), based on patch by riderkick, bug #26553

git-svn-id: trunk@52679 -
This commit is contained in:
maxim 2016-07-13 23:23:45 +00:00
parent 95e8ab1cd8
commit a341cc7358
4 changed files with 153 additions and 51 deletions

View File

@ -235,7 +235,7 @@ begin
for i:=0 to Files.Count-1 do begin
RSTFilename:=RSTDirectory+Files[i];
Ext:=LowerCase(ExtractFileExt(RSTFilename));
if (Ext<>'.rst') and (Ext<>'.lrt') and (Ext<>'.rsj') then
if (Ext<>'.rst') and (Ext<>'.rsj') and (Ext<>'.lrj') then
continue;
if POFilename='' then
OutputFilename:=PODirectory+ChangeFileExt(Files[i],'.po')
@ -258,13 +258,13 @@ begin
end else begin
// there is already a source file for this .po file
//debugln(['ConvertRSTFiles found another source: ',RSTFilename]);
if (Ext='.rsj') or (Ext='.rst') then begin
if (Ext='.rsj') or (Ext='.rst') or (Ext='.lrj') then begin
// rsj are created by FPC 2.7.1+, rst by older => use only the newest
for j:=Item^.RSTFileList.Count-1 downto 0 do begin
OtherRSTFilename:=Item^.RSTFileList[j];
//debugln(['ConvertRSTFiles old: ',OtherRSTFilename]);
OtherExt:=LowerCase(ExtractFileExt(OtherRSTFilename));
if (OtherExt='.rsj') or (OtherExt='.rst') then begin
if (OtherExt='.rsj') or (OtherExt='.rst') or (OtherExt='.lrj') then begin
if FileAgeCached(RSTFilename)<=FileAgeCached(OtherRSTFilename) then
begin
// this one is older => skip
@ -376,11 +376,11 @@ begin
BasePOFile.ReadPOText(POBuf.Source);
BasePOFile.Tag:=1;
// Update po file with lrt or/and rst/rsj files
// Update po file with lrj or/and rst/rsj files
for i:=0 to SrcFiles.Count-1 do begin
Filename:=SrcFiles[i];
if CompareFileExt(Filename,'.lrt',false)=0 then
FileType:=stLrt
if CompareFileExt(Filename,'.lrj',false)=0 then
FileType:=stLrj
else if CompareFileExt(Filename,'.rst',false)=0 then
FileType:=stRst
else if CompareFileExt(Filename,'.rsj',false)=0 then

View File

@ -4138,7 +4138,7 @@ var
POFileAge: LongInt;
POFileAgeValid: Boolean;
POOutDir: String;
LRTFilename: String;
LRJFilename: String;
UnitOutputDir: String;
RSTFilename: String;
RSJFilename: String;
@ -4188,11 +4188,11 @@ begin
if (AProject.MainFilename<>CurFilename)
and (not FilenameIsPascalUnit(CurFilename)) then
continue;
// check .lrt file
LRTFilename:=ChangeFileExt(CurFilename,'.lrt');
if FileExistsCached(LRTFilename)
and ((not POFileAgeValid) or (FileAgeCached(LRTFilename)>POFileAge)) then
Files[LRTFilename]:=nil;
// check .lrj file
LRJFilename:=ChangeFileExt(CurFilename,'.lrj');
if FileExistsCached(LRJFilename)
and ((not POFileAgeValid) or (FileAgeCached(LRJFilename)>POFileAge)) then
Files[LRJFilename]:=nil;
// check .rst/.rsj file
RSTFilename:=ChangeFileExt(CurFilename,'.rst');
RSJFilename:=ChangeFileExt(CurFilename,'.rsj');

View File

@ -47,7 +47,7 @@ uses
CodeToolsStructs, ConvCodeTool, CodeCache, CodeTree, FindDeclarationTool,
BasicCodeTools, SynEdit, UnitResources, IDEExternToolIntf, ObjectInspector,
PublishModule, etMessagesWnd,
FormEditingIntf;
FormEditingIntf, fpjson;
type
@ -4782,34 +4782,146 @@ begin
end;
type
TLRTGrubber = class(TObject)
TTranslateStringItem = record
Name: String;
Value: String;
end;
TTranslateStrings = class
private
FGrubbed: TStrings;
FList: array of TTranslateStringItem;
function CalcHash(const S: string): Cardinal;
function GetSourceBytes(const S: string): string;
function GetValue(const S: string): string;
public
destructor Destroy; override;
procedure Add(const AName, AValue: String);
function Count: Integer;
function Text: String;
end;
TLRJGrubber = class(TObject)
private
FGrubbed: TTranslateStrings;
FWriter: TWriter;
public
constructor Create(TheWriter: TWriter);
destructor Destroy; override;
procedure Grub(Sender: TObject; const Instance: TPersistent;
PropInfo: PPropInfo; var Content: string);
property Grubbed: TStrings read FGrubbed;
property Grubbed: TTranslateStrings read FGrubbed;
property Writer: TWriter read FWriter write FWriter;
end;
constructor TLRTGrubber.Create(TheWriter: TWriter);
function TTranslateStrings.CalcHash(const S: string): Cardinal;
var
g: Cardinal;
i: Longint;
begin
Result:=0;
for i:=1 to Length(s) do
begin
Result:=Result shl 4;
inc(Result,Ord(S[i]));
g:=Result and ($f shl 28);
if g<>0 then
begin
Result:=Result xor (g shr 24);
Result:=Result xor g;
end;
end;
If Result=0 then
Result:=$ffffffff;
end;
function TTranslateStrings.GetSourceBytes(const S: string): string;
var
i, l: Integer;
begin
Result:='';
l:=Length(S);
for i:=1 to l do
begin
Result:=Result+IntToStr(Ord(S[i]));
if i<>l then
Result:=Result+',';
end;
end;
function TTranslateStrings.GetValue(const S: string): string;
var
i, l: Integer;
jsonstr: string;
begin
Result:='';
jsonstr:=StringToJSONString(S);
l:=Length(jsonstr);
for i:=1 to l do
begin
if (Ord(jsonstr[i])<32) or (Ord(jsonstr[i])>=127) then
Result:=Result+'\u'+HexStr(Ord(jsonstr[i]), 4)
else
Result:=Result+jsonstr[i];
end;
end;
destructor TTranslateStrings.Destroy;
begin
SetLength(FList,0);
end;
procedure TTranslateStrings.Add(const AName, AValue: String);
begin
SetLength(FList,Length(FList)+1);
with FList[High(FList)] do
begin
Name:=AName;
Value:=AValue;
end;
end;
function TTranslateStrings.Count: Integer;
begin
Result:=Length(FList);
end;
function TTranslateStrings.Text: String;
var
i: Integer;
R: TTranslateStringItem;
begin
Result:='';
if Length(FList)=0 then Exit;
Result:='{"version":1,"strings":['+LineEnding;
for i:=Low(FList) to High(FList) do
begin
R:=TTranslateStringItem(FList[i]);
Result:=Result+'{"hash":'+IntToStr(CalcHash(R.Value))+',"name":"'+R.Name+
'","sourcebytes":['+GetSourceBytes(R.Value)+
'],"value":"'+GetValue(R.Value)+'"}';
if i<High(FList) then
Result:=Result+','+LineEnding
else
Result:=Result+LineEnding;
end;
Result:=Result+']}'+LineEnding;
end;
constructor TLRJGrubber.Create(TheWriter: TWriter);
begin
inherited Create;
FGrubbed:=TStringList.Create;
FGrubbed:=TTranslateStrings.Create;
FWriter:=TheWriter;
FWriter.OnWriteStringProperty:=@Grub;
end;
destructor TLRTGrubber.Destroy;
destructor TLRJGrubber.Destroy;
begin
FGrubbed.Free;
inherited Destroy;
end;
procedure TLRTGrubber.Grub(Sender: TObject; const Instance: TPersistent;
procedure TLRJGrubber.Grub(Sender: TObject; const Instance: TPersistent;
PropInfo: PPropInfo; var Content: string);
var
LRSWriter: TLRSObjectWriter;
@ -4824,8 +4936,7 @@ begin
end else begin
Path:=Instance.ClassName+'.'+PropInfo^.Name;
end;
FGrubbed.Add(Uppercase(Path)+'='+Content);
//DebugLn(['TLRTGrubber.Grub "',FGrubbed[FGrubbed.Count-1],'"']);
FGrubbed.Add(LowerCase(Path),Content);
end;
function TLazSourceFileManager.SaveUnitComponent(AnUnitInfo: TUnitInfo;
@ -4869,8 +4980,8 @@ var
ACaption, AText: string;
CompResourceCode, LFMFilename, TestFilename: string;
ADesigner: TIDesigner;
Grubber: TLRTGrubber;
LRTFilename: String;
Grubber: TLRJGrubber;
LRJFilename: String;
AncestorUnit: TUnitInfo;
Ancestor: TComponent;
HasI18N: Boolean;
@ -4929,10 +5040,10 @@ begin
try
BinCompStream.Position:=0;
Writer:=AnUnitInfo.UnitResourceFileformat.CreateWriter(BinCompStream,DestroyDriver);
// used to save lrt files
// used to save lrj files
HasI18N:=IsI18NEnabled(UnitOwners);
if HasI18N then
Grubber:=TLRTGrubber.Create(Writer);
Grubber:=TLRJGrubber.Create(Writer);
Writer.OnWriteMethodProperty:=@FormEditor1.WriteMethodPropertyEvent;
//DebugLn(['TLazSourceFileManager.SaveUnitComponent AncestorInstance=',dbgsName(AncestorInstance)]);
Writer.OnFindAncestor:=@FormEditor1.WriterFindAncestor;
@ -5101,15 +5212,15 @@ begin
// Now the most important file (.lfm) is saved.
// Now save the secondary files
// save the .lrt file containing the list of all translatable strings of
// save the .lrj file containing the list of all translatable strings of
// the component
if ComponentSavingOk
and (Grubber<>nil) and (Grubber.Grubbed.Count>0)
and (not (sfSaveToTestDir in Flags))
and (not AnUnitInfo.IsVirtual) then begin
LRTFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lrt');
DebugLn(['TLazSourceFileManager.SaveUnitComponent save lrt: ',LRTFilename]);
Result:=SaveStringToFile(LRTFilename,Grubber.Grubbed.Text,
LRJFilename:=ChangeFileExt(AnUnitInfo.Filename,'.lrj');
DebugLn(['TLazSourceFileManager.SaveUnitComponent save lrj: ',LRJFilename]);
Result:=SaveStringToFile(LRJFilename,Grubber.Grubbed.Text,
[mbIgnore,mbAbort],AnUnitInfo.Filename);
if (Result<>mrOk) and (Result<>mrIgnore) then exit;
end;

View File

@ -92,7 +92,7 @@ uses
type
TStringsType = (
stLrt, // Lazarus resource string table
stLrj, // Lazarus resource string table in JSON format
stRst, // FPC resource string table (before FPC 2.7.1)
stRsj // FPC resource string table in JSON format (since FPC 2.7.1)
);
@ -533,10 +533,10 @@ begin
BasePOFile := TPOFile.Create;
BasePOFile.Tag:=1;
// Update po file with lrt,rst/rsj of RSTFiles
// Update po file with lrj, rst/rsj of RSTFiles
for i:=0 to RSTFiles.Count-1 do begin
Filename:=RSTFiles[i];
if (CompareFileExt(Filename,'.lrt')=0) or
if (CompareFileExt(Filename,'.lrj')=0) or
(CompareFileExt(Filename,'.rst')=0) or
(CompareFileExt(Filename,'.rsj')=0) then
try
@ -545,14 +545,13 @@ begin
InputLines.Clear;
InputLines.LoadFromFile(FileName);
if CompareFileExt(Filename,'.lrt')=0 then
BasePOFile.UpdateStrings(InputLines, stLrt)
if CompareFileExt(Filename,'.lrj')=0 then
BasePOFile.UpdateStrings(InputLines, stLrj)
else
if CompareFileExt(Filename,'.rsj')=0 then
BasePOFile.UpdateStrings(InputLines, stRsj)
else
BasePOFile.UpdateStrings(InputLines, stRst);
if CompareFileExt(Filename,'.rsj')=0 then
BasePOFile.UpdateStrings(InputLines, stRsj)
else
BasePOFile.UpdateStrings(InputLines, stRst);
except
on Ex: Exception do begin
E := EPOFileError.Create(Ex.Message);
@ -1406,8 +1405,8 @@ var
begin
ClearModuleList;
UntagAll;
if SType = stRsj then
// .rsj file
if (SType = stLrj) or (SType = stRsj) then
// .lrj/.rsj file
UpdateFromRSJ
else
begin
@ -1424,15 +1423,7 @@ begin
if n=0 then
// empty line
else
if SType=stLrt then begin
// .lrt file
p:=Pos('=',Line);
Value :=copy(Line,p+1,n-p); //if p=0, that's OK, all the string
Identifier:=copy(Line,1,p-1);
UpdateItem(Identifier, Value);
end else begin
else begin
// .rst file
if Line[1]='#' then begin
// rst file: comment