objpas.pp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  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. Procedure AssignFile(out f:File;const Name:UnicodeString);
  81. Procedure AssignFile(out f:File;const Name:RawByteString);
  82. Procedure CloseFile(var f:File);
  83. {$endif FPC_HAS_FEATURE_FILEIO}
  84. {$ifdef FPC_HAS_FEATURE_TEXTIO}
  85. { Text file support }
  86. Procedure AssignFile(out t:Text;p:pchar);
  87. Procedure AssignFile(out t:Text;c:char);
  88. Procedure AssignFile(out t:Text;const Name:UnicodeString);
  89. Procedure AssignFile(out t:Text;const Name:RawByteString);
  90. Procedure CloseFile(Var t:Text);
  91. {$endif FPC_HAS_FEATURE_TEXTIO}
  92. {$ifdef FPC_HAS_FEATURE_FILEIO}
  93. { Typed file supoort }
  94. Procedure AssignFile(out f:TypedFile;p:pchar);
  95. Procedure AssignFile(out f:TypedFile;c:char);
  96. Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
  97. Procedure AssignFile(out f:TypedFile;const Name:RawByteString);
  98. {$endif FPC_HAS_FEATURE_FILEIO}
  99. {$ifdef FPC_HAS_FEATURE_COMMANDARGS}
  100. { ParamStr should return also an ansistring }
  101. Function ParamStr(Param : Integer) : Ansistring;
  102. {$endif FPC_HAS_FEATURE_COMMANDARGS}
  103. {****************************************************************************
  104. Resource strings.
  105. ****************************************************************************}
  106. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  107. type
  108. TResourceIterator = Function (Name,Value : AnsiString; Hash : Longint; arg:pointer) : AnsiString;
  109. Function Hash(S : AnsiString) : LongWord;
  110. Procedure ResetResourceTables;
  111. Procedure FinalizeResourceTables;
  112. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  113. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  114. {$ifndef RESSTRSECTIONS}
  115. Function ResourceStringTableCount : Longint;
  116. Function ResourceStringCount(TableIndex : longint) : longint;
  117. Function GetResourceStringName(TableIndex,StringIndex : Longint) : Ansistring;
  118. Function GetResourceStringHash(TableIndex,StringIndex : Longint) : Longint;
  119. Function GetResourceStringDefaultValue(TableIndex,StringIndex : Longint) : AnsiString;
  120. Function GetResourceStringCurrentValue(TableIndex,StringIndex : Longint) : AnsiString;
  121. Function SetResourceStringValue(TableIndex,StringIndex : longint; Value : Ansistring) : Boolean;
  122. {$endif RESSTRSECTIONS}
  123. { Delphi compatibility }
  124. type
  125. PResStringRec=^AnsiString;
  126. TResStringRec=AnsiString;
  127. Function LoadResString(p:PResStringRec):AnsiString;
  128. {$endif FPC_HAS_FEATURE_RESOURCES}
  129. implementation
  130. {****************************************************************************
  131. Compatibility routines.
  132. ****************************************************************************}
  133. {$ifdef FPC_HAS_FEATURE_FILEIO}
  134. { Untyped file support }
  135. Procedure AssignFile(out f:File;p:pchar);
  136. begin
  137. System.Assign (F,p);
  138. end;
  139. Procedure AssignFile(out f:File;c:char);
  140. begin
  141. System.Assign (F,c);
  142. end;
  143. Procedure AssignFile(out f:File;const Name:RawBytestring);
  144. begin
  145. System.Assign (F,Name);
  146. end;
  147. Procedure AssignFile(out f:File;const Name:UnicodeString);
  148. begin
  149. System.Assign (F,Name);
  150. end;
  151. Procedure CloseFile(Var f:File); [IOCheck];
  152. begin
  153. { Catch Runtime error/Exception }
  154. System.Close(f);
  155. end;
  156. {$endif FPC_HAS_FEATURE_FILEIO}
  157. {$ifdef FPC_HAS_FEATURE_TEXTIO}
  158. { Text file support }
  159. Procedure AssignFile(out t:Text;p:pchar);
  160. begin
  161. System.Assign (T,p);
  162. end;
  163. Procedure AssignFile(out t:Text;c:char);
  164. begin
  165. System.Assign (T,c);
  166. end;
  167. Procedure AssignFile(out t:Text;const Name:RawBytestring);
  168. begin
  169. System.Assign (T,Name);
  170. end;
  171. Procedure AssignFile(out t:Text;const Name:UnicodeString);
  172. begin
  173. System.Assign (T,Name);
  174. end;
  175. Procedure CloseFile(Var t:Text); [IOCheck];
  176. begin
  177. { Catch Runtime error/Exception }
  178. System.Close(T);
  179. end;
  180. {$endif FPC_HAS_FEATURE_TEXTIO}
  181. {$ifdef FPC_HAS_FEATURE_FILEIO}
  182. { Typed file support }
  183. Procedure AssignFile(out f:TypedFile;p:pchar);
  184. begin
  185. System.Assign (F,p);
  186. end;
  187. Procedure AssignFile(out f:TypedFile;c:char);
  188. begin
  189. System.Assign (F,c);
  190. end;
  191. Procedure AssignFile(out f:TypedFile;const Name:RawBytestring);
  192. begin
  193. System.Assign (F,Name);
  194. end;
  195. Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
  196. begin
  197. System.Assign (F,Name);
  198. end;
  199. {$endif FPC_HAS_FEATURE_FILEIO}
  200. {$ifdef FPC_HAS_FEATURE_COMMANDARGS}
  201. Function ParamStr(Param : Integer) : ansistring;
  202. begin
  203. {
  204. Paramstr(0) should return the name of the binary.
  205. Since this functionality is included in the system unit,
  206. we fetch it from there.
  207. Normally, pathnames are less than 255 chars anyway,
  208. so this will work correct in 99% of all cases.
  209. In time, the system unit should get a GetExeName call.
  210. }
  211. if (Param=0) then
  212. Result:=System.Paramstr(0)
  213. else if (Param>0) and (Param<argc) then
  214. Result:=Argv[Param]
  215. else
  216. Result:='';
  217. end;
  218. {$endif FPC_HAS_FEATURE_COMMANDARGS}
  219. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  220. { ---------------------------------------------------------------------
  221. ResourceString support
  222. ---------------------------------------------------------------------}
  223. Function Hash(S : AnsiString) : LongWord;
  224. Var
  225. thehash,g,I : LongWord;
  226. begin
  227. thehash:=0;
  228. For I:=1 to Length(S) do { 0 terminated }
  229. begin
  230. thehash:=thehash shl 4;
  231. inc(theHash,Ord(S[i]));
  232. g:=thehash and LongWord($f shl 28);
  233. if g<>0 then
  234. begin
  235. thehash:=thehash xor (g shr 24);
  236. thehash:=thehash xor g;
  237. end;
  238. end;
  239. If theHash=0 then
  240. Hash:=$ffffffff
  241. else
  242. Hash:=TheHash;
  243. end;
  244. {$ifdef RESSTRSECTIONS}
  245. Type
  246. PResourceStringRecord = ^TResourceStringRecord;
  247. TResourceStringRecord = Packed Record
  248. Name,
  249. CurrentValue,
  250. DefaultValue : AnsiString;
  251. HashValue : LongWord;
  252. {$ifdef cpu64}
  253. Dummy : LongWord; // alignment
  254. {$endif cpu64}
  255. end;
  256. PPResourceStringRecord = ^PResourceStringRecord;
  257. TResourceStringTableList = Packed Record
  258. Count : sizeint;
  259. Tables : Array[{$ifdef cpu16}Byte{$else cpu16}Word{$endif cpu16}] of record
  260. {$ifndef ver2_6}
  261. TableStart,
  262. TableEnd : PPResourceStringRecord;
  263. {$else ver2_6}
  264. TableStart,
  265. TableEnd : PResourceStringRecord;
  266. {$endif ver2_6}
  267. end;
  268. end;
  269. PResourceStringTableList = ^TResourceStringTableList;
  270. {$if defined(win32) or (defined(darwin) and not defined(ver2_6))}
  271. {$define FPC_HAS_INDIRECT_MAIN_INFORMATION}
  272. {$endif}
  273. { Support for string constants initialized with resourcestrings }
  274. {$ifdef FPC_HAS_RESSTRINITS}
  275. PResStrInitEntry = ^TResStrInitEntry;
  276. TResStrInitEntry = record
  277. Addr: PPointer;
  278. Data: PResourceStringRecord;
  279. end;
  280. PPResStrInitEntry = ^PResStrInitEntry;
  281. TResStrInitTable = packed record
  282. Count: {$ifdef VER2_6}longint{$else}sizeint{$endif};
  283. Tables: packed array[1..{$ifdef cpu16}8191{$else cpu16}32767{$endif cpu16}] of {$ifndef ver2_6}PPResStrInitEntry{$else}PResStrInitEntry{$endif};
  284. end;
  285. PResStrInitTable = ^TResStrInitTable;
  286. var
  287. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  288. ResStrInitTable : PResStrInitTable; external name '_FPC_ResStrInitTables';
  289. {$else}
  290. ResStrInitTableVar : TResStrInitTable; external name 'FPC_RESSTRINITTABLES';
  291. ResStrInitTable : PResStrInitTable = @ResStrInitTableVar;
  292. {$endif}
  293. procedure UpdateResourceStringRefs;
  294. var
  295. i: integer;
  296. ptable: PResStrInitEntry;
  297. begin
  298. for i:=1 to ResStrInitTable^.Count do
  299. begin
  300. ptable:=ResStrInitTable^.Tables[i]{$ifndef ver2_6}^{$endif};
  301. while Assigned(ptable^.Addr) do
  302. begin
  303. AnsiString(ptable^.Addr^):=ptable^.Data^.CurrentValue;
  304. Inc(ptable);
  305. end;
  306. end;
  307. end;
  308. {$endif FPC_HAS_RESSTRINITS}
  309. var
  310. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  311. ResourceStringTable : PResourceStringTableList; external name '_FPC_ResourceStringTables';
  312. {$else}
  313. ResourceStringTableVar : TResourceStringTableList; External Name 'FPC_RESOURCESTRINGTABLES';
  314. ResourceStringTable : PResourceStringTableList = @ResourceStringTableVar;
  315. {$endif}
  316. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  317. Var
  318. ResStr : PResourceStringRecord;
  319. i : integer;
  320. s : AnsiString;
  321. begin
  322. With ResourceStringTable^ do
  323. begin
  324. For i:=0 to Count-1 do
  325. begin
  326. ResStr:=Tables[I].TableStart{$ifndef ver2_6}^{$endif};
  327. { Skip first entry (name of the Unit) }
  328. inc(ResStr);
  329. while ResStr<Tables[I].TableEnd{$ifndef ver2_6}^{$endif} do
  330. begin
  331. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  332. if s<>'' then
  333. ResStr^.CurrentValue:=s;
  334. inc(ResStr);
  335. end;
  336. end;
  337. end;
  338. {$ifdef FPC_HAS_RESSTRINITS}
  339. UpdateResourceStringRefs;
  340. {$endif FPC_HAS_RESSTRINITS}
  341. end;
  342. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  343. Var
  344. ResStr : PResourceStringRecord;
  345. i : integer;
  346. s,
  347. UpUnitName : AnsiString;
  348. begin
  349. With ResourceStringTable^ do
  350. begin
  351. UpUnitName:=UpCase(UnitName);
  352. For i:=0 to Count-1 do
  353. begin
  354. ResStr:=Tables[I].TableStart{$ifndef ver2_6}^{$endif};
  355. { Check name of the Unit }
  356. if ResStr^.Name<>UpUnitName then
  357. continue;
  358. inc(ResStr);
  359. while ResStr<Tables[I].TableEnd{$ifndef ver2_6}^{$endif} do
  360. begin
  361. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  362. if s<>'' then
  363. ResStr^.CurrentValue:=s;
  364. inc(ResStr);
  365. end;
  366. end;
  367. end;
  368. {$ifdef FPC_HAS_RESSTRINITS}
  369. { Resourcestrings of one unit may be referenced from other units,
  370. so updating everything is the only option. }
  371. UpdateResourceStringRefs;
  372. {$endif FPC_HAS_RESSTRINITS}
  373. end;
  374. Procedure ResetResourceTables;
  375. Var
  376. ResStr : PResourceStringRecord;
  377. i : integer;
  378. begin
  379. With ResourceStringTable^ do
  380. begin
  381. For i:=0 to Count-1 do
  382. begin
  383. ResStr:=Tables[I].TableStart{$ifndef ver2_6}^{$endif};
  384. { Skip first entry (name of the Unit) }
  385. inc(ResStr);
  386. while ResStr<Tables[I].TableEnd{$ifndef ver2_6}^{$endif} do
  387. begin
  388. ResStr^.CurrentValue:=ResStr^.DefaultValue;
  389. inc(ResStr);
  390. end;
  391. end;
  392. end;
  393. end;
  394. Procedure FinalizeResourceTables;
  395. Var
  396. ResStr : PResourceStringRecord;
  397. i : integer;
  398. begin
  399. With ResourceStringTable^ do
  400. begin
  401. For i:=0 to Count-1 do
  402. begin
  403. ResStr:=Tables[I].TableStart{$ifndef ver2_6}^{$endif};
  404. { Skip first entry (name of the Unit) }
  405. inc(ResStr);
  406. while ResStr<Tables[I].TableEnd{$ifndef ver2_6}^{$endif} do
  407. begin
  408. ResStr^.CurrentValue:='';
  409. inc(ResStr);
  410. end;
  411. end;
  412. end;
  413. end;
  414. {$else RESSTRSECTIONS}
  415. Type
  416. PResourceStringRecord = ^TResourceStringRecord;
  417. TResourceStringRecord = Packed Record
  418. DefaultValue,
  419. CurrentValue : AnsiString;
  420. HashValue : LongWord;
  421. Name : AnsiString;
  422. end;
  423. TResourceStringTable = Packed Record
  424. Count : longint;
  425. Resrec : Array[Word] of TResourceStringRecord;
  426. end;
  427. PResourceStringTable = ^TResourceStringTable;
  428. TResourceTableList = Packed Record
  429. Count : longint;
  430. Tables : Array[Word] of PResourceStringTable;
  431. end;
  432. var
  433. {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
  434. ResourceStringTable : PResourceTableList; external name '_FPC_ResourceStringTables';
  435. {$else}
  436. ResourceStringTableVar : TResourceTablelist; External Name 'FPC_RESOURCESTRINGTABLES';
  437. ResourceStringTable : PResourceTableList = @ResourceStringTableVar;
  438. {$endif}
  439. Function GetResourceString(Const TheTable: TResourceStringTable;Index : longint) : AnsiString;[Public,Alias : 'FPC_GETRESOURCESTRING'];
  440. begin
  441. If (Index>=0) and (Index<TheTAble.Count) then
  442. Result:=TheTable.ResRec[Index].CurrentValue
  443. else
  444. Result:='';
  445. end;
  446. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  447. Var I,J : longint;
  448. begin
  449. With ResourceStringTable^ do
  450. For I:=0 to Count-1 do
  451. With Tables[I]^ do
  452. For J:=0 to Count-1 do
  453. With ResRec[J] do
  454. CurrentValue:=SetFunction(Name,DefaultValue,Longint(HashValue),arg);
  455. end;
  456. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  457. begin
  458. SetResourceStrings (SetFunction,arg);
  459. end;
  460. Procedure ResetResourceTables;
  461. Var I,J : longint;
  462. begin
  463. With ResourceStringTable^ do
  464. For I:=0 to Count-1 do
  465. With Tables[I]^ do
  466. For J:=0 to Count-1 do
  467. With ResRec[J] do
  468. CurrentValue:=DefaultValue;
  469. end;
  470. Procedure FinalizeResourceTables;
  471. Var I,J : longint;
  472. begin
  473. With ResourceStringTable^ do
  474. For I:=0 to Count-1 do
  475. With Tables[I]^ do
  476. For J:=0 to Count-1 do
  477. With ResRec[J] do
  478. CurrentValue:='';
  479. end;
  480. Function ResourceStringTableCount : Longint;
  481. begin
  482. Result:=ResourceStringTable^.Count;
  483. end;
  484. Function CheckTableIndex (Index: longint) : Boolean;
  485. begin
  486. Result:=(Index<ResourceStringTable^.Count) and (Index>=0)
  487. end;
  488. Function CheckStringIndex (TableIndex,Index: longint) : Boolean;
  489. begin
  490. Result:=(TableIndex<ResourceStringTable^.Count) and (TableIndex>=0) and
  491. (Index<ResourceStringTable^.Tables[TableIndex]^.Count) and (Index>=0)
  492. end;
  493. Function ResourceStringCount(TableIndex : longint) : longint;
  494. begin
  495. If not CheckTableIndex(TableIndex) then
  496. Result:=-1
  497. else
  498. Result:=ResourceStringTable^.Tables[TableIndex]^.Count;
  499. end;
  500. Function GetResourceStringName(TableIndex,StringIndex : Longint) : Ansistring;
  501. begin
  502. If not CheckStringIndex(Tableindex,StringIndex) then
  503. Result:=''
  504. else
  505. result:=ResourceStringTable^.Tables[TableIndex]^.ResRec[StringIndex].Name;
  506. end;
  507. Function GetResourceStringHash(TableIndex,StringIndex : Longint) : Longint;
  508. begin
  509. If not CheckStringIndex(Tableindex,StringIndex) then
  510. Result:=0
  511. else
  512. result:=ResourceStringTable^.Tables[TableIndex]^.ResRec[StringIndex].HashValue;
  513. end;
  514. Function GetResourceStringDefaultValue(TableIndex,StringIndex : Longint) : AnsiString;
  515. begin
  516. If not CheckStringIndex(Tableindex,StringIndex) then
  517. Result:=''
  518. else
  519. result:=ResourceStringTable^.Tables[TableIndex]^.ResRec[StringIndex].DefaultValue;
  520. end;
  521. Function GetResourceStringCurrentValue(TableIndex,StringIndex : Longint) : AnsiString;
  522. begin
  523. If not CheckStringIndex(Tableindex,StringIndex) then
  524. Result:=''
  525. else
  526. result:=ResourceStringTable^.Tables[TableIndex]^.ResRec[StringIndex].CurrentValue;
  527. end;
  528. Function SetResourceStringValue(TableIndex,StringIndex : longint; Value : Ansistring) : Boolean;
  529. begin
  530. Result:=CheckStringIndex(Tableindex,StringIndex);
  531. If Result then
  532. ResourceStringTable^.Tables[TableIndex]^.ResRec[StringIndex].CurrentValue:=Value;
  533. end;
  534. {$endif RESSTRSECTIONS}
  535. Function LoadResString(p:PResStringRec):AnsiString;
  536. begin
  537. Result:=p^;
  538. end;
  539. {$endif FPC_HAS_FEATURE_RESOURCES}
  540. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  541. Initialization
  542. { ResetResourceTables;}
  543. finalization
  544. FinalizeResourceTables;
  545. {$endif FPC_HAS_FEATURE_RESOURCES}
  546. end.