objpas.pp 15 KB

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