objpas.pp 16 KB

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