msgdif.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. {
  2. $Id$
  3. This program is part of the Free Pascal run time library.
  4. Copyright (c) 1998 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. suppress : boolean;
  20. enum : TEnum;
  21. text : TText;
  22. Next,Prev : PMsg;
  23. FileNext,
  24. Equivalent : PMsg;
  25. end;
  26. Var
  27. OrgFileName,DiffFileName : String;
  28. OrgRoot,DiffRoot : PMsg;
  29. OrgFirst,DiffFirst : PMsg;
  30. Last : PMsg;
  31. Function NewMsg (Var RM : PMsg; L : Longint; Const E : TEnum;Const T : TText) : PMsg;
  32. Var
  33. P,R : PMsg;
  34. begin
  35. New(P);
  36. with P^ do
  37. begin
  38. Line:=L;
  39. suppress:=false;
  40. Text:=T;
  41. enum:=E;
  42. next:=Nil;
  43. prev:=Nil;
  44. filenext:=nil;
  45. equivalent:=nil;
  46. if assigned(last) then
  47. last^.FileNext:=P;
  48. last:=P;
  49. end;
  50. R:=RM;
  51. While (R<>Nil) and (R^.enum<P^.Enum) do
  52. begin
  53. P^.Prev:=R;
  54. R:=R^.next;
  55. end;
  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 Usage;
  66. begin
  67. Writeln ('Usage : msgdif orgfile diffile');
  68. halt(1)
  69. end;
  70. Procedure ProcessOptions;
  71. begin
  72. If ParamCount<>2 then
  73. Usage;
  74. OrgfileName:=Paramstr(1);
  75. DiffFileName:=Paramstr(2);
  76. end;
  77. Procedure ProcessFile (FileName : String; Var Root,First : PMsg);
  78. Var F : Text;
  79. S : String;
  80. J,LineNo,Count : Longint;
  81. begin
  82. Assign(F,FileName);
  83. Reset(F);
  84. Write ('Processing: ',Filename,'...');
  85. LineNo:=0;
  86. Count:=0;
  87. Root:=Nil;
  88. First:=nil;
  89. Last:=nil;
  90. While not eof(f) do
  91. begin
  92. Readln(F,S);
  93. Inc(LineNo);
  94. If (length(S)>0) and Not (S[1] in ['%','#']) Then
  95. begin
  96. J:=Pos('=',S);
  97. If j<1 then
  98. writeln (Filename,'(',LineNo,') : Invalid entry')
  99. else
  100. begin
  101. NewMsg(Root,LineNo,Copy(S,1,J-1),Copy(S,j+1,255));
  102. if First=nil then
  103. First:=Root;
  104. Inc(Count);
  105. end;
  106. end;
  107. end;
  108. Writeln (' Done. Read ',LineNo,' lines, got ',Count,' constants.');
  109. Close(f);
  110. end;
  111. Procedure ShowDiff (POrg,PDiff : PMsg);
  112. Procedure NotFound (Org : Boolean; P : PMsg);
  113. begin
  114. With P^ do
  115. If Org Then
  116. Writeln ('Not found in ',DiffFileName,' : ',Enum,' ',OrgFileName,'(',Line,')')
  117. else
  118. Writeln ('Extra in ',DiffFileName,'(',line,') : ',enum)
  119. end;
  120. Var P : PMsg;
  121. count : longint;
  122. begin
  123. count:=0;
  124. While (Porg<>Nil) and (PDiff<>Nil) do
  125. begin
  126. // Writeln (POrg^.enum,'<=>',PDiff^.Enum);
  127. If Porg^.Enum<PDiff^.Enum then
  128. begin
  129. NotFound (True,Porg);
  130. POrg:=POrg^.Next
  131. end
  132. else If POrg^.enum=PDiff^.Enum then
  133. begin
  134. inc(count);
  135. POrg^.Equivalent:=PDiff;
  136. PDiff^.Equivalent:=POrg;
  137. POrg:=POrg^.Next;
  138. PDiff:=PDiff^.Next;
  139. end
  140. else
  141. begin
  142. NotFound (False,PDiff);
  143. PDiff:=PDiff^.Next
  144. end;
  145. end;
  146. While POrg<>Nil do
  147. begin
  148. NotFound(True,Porg);
  149. POrg:=pOrg^.Next;
  150. end;
  151. While PDiff<>Nil do
  152. begin
  153. NotFound(False,PDiff);
  154. PDiff:=PDiff^.Next;
  155. end;
  156. Writeln(count,' messages found in both files');
  157. end;
  158. procedure WriteReorderedFile(FileName : string;orgnext,diffnext : PMsg);
  159. var t,t2,t3 : text;
  160. i,i2,i3 : longint;
  161. s,s3 : string;
  162. CurrentMsg : PMsg;
  163. nextdiffkept : pmsg;
  164. begin
  165. Assign(t,FileName);
  166. Rewrite(t);
  167. Writeln(t,'%%% Reordering of ',DiffFileName,' respective to ',OrgFileName);
  168. Writeln(t,'%%% Contains all comments from ',DiffFileName);
  169. Assign(t2,DiffFileName);
  170. Reset(t2);
  171. Assign(t3,OrgFileName);
  172. Reset(t3);
  173. i:=2;i2:=0;i3:=0;
  174. s:='';s3:='';
  175. nextdiffkept:=diffnext;
  176. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  177. nextdiffkept:=nextdiffkept^.filenext;
  178. While not eof(t2) do
  179. begin
  180. while assigned(orgnext) and assigned(nextdiffkept) and
  181. (orgnext^.enum<>nextdiffkept^.enum) and not(eof(t3)) do
  182. begin
  183. { Insert a new error msg with the english comments }
  184. while i3<orgnext^.line do
  185. begin
  186. readln(t3,s3);
  187. inc(i3);
  188. end;
  189. write(t,orgnext^.enum,'=');
  190. if assigned(orgnext^.equivalent) then
  191. begin
  192. writeln(t,orgnext^.equivalent^.text);
  193. if assigned(orgnext^.equivalent^.filenext) and
  194. (orgnext^.equivalent^.line+1=orgnext^.equivalent^.filenext^.line) then
  195. orgnext^.equivalent^.suppress:=true;
  196. end
  197. else
  198. writeln(t,orgnext^.text);
  199. inc(i);
  200. readln(t3,s3);
  201. inc(i3);
  202. while (s3<>'') and (s3[1] in ['#','%']) do
  203. begin
  204. writeln(t,s3);
  205. inc(i);
  206. readln(t3,s3);
  207. inc(i3);
  208. end;
  209. Writeln('New error ',orgnext^.enum,' added');
  210. orgnext:=orgnext^.filenext;
  211. end;
  212. if s='' then
  213. begin
  214. readln(t2,s);
  215. inc(i2);
  216. end;
  217. if assigned(orgnext) and
  218. assigned(diffnext) and (i2=diffnext^.line) then
  219. begin
  220. if assigned(diffnext^.Equivalent) then
  221. begin
  222. if (diffnext^.equivalent<>orgnext) and
  223. not(diffnext^.suppress) then
  224. Writeln('Problem inside WriteReorderedFile');
  225. Writeln(t,s);
  226. s:='';
  227. inc(i);
  228. readln(t2,s);
  229. inc(i2);
  230. while (s<>'') and (s[1] in ['#','%']) do
  231. begin
  232. writeln(t,s);
  233. inc(i);
  234. readln(t2,s);
  235. inc(i2);
  236. end;
  237. if diffnext^.Equivalent^.Text=diffnext^.Text then
  238. Writeln(diffnext^.Enum,': ',DiffFileName,'(',i2,') not translated');
  239. Diffnext:=Diffnext^.FileNext;
  240. while assigned(diffnext) and (diffnext^.suppress) do
  241. diffnext:=diffnext^.filenext;
  242. nextdiffkept:=diffnext;
  243. while assigned(nextdiffkept) and
  244. ((nextdiffkept^.equivalent=nil) or
  245. (nextdiffkept^.suppress)) do
  246. nextdiffkept:=nextdiffkept^.filenext;
  247. Orgnext:=orgnext^.filenext;
  248. end
  249. else
  250. begin
  251. { Skip removed enum in errore.msg}
  252. { maybe a renaming of an enum !}
  253. Writeln(diffnext^.enum,' commented out');
  254. Writeln(t,'%%% ',s);
  255. inc(i);
  256. readln(t2,s);
  257. inc(i2);
  258. Diffnext:=Diffnext^.FileNext;
  259. nextdiffkept:=diffnext;
  260. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  261. nextdiffkept:=nextdiffkept^.filenext;
  262. if assigned(diffnext) then
  263. while (i2<diffnext^.line) do
  264. begin
  265. writeln(t,'%%% ',s);
  266. inc(i);
  267. readln(t2,s);
  268. inc(i2);
  269. end;
  270. end;
  271. end
  272. else
  273. begin
  274. writeln(t,s);
  275. inc(i);
  276. s:='';
  277. end;
  278. end;
  279. Close(t);
  280. Close(t2);
  281. Close(t3);
  282. end;
  283. procedure WriteReorderedFile2(FileName : string;orgnext,diffnext : PMsg);
  284. var t,t2,t3 : text;
  285. i,i2,i3 : longint;
  286. s,s3 : string;
  287. CurrentMsg : PMsg;
  288. nextdiffkept : pmsg;
  289. begin
  290. Assign(t,FileName);
  291. Rewrite(t);
  292. Writeln(t,'%%% Reordering of ',DiffFileName,' respective to ',OrgFileName);
  293. Writeln(t,'%%% Contains all comments from ',DiffFileName);
  294. Assign(t2,DiffFileName);
  295. Reset(t2);
  296. Assign(t3,OrgFileName);
  297. Reset(t3);
  298. i:=2;i2:=0;i3:=0;
  299. s:='';s3:='';
  300. nextdiffkept:=diffnext;
  301. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  302. nextdiffkept:=nextdiffkept^.filenext;
  303. While not eof(t2) do
  304. begin
  305. while assigned(orgnext) and not(eof(t3)) do
  306. begin
  307. { Insert a new error msg with the english comments }
  308. while i3<orgnext^.line do
  309. begin
  310. readln(t3,s3);
  311. inc(i3);
  312. if i3<orgnext^.line then
  313. begin
  314. writeln(t,s3);
  315. inc(i);
  316. end;
  317. end;
  318. write(t,orgnext^.enum,'=');
  319. if assigned(orgnext^.equivalent) then
  320. begin
  321. writeln(t,orgnext^.equivalent^.text);
  322. if assigned(orgnext^.equivalent^.filenext) and
  323. (orgnext^.equivalent^.line+1=orgnext^.equivalent^.filenext^.line) then
  324. orgnext^.equivalent^.suppress:=true;
  325. end
  326. else
  327. writeln(t,orgnext^.text);
  328. inc(i);
  329. readln(t3,s3);
  330. inc(i3);
  331. while (s3<>'') and (s3[1] in ['#','%']) do
  332. begin
  333. writeln(t,s3);
  334. inc(i);
  335. readln(t3,s3);
  336. inc(i3);
  337. end;
  338. Writeln('New error ',orgnext^.enum,' added');
  339. orgnext:=orgnext^.filenext;
  340. end;
  341. if s='' then
  342. begin
  343. readln(t2,s);
  344. inc(i2);
  345. end;
  346. if assigned(orgnext) and
  347. assigned(diffnext) and (i2=diffnext^.line) then
  348. begin
  349. if assigned(diffnext^.Equivalent) then
  350. begin
  351. if (diffnext^.equivalent<>orgnext) and
  352. not(diffnext^.suppress) then
  353. Writeln('Problem inside WriteReorderedFile');
  354. Writeln(t,s);
  355. s:='';
  356. inc(i);
  357. readln(t2,s);
  358. inc(i2);
  359. while (s<>'') and (s[1] in ['#','%']) do
  360. begin
  361. writeln(t,s);
  362. inc(i);
  363. readln(t2,s);
  364. inc(i2);
  365. end;
  366. if diffnext^.Equivalent^.Text=diffnext^.Text then
  367. Writeln(diffnext^.Enum,': ',DiffFileName,'(',i2,') not translated');
  368. Diffnext:=Diffnext^.FileNext;
  369. while assigned(diffnext) and (diffnext^.suppress) do
  370. diffnext:=diffnext^.filenext;
  371. nextdiffkept:=diffnext;
  372. while assigned(nextdiffkept) and
  373. ((nextdiffkept^.equivalent=nil) or
  374. (nextdiffkept^.suppress)) do
  375. nextdiffkept:=nextdiffkept^.filenext;
  376. Orgnext:=orgnext^.filenext;
  377. end
  378. else
  379. begin
  380. { Skip removed enum in errore.msg}
  381. { maybe a renaming of an enum !}
  382. Writeln(diffnext^.enum,' commented out');
  383. Writeln(t,'%%% ',s);
  384. inc(i);
  385. readln(t2,s);
  386. inc(i2);
  387. Diffnext:=Diffnext^.FileNext;
  388. nextdiffkept:=diffnext;
  389. while assigned(nextdiffkept) and (nextdiffkept^.equivalent=nil) do
  390. nextdiffkept:=nextdiffkept^.filenext;
  391. if assigned(diffnext) then
  392. while (i2<diffnext^.line) do
  393. begin
  394. writeln(t,'%%% ',s);
  395. inc(i);
  396. readln(t2,s);
  397. inc(i2);
  398. end;
  399. end;
  400. end
  401. else
  402. begin
  403. writeln(t,s);
  404. inc(i);
  405. s:='';
  406. end;
  407. end;
  408. Close(t);
  409. Close(t2);
  410. Close(t3);
  411. end;
  412. begin
  413. ProcessOptions;
  414. ProcessFile(OrgFileName,orgroot,orgfirst);
  415. ProcessFile(DiffFileName,diffRoot,difffirst);
  416. ShowDiff (OrgRoot,DiffRoot);
  417. WriteReorderedFile2('new.msg',orgfirst,difffirst);
  418. end.
  419. {
  420. $Log$
  421. Revision 1.6 1999-06-22 16:24:52 pierre
  422. * local browser stuff corrected
  423. Revision 1.5 1999/06/11 13:06:45 peter
  424. * fixed crash with errorn.msg
  425. Revision 1.4 1999/06/09 12:17:34 pierre
  426. * bugfix from fixes-0_99_12 merged
  427. Revision 1.2.2.2 1999/06/09 12:12:19 pierre
  428. * small bug fixed
  429. Revision 1.3 1999/06/09 11:57:29 pierre
  430. * fix branch changes merged
  431. Revision 1.2.2.1 1999/06/09 11:48:18 pierre
  432. * msgdif enhanced: see readme
  433. Revision 1.2 1999/05/17 15:13:43 michael
  434. + Fixed a bug that caused messages inserted at root not to appear...
  435. Revision 1.1 1999/05/12 16:17:09 peter
  436. * init
  437. }