msgdif.pp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. {
  2. $Id$
  3. This program is part of the Free Pascal run time library.
  4. Copyright (c) 1998-2000 by Peter Vreman
  5. Show the differences between two .msg files
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. Program messagedif;
  13. Type
  14. TEnum = String;
  15. TText = String;
  16. PMsg = ^TMsg;
  17. TMsg = Record
  18. Line : Longint;
  19. enum : TEnum;
  20. text : TText;
  21. Next,Prev : PMsg;
  22. FileNext,
  23. Equivalent : PMsg;
  24. end;
  25. Var
  26. OrgFileName,DiffFileName : String;
  27. OrgRoot,DiffRoot : PMsg;
  28. OrgFirst,DiffFirst : PMsg;
  29. Last : PMsg;
  30. Function NewMsg (Var RM : PMsg; L : Longint; Const E : TEnum;Const T : TText) : PMsg;
  31. Var
  32. P,R : PMsg;
  33. begin
  34. New(P);
  35. with P^ do
  36. begin
  37. Line:=L;
  38. Text:=T;
  39. enum:=E;
  40. next:=Nil;
  41. prev:=Nil;
  42. filenext:=nil;
  43. equivalent:=nil;
  44. if assigned(last) then
  45. last^.FileNext:=P;
  46. last:=P;
  47. end;
  48. R:=RM;
  49. While (R<>Nil) and (UpCase(R^.enum)>UpCase(P^.Enum)) do
  50. begin
  51. P^.Prev:=R;
  52. R:=R^.next;
  53. end;
  54. if assigned(R) and (UpCase(R^.Enum)=UpCase(P^.Enum)) then
  55. Writeln('Error ',R^.Enum,' duplicate');
  56. P^.Next:=R;
  57. If R<>Nil then
  58. R^.Prev:=P;
  59. If P^.Prev<>Nil then
  60. P^.Prev^.Next:=P
  61. else
  62. RM:=P;
  63. NewMsg:=P;
  64. end;
  65. Procedure PrintList(const name : string;R : PMsg);
  66. var
  67. P : PMsg;
  68. f : text;
  69. begin
  70. P:=R;
  71. Assign(f,name);
  72. Rewrite(f);
  73. while assigned(P) do
  74. begin
  75. Writeln(f,UpCase(P^.Enum));
  76. P:=P^.Next;
  77. end;
  78. Close(f);
  79. end;
  80. Procedure Usage;
  81. begin
  82. Writeln ('Usage : msgdif orgfile diffile');
  83. halt(1)
  84. end;
  85. Procedure ProcessOptions;
  86. begin
  87. If ParamCount<>2 then
  88. Usage;
  89. OrgfileName:=Paramstr(1);
  90. DiffFileName:=Paramstr(2);
  91. end;
  92. Procedure ProcessFile (FileName : String; Var Root,First : PMsg);
  93. Var F : Text;
  94. S : String;
  95. J,LineNo,Count : Longint;
  96. begin
  97. Assign(F,FileName);
  98. Reset(F);
  99. Write ('Processing: ',Filename,'...');
  100. LineNo:=0;
  101. Count:=0;
  102. Root:=Nil;
  103. First:=nil;
  104. Last:=nil;
  105. While not eof(f) do
  106. begin
  107. Readln(F,S);
  108. Inc(LineNo);
  109. If (length(S)>0) and Not (S[1] in ['%','#']) Then
  110. begin
  111. J:=Pos('=',S);
  112. If j<1 then
  113. writeln (Filename,'(',LineNo,') : Invalid entry')
  114. else
  115. begin
  116. NewMsg(Root,LineNo,Copy(S,1,J-1),Copy(S,j+1,255));
  117. if First=nil then
  118. First:=Root;
  119. Inc(Count);
  120. end;
  121. end;
  122. end;
  123. Writeln (' Done. Read ',LineNo,' lines, got ',Count,' constants.');
  124. Close(f);
  125. end;
  126. Procedure ShowDiff (POrg,PDiff : PMsg);
  127. Var P : PMsg;
  128. count,orgcount,diffcount : longint;
  129. Procedure NotFound (Org : Boolean; P : PMsg);
  130. begin
  131. With P^ do
  132. If Org Then
  133. Writeln ('Not found in ',DiffFileName,' : ',Enum,' ',OrgFileName,'(',Line,')')
  134. else
  135. Writeln ('Extra in ',DiffFileName,'(',line,') : ',enum);
  136. if org then
  137. inc(orgcount)
  138. else
  139. inc(diffcount);
  140. end;
  141. begin
  142. orgcount:=0;
  143. diffcount:=0;
  144. count:=0;
  145. While (Porg<>Nil) and (PDiff<>Nil) do
  146. begin
  147. // Writeln (POrg^.enum,'<=>',PDiff^.Enum);
  148. If UpCase(Porg^.Enum)>UpCase(PDiff^.Enum) then
  149. begin
  150. NotFound (True,Porg);
  151. POrg:=POrg^.Next
  152. end
  153. else If UpCase(POrg^.enum)=UpCase(PDiff^.Enum) then
  154. begin
  155. inc(count);
  156. POrg^.Equivalent:=PDiff;
  157. PDiff^.Equivalent:=POrg;
  158. POrg:=POrg^.Next;
  159. PDiff:=PDiff^.Next;
  160. end
  161. else
  162. begin
  163. NotFound (False,PDiff);
  164. PDiff:=PDiff^.Next
  165. end;
  166. end;
  167. While POrg<>Nil do
  168. begin
  169. NotFound(True,Porg);
  170. POrg:=pOrg^.Next;
  171. end;
  172. While PDiff<>Nil do
  173. begin
  174. NotFound(False,PDiff);
  175. PDiff:=PDiff^.Next;
  176. end;
  177. Writeln(count,' messages found in common to both files');
  178. Writeln(orgcount,' messages only in ',OrgFileName);
  179. Writeln(diffcount,' messages only in ',DiffFileName);
  180. end;
  181. procedure WriteReorderedFile(FileName : string;orgnext,diffnext : PMsg);
  182. var t,t2,t3 : text;
  183. i,i2,i3,ntcount : longint;
  184. s,s3 : string;
  185. CurrentMsg : PMsg;
  186. nextdiffkept : pmsg;
  187. begin
  188. ntcount:=0;
  189. Assign(t,FileName);
  190. Rewrite(t);
  191. Writeln(t,'%%% Reordering of ',DiffFileName,' respective to ',OrgFileName);
  192. Writeln(t,'%%% Contains all comments from ',DiffFileName);
  193. Assign(t2,DiffFileName);
  194. Reset(t2);
  195. Assign(t3,OrgFileName);
  196. Reset(t3);
  197. i:=2;i2:=0;i3:=0;
  198. s:='';s3:='';
  199. nextdiffkept:=diffnext;
  200. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  201. nextdiffkept:=nextdiffkept^.filenext;
  202. While not eof(t2) do
  203. begin
  204. while assigned(orgnext) and assigned(nextdiffkept) and
  205. (UpCase(orgnext^.enum)<>UpCase(nextdiffkept^.enum)) and not(eof(t3)) do
  206. begin
  207. if not assigned(orgnext^.equivalent) then
  208. begin
  209. { Insert a new error msg with the english comments }
  210. while i3<orgnext^.line do
  211. begin
  212. readln(t3,s3);
  213. inc(i3);
  214. end;
  215. writeln(t,s3);
  216. inc(i);
  217. readln(t3,s3);
  218. inc(i3);
  219. while (s3<>'') and (s3[1] in ['#','%']) do
  220. begin
  221. writeln(t,s3);
  222. inc(i);
  223. readln(t3,s3);
  224. inc(i3);
  225. end;
  226. Writeln('New error ',orgnext^.enum,' added');
  227. end;
  228. orgnext:=orgnext^.filenext;
  229. end;
  230. if s='' then
  231. begin
  232. readln(t2,s);
  233. inc(i2);
  234. end;
  235. if assigned(orgnext) and
  236. assigned(diffnext) and (i2=diffnext^.line) then
  237. begin
  238. if assigned(diffnext^.Equivalent) then
  239. begin
  240. if diffnext^.equivalent<>orgnext then
  241. Writeln('Problem inside WriteReorderedFile');
  242. Writeln(t,s);
  243. if diffnext^.Equivalent^.Text=diffnext^.Text then
  244. begin
  245. Writeln(diffnext^.Enum,': ',DiffFileName,'(',i2,') not translated');
  246. inc(ntcount);
  247. end;
  248. s:='';
  249. inc(i);
  250. readln(t2,s);
  251. inc(i2);
  252. while (s<>'') and (s[1] in ['#','%']) do
  253. begin
  254. writeln(t,s);
  255. inc(i);
  256. readln(t2,s);
  257. inc(i2);
  258. end;
  259. Diffnext:=Diffnext^.FileNext;
  260. nextdiffkept:=diffnext;
  261. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  262. nextdiffkept:=nextdiffkept^.filenext;
  263. Orgnext:=orgnext^.filenext;
  264. end
  265. else
  266. begin
  267. { Skip removed enum in errore.msg}
  268. { maybe a renaming of an enum !}
  269. Writeln(diffnext^.enum,' commented out');
  270. Writeln(t,'%%% ',s);
  271. inc(i);
  272. readln(t2,s);
  273. inc(i2);
  274. Diffnext:=Diffnext^.FileNext;
  275. nextdiffkept:=diffnext;
  276. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  277. nextdiffkept:=nextdiffkept^.filenext;
  278. if assigned(diffnext) then
  279. while (i2<diffnext^.line) do
  280. begin
  281. writeln(t,'%%% ',s);
  282. inc(i);
  283. readln(t2,s);
  284. inc(i2);
  285. end;
  286. end;
  287. end
  288. else
  289. begin
  290. writeln(t,s);
  291. inc(i);
  292. s:='';
  293. end;
  294. end;
  295. Close(t);
  296. Close(t2);
  297. Close(t3);
  298. Writeln(ntcount,' not translated items found');
  299. end;
  300. begin
  301. ProcessOptions;
  302. ProcessFile(OrgFileName,orgroot,orgfirst);
  303. ProcessFile(DiffFileName,diffRoot,difffirst);
  304. PrintList('Org.lst',OrgRoot);
  305. PrintList('Diff.lst',DiffRoot);
  306. ShowDiff (OrgRoot,DiffRoot);
  307. WriteReorderedFile('new.msg',orgfirst,difffirst);
  308. end.
  309. {
  310. $Log$
  311. Revision 1.10 2000-05-11 13:37:37 pierre
  312. * ordering bugs fixed
  313. Revision 1.9 2000/02/09 13:23:11 peter
  314. * log truncated
  315. Revision 1.8 2000/01/07 01:15:01 peter
  316. * updated copyright to 2000
  317. }