objpas.pp 14 KB

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