cresstr.pas 9.5 KB

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