cresstr.pas 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.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,
  50. verbose,fmodule,
  51. aasmbase,aasmtai,
  52. aasmcpu,cpuinfo;
  53. { ---------------------------------------------------------------------
  54. Calculate hash value, based on the string
  55. ---------------------------------------------------------------------}
  56. { ---------------------------------------------------------------------
  57. TRESOURCESTRING_ITEM
  58. ---------------------------------------------------------------------}
  59. constructor TResourceStringItem.Create(const AName:string;AValue:pchar;ALen:longint);
  60. begin
  61. inherited Create;
  62. Name:=AName;
  63. Len:=ALen;
  64. GetMem(Value,Len);
  65. Move(AValue^,Value^,Len);
  66. CalcHash;
  67. end;
  68. destructor TResourceStringItem.Destroy;
  69. begin
  70. FreeMem(Value,Len);
  71. end;
  72. {$ifopt r+}
  73. {$define rangeon}
  74. {$r-}
  75. {$endif}
  76. procedure TResourceStringItem.CalcHash;
  77. Var
  78. g,I : longint;
  79. begin
  80. hash:=0;
  81. For I:=0 to Len-1 do { 0 terminated }
  82. begin
  83. hash:=hash shl 4;
  84. inc(Hash,Ord(Value[i]));
  85. g:=hash and ($f shl 28);
  86. if g<>0 then
  87. begin
  88. hash:=hash xor (g shr 24);
  89. hash:=hash xor g;
  90. end;
  91. end;
  92. If Hash=0 then
  93. Hash:=Not(0);
  94. end;
  95. {$ifdef rangeon}
  96. {$r+}
  97. {$undef rangeon}
  98. {$endif}
  99. { ---------------------------------------------------------------------
  100. TRESOURCESTRINGS
  101. ---------------------------------------------------------------------}
  102. Constructor TResourceStrings.Create;
  103. begin
  104. List:=TStringList.Create;
  105. ResStrCount:=0;
  106. end;
  107. Destructor TResourceStrings.Destroy;
  108. begin
  109. List.Free;
  110. end;
  111. { ---------------------------------------------------------------------
  112. Create the full asmlist for resourcestrings.
  113. ---------------------------------------------------------------------}
  114. procedure TResourceStrings.CreateResourceStringList;
  115. Procedure AppendToAsmResList (P : TResourceStringItem);
  116. Var
  117. l1 : tasmlabel;
  118. s : pchar;
  119. l : longint;
  120. begin
  121. With P Do
  122. begin
  123. if (Value=nil) or (len=0) then
  124. resourcestringlist.concat(tai_const.create_32bit(0))
  125. else
  126. begin
  127. objectlibrary.getdatalabel(l1);
  128. resourcestringlist.concat(tai_const_symbol.create(l1));
  129. consts.concat(tai_align.Create(const_align(pointer_size)));
  130. consts.concat(tai_const.create_32bit(len));
  131. consts.concat(tai_const.create_32bit(len));
  132. consts.concat(tai_const.create_32bit(-1));
  133. consts.concat(tai_label.create(l1));
  134. getmem(s,len+1);
  135. move(Value^,s^,len);
  136. s[len]:=#0;
  137. consts.concat(tai_string.create_length_pchar(s,len));
  138. consts.concat(tai_const.create_8bit(0));
  139. end;
  140. { append Current value (nil) and hash...}
  141. resourcestringlist.concat(tai_const.create_32bit(0));
  142. resourcestringlist.concat(tai_const.create_32bit(hash));
  143. { Append the name as a ansistring. }
  144. objectlibrary.getdatalabel(l1);
  145. L:=Length(Name);
  146. resourcestringlist.concat(tai_const_symbol.create(l1));
  147. consts.concat(tai_align.Create(const_align(pointer_size)));
  148. consts.concat(tai_const.create_32bit(l));
  149. consts.concat(tai_const.create_32bit(l));
  150. consts.concat(tai_const.create_32bit(-1));
  151. consts.concat(tai_label.create(l1));
  152. getmem(s,l+1);
  153. move(Name[1],s^,l);
  154. s[l]:=#0;
  155. consts.concat(tai_string.create_length_pchar(s,l));
  156. consts.concat(tai_const.create_8bit(0));
  157. end;
  158. end;
  159. Var
  160. R : tresourceStringItem;
  161. begin
  162. if not(assigned(resourcestringlist)) then
  163. resourcestringlist:=taasmoutput.create;
  164. resourcestringlist.insert(tai_const.create_32bit(resstrcount));
  165. resourcestringlist.insert(tai_symbol.createdataname_global(current_module.modulename^+'_'+'RESOURCESTRINGLIST',0));
  166. resourcestringlist.insert(tai_align.Create(const_align(pointer_size)));
  167. R:=TResourceStringItem(List.First);
  168. While assigned(R) do
  169. begin
  170. AppendToAsmResList(R);
  171. R:=TResourceStringItem(R.Next);
  172. end;
  173. resourcestringlist.concat(tai_symbol_end.createname(current_module.modulename^+'_'+'RESOURCESTRINGLIST'));
  174. end;
  175. { ---------------------------------------------------------------------
  176. Insert 1 resource string in all tables.
  177. ---------------------------------------------------------------------}
  178. function TResourceStrings.Register(const name : string;p : pchar;len : longint) : longint;
  179. begin
  180. List.Concat(tResourceStringItem.Create(lower(current_module.modulename^+'.'+Name),p,len));
  181. Register:=ResStrCount;
  182. inc(ResStrCount);
  183. end;
  184. Procedure TResourceStrings.WriteResourceFile(const FileName : String);
  185. Type
  186. TMode = (quoted,unquoted);
  187. Var
  188. F : Text;
  189. Mode : TMode;
  190. R : TResourceStringItem;
  191. C : char;
  192. Col,i : longint;
  193. Procedure Add(Const S : String);
  194. begin
  195. Write(F,S);
  196. Col:=Col+length(s);
  197. end;
  198. begin
  199. If List.Empty then
  200. exit;
  201. message1 (general_i_writingresourcefile,SplitFileName(filename));
  202. Assign(F,Filename);
  203. {$i-}
  204. Rewrite(f);
  205. {$i+}
  206. If IOresult<>0 then
  207. begin
  208. message(general_e_errorwritingresourcefile);
  209. exit;
  210. end;
  211. R:=TResourceStringItem(List.First);
  212. While assigned(R) do
  213. begin
  214. writeln(f);
  215. Writeln(f,'# hash value = ',R.hash);
  216. col:=0;
  217. Add(R.Name+'=');
  218. Mode:=unquoted;
  219. For I:=0 to R.Len-1 do
  220. begin
  221. C:=R.Value[i];
  222. If (ord(C)>31) and (Ord(c)<=128) and (c<>'''') then
  223. begin
  224. If mode=Quoted then
  225. Add(c)
  226. else
  227. begin
  228. Add(''''+c);
  229. mode:=quoted
  230. end;
  231. end
  232. else
  233. begin
  234. If Mode=quoted then
  235. begin
  236. Add('''');
  237. mode:=unquoted;
  238. end;
  239. Add('#'+tostr(ord(c)));
  240. end;
  241. If Col>72 then
  242. begin
  243. if mode=quoted then
  244. Write (F,'''');
  245. Writeln(F,'+');
  246. Col:=0;
  247. Mode:=unQuoted;
  248. end;
  249. end;
  250. if mode=quoted then
  251. writeln (f,'''');
  252. Writeln(f);
  253. R:=TResourceStringItem(R.Next);
  254. end;
  255. close(f);
  256. end;
  257. end.
  258. {
  259. $Log$
  260. Revision 1.17 2002-11-09 15:39:03 carl
  261. + resource string tables are now aligned
  262. Revision 1.16 2002/08/11 14:32:26 peter
  263. * renamed current_library to objectlibrary
  264. Revision 1.15 2002/08/11 13:24:11 peter
  265. * saving of asmsymbols in ppu supported
  266. * asmsymbollist global is removed and moved into a new class
  267. tasmlibrarydata that will hold the info of a .a file which
  268. corresponds with a single module. Added librarydata to tmodule
  269. to keep the library info stored for the module. In the future the
  270. objectfiles will also be stored to the tasmlibrarydata class
  271. * all getlabel/newasmsymbol and friends are moved to the new class
  272. Revision 1.14 2002/07/01 18:46:22 peter
  273. * internal linker
  274. * reorganized aasm layer
  275. Revision 1.13 2002/05/18 13:34:06 peter
  276. * readded missing revisions
  277. Revision 1.12 2002/05/16 19:46:35 carl
  278. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  279. + try to fix temp allocation (still in ifdef)
  280. + generic constructor calls
  281. + start of tassembler / tmodulebase class cleanup
  282. }