objpas.pp 15 KB

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