objpas.pp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  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. { Delphi compatibility }
  131. type
  132. PResStringRec=^AnsiString;
  133. TResStringRec=AnsiString;
  134. Function LoadResString(p:PResStringRec):AnsiString;
  135. {$endif FPC_HAS_FEATURE_RESOURCES}
  136. implementation
  137. {****************************************************************************
  138. Compatibility routines.
  139. ****************************************************************************}
  140. {$ifdef FPC_HAS_FEATURE_FILEIO}
  141. { Untyped file support }
  142. Procedure AssignFile(out f:File;p:pchar);
  143. begin
  144. System.Assign (F,p);
  145. end;
  146. Procedure AssignFile(out f:File;c:char);
  147. begin
  148. System.Assign (F,c);
  149. end;
  150. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  151. Procedure AssignFile(out f:File;const Name:RawBytestring);
  152. begin
  153. System.Assign (F,Name);
  154. end;
  155. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  156. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  157. Procedure AssignFile(out f:File;const Name:UnicodeString);
  158. begin
  159. System.Assign (F,Name);
  160. end;
  161. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  162. Procedure CloseFile(Var f:File); [IOCheck];
  163. begin
  164. { Catch Runtime error/Exception }
  165. System.Close(f);
  166. end;
  167. {$endif FPC_HAS_FEATURE_FILEIO}
  168. {$ifdef FPC_HAS_FEATURE_TEXTIO}
  169. { Text file support }
  170. Procedure AssignFile(out t:Text;p:pchar);
  171. begin
  172. System.Assign (T,p);
  173. end;
  174. Procedure AssignFile(out t:Text;c:char);
  175. begin
  176. System.Assign (T,c);
  177. end;
  178. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  179. Procedure AssignFile(out t:Text;const Name:RawBytestring);
  180. begin
  181. System.Assign (T,Name);
  182. end;
  183. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  184. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  185. Procedure AssignFile(out t:Text;const Name:UnicodeString);
  186. begin
  187. System.Assign (T,Name);
  188. end;
  189. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  190. Procedure CloseFile(Var t:Text); [IOCheck];
  191. begin
  192. { Catch Runtime error/Exception }
  193. System.Close(T);
  194. end;
  195. {$endif FPC_HAS_FEATURE_TEXTIO}
  196. {$ifdef FPC_HAS_FEATURE_FILEIO}
  197. { Typed file support }
  198. Procedure AssignFile(out f:TypedFile;p:pchar);
  199. begin
  200. System.Assign (F,p);
  201. end;
  202. Procedure AssignFile(out f:TypedFile;c:char);
  203. begin
  204. System.Assign (F,c);
  205. end;
  206. {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
  207. Procedure AssignFile(out f:TypedFile;const Name:RawBytestring);
  208. begin
  209. System.Assign (F,Name);
  210. end;
  211. {$endif FPC_HAS_FEATURE_ANSISTRINGS}
  212. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  213. Procedure AssignFile(out f:TypedFile;const Name:UnicodeString);
  214. begin
  215. System.Assign (F,Name);
  216. end;
  217. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  218. {$endif FPC_HAS_FEATURE_FILEIO}
  219. {$ifdef FPC_HAS_FEATURE_COMMANDARGS}
  220. Function ParamStr(Param : Integer) : ansistring;
  221. begin
  222. {
  223. Paramstr(0) should return the name of the binary.
  224. Since this functionality is included in the system unit,
  225. we fetch it from there.
  226. Normally, pathnames are less than 255 chars anyway,
  227. so this will work correct in 99% of all cases.
  228. In time, the system unit should get a GetExeName call.
  229. }
  230. if (Param=0) then
  231. Result:=System.Paramstr(0)
  232. else if (Param>0) and (Param<argc) then
  233. Result:=Argv[Param]
  234. else
  235. Result:='';
  236. end;
  237. {$endif FPC_HAS_FEATURE_COMMANDARGS}
  238. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  239. { ---------------------------------------------------------------------
  240. ResourceString support
  241. ---------------------------------------------------------------------}
  242. Function Hash(S : AnsiString) : LongWord;
  243. Var
  244. thehash,g,I : LongWord;
  245. begin
  246. thehash:=0;
  247. For I:=1 to Length(S) do { 0 terminated }
  248. begin
  249. thehash:=thehash shl 4;
  250. inc(theHash,Ord(S[i]));
  251. g:=thehash and LongWord($f shl 28);
  252. if g<>0 then
  253. begin
  254. thehash:=thehash xor (g shr 24);
  255. thehash:=thehash xor g;
  256. end;
  257. end;
  258. If theHash=0 then
  259. Hash:=$ffffffff
  260. else
  261. Hash:=TheHash;
  262. end;
  263. Type
  264. PResourceStringRecord = ^TResourceStringRecord;
  265. TResourceStringRecord = Packed Record
  266. Name,
  267. CurrentValue,
  268. DefaultValue : AnsiString;
  269. HashValue : LongWord;
  270. {$ifdef cpu64}
  271. Dummy : LongWord; // alignment
  272. {$endif cpu64}
  273. end;
  274. TResourceStringTableList = Packed Record
  275. Count : sizeint;
  276. Tables : Array[{$ifdef cpu16}Byte{$else cpu16}Word{$endif cpu16}] of record
  277. TableStart,
  278. TableEnd : PResourceStringRecord;
  279. end;
  280. end;
  281. { Support for string constants initialized with resourcestrings }
  282. {$ifdef FPC_HAS_RESSTRINITS}
  283. PResStrInitEntry = ^TResStrInitEntry;
  284. TResStrInitEntry = record
  285. Addr: PPointer;
  286. Data: PResourceStringRecord;
  287. end;
  288. TResStrInitTable = packed record
  289. Count: {$ifdef VER2_6}longint{$else}sizeint{$endif};
  290. Tables: packed array[1..{$ifdef cpu16}8191{$else cpu16}32767{$endif cpu16}] of PResStrInitEntry;
  291. end;
  292. var
  293. ResStrInitTable : TResStrInitTable; external name 'FPC_RESSTRINITTABLES';
  294. procedure UpdateResourceStringRefs;
  295. var
  296. i: integer;
  297. ptable: PResStrInitEntry;
  298. begin
  299. for i:=1 to ResStrInitTable.Count do
  300. begin
  301. ptable:=ResStrInitTable.Tables[i];
  302. while Assigned(ptable^.Addr) do
  303. begin
  304. AnsiString(ptable^.Addr^):=ptable^.Data^.CurrentValue;
  305. Inc(ptable);
  306. end;
  307. end;
  308. end;
  309. {$endif FPC_HAS_RESSTRINITS}
  310. Var
  311. ResourceStringTable : TResourceStringTableList; External Name 'FPC_RESOURCESTRINGTABLES';
  312. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  313. Var
  314. ResStr : PResourceStringRecord;
  315. i : integer;
  316. s : AnsiString;
  317. begin
  318. With ResourceStringTable do
  319. begin
  320. For i:=0 to Count-1 do
  321. begin
  322. ResStr:=Tables[I].TableStart;
  323. { Skip first entry (name of the Unit) }
  324. inc(ResStr);
  325. while ResStr<Tables[I].TableEnd do
  326. begin
  327. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  328. if s<>'' then
  329. ResStr^.CurrentValue:=s;
  330. inc(ResStr);
  331. end;
  332. end;
  333. end;
  334. {$ifdef FPC_HAS_RESSTRINITS}
  335. UpdateResourceStringRefs;
  336. {$endif FPC_HAS_RESSTRINITS}
  337. end;
  338. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  339. Var
  340. ResStr : PResourceStringRecord;
  341. i : integer;
  342. s,
  343. UpUnitName : AnsiString;
  344. begin
  345. With ResourceStringTable do
  346. begin
  347. UpUnitName:=UpCase(UnitName);
  348. For i:=0 to Count-1 do
  349. begin
  350. ResStr:=Tables[I].TableStart;
  351. { Check name of the Unit }
  352. if ResStr^.Name<>UpUnitName then
  353. continue;
  354. inc(ResStr);
  355. while ResStr<Tables[I].TableEnd do
  356. begin
  357. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  358. if s<>'' then
  359. ResStr^.CurrentValue:=s;
  360. inc(ResStr);
  361. end;
  362. end;
  363. end;
  364. {$ifdef FPC_HAS_RESSTRINITS}
  365. { Resourcestrings of one unit may be referenced from other units,
  366. so updating everything is the only option. }
  367. UpdateResourceStringRefs;
  368. {$endif FPC_HAS_RESSTRINITS}
  369. end;
  370. Procedure ResetResourceTables;
  371. Var
  372. ResStr : PResourceStringRecord;
  373. i : integer;
  374. begin
  375. With ResourceStringTable do
  376. begin
  377. For i:=0 to Count-1 do
  378. begin
  379. ResStr:=Tables[I].TableStart;
  380. { Skip first entry (name of the Unit) }
  381. inc(ResStr);
  382. while ResStr<Tables[I].TableEnd do
  383. begin
  384. ResStr^.CurrentValue:=ResStr^.DefaultValue;
  385. inc(ResStr);
  386. end;
  387. end;
  388. end;
  389. end;
  390. Procedure FinalizeResourceTables;
  391. Var
  392. ResStr : PResourceStringRecord;
  393. i : integer;
  394. begin
  395. With ResourceStringTable do
  396. begin
  397. For i:=0 to Count-1 do
  398. begin
  399. ResStr:=Tables[I].TableStart;
  400. { Skip first entry (name of the Unit) }
  401. inc(ResStr);
  402. while ResStr<Tables[I].TableEnd do
  403. begin
  404. ResStr^.CurrentValue:='';
  405. inc(ResStr);
  406. end;
  407. end;
  408. end;
  409. end;
  410. Function LoadResString(p:PResStringRec):AnsiString;
  411. begin
  412. Result:=p^;
  413. end;
  414. {$endif FPC_HAS_FEATURE_RESOURCES}
  415. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  416. Initialization
  417. { ResetResourceTables;}
  418. finalization
  419. FinalizeResourceTables;
  420. {$endif FPC_HAS_FEATURE_RESOURCES}
  421. end.