2
0

cresstr.pas 9.1 KB

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