objpas.pp 16 KB

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