cresstr.pas 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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(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(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. FileName:=current_module.outputpath^+FixFileName(ForceExtension(FileName,'.rst'));
  196. message1 (general_i_writingresourcefile,filename);
  197. Assign(F,Filename);
  198. {$i-}
  199. Rewrite(f);
  200. {$i+}
  201. If IOresult<>0 then
  202. begin
  203. message(general_e_errorwritingresourcefile);
  204. exit;
  205. end;
  206. R:=TResourceStringItem(List.First);
  207. While assigned(R) do
  208. begin
  209. writeln(f);
  210. Writeln(f,'# hash value = ',R.hash);
  211. col:=0;
  212. Add(R.Name+'=');
  213. Mode:=unquoted;
  214. For I:=0 to R.Len-1 do
  215. begin
  216. C:=R.Value[i];
  217. If (ord(C)>31) and (Ord(c)<=128) and (c<>'''') then
  218. begin
  219. If mode=Quoted then
  220. Add(c)
  221. else
  222. begin
  223. Add(''''+c);
  224. mode:=quoted
  225. end;
  226. end
  227. else
  228. begin
  229. If Mode=quoted then
  230. begin
  231. Add('''');
  232. mode:=unquoted;
  233. end;
  234. Add('#'+tostr(ord(c)));
  235. end;
  236. If Col>72 then
  237. begin
  238. if mode=quoted then
  239. Write (F,'''');
  240. Writeln(F,'+');
  241. Col:=0;
  242. Mode:=unQuoted;
  243. end;
  244. end;
  245. if mode=quoted then
  246. writeln (f,'''');
  247. Writeln(f);
  248. R:=TResourceStringItem(R.Next);
  249. end;
  250. close(f);
  251. end;
  252. end.
  253. {
  254. $Log$
  255. Revision 1.8 2000-12-25 00:07:25 peter
  256. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  257. tlinkedlist objects)
  258. Revision 1.7 2000/11/13 14:44:35 jonas
  259. * fixes so no more range errors with improved range checking code
  260. Revision 1.6 2000/09/24 15:06:14 peter
  261. * use defines.inc
  262. Revision 1.5 2000/08/27 16:11:50 peter
  263. * moved some util functions from globals,cobjects to cutils
  264. * splitted files into finput,fmodule
  265. Revision 1.4 2000/08/15 09:45:29 michael
  266. + Merged changes in fixbranch
  267. Revision 1.1.2.1 2000/08/15 09:41:56 michael
  268. + Fix to write rst file in output directory of module
  269. Revision 1.1 2000/07/13 06:29:48 michael
  270. + Initial import
  271. }