1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
{
Author: Mattias Gaertner
Abstract:
Scan all FPC error message files (fpc/compiler/msg/error*.msg) and compare
them with the original file (english, errore.msg).
}
program scanfpcerrormsgfiles;
{$mode objfpc}{$H+}
uses
sysutils,
// LazUtils
LazFileUtils, AvgLvlTree,
// CodeTools
CodeToolsFPCMsgs, CodeToolsStructs;
procedure WriteUsage;
begin
writeln('Usage:');
writeln;
writeln(' ',ParamStr(0),' <fpcsrcdirectory>/compiler/msg [-v]');
writeln('');
writeln(' -v - verbose output, showing exactly what messages are missing and/or mismatched');
end;
type
THaveParams = array[0..9] of boolean;
procedure GetHaveParams(Pattern: string; out Params: THaveParams);
var
i: integer;
p: PChar;
begin
for i:=0 to 9 do
Params[i]:=false;
p:=PChar(Pattern);
repeat
case p^ of
#0: break;
'$':
if p[1] in ['0'..'9'] then begin
inc(p);
Params[ord(p^)-ord('0')]:=true;
end;
end;
inc(p);
until false;
end;
procedure ScanDir(Dir: string; ShowVerbose: Boolean = false );
var
Info: TSearchRec;
Filename: TFilename;
aFile: TFPCMsgFile;
FPCMsgFileList: TFilenameToPointerTree;
EnglishFile: TFPCMsgFile;
S2PItem: PStringToPointerTreeItem;
i: Integer;
EnglishMsg: TFPCMsgItem;
TranslatedMsg: TFPCMsgItem;
GoodCount: Integer;
MissingCount: Integer;
MismatchCount: Integer;
EnglishParams, TranslatedParams: THaveParams;
k: integer;
msd: String;
begin
FPCMsgFileList:=TFilenameToPointerTree.Create(false);
FPCMsgFileList.FreeValues:=true;
try
// search *.msg files
Dir:=AppendPathDelim(Dir);
if not FindFirstUTF8(Dir+'*.msg',faAnyFile,Info)=0 then begin
writeln('Error: no *.msg file found in ',Dir);
Halt(3);
end;
// load all *.msg files
EnglishFile:=nil;
repeat
Filename:=Info.Name;
if (Filename='') or (Filename='.') or (Filename='..') then continue;
if faDirectory and Info.Attr>0 then continue;
//writeln('loading "',Filename,'" ...');
aFile:=TFPCMsgFile.Create;
aFile.LoadFromFile(Dir+Filename);
if Filename='errore.msg' then
EnglishFile:=aFile
else
FPCMsgFileList[Filename]:=aFile;
until FindNextUTF8(Info)<>0;
FindCloseUTF8(Info);
if EnglishFile=nil then begin
writeln('Error: missing file errore.msg');
Halt(4);
end;
// compare each file with errore
writeln('errore.msg Count=',EnglishFile.Count);
for S2PItem in FPCMsgFileList do begin
Filename:=S2PItem^.Name;
aFile:=TFPCMsgFile(S2PItem^.Value);
GoodCount:=0;
MissingCount:=0;
MismatchCount:=0; // id is there, but $ parameters don't fit
msd:='';
for i:=0 to EnglishFile.Count-1 do begin
EnglishMsg:=EnglishFile[i];
TranslatedMsg:=aFile.FindWithID(EnglishMsg.ID);
if TranslatedMsg=nil then begin
inc(MissingCount);
if ShowVerbose then msd:=msd+' missing: '+IntToStr(EnglishMsg.ID)+' '+EnglishMsg.Pattern+LineEnding;
end else begin
GetHaveParams(EnglishMsg.Pattern,EnglishParams);
GetHaveParams(TranslatedMsg.Pattern,TranslatedParams);
k:=9;
while (k>=0) and (EnglishParams[k]=TranslatedParams[k]) do
dec(k);
if k<0 then
inc(GoodCount)
else begin
//writeln('Mismatch in ',Filename,' English="',EnglishMsg.Pattern,'" Translated="',TranslatedMsg.Pattern,'"');
inc(MismatchCount);
if ShowVerbose then begin
msd:=msd+' mismatch: '+LineEnding;
msd:=msd+' eng: '+EnglishMsg.Pattern+LineEnding;
msd:=msd+' trn: '+TranslatedMsg.Pattern+LineEnding;
end;
end;
end;
end;
writeln(Filename,' Count=',aFile.Count,' Good=',GoodCount,' Missing=',MissingCount,' Mismatch=',MismatchCount);
if ShowVerbose then write(msd);
end;
finally
FPCMsgFileList.Free;
end;
end;
var
MsgDir: String;
ShowVerbose: Boolean = false;
begin
if ParamCount<1 then begin
WriteUsage;
Halt(1);
end;
MsgDir:=CleanAndExpandDirectory(ParamStr(1));
if not DirPathExists(MsgDir) then begin
writeln('Error: directory not found: ',MsgDir);
Halt(2);
end;
ShowVerbose:=(ParamCount>1) and (LowerCase(ParamStr(2))='-v');
ScanDir(MsgDir, ShowVerbose);
end.
|