messages.pas 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Peter Vreman
  4. This unit implements the message object
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit Messages;
  19. interface
  20. type
  21. ppchar=^pchar;
  22. PMessage=^TMessage;
  23. TMessage=object
  24. msgfilename : string;
  25. msgallocsize,
  26. msgsize,
  27. msgcrc,
  28. msgs : longint;
  29. msgtxt : pchar;
  30. msgidx : ppchar;
  31. constructor Init(p:pointer;n:longint);
  32. constructor InitExtern(const fn:string;n:longint);
  33. destructor Done;
  34. procedure CreateIdx;
  35. function Get(nr:longint):string;
  36. function Get3(nr:longint;const s1,s2,s3:string):string;
  37. function Get2(nr:longint;const s1,s2:string):string;
  38. function Get1(nr:longint;const s1:string):string;
  39. end;
  40. implementation
  41. uses
  42. globals,crc,
  43. verbose,
  44. {$ifdef DELPHI}
  45. sysutils;
  46. {$else DELPHI}
  47. strings;
  48. {$endif DELPHI}
  49. constructor TMessage.Init(p:pointer;n:longint);
  50. begin
  51. msgtxt:=pchar(p);
  52. msgallocsize:=0;
  53. msgsize:=0;
  54. msgcrc:=MsgCrcValue;
  55. msgs:=n;
  56. CreateIdx;
  57. end;
  58. constructor TMessage.InitExtern(const fn:string;n:longint);
  59. {$ifndef FPC}
  60. procedure readln(var t:text;var s:string);
  61. var
  62. c : char;
  63. i : longint;
  64. begin
  65. c:=#0;
  66. i:=0;
  67. while (not eof(t)) and (c<>#10) do
  68. begin
  69. read(t,c);
  70. if c<>#10 then
  71. begin
  72. inc(i);
  73. s[i]:=c;
  74. end;
  75. end;
  76. if (i>0) and (s[i]=#13) then
  77. dec(i);
  78. s[0]:=chr(i);
  79. end;
  80. {$endif}
  81. const
  82. bufsize=8192;
  83. var
  84. f : text;
  85. {$ifdef DEBUGCRC}
  86. f2 : text;
  87. {$endif DEBUGCRC}
  88. msgsread,
  89. line,i,crc : longint;
  90. ptxt : pchar;
  91. s,s1 : string;
  92. buf : pointer;
  93. begin
  94. crc:=longint($ffffffff);
  95. getmem(buf,bufsize);
  96. {Read the message file}
  97. assign(f,fn);
  98. {$ifdef DEBUGCRC}
  99. assign(f2,'crcmsg.tst');
  100. rewrite(f2);
  101. Writeln(f2,crc);
  102. {$endif DEBUGCRC}
  103. {$I-}
  104. reset(f);
  105. {$I+}
  106. if ioresult<>0 then
  107. begin
  108. WriteLn('*** message file '+fn+' not found ***');
  109. fail;
  110. end;
  111. settextbuf(f,buf^,bufsize);
  112. { First parse the file and count bytes needed }
  113. line:=0;
  114. msgs:=n;
  115. msgsize:=0;
  116. msgsread:=0;
  117. while not eof(f) do
  118. begin
  119. readln(f,s);
  120. inc(line);
  121. if (s<>'') and not(s[1] in ['#',';','%']) then
  122. begin
  123. i:=pos('=',s);
  124. if i>0 then
  125. begin
  126. inc(msgsize,length(s)-i+1);
  127. inc(msgsread);
  128. end
  129. else
  130. writeln('error in line: ',line,' skipping');
  131. end;
  132. end;
  133. { check amount of messages }
  134. if msgsread<>msgs then
  135. begin
  136. WriteLn('*** message file '+fn+' is corrupt: read ',msgsread,' of ',msgs,' msgs ***');
  137. close(f);
  138. freemem(buf,bufsize);
  139. fail;
  140. end;
  141. { now read the buffer in mem }
  142. msgallocsize:=msgsize;
  143. getmem(msgtxt,msgallocsize);
  144. ptxt:=msgtxt;
  145. reset(f);
  146. while not eof(f) do
  147. begin
  148. readln(f,s);
  149. if (s<>'') and not(s[1] in ['#',';','%']) then
  150. begin
  151. i:=pos('=',s);
  152. if i>0 then
  153. begin
  154. {txt}
  155. s1:=Copy(s,i+1,255);
  156. { support <lf> for empty lines }
  157. if s1='<lf>' then
  158. begin
  159. s1:='';
  160. { update the msgsize also! }
  161. dec(msgsize,4);
  162. end;
  163. {txt}
  164. move(s1[1],ptxt^,length(s1));
  165. inc(ptxt,length(s1));
  166. ptxt^:=#0;
  167. inc(ptxt);
  168. s1:=upper(copy(s,1,i-1));
  169. crc:=UpdateCRC32(crc,s1[1],length(s1));
  170. {$ifdef DEBUGCRC}
  171. Writeln(f2,s1);
  172. Writeln(f2,crc);
  173. {$endif DEBUGCRC}
  174. end;
  175. end;
  176. end;
  177. close(f);
  178. {$ifdef DEBUGCRC}
  179. close(f2);
  180. {$endif DEBUGCRC}
  181. freemem(buf,bufsize);
  182. { check amount of messages }
  183. if (MsgCrcValue<>0) and (crc<>MsgCrcValue) then
  184. begin
  185. WriteLn('*** message file '+fn+' is incompatible : wrong CRC value ***');
  186. fail;
  187. end;
  188. { now we can create the index }
  189. CreateIdx;
  190. end;
  191. destructor TMessage.Done;
  192. begin
  193. if assigned(msgidx) then
  194. begin
  195. freemem(msgidx,msgs shl 2);
  196. msgidx:=nil;
  197. end;
  198. if msgallocsize>0 then
  199. begin
  200. freemem(msgtxt,msgallocsize);
  201. msgtxt:=nil;
  202. msgallocsize:=0;
  203. end;
  204. end;
  205. procedure TMessage.CreateIdx;
  206. var
  207. hp : pchar;
  208. hpl : ppchar;
  209. n : longint;
  210. begin
  211. getmem(msgidx,msgs shl 2);
  212. hpl:=msgidx;
  213. hp:=msgtxt;
  214. n:=0;
  215. while (n<msgs) do
  216. begin
  217. hpl^:=hp;
  218. hpl:=pointer(longint(hpl)+4);
  219. inc(n);
  220. hp:=pchar(@hp[strlen(hp)+1]);
  221. end;
  222. end;
  223. function TMessage.Get(nr:longint):string;
  224. var
  225. s : string[16];
  226. hp : pchar;
  227. begin
  228. if msgidx=nil then
  229. hp:=nil
  230. else
  231. hp:=pchar(pointer(longint(msgidx)+nr shl 2)^);
  232. if hp=nil then
  233. begin
  234. Str(nr,s);
  235. Get:='msg nr '+s;
  236. end
  237. else
  238. Get:=StrPas(hp);
  239. end;
  240. function TMessage.Get3(nr:longint;const s1,s2,s3:string):string;
  241. var
  242. i : longint;
  243. s : string;
  244. begin
  245. s:=Get(nr);
  246. { $1 -> s1 }
  247. if s1<>'$1' then
  248. repeat
  249. i:=pos('$1',s);
  250. if i>0 then
  251. begin
  252. Delete(s,i,2);
  253. Insert(s1,s,i);
  254. end;
  255. until i=0;
  256. { $2 -> s2 }
  257. if s1<>'$2' then
  258. repeat
  259. i:=pos('$2',s);
  260. if i>0 then
  261. begin
  262. Delete(s,i,2);
  263. Insert(s2,s,i);
  264. end;
  265. until i=0;
  266. { $3 -> s3 }
  267. if s1<>'S3' then
  268. repeat
  269. i:=pos('$3',s);
  270. if i>0 then
  271. begin
  272. Delete(s,i,2);
  273. Insert(s3,s,i);
  274. end;
  275. until i=0;
  276. Get3:=s;
  277. end;
  278. function TMessage.Get2(nr:longint;const s1,s2:string):string;
  279. begin
  280. Get2:=Get3(nr,s1,s2,'');
  281. end;
  282. function TMessage.Get1(nr:longint;const s1:string):string;
  283. begin
  284. Get1:=Get3(nr,s1,'','');
  285. end;
  286. end.
  287. {
  288. $Log$
  289. Revision 1.14 2000-05-23 20:32:11 peter
  290. * fixed wrong code not detected due a bug in FPC
  291. Revision 1.13 2000/05/15 14:07:33 pierre
  292. + calculate CRC value and check if consistant
  293. Revision 1.12 2000/03/01 22:29:18 peter
  294. * message files are check for amount of msgs found. If not correct a
  295. line is written to stdout and switched to internal messages
  296. Revision 1.11 2000/02/09 13:22:54 peter
  297. * log truncated
  298. Revision 1.10 2000/01/23 16:32:08 peter
  299. * fixed wrong freemem size when loading message file
  300. Revision 1.9 2000/01/07 01:14:27 peter
  301. * updated copyright to 2000
  302. }