cresstr.pas 8.4 KB

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