objpas.pp 15 KB

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