cresstr.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Michael van Canneyt
  4. Handles resourcestrings
  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 cresstr;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. cclasses;
  23. Type
  24. { These are used to form a singly-linked list, ordered by hash value }
  25. TResourceStringItem = class(TLinkedListItem)
  26. Name : String;
  27. Value : Pchar;
  28. Len,
  29. hash : longint;
  30. constructor Create(const AName:string;AValue:pchar;ALen:longint);
  31. destructor Destroy;override;
  32. procedure CalcHash;
  33. end;
  34. TResourceStrings=class
  35. private
  36. List : TLinkedList;
  37. public
  38. ResStrCount : longint;
  39. constructor Create;
  40. destructor Destroy;override;
  41. function Register(Const name : string;p : pchar;len : longint) : longint;
  42. procedure CreateResourceStringList;
  43. Procedure WriteResourceFile(const FileName : String);
  44. end;
  45. var
  46. ResourceStrings : TResourceStrings;
  47. implementation
  48. uses
  49. cutils,globals,aasm,verbose,fmodule;
  50. { ---------------------------------------------------------------------
  51. Calculate hash value, based on the string
  52. ---------------------------------------------------------------------}
  53. { ---------------------------------------------------------------------
  54. TRESOURCESTRING_ITEM
  55. ---------------------------------------------------------------------}
  56. constructor TResourceStringItem.Create(const AName:string;AValue:pchar;ALen:longint);
  57. begin
  58. inherited Create;
  59. Name:=AName;
  60. Len:=ALen;
  61. GetMem(Value,Len);
  62. Move(AValue^,Value^,Len);
  63. CalcHash;
  64. end;
  65. destructor TResourceStringItem.Destroy;
  66. begin
  67. FreeMem(Value,Len);
  68. end;
  69. {$ifopt r+}
  70. {$define rangeon}
  71. {$r-}
  72. {$endif}
  73. procedure TResourceStringItem.CalcHash;
  74. Var
  75. g,I : longint;
  76. begin
  77. hash:=0;
  78. For I:=0 to Len-1 do { 0 terminated }
  79. begin
  80. hash:=hash shl 4;
  81. inc(Hash,Ord(Value[i]));
  82. g:=hash and ($f shl 28);
  83. if g<>0 then
  84. begin
  85. hash:=hash xor (g shr 24);
  86. hash:=hash xor g;
  87. end;
  88. end;
  89. If Hash=0 then
  90. Hash:=Not(0);
  91. end;
  92. {$ifdef rangeon}
  93. {$r+}
  94. {$undef rangeon}
  95. {$endif}
  96. { ---------------------------------------------------------------------
  97. TRESOURCESTRINGS
  98. ---------------------------------------------------------------------}
  99. Constructor TResourceStrings.Create;
  100. begin
  101. List:=TStringList.Create;
  102. ResStrCount:=0;
  103. end;
  104. Destructor TResourceStrings.Destroy;
  105. begin
  106. List.Free;
  107. end;
  108. { ---------------------------------------------------------------------
  109. Create the full asmlist for resourcestrings.
  110. ---------------------------------------------------------------------}
  111. procedure TResourceStrings.CreateResourceStringList;
  112. Procedure AppendToAsmResList (P : TResourceStringItem);
  113. Var
  114. l1 : pasmlabel;
  115. s : pchar;
  116. l : longint;
  117. begin
  118. With P Do
  119. begin
  120. if (Value=nil) or (len=0) then
  121. resourcestringlist.concat(tai_const.create_32bit(0))
  122. else
  123. begin
  124. getdatalabel(l1);
  125. resourcestringlist.concat(tai_const_symbol.create(l1));
  126. consts.concat(tai_const.create_32bit(len));
  127. consts.concat(tai_const.create_32bit(len));
  128. consts.concat(tai_const.create_32bit(-1));
  129. consts.concat(tai_label.create(l1));
  130. getmem(s,len+1);
  131. move(Value^,s^,len);
  132. s[len]:=#0;
  133. consts.concat(tai_string.create_length_pchar(s,len));
  134. consts.concat(tai_const.create_8bit(0));
  135. end;
  136. { append Current value (nil) and hash...}
  137. resourcestringlist.concat(tai_const.create_32bit(0));
  138. resourcestringlist.concat(tai_const.create_32bit(hash));
  139. { Append the name as a ansistring. }
  140. getdatalabel(l1);
  141. L:=Length(Name);
  142. resourcestringlist.concat(tai_const_symbol.create(l1));
  143. consts.concat(tai_const.create_32bit(l));
  144. consts.concat(tai_const.create_32bit(l));
  145. consts.concat(tai_const.create_32bit(-1));
  146. consts.concat(tai_label.create(l1));
  147. getmem(s,l+1);
  148. move(Name[1],s^,l);
  149. s[l]:=#0;
  150. consts.concat(tai_string.create_length_pchar(s,l));
  151. consts.concat(tai_const.create_8bit(0));
  152. end;
  153. end;
  154. Var
  155. R : tresourceStringItem;
  156. begin
  157. if not(assigned(resourcestringlist)) then
  158. resourcestringlist:=taasmoutput.create;
  159. resourcestringlist.insert(tai_const.create_32bit(resstrcount));
  160. resourcestringlist.insert(tai_symbol.createdataname_global(current_module.modulename^+'_'+'RESOURCESTRINGLIST',0));
  161. R:=TResourceStringItem(List.First);
  162. While assigned(R) do
  163. begin
  164. AppendToAsmResList(R);
  165. R:=TResourceStringItem(R.Next);
  166. end;
  167. resourcestringlist.concat(tai_symbol_end.createname(current_module.modulename^+'_'+'RESOURCESTRINGLIST'));
  168. end;
  169. { ---------------------------------------------------------------------
  170. Insert 1 resource string in all tables.
  171. ---------------------------------------------------------------------}
  172. function TResourceStrings.Register(const name : string;p : pchar;len : longint) : longint;
  173. begin
  174. List.Concat(tResourceStringItem.Create(lower(current_module.modulename^+'.'+Name),p,len));
  175. Register:=ResStrCount;
  176. inc(ResStrCount);
  177. end;
  178. Procedure TResourceStrings.WriteResourceFile(const FileName : String);
  179. Type
  180. TMode = (quoted,unquoted);
  181. Var
  182. F : Text;
  183. Mode : TMode;
  184. R : TResourceStringItem;
  185. C : char;
  186. Col,i : longint;
  187. Procedure Add(Const S : String);
  188. begin
  189. Write(F,S);
  190. Col:=Col+length(s);
  191. end;
  192. begin
  193. If List.Empty then
  194. exit;
  195. message1 (general_i_writingresourcefile,SplitFileName(filename));
  196. Assign(F,Filename);
  197. {$i-}
  198. Rewrite(f);
  199. {$i+}
  200. If IOresult<>0 then
  201. begin
  202. message(general_e_errorwritingresourcefile);
  203. exit;
  204. end;
  205. R:=TResourceStringItem(List.First);
  206. While assigned(R) do
  207. begin
  208. writeln(f);
  209. Writeln(f,'# hash value = ',R.hash);
  210. col:=0;
  211. Add(R.Name+'=');
  212. Mode:=unquoted;
  213. For I:=0 to R.Len-1 do
  214. begin
  215. C:=R.Value[i];
  216. If (ord(C)>31) and (Ord(c)<=128) and (c<>'''') then
  217. begin
  218. If mode=Quoted then
  219. Add(c)
  220. else
  221. begin
  222. Add(''''+c);
  223. mode:=quoted
  224. end;
  225. end
  226. else
  227. begin
  228. If Mode=quoted then
  229. begin
  230. Add('''');
  231. mode:=unquoted;
  232. end;
  233. Add('#'+tostr(ord(c)));
  234. end;
  235. If Col>72 then
  236. begin
  237. if mode=quoted then
  238. Write (F,'''');
  239. Writeln(F,'+');
  240. Col:=0;
  241. Mode:=unQuoted;
  242. end;
  243. end;
  244. if mode=quoted then
  245. writeln (f,'''');
  246. Writeln(f);
  247. R:=TResourceStringItem(R.Next);
  248. end;
  249. close(f);
  250. end;
  251. end.
  252. {
  253. $Log$
  254. Revision 1.9 2001-02-24 10:44:55 peter
  255. * generate .rst from ppufilename instead of modulename
  256. Revision 1.8 2000/12/25 00:07:25 peter
  257. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  258. tlinkedlist objects)
  259. Revision 1.7 2000/11/13 14:44:35 jonas
  260. * fixes so no more range errors with improved range checking code
  261. Revision 1.6 2000/09/24 15:06:14 peter
  262. * use defines.inc
  263. Revision 1.5 2000/08/27 16:11:50 peter
  264. * moved some util functions from globals,cobjects to cutils
  265. * splitted files into finput,fmodule
  266. Revision 1.4 2000/08/15 09:45:29 michael
  267. + Merged changes in fixbranch
  268. Revision 1.1.2.1 2000/08/15 09:41:56 michael
  269. + Fix to write rst file in output directory of module
  270. Revision 1.1 2000/07/13 06:29:48 michael
  271. + Initial import
  272. }