cresstr.pas 9.7 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. {$ifdef ver1_0}
  74. {$R-}
  75. {$endif}
  76. procedure TResourceStringItem.CalcHash;
  77. Var
  78. g : Cardinal;
  79. I : longint;
  80. begin
  81. hash:=0;
  82. For I:=0 to Len-1 do { 0 terminated }
  83. begin
  84. hash:=hash shl 4;
  85. inc(Hash,Ord(Value[i]));
  86. g:=hash and ($f shl 28);
  87. if g<>0 then
  88. begin
  89. hash:=hash xor (g shr 24);
  90. hash:=hash xor g;
  91. end;
  92. end;
  93. If Hash=0 then
  94. Hash:=$ffffffff;
  95. end;
  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 : tasmlabel;
  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_ptr(0))
  122. else
  123. begin
  124. objectlibrary.getdatalabel(l1);
  125. resourcestringlist.concat(tai_const_symbol.create(l1));
  126. consts.concat(tai_align.Create(const_align(pointer_size)));
  127. consts.concat(tai_const.create_32bit(len));
  128. consts.concat(tai_const.create_32bit(len));
  129. consts.concat(tai_const.create_32bit(cardinal(-1)));
  130. consts.concat(tai_label.create(l1));
  131. getmem(s,len+1);
  132. move(Value^,s^,len);
  133. s[len]:=#0;
  134. consts.concat(tai_string.create_length_pchar(s,len));
  135. consts.concat(tai_const.create_8bit(0));
  136. end;
  137. { append Current value (nil) and hash...}
  138. resourcestringlist.concat(tai_const.create_ptr(0));
  139. resourcestringlist.concat(tai_const.create_32bit(hash));
  140. { Append the name as a ansistring. }
  141. objectlibrary.getdatalabel(l1);
  142. L:=Length(Name);
  143. resourcestringlist.concat(tai_const_symbol.create(l1));
  144. consts.concat(tai_align.Create(const_align(pointer_size)));
  145. consts.concat(tai_const.create_32bit(l));
  146. consts.concat(tai_const.create_32bit(l));
  147. consts.concat(tai_const.create_32bit(cardinal(-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.createname_global(make_mangledname('RESOURCESTRINGLIST',current_module.localsymtable,''),AT_DATA,0));
  163. resourcestringlist.insert(tai_align.Create(const_align(pointer_size)));
  164. R:=TResourceStringItem(List.First);
  165. While assigned(R) do
  166. begin
  167. AppendToAsmResList(R);
  168. R:=TResourceStringItem(R.Next);
  169. end;
  170. resourcestringlist.concat(tai_symbol_end.createname(current_module.modulename^+'_'+'RESOURCESTRINGLIST'));
  171. end;
  172. { ---------------------------------------------------------------------
  173. Insert 1 resource string in all tables.
  174. ---------------------------------------------------------------------}
  175. function TResourceStrings.Register(const name : string;p : pchar;len : longint) : longint;
  176. begin
  177. List.Concat(tResourceStringItem.Create(lower(current_module.modulename^+'.'+Name),p,len));
  178. Register:=ResStrCount;
  179. inc(ResStrCount);
  180. end;
  181. Procedure TResourceStrings.WriteResourceFile(const FileName : String);
  182. Type
  183. TMode = (quoted,unquoted);
  184. Var
  185. F : Text;
  186. Mode : TMode;
  187. R : TResourceStringItem;
  188. C : char;
  189. Col,i : longint;
  190. Procedure Add(Const S : String);
  191. begin
  192. Write(F,S);
  193. Col:=Col+length(s);
  194. end;
  195. begin
  196. If List.Empty then
  197. exit;
  198. message1 (general_i_writingresourcefile,SplitFileName(filename));
  199. Assign(F,Filename);
  200. {$i-}
  201. Rewrite(f);
  202. {$i+}
  203. If IOresult<>0 then
  204. begin
  205. message1(general_e_errorwritingresourcefile,filename);
  206. exit;
  207. end;
  208. R:=TResourceStringItem(List.First);
  209. While assigned(R) do
  210. begin
  211. writeln(f);
  212. Writeln(f,'# hash value = ',R.hash);
  213. col:=0;
  214. Add(R.Name+'=');
  215. Mode:=unquoted;
  216. For I:=0 to R.Len-1 do
  217. begin
  218. C:=R.Value[i];
  219. If (ord(C)>31) and (Ord(c)<=128) and (c<>'''') then
  220. begin
  221. If mode=Quoted then
  222. Add(c)
  223. else
  224. begin
  225. Add(''''+c);
  226. mode:=quoted
  227. end;
  228. end
  229. else
  230. begin
  231. If Mode=quoted then
  232. begin
  233. Add('''');
  234. mode:=unquoted;
  235. end;
  236. Add('#'+tostr(ord(c)));
  237. end;
  238. If Col>72 then
  239. begin
  240. if mode=quoted then
  241. Write (F,'''');
  242. Writeln(F,'+');
  243. Col:=0;
  244. Mode:=unQuoted;
  245. end;
  246. end;
  247. if mode=quoted then
  248. writeln (f,'''');
  249. Writeln(f);
  250. R:=TResourceStringItem(R.Next);
  251. end;
  252. close(f);
  253. end;
  254. end.
  255. {
  256. $Log$
  257. Revision 1.23 2004-05-23 15:23:30 peter
  258. * fixed qword(longint) that removed sign from the number
  259. * removed code in the compiler that relied on wrong qword(longint)
  260. code generation
  261. Revision 1.22 2004/03/02 00:36:33 olle
  262. * big transformation of Tai_[const_]Symbol.Create[data]name*
  263. Revision 1.21 2004/02/26 16:16:38 peter
  264. * tai_const.create_ptr added
  265. Revision 1.20 2003/12/29 19:31:20 florian
  266. * fixed error message, if a resource file can't be written
  267. Revision 1.19 2003/12/08 22:34:24 peter
  268. * tai_const.create_32bit changed to cardinal
  269. Revision 1.18 2003/10/29 19:48:50 peter
  270. * renamed mangeldname_prefix to make_mangledname and made it more
  271. generic
  272. * make_mangledname is now also used for internal threadvar/resstring
  273. lists
  274. * Add P$ in front of program modulename to prevent duplicated symbols
  275. at assembler level, because the main program can have the same name
  276. as a unit, see webtbs/tw1251b
  277. Revision 1.17 2002/11/09 15:39:03 carl
  278. + resource string tables are now aligned
  279. Revision 1.16 2002/08/11 14:32:26 peter
  280. * renamed current_library to objectlibrary
  281. Revision 1.15 2002/08/11 13:24:11 peter
  282. * saving of asmsymbols in ppu supported
  283. * asmsymbollist global is removed and moved into a new class
  284. tasmlibrarydata that will hold the info of a .a file which
  285. corresponds with a single module. Added librarydata to tmodule
  286. to keep the library info stored for the module. In the future the
  287. objectfiles will also be stored to the tasmlibrarydata class
  288. * all getlabel/newasmsymbol and friends are moved to the new class
  289. Revision 1.14 2002/07/01 18:46:22 peter
  290. * internal linker
  291. * reorganized aasm layer
  292. Revision 1.13 2002/05/18 13:34:06 peter
  293. * readded missing revisions
  294. Revision 1.12 2002/05/16 19:46:35 carl
  295. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  296. + try to fix temp allocation (still in ifdef)
  297. + generic constructor calls
  298. + start of tassembler / tmodulebase class cleanup
  299. }