File: scanfpcerrormsgfiles.lpr

package info (click to toggle)
lazarus 2.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 214,460 kB
  • sloc: pascal: 1,862,622; xml: 265,709; cpp: 56,595; sh: 3,008; java: 609; makefile: 535; perl: 297; sql: 222; ansic: 137
file content (160 lines) | stat: -rw-r--r-- 4,399 bytes parent folder | download | duplicates (6)
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.