objpas.pp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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. {$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
  74. Procedure MkDir(s:ansistring);overload;
  75. Procedure RmDir(s:ansistring);overload;
  76. Procedure ChDir(s:ansistring);overload;
  77. {$endif defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
  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. {$if defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
  194. { xxDirPChar procedures can adjust directory separators in supplied string (at least
  195. Windows implementation does so). Therefore full copy of argument is needed,
  196. just passing by value isn't enough because it won't copy a string literal. }
  197. Procedure MkDir(s:ansistring);[IOCheck];
  198. begin
  199. UniqueString(s);
  200. mkdirpchar(pchar(s),length(s));
  201. end;
  202. Procedure RmDir(s:ansistring);[IOCheck];
  203. begin
  204. UniqueString(s);
  205. RmDirpchar(pchar(s),length(s));
  206. end;
  207. Procedure ChDir(s:ansistring);[IOCheck];
  208. begin
  209. UniqueString(s);
  210. ChDirpchar(pchar(s),length(s));
  211. end;
  212. {$endif defined(FPC_HAS_FEATURE_FILEIO) and defined(FPC_HAS_FEATURE_ANSISTRINGS)}
  213. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  214. { ---------------------------------------------------------------------
  215. ResourceString support
  216. ---------------------------------------------------------------------}
  217. Function Hash(S : AnsiString) : LongWord;
  218. Var
  219. thehash,g,I : LongWord;
  220. begin
  221. thehash:=0;
  222. For I:=1 to Length(S) do { 0 terminated }
  223. begin
  224. thehash:=thehash shl 4;
  225. inc(theHash,Ord(S[i]));
  226. g:=thehash and LongWord($f shl 28);
  227. if g<>0 then
  228. begin
  229. thehash:=thehash xor (g shr 24);
  230. thehash:=thehash xor g;
  231. end;
  232. end;
  233. If theHash=0 then
  234. Hash:=$ffffffff
  235. else
  236. Hash:=TheHash;
  237. end;
  238. {$ifdef RESSTRSECTIONS}
  239. Type
  240. PResourceStringRecord = ^TResourceStringRecord;
  241. TResourceStringRecord = Packed Record
  242. Name,
  243. CurrentValue,
  244. DefaultValue : AnsiString;
  245. HashValue : LongWord;
  246. {$ifdef cpu64}
  247. Dummy : LongWord; // alignment
  248. {$endif cpu64}
  249. end;
  250. TResourceStringTableList = Packed Record
  251. Count : ptrint;
  252. Tables : Array[{$ifdef cpu16}Byte{$else cpu16}Word{$endif cpu16}] of record
  253. TableStart,
  254. TableEnd : PResourceStringRecord;
  255. end;
  256. end;
  257. { Support for string constants initialized with resourcestrings }
  258. {$ifdef FPC_HAS_RESSTRINITS}
  259. PResStrInitEntry = ^TResStrInitEntry;
  260. TResStrInitEntry = record
  261. Addr: PPointer;
  262. Data: PResourceStringRecord;
  263. end;
  264. TResStrInitTable = packed record
  265. Count: longint;
  266. Tables: packed array[1..{$ifdef cpu16}8191{$else cpu16}32767{$endif cpu16}] of PResStrInitEntry;
  267. end;
  268. var
  269. ResStrInitTable : TResStrInitTable; external name 'FPC_RESSTRINITTABLES';
  270. procedure UpdateResourceStringRefs;
  271. var
  272. i: Longint;
  273. ptable: PResStrInitEntry;
  274. begin
  275. for i:=1 to ResStrInitTable.Count do
  276. begin
  277. ptable:=ResStrInitTable.Tables[i];
  278. while Assigned(ptable^.Addr) do
  279. begin
  280. AnsiString(ptable^.Addr^):=ptable^.Data^.CurrentValue;
  281. Inc(ptable);
  282. end;
  283. end;
  284. end;
  285. {$endif FPC_HAS_RESSTRINITS}
  286. Var
  287. ResourceStringTable : TResourceStringTableList; External Name 'FPC_RESOURCESTRINGTABLES';
  288. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  289. Var
  290. ResStr : PResourceStringRecord;
  291. i : Longint;
  292. s : AnsiString;
  293. begin
  294. With ResourceStringTable do
  295. begin
  296. For i:=0 to Count-1 do
  297. begin
  298. ResStr:=Tables[I].TableStart;
  299. { Skip first entry (name of the Unit) }
  300. inc(ResStr);
  301. while ResStr<Tables[I].TableEnd do
  302. begin
  303. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  304. if s<>'' then
  305. ResStr^.CurrentValue:=s;
  306. inc(ResStr);
  307. end;
  308. end;
  309. end;
  310. {$ifdef FPC_HAS_RESSTRINITS}
  311. UpdateResourceStringRefs;
  312. {$endif FPC_HAS_RESSTRINITS}
  313. end;
  314. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  315. Var
  316. ResStr : PResourceStringRecord;
  317. i : Longint;
  318. s,
  319. UpUnitName : AnsiString;
  320. begin
  321. With ResourceStringTable do
  322. begin
  323. UpUnitName:=UpCase(UnitName);
  324. For i:=0 to Count-1 do
  325. begin
  326. ResStr:=Tables[I].TableStart;
  327. { Check name of the Unit }
  328. if ResStr^.Name<>UpUnitName then
  329. continue;
  330. inc(ResStr);
  331. while ResStr<Tables[I].TableEnd do
  332. begin
  333. s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg);
  334. if s<>'' then
  335. ResStr^.CurrentValue:=s;
  336. inc(ResStr);
  337. end;
  338. end;
  339. end;
  340. {$ifdef FPC_HAS_RESSTRINITS}
  341. { Resourcestrings of one unit may be referenced from other units,
  342. so updating everything is the only option. }
  343. UpdateResourceStringRefs;
  344. {$endif FPC_HAS_RESSTRINITS}
  345. end;
  346. Procedure ResetResourceTables;
  347. Var
  348. ResStr : PResourceStringRecord;
  349. i : Longint;
  350. begin
  351. With ResourceStringTable do
  352. begin
  353. For i:=0 to Count-1 do
  354. begin
  355. ResStr:=Tables[I].TableStart;
  356. { Skip first entry (name of the Unit) }
  357. inc(ResStr);
  358. while ResStr<Tables[I].TableEnd do
  359. begin
  360. ResStr^.CurrentValue:=ResStr^.DefaultValue;
  361. inc(ResStr);
  362. end;
  363. end;
  364. end;
  365. end;
  366. Procedure FinalizeResourceTables;
  367. Var
  368. ResStr : PResourceStringRecord;
  369. i : Longint;
  370. begin
  371. With ResourceStringTable do
  372. begin
  373. For i:=0 to Count-1 do
  374. begin
  375. ResStr:=Tables[I].TableStart;
  376. { Skip first entry (name of the Unit) }
  377. inc(ResStr);
  378. while ResStr<Tables[I].TableEnd do
  379. begin
  380. ResStr^.CurrentValue:='';
  381. inc(ResStr);
  382. end;
  383. end;
  384. end;
  385. end;
  386. {$else RESSTRSECTIONS}
  387. Type
  388. PResourceStringRecord = ^TResourceStringRecord;
  389. TResourceStringRecord = Packed Record
  390. DefaultValue,
  391. CurrentValue : AnsiString;
  392. HashValue : LongWord;
  393. Name : AnsiString;
  394. end;
  395. TResourceStringTable = Packed Record
  396. Count : longint;
  397. Resrec : Array[Word] of TResourceStringRecord;
  398. end;
  399. PResourceStringTable = ^TResourceStringTable;
  400. TResourceTableList = Packed Record
  401. Count : longint;
  402. Tables : Array[Word] of PResourceStringTable;
  403. end;
  404. Var
  405. ResourceStringTable : TResourceTablelist; External Name 'FPC_RESOURCESTRINGTABLES';
  406. Function GetResourceString(Const TheTable: TResourceStringTable;Index : longint) : AnsiString;[Public,Alias : 'FPC_GETRESOURCESTRING'];
  407. begin
  408. If (Index>=0) and (Index<TheTAble.Count) then
  409. Result:=TheTable.ResRec[Index].CurrentValue
  410. else
  411. Result:='';
  412. end;
  413. Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer);
  414. Var I,J : longint;
  415. begin
  416. With ResourceStringTable do
  417. For I:=0 to Count-1 do
  418. With Tables[I]^ do
  419. For J:=0 to Count-1 do
  420. With ResRec[J] do
  421. CurrentValue:=SetFunction(Name,DefaultValue,Longint(HashValue),arg);
  422. end;
  423. Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer);
  424. begin
  425. SetResourceStrings (SetFunction,arg);
  426. end;
  427. Procedure ResetResourceTables;
  428. Var I,J : longint;
  429. begin
  430. With ResourceStringTable do
  431. For I:=0 to Count-1 do
  432. With Tables[I]^ do
  433. For J:=0 to Count-1 do
  434. With ResRec[J] do
  435. CurrentValue:=DefaultValue;
  436. end;
  437. Procedure FinalizeResourceTables;
  438. Var I,J : longint;
  439. begin
  440. With ResourceStringTable do
  441. For I:=0 to Count-1 do
  442. With Tables[I]^ do
  443. For J:=0 to Count-1 do
  444. With ResRec[J] do
  445. CurrentValue:='';
  446. end;
  447. Function ResourceStringTableCount : Longint;
  448. begin
  449. Result:=ResourceStringTable.Count;
  450. end;
  451. Function CheckTableIndex (Index: longint) : Boolean;
  452. begin
  453. Result:=(Index<ResourceStringTable.Count) and (Index>=0)
  454. end;
  455. Function CheckStringIndex (TableIndex,Index: longint) : Boolean;
  456. begin
  457. Result:=(TableIndex<ResourceStringTable.Count) and (TableIndex>=0) and
  458. (Index<ResourceStringTable.Tables[TableIndex]^.Count) and (Index>=0)
  459. end;
  460. Function ResourceStringCount(TableIndex : longint) : longint;
  461. begin
  462. If not CheckTableIndex(TableIndex) then
  463. Result:=-1
  464. else
  465. Result:=ResourceStringTable.Tables[TableIndex]^.Count;
  466. end;
  467. Function GetResourceStringName(TableIndex,StringIndex : Longint) : Ansistring;
  468. begin
  469. If not CheckStringIndex(Tableindex,StringIndex) then
  470. Result:=''
  471. else
  472. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].Name;
  473. end;
  474. Function GetResourceStringHash(TableIndex,StringIndex : Longint) : Longint;
  475. begin
  476. If not CheckStringIndex(Tableindex,StringIndex) then
  477. Result:=0
  478. else
  479. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].HashValue;
  480. end;
  481. Function GetResourceStringDefaultValue(TableIndex,StringIndex : Longint) : AnsiString;
  482. begin
  483. If not CheckStringIndex(Tableindex,StringIndex) then
  484. Result:=''
  485. else
  486. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].DefaultValue;
  487. end;
  488. Function GetResourceStringCurrentValue(TableIndex,StringIndex : Longint) : AnsiString;
  489. begin
  490. If not CheckStringIndex(Tableindex,StringIndex) then
  491. Result:=''
  492. else
  493. result:=ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].CurrentValue;
  494. end;
  495. Function SetResourceStringValue(TableIndex,StringIndex : longint; Value : Ansistring) : Boolean;
  496. begin
  497. Result:=CheckStringIndex(Tableindex,StringIndex);
  498. If Result then
  499. ResourceStringTable.Tables[TableIndex]^.ResRec[StringIndex].CurrentValue:=Value;
  500. end;
  501. {$endif RESSTRSECTIONS}
  502. Function LoadResString(p:PResStringRec):AnsiString;
  503. begin
  504. Result:=p^;
  505. end;
  506. {$endif FPC_HAS_FEATURE_RESOURCES}
  507. {$ifdef FPC_HAS_FEATURE_RESOURCES}
  508. Initialization
  509. { ResetResourceTables;}
  510. finalization
  511. FinalizeResourceTables;
  512. {$endif FPC_HAS_FEATURE_RESOURCES}
  513. end.