objpas.pp 16 KB

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