cresstr.pas 9.4 KB

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