objpas.pp 14 KB

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