cresstr.pas 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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,globtype,globals,
  50. symdef,
  51. verbose,fmodule,
  52. aasmbase,aasmtai,
  53. aasmcpu;
  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_sym(nil))
  122. else
  123. begin
  124. objectlibrary.getdatalabel(l1);
  125. resourcestringlist.concat(tai_const.create_sym(l1));
  126. consts.concat(tai_align.Create(const_align(sizeof(aint))));
  127. consts.concat(tai_const.create_32bit(len));
  128. consts.concat(tai_const.create_32bit(len));
  129. consts.concat(tai_const.create_32bit(-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_sym(nil));
  139. resourcestringlist.concat(tai_const.create_32bit(longint(hash)));
  140. { Append the name as a ansistring. }
  141. objectlibrary.getdatalabel(l1);
  142. L:=Length(Name);
  143. resourcestringlist.concat(tai_const.create_sym(l1));
  144. consts.concat(tai_align.Create(const_align(sizeof(aint))));
  145. consts.concat(tai_const.create_32bit(l));
  146. consts.concat(tai_const.create_32bit(l));
  147. consts.concat(tai_const.create_32bit(-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(sizeof(aint))));
  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.24 2004-06-16 20:07:07 florian
  258. * dwarf branch merged
  259. Revision 1.23 2004/05/23 15:23:30 peter
  260. * fixed qword(longint) that removed sign from the number
  261. * removed code in the compiler that relied on wrong qword(longint)
  262. code generation
  263. Revision 1.22.2.3 2004/05/01 16:02:09 peter
  264. * POINTER_SIZE replaced with sizeof(aint)
  265. * aint,aword,tconst*int moved to globtype
  266. Revision 1.22.2.2 2004/04/27 18:18:25 peter
  267. * aword -> aint
  268. Revision 1.22.2.1 2004/04/12 14:45:11 peter
  269. * tai_const_symbol and tai_const merged
  270. Revision 1.22 2004/03/02 00:36:33 olle
  271. * big transformation of Tai_[const_]Symbol.Create[data]name*
  272. Revision 1.21 2004/02/26 16:16:38 peter
  273. * tai_const.create_ptr added
  274. Revision 1.20 2003/12/29 19:31:20 florian
  275. * fixed error message, if a resource file can't be written
  276. Revision 1.19 2003/12/08 22:34:24 peter
  277. * tai_const.create_32bit changed to cardinal
  278. Revision 1.18 2003/10/29 19:48:50 peter
  279. * renamed mangeldname_prefix to make_mangledname and made it more
  280. generic
  281. * make_mangledname is now also used for internal threadvar/resstring
  282. lists
  283. * Add P$ in front of program modulename to prevent duplicated symbols
  284. at assembler level, because the main program can have the same name
  285. as a unit, see webtbs/tw1251b
  286. Revision 1.17 2002/11/09 15:39:03 carl
  287. + resource string tables are now aligned
  288. Revision 1.16 2002/08/11 14:32:26 peter
  289. * renamed current_library to objectlibrary
  290. Revision 1.15 2002/08/11 13:24:11 peter
  291. * saving of asmsymbols in ppu supported
  292. * asmsymbollist global is removed and moved into a new class
  293. tasmlibrarydata that will hold the info of a .a file which
  294. corresponds with a single module. Added librarydata to tmodule
  295. to keep the library info stored for the module. In the future the
  296. objectfiles will also be stored to the tasmlibrarydata class
  297. * all getlabel/newasmsymbol and friends are moved to the new class
  298. Revision 1.14 2002/07/01 18:46:22 peter
  299. * internal linker
  300. * reorganized aasm layer
  301. Revision 1.13 2002/05/18 13:34:06 peter
  302. * readded missing revisions
  303. Revision 1.12 2002/05/16 19:46:35 carl
  304. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  305. + try to fix temp allocation (still in ifdef)
  306. + generic constructor calls
  307. + start of tassembler / tmodulebase class cleanup
  308. }