objpas.pp 13 KB

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