cresstr.pas 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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.createname_global(make_mangledname('RESOURCESTRINGLIST',current_module.localsymtable,''),AT_DATA,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.22 2004-03-02 00:36:33 olle
  263. * big transformation of Tai_[const_]Symbol.Create[data]name*
  264. Revision 1.21 2004/02/26 16:16:38 peter
  265. * tai_const.create_ptr added
  266. Revision 1.20 2003/12/29 19:31:20 florian
  267. * fixed error message, if a resource file can't be written
  268. Revision 1.19 2003/12/08 22:34:24 peter
  269. * tai_const.create_32bit changed to cardinal
  270. Revision 1.18 2003/10/29 19:48:50 peter
  271. * renamed mangeldname_prefix to make_mangledname and made it more
  272. generic
  273. * make_mangledname is now also used for internal threadvar/resstring
  274. lists
  275. * Add P$ in front of program modulename to prevent duplicated symbols
  276. at assembler level, because the main program can have the same name
  277. as a unit, see webtbs/tw1251b
  278. Revision 1.17 2002/11/09 15:39:03 carl
  279. + resource string tables are now aligned
  280. Revision 1.16 2002/08/11 14:32:26 peter
  281. * renamed current_library to objectlibrary
  282. Revision 1.15 2002/08/11 13:24:11 peter
  283. * saving of asmsymbols in ppu supported
  284. * asmsymbollist global is removed and moved into a new class
  285. tasmlibrarydata that will hold the info of a .a file which
  286. corresponds with a single module. Added librarydata to tmodule
  287. to keep the library info stored for the module. In the future the
  288. objectfiles will also be stored to the tasmlibrarydata class
  289. * all getlabel/newasmsymbol and friends are moved to the new class
  290. Revision 1.14 2002/07/01 18:46:22 peter
  291. * internal linker
  292. * reorganized aasm layer
  293. Revision 1.13 2002/05/18 13:34:06 peter
  294. * readded missing revisions
  295. Revision 1.12 2002/05/16 19:46:35 carl
  296. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  297. + try to fix temp allocation (still in ifdef)
  298. + generic constructor calls
  299. + start of tassembler / tmodulebase class cleanup
  300. }