objpas.pp 18 KB

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