objpas.pp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by the Free Pascal development team
  4. This unit makes Free Pascal as much as possible Delphi compatible
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$Mode ObjFpc}
  12. {$I-}
  13. {$ifndef Unix}
  14. {$S-}
  15. {$endif}
  16. unit objpas;
  17. interface
  18. { first, in object pascal, the integer type must be redefined }
  19. {$ifdef CPU16}
  20. const
  21. MaxInt = MaxSmallint;
  22. type
  23. Integer = smallint;
  24. PInteger = ^Integer;
  25. {$else CPU16}
  26. const
  27. MaxInt = MaxLongint;
  28. type
  29. Integer = longint;
  30. PInteger = ^Integer;
  31. {$endif CPU16}
  32. { Ansistring are the default }
  33. PString = PAnsiString;
  34. { array types }
  35. {$ifdef CPU16}
  36. IntegerArray = array[0..(32768 div SizeOf(Integer))-2] of Integer;
  37. {$else CPU16}
  38. IntegerArray = array[0..$effffff] of Integer;
  39. {$endif CPU16}
  40. TIntegerArray = IntegerArray;
  41. PIntegerArray = ^IntegerArray;
  42. {$ifdef CPU16}
  43. PointerArray = array [0..(32768 div SizeOf(Pointer))-2] of Pointer;
  44. {$else CPU16}
  45. PointerArray = array [0..512*1024*1024-2] of Pointer;
  46. {$endif CPU16}
  47. TPointerArray = PointerArray;
  48. PPointerArray = ^PointerArray;
  49. TBoundArray = array of integer;
  50. {$if FPC_FULLVERSION >= 20701}
  51. { Generic support for enumerator interfaces. These are added here, because
  52. mode (Obj)FPC does currently not allow the overloading of types with
  53. generic types (this will need a modeswitch...) }
  54. { Note: In Delphi these two generic types inherit from the two interfaces
  55. above, but in FPC as well as in Delphi(!) this leads to problems,
  56. because of method hiding and method implementation. E.g.
  57. consider a class which enumerates integers one needs to implement
  58. a GetCurrent for TObject as well... }
  59. generic IEnumerator<T> = interface
  60. function GetCurrent: T;
  61. function MoveNext: Boolean;
  62. procedure Reset;
  63. property Current: T read GetCurrent;
  64. end;
  65. generic IEnumerable<T> = interface
  66. function GetEnumerator: specialize IEnumerator<T>;
  67. end;
  68. {$endif}
  69. {$ifdef FPC_HAS_FEATURE_CLASSES}
  70. Var
  71. ExceptionClass: TClass; { Exception base class (must actually be Exception, defined in sysutils ) }
  72. {$endif FPC_HAS_FEATURE_CLASSES}
  73. {****************************************************************************
  74. Compatibility routines.
  75. ****************************************************************************}
  76. {$ifdef FPC_HAS_FEATURE_FILEIO}
  77. { Untyped file support }
  78. Procedure AssignFile(out f:File;p:pchar);
  79. Procedure AssignFile(out f:File;c:char);
  80. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  81. Procedure AssignFile(out f:File;const Name:UnicodeString);
  82. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  83. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  84. Procedure AssignFile(out f:File;const Name:RawByteString);
  85. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  86. Procedure CloseFile(var f:File);
  87. {$endif FPC_HAS_FEATURE_FILEIO}
  88. {$ifdef FPC_HAS_FEATURE_TEXTIO}
  89. { Text file support }
  90. Procedure AssignFile(out t:Text;p:pchar);
  91. Procedure AssignFile(out t:Text;c:char);
  92. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  93. Procedure AssignFile(out t:Text;const Name:UnicodeString);
  94. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  95. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  96. Procedure AssignFile(out t:Text;const Name:RawByteString);
  97. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  98. Procedure CloseFile(Var t:Text);
  99. {$endif FPC_HAS_FEATURE_TEXTIO}
  100. {$ifdef FPC_HAS_FEATURE_FILEIO}
  101. { Typed file supoort }
  102. Procedure AssignFile(out f:TypedFile;p:pchar);
  103. Procedure AssignFile(out f:TypedFile;c:char);
  104. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  105. Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
  106. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  107. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  108. Procedure AssignFile(out f:TypedFile;const Name:RawByteString);
  109. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  110. {$endif FPC_HAS_FEATURE_FILEIO}
  111. {$ifdef FPC_HAS_FEATURE_COMMANDARGS}
  112. { ParamStr should return also an ansistring }
  113. Function ParamStr(Param : Integer) : Ansistring;
  114. {$endif FPC_HAS_FEATURE_COMMANDARGS}
  115. {****************************************************************************
  116. Resource strings.
  117. ****************************************************************************}
  118. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  119. type
  120. TResourceIterator = Function (Name,Value : AnsiString; Hash : Longint; arg:pointer) : AnsiString;
  121. Function Hash(S : AnsiString) : LongWord;
  122. Procedure ResetResourceTables;
  123. Procedure FinalizeResourceTables;
  124. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  125. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  126. {$ifndef RESSTRSECTIONS}
  127. Function ResourceStringTableCount : Longint;
  128. Function ResourceStringCount(TableIndex : longint) : longint;
  129. Function GetResourceStringName(TableIndex,StringIndex : Longint) : Ansistring;
  130. Function GetResourceStringHash(TableIndex,StringIndex : Longint) : Longint;
  131. Function GetResourceStringDefaultValue(TableIndex,StringIndex : Longint) : AnsiString;
  132. Function GetResourceStringCurrentValue(TableIndex,StringIndex : Longint) : AnsiString;
  133. Function SetResourceStringValue(TableIndex,StringIndex : longint; Value : Ansistring) : Boolean;
  134. {$endif RESSTRSECTIONS}
  135. { Delphi compatibility }
  136. type
  137. PResStringRec=^AnsiString;
  138. TResStringRec=AnsiString;
  139. Function LoadResString(p:PResStringRec):AnsiString;
  140. {$endif FPC_HAS_FEATURE_RESOURCES}
  141. implementation
  142. {****************************************************************************
  143. Compatibility routines.
  144. ****************************************************************************}
  145. {$ifdef FPC_HAS_FEATURE_FILEIO}
  146. { Untyped file support }
  147. Procedure AssignFile(out f:File;p:pchar);
  148. begin
  149. System.Assign (F,p);
  150. end;
  151. Procedure AssignFile(out f:File;c:char);
  152. begin
  153. System.Assign (F,c);
  154. end;
  155. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  156. Procedure AssignFile(out f:File;const Name:RawBytestring);
  157. begin
  158. System.Assign (F,Name);
  159. end;
  160. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  161. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  162. Procedure AssignFile(out f:File;const Name:UnicodeString);
  163. begin
  164. System.Assign (F,Name);
  165. end;
  166. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  167. Procedure CloseFile(Var f:File); [IOCheck];
  168. begin
  169. { Catch Runtime error/Exception }
  170. System.Close(f);
  171. end;
  172. {$endif FPC_HAS_FEATURE_FILEIO}
  173. {$ifdef FPC_HAS_FEATURE_TEXTIO}
  174. { Text file support }
  175. Procedure AssignFile(out t:Text;p:pchar);
  176. begin
  177. System.Assign (T,p);
  178. end;
  179. Procedure AssignFile(out t:Text;c:char);
  180. begin
  181. System.Assign (T,c);
  182. end;
  183. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  184. Procedure AssignFile(out t:Text;const Name:RawBytestring);
  185. begin
  186. System.Assign (T,Name);
  187. end;
  188. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  189. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  190. Procedure AssignFile(out t:Text;const Name:UnicodeString);
  191. begin
  192. System.Assign (T,Name);
  193. end;
  194. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  195. Procedure CloseFile(Var t:Text); [IOCheck];
  196. begin
  197. { Catch Runtime error/Exception }
  198. System.Close(T);
  199. end;
  200. {$endif FPC_HAS_FEATURE_TEXTIO}
  201. {$ifdef FPC_HAS_FEATURE_FILEIO}
  202. { Typed file support }
  203. Procedure AssignFile(out f:TypedFile;p:pchar);
  204. begin
  205. System.Assign (F,p);
  206. end;
  207. Procedure AssignFile(out f:TypedFile;c:char);
  208. begin
  209. System.Assign (F,c);
  210. end;
  211. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  212. Procedure AssignFile(out f:TypedFile;const Name:RawBytestring);
  213. begin
  214. System.Assign (F,Name);
  215. end;
  216. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  217. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  218. Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
  219. begin
  220. System.Assign (F,Name);
  221. end;
  222. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  223. {$endif FPC_HAS_FEATURE_FILEIO}
  224. {$ifdef FPC_HAS_FEATURE_COMMANDARGS}
  225. Function ParamStr(Param : Integer) : ansistring;
  226. begin
  227. {
  228. Paramstr(0) should return the name of the binary.
  229. Since this functionality is included in the system unit,
  230. we fetch it from there.
  231. Normally, pathnames are less than 255 chars anyway,
  232. so this will work correct in 99% of all cases.
  233. In time, the system unit should get a GetExeName call.
  234. }
  235. if (Param=0) then
  236. Result:=System.Paramstr(0)
  237. else if (Param>0) and (Param<argc) then
  238. Result:=Argv[Param]
  239. else
  240. Result:='';
  241. end;
  242. {$endif FPC_HAS_FEATURE_COMMANDARGS}
  243. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  244. { ---------------------------------------------------------------------
  245. ResourceString support
  246. ---------------------------------------------------------------------}
  247. Function Hash(S : AnsiString) : LongWord;
  248. Var
  249. thehash,g,I : LongWord;
  250. begin
  251. thehash:=0;
  252. For I:=1 to Length(S) do { 0 terminated }
  253. begin
  254. thehash:=thehash shl 4;
  255. inc(theHash,Ord(S[i]));
  256. g:=thehash and LongWord($f shl 28);
  257. if g<>0 then
  258. begin
  259. thehash:=thehash xor (g shr 24);
  260. thehash:=thehash xor g;
  261. end;
  262. end;
  263. If theHash=0 then
  264. Hash:=$ffffffff
  265. else
  266. Hash:=TheHash;
  267. end;
  268. {$ifdef RESSTRSECTIONS}
  269. Type
  270. PResourceStringRecord = ^TResourceStringRecord;
  271. TResourceStringRecord = Packed Record
  272. Name,
  273. CurrentValue,
  274. DefaultValue : AnsiString;
  275. HashValue : LongWord;
  276. {$ifdef cpu64}
  277. Dummy : LongWord; // alignment
  278. {$endif cpu64}
  279. end;
  280. TResourceStringTableList = Packed Record
  281. Count : sizeint;
  282. Tables : Array[{$ifdef cpu16}Byte{$else cpu16}Word{$endif cpu16}] of record
  283. TableStart,
  284. TableEnd : PResourceStringRecord;
  285. end;
  286. end;
  287. { Support for string constants initialized with resourcestrings }
  288. {$ifdef FPC_HAS_RESSTRINITS}
  289. PResStrInitEntry = ^TResStrInitEntry;
  290. TResStrInitEntry = record
  291. Addr: PPointer;
  292. Data: PResourceStringRecord;
  293. end;
  294. TResStrInitTable = packed record
  295. Count: {$ifdef VER2_6}longint{$else}sizeint{$endif};
  296. Tables: packed array[1..{$ifdef cpu16}8191{$else cpu16}32767{$endif cpu16}] of PResStrInitEntry;
  297. end;
  298. var
  299. ResStrInitTable : TResStrInitTable; external name 'FPC_RESSTRINITTABLES';
  300. procedure UpdateResourceStringRefs;
  301. var
  302. i: integer;
  303. ptable: PResStrInitEntry;
  304. begin
  305. for i:=1 to ResStrInitTable.Count do
  306. begin
  307. ptable:=ResStrInitTable.Tables[i];
  308. while Assigned(ptable^.Addr) do
  309. begin
  310. AnsiString(ptable^.Addr^):=ptable^.Data^.CurrentValue;
  311. Inc(ptable);
  312. end;
  313. end;
  314. end;
  315. {$endif FPC_HAS_RESSTRINITS}
  316. Var
  317. ResourceStringTable : TResourceStringTableList; External Name 'FPC_RESOURCESTRINGTABLES';
  318. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  319. Var
  320. ResStr : PResourceStringRecord;
  321. i : integer;
  322. s : AnsiString;
  323. begin
  324. With ResourceStringTable do
  325. begin
  326. For i:=0 to Count-1 do
  327. begin
  328. ResStr:=Tables[I].TableStart;
  329. { Skip first entry (name of the Unit) }
  330. inc(ResStr);
  331. while ResStr<Tables[I].TableEnd do
  332. begin
  333. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  334. if s<>'' then
  335. ResStr^.CurrentValue:=s;
  336. inc(ResStr);
  337. end;
  338. end;
  339. end;
  340. {$ifdef FPC_HAS_RESSTRINITS}
  341. UpdateResourceStringRefs;
  342. {$endif FPC_HAS_RESSTRINITS}
  343. end;
  344. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  345. Var
  346. ResStr : PResourceStringRecord;
  347. i : integer;
  348. s,
  349. UpUnitName : AnsiString;
  350. begin
  351. With ResourceStringTable do
  352. begin
  353. UpUnitName:=UpCase(UnitName);
  354. For i:=0 to Count-1 do
  355. begin
  356. ResStr:=Tables[I].TableStart;
  357. { Check name of the Unit }
  358. if ResStr^.Name<>UpUnitName then
  359. continue;
  360. inc(ResStr);
  361. while ResStr<Tables[I].TableEnd do
  362. begin
  363. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  364. if s<>'' then
  365. ResStr^.CurrentValue:=s;
  366. inc(ResStr);
  367. end;
  368. end;
  369. end;
  370. {$ifdef FPC_HAS_RESSTRINITS}
  371. { Resourcestrings of one unit may be referenced from other units,
  372. so updating everything is the only option. }
  373. UpdateResourceStringRefs;
  374. {$endif FPC_HAS_RESSTRINITS}
  375. end;
  376. Procedure ResetResourceTables;
  377. Var
  378. ResStr : PResourceStringRecord;
  379. i : integer;
  380. begin
  381. With ResourceStringTable do
  382. begin
  383. For i:=0 to Count-1 do
  384. begin
  385. ResStr:=Tables[I].TableStart;
  386. { Skip first entry (name of the Unit) }
  387. inc(ResStr);
  388. while ResStr<Tables[I].TableEnd do
  389. begin
  390. ResStr^.CurrentValue:=ResStr^.DefaultValue;
  391. inc(ResStr);
  392. end;
  393. end;
  394. end;
  395. end;
  396. Procedure FinalizeResourceTables;
  397. Var
  398. ResStr : PResourceStringRecord;
  399. i : integer;
  400. begin
  401. With ResourceStringTable do
  402. begin
  403. For i:=0 to Count-1 do
  404. begin
  405. ResStr:=Tables[I].TableStart;
  406. { Skip first entry (name of the Unit) }
  407. inc(ResStr);
  408. while ResStr<Tables[I].TableEnd do
  409. begin
  410. ResStr^.CurrentValue:='';
  411. inc(ResStr);
  412. end;
  413. end;
  414. end;
  415. end;
  416. {$else RESSTRSECTIONS}
  417. Type
  418. PResourceStringRecord = ^TResourceStringRecord;
  419. TResourceStringRecord = Packed Record
  420. DefaultValue,
  421. CurrentValue : AnsiString;
  422. HashValue : LongWord;
  423. Name : AnsiString;
  424. end;
  425. TResourceStringTable = Packed Record
  426. Count : longint;
  427. Resrec : Array[Word] of TResourceStringRecord;
  428. end;
  429. PResourceStringTable = ^TResourceStringTable;
  430. TResourceTableList = Packed Record
  431. Count : longint;
  432. Tables : Array[Word] of PResourceStringTable;
  433. end;
  434. Var
  435. ResourceStringTable : TResourceTablelist; External Name 'FPC_RESOURCESTRINGTABLES';
  436. Function GetResourceString(Const TheTable: TResourceStringTable;Index : longint) : AnsiString;[Public,Alias : 'FPC_GETRESOURCESTRING'];
  437. begin
  438. If (Index>=0) and (Index<TheTAble.Count) then
  439. Result:=TheTable.ResRec[Index].CurrentValue
  440. else
  441. Result:='';
  442. end;
  443. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  444. Var I,J : longint;
  445. begin
  446. With ResourceStringTable do
  447. For I:=0 to Count-1 do
  448. With Tables[I]^ do
  449. For J:=0 to Count-1 do
  450. With ResRec[J] do
  451. CurrentValue:=SetFunction(Name,DefaultValue,Longint(HashValue),arg);
  452. end;
  453. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  454. begin
  455. SetResourceStrings (SetFunction,arg);
  456. end;
  457. Procedure ResetResourceTables;
  458. Var I,J : longint;
  459. begin
  460. With ResourceStringTable do
  461. For I:=0 to Count-1 do
  462. With Tables[I]^ do
  463. For J:=0 to Count-1 do
  464. With ResRec[J] do
  465. CurrentValue:=DefaultValue;
  466. end;
  467. Procedure FinalizeResourceTables;
  468. Var I,J : longint;
  469. begin
  470. With ResourceStringTable do
  471. For I:=0 to Count-1 do
  472. With Tables[I]^ do
  473. For J:=0 to Count-1 do
  474. With ResRec[J] do
  475. CurrentValue:='';
  476. end;
  477. Function ResourceStringTableCount : Longint;
  478. begin
  479. Result:=ResourceStringTable.Count;
  480. end;
  481. Function CheckTableIndex (Index: longint) : Boolean;
  482. begin
  483. Result:=(Index<ResourceStringTable.Count) and (Index>=0)
  484. end;
  485. Function CheckStringIndex (TableIndex,Index: longint) : Boolean;
  486. begin
  487. Result:=(TableIndex<ResourceStringTable.Count) and (TableIndex>=0) and
  488. (Index<ResourceStringTable.Tables[TableIndex]^.Count) and (Index>=0)
  489. end;
  490. Function ResourceStringCount(TableIndex : longint) : longint;
  491. begin
  492. If not CheckTableIndex(TableIndex) then
  493. Result:=-1
  494. else
  495. Result:=ResourceStringTable.Tables[TableIndex]^.Count;
  496. end;
  497. Function GetResourceStringName(TableIndex,StringIndex : Longint) : Ansistring;
  498. begin
  499. If not CheckStringIndex(Tableindex,StringIndex) then
  500. Result:=''
  501. else
  502. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].Name;
  503. end;
  504. Function GetResourceStringHash(TableIndex,StringIndex : Longint) : Longint;
  505. begin
  506. If not CheckStringIndex(Tableindex,StringIndex) then
  507. Result:=0
  508. else
  509. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].HashValue;
  510. end;
  511. Function GetResourceStringDefaultValue(TableIndex,StringIndex : Longint) : AnsiString;
  512. begin
  513. If not CheckStringIndex(Tableindex,StringIndex) then
  514. Result:=''
  515. else
  516. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].DefaultValue;
  517. end;
  518. Function GetResourceStringCurrentValue(TableIndex,StringIndex : Longint) : AnsiString;
  519. begin
  520. If not CheckStringIndex(Tableindex,StringIndex) then
  521. Result:=''
  522. else
  523. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].CurrentValue;
  524. end;
  525. Function SetResourceStringValue(TableIndex,StringIndex : longint; Value : Ansistring) : Boolean;
  526. begin
  527. Result:=CheckStringIndex(Tableindex,StringIndex);
  528. If Result then
  529. ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].CurrentValue:=Value;
  530. end;
  531. {$endif RESSTRSECTIONS}
  532. Function LoadResString(p:PResStringRec):AnsiString;
  533. begin
  534. Result:=p^;
  535. end;
  536. {$endif FPC_HAS_FEATURE_RESOURCES}
  537. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  538. Initialization
  539. { ResetResourceTables;}
  540. finalization
  541. FinalizeResourceTables;
  542. {$endif FPC_HAS_FEATURE_RESOURCES}
  543. end.