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 5 This unit makes Free Pascal as much as possible Delphi compatible 6 7 See the file COPYING.FPC, included in this distribution, 8 for details about the copyright. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 **********************************************************************} 15{$Mode ObjFpc} 16{$I-} 17{$ifndef Unix} 18 {$S-} 19{$endif} 20unit objpas; 21 22interface 23 24 { first, in object pascal, the integer type must be redefined } 25{$ifdef CPU16} 26 const 27 MaxInt = MaxSmallint; 28 type 29 Integer = smallint; 30 PInteger = ^Integer; 31{$else CPU16} 32 const 33 MaxInt = MaxLongint; 34 type 35 Integer = longint; 36 PInteger = ^Integer; 37{$endif CPU16} 38 39 { Ansistring are the default } 40 PString = PAnsiString; 41 42 { array types } 43{$ifdef CPU16} 44 IntegerArray = array[0..(32768 div SizeOf(Integer))-2] of Integer; 45{$else CPU16} 46 IntegerArray = array[0..$effffff] of Integer; 47{$endif CPU16} 48 TIntegerArray = IntegerArray; 49 PIntegerArray = ^IntegerArray; 50{$ifdef CPU16} 51 PointerArray = array [0..(32768 div SizeOf(Pointer))-2] of Pointer; 52{$else CPU16} 53 PointerArray = array [0..512*1024*1024-2] of Pointer; 54{$endif CPU16} 55 TPointerArray = PointerArray; 56 PPointerArray = ^PointerArray; 57 58 // Delphi Berlin compatibility 59 FixedInt = Int32; 60 FixedUInt = UInt32; 61 62{$if FPC_FULLVERSION >= 20701} 63 64 { Generic array type. 65 Slightly Less useful in FPC, since dyn array compatibility is at the element level. 66 But still useful for generic methods and of course Delphi compatibility} 67 68 Generic TArray<T> = Array of T; 69 70 { Generic support for enumerator interfaces. These are added here, because 71 mode (Obj)FPC does currently not allow the overloading of types with 72 generic types (this will need a modeswitch...) } 73 74 { Note: In Delphi these two generic types inherit from the two interfaces 75 above, but in FPC as well as in Delphi(!) this leads to problems, 76 because of method hiding and method implementation. E.g. 77 consider a class which enumerates integers one needs to implement 78 a GetCurrent for TObject as well... } 79 generic IEnumerator<T> = interface 80 function GetCurrent: T; 81 function MoveNext: Boolean; 82 procedure Reset; 83 property Current: T read GetCurrent; 84 end; 85 86 generic IEnumerable<T> = interface 87 function GetEnumerator: specialize IEnumerator<T>; 88 end; 89{$endif} 90 91{$SCOPEDENUMS ON} 92 TEndian = (Little,Big); 93{$SCOPEDENUMS OFF} 94 95{$ifdef FPC_HAS_FEATURE_CLASSES} 96Var 97 ExceptionClass: TClass; { Exception base class (must actually be Exception, defined in sysutils ) } 98{$endif FPC_HAS_FEATURE_CLASSES} 99 100{**************************************************************************** 101 Compatibility routines. 102****************************************************************************} 103 104{$ifdef FPC_HAS_FEATURE_FILEIO} 105 { Untyped file support } 106 Procedure AssignFile(out f:File;p:pchar); 107 Procedure AssignFile(out f:File;c:char); 108 {$ifdef FPC_HAS_FEATURE_WIDESTRINGS} 109 Procedure AssignFile(out f:File;const Name:UnicodeString); 110 {$endif FPC_HAS_FEATURE_WIDESTRINGS} 111 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS} 112 Procedure AssignFile(out f:File;const Name:RawByteString); 113 {$endif FPC_HAS_FEATURE_ANSISTRINGS} 114 Procedure CloseFile(var f:File); 115{$endif FPC_HAS_FEATURE_FILEIO} 116 117{$ifdef FPC_HAS_FEATURE_TEXTIO} 118 { Text file support } 119 Procedure AssignFile(out t:Text;p:pchar); 120 Procedure AssignFile(out t:Text;c:char); 121 Procedure AssignFile(out t:Text;p:pchar; aCodePage : TSystemCodePage); 122 Procedure AssignFile(out t:Text;c:char; aCodePage : TSystemCodePage); 123 {$ifdef FPC_HAS_FEATURE_WIDESTRINGS} 124 Procedure AssignFile(out t:Text;const Name:UnicodeString); 125 Procedure AssignFile(out t:Text;const Name:UnicodeString; aCodePage : TSystemCodePage); 126 {$endif FPC_HAS_FEATURE_WIDESTRINGS} 127 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS} 128 Procedure AssignFile(out t:Text;const Name:RawByteString); 129 Procedure AssignFile(out t:Text;const Name:RawByteString; aCodePage : TSystemCodePage); 130 {$endif FPC_HAS_FEATURE_ANSISTRINGS} 131 Procedure CloseFile(Var t:Text); 132{$endif FPC_HAS_FEATURE_TEXTIO} 133 134{$ifdef FPC_HAS_FEATURE_FILEIO} 135 { Typed file supoort } 136 Procedure AssignFile(out f:TypedFile;p:pchar); 137 Procedure AssignFile(out f:TypedFile;c:char); 138 {$ifdef FPC_HAS_FEATURE_WIDESTRINGS} 139 Procedure AssignFile(out f:TypedFile;const Name:UnicodeString); 140 {$endif FPC_HAS_FEATURE_WIDESTRINGS} 141 {$ifdef FPC_HAS_FEATURE_ANSISTRINGS} 142 Procedure AssignFile(out f:TypedFile;const Name:RawByteString); 143 {$endif FPC_HAS_FEATURE_ANSISTRINGS} 144{$endif FPC_HAS_FEATURE_FILEIO} 145 146{$ifdef FPC_HAS_FEATURE_COMMANDARGS} 147 { ParamStr should return also an ansistring } 148 Function ParamStr(Param : Integer) : Ansistring; 149{$endif FPC_HAS_FEATURE_COMMANDARGS} 150 151{**************************************************************************** 152 Resource strings. 153****************************************************************************} 154 155{$ifdef FPC_HAS_FEATURE_RESOURCES} 156 type 157 TResourceIterator = Function (Name,Value : AnsiString; Hash : Longint; arg:pointer) : AnsiString; 158 159 Function Hash(S : AnsiString) : LongWord; 160 Procedure ResetResourceTables; 161 Procedure FinalizeResourceTables; 162 Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer); 163 Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer); 164 165 { Delphi compatibility } 166 type 167 PResStringRec=^AnsiString; 168 TResStringRec=AnsiString; 169 Function LoadResString(p:PResStringRec):AnsiString; 170{$endif FPC_HAS_FEATURE_RESOURCES} 171 172 implementation 173 174{**************************************************************************** 175 Compatibility routines. 176****************************************************************************} 177 178{$ifdef FPC_HAS_FEATURE_FILEIO} 179 180{ Untyped file support } 181 182Procedure AssignFile(out f:File;p:pchar); 183begin 184 System.Assign (F,p); 185end; 186 187Procedure AssignFile(out f:File;c:char); 188begin 189 System.Assign (F,c); 190end; 191 192{$ifdef FPC_HAS_FEATURE_ANSISTRINGS} 193Procedure AssignFile(out f:File;const Name:RawBytestring); 194begin 195 System.Assign (F,Name); 196end; 197{$endif FPC_HAS_FEATURE_ANSISTRINGS} 198 199{$ifdef FPC_HAS_FEATURE_WIDESTRINGS} 200Procedure AssignFile(out f:File;const Name:UnicodeString); 201begin 202 System.Assign (F,Name); 203end; 204{$endif FPC_HAS_FEATURE_WIDESTRINGS} 205 206Procedure CloseFile(Var f:File); [IOCheck]; 207 208begin 209 { Catch Runtime error/Exception } 210 System.Close(f); 211end; 212{$endif FPC_HAS_FEATURE_FILEIO} 213 214{$ifdef FPC_HAS_FEATURE_TEXTIO} 215{ Text file support } 216 217Procedure AssignFile(out t:Text;p:pchar); 218begin 219 System.Assign (T,p); 220end; 221 222Procedure AssignFile(out t:Text;p:pchar; aCodePage : TSystemCodePage); 223begin 224 System.Assign (T,p); 225 SetTextCodePage(T,aCodePage); 226end; 227 228Procedure AssignFile(out t:Text;c:char); 229begin 230 System.Assign (T,c); 231end; 232 233 234Procedure AssignFile(out t:Text;c:char; aCodePage : TSystemCodePage); 235begin 236 System.Assign (T,c); 237 SetTextCodePage(T,aCodePage); 238end; 239 240{$ifdef FPC_HAS_FEATURE_ANSISTRINGS} 241Procedure AssignFile(out t:Text;const Name:RawBytestring; aCodePage : TSystemCodePage); 242begin 243 System.Assign (T,Name); 244 SetTextCodePage(T,aCodePage); 245end; 246 247Procedure AssignFile(out t:Text;const Name:RawBytestring); 248begin 249 System.Assign (T,Name); 250end; 251{$endif FPC_HAS_FEATURE_ANSISTRINGS} 252 253{$ifdef FPC_HAS_FEATURE_WIDESTRINGS} 254Procedure AssignFile(out t:Text;const Name:UnicodeString; aCodePage : TSystemCodePage); 255begin 256 System.Assign (T,Name); 257 SetTextCodePage(T,aCodePage); 258end; 259 260Procedure AssignFile(out t:Text;const Name:UnicodeString); 261begin 262 System.Assign (T,Name); 263end; 264{$endif FPC_HAS_FEATURE_WIDESTRINGS} 265 266Procedure CloseFile(Var t:Text); [IOCheck]; 267 268begin 269 { Catch Runtime error/Exception } 270 System.Close(T); 271end; 272{$endif FPC_HAS_FEATURE_TEXTIO} 273 274{$ifdef FPC_HAS_FEATURE_FILEIO} 275{ Typed file support } 276 277Procedure AssignFile(out f:TypedFile;p:pchar); 278begin 279 System.Assign (F,p); 280end; 281 282Procedure AssignFile(out f:TypedFile;c:char); 283begin 284 System.Assign (F,c); 285end; 286 287{$ifdef FPC_HAS_FEATURE_ANSISTRINGS} 288Procedure AssignFile(out f:TypedFile;const Name:RawBytestring); 289begin 290 System.Assign (F,Name); 291end; 292{$endif FPC_HAS_FEATURE_ANSISTRINGS} 293 294{$ifdef FPC_HAS_FEATURE_WIDESTRINGS} 295Procedure AssignFile(out f:TypedFile;const Name:UnicodeString); 296begin 297 System.Assign (F,Name); 298end; 299{$endif FPC_HAS_FEATURE_WIDESTRINGS} 300{$endif FPC_HAS_FEATURE_FILEIO} 301 302{$ifdef FPC_HAS_FEATURE_COMMANDARGS} 303Function ParamStr(Param : Integer) : ansistring; 304 begin 305 { 306 Paramstr(0) should return the name of the binary. 307 Since this functionality is included in the system unit, 308 we fetch it from there. 309 Normally, pathnames are less than 255 chars anyway, 310 so this will work correct in 99% of all cases. 311 In time, the system unit should get a GetExeName call. 312 } 313 if (Param=0) then 314 Result:=System.Paramstr(0) 315 else if (Param>0) and (Param<argc) then 316 Result:=Argv[Param] 317 else 318 Result:=''; 319 end; 320{$endif FPC_HAS_FEATURE_COMMANDARGS} 321 322{$ifdef FPC_HAS_FEATURE_RESOURCES} 323{ --------------------------------------------------------------------- 324 ResourceString support 325 ---------------------------------------------------------------------} 326Function Hash(S : AnsiString) : LongWord; 327Var 328 thehash,g,I : LongWord; 329begin 330 thehash:=0; 331 For I:=1 to Length(S) do { 0 terminated } 332 begin 333 thehash:=thehash shl 4; 334 inc(theHash,Ord(S[i])); 335 g:=thehash and LongWord($f shl 28); 336 if g<>0 then 337 begin 338 thehash:=thehash xor (g shr 24); 339 thehash:=thehash xor g; 340 end; 341 end; 342 If theHash=0 then 343 Hash:=$ffffffff 344 else 345 Hash:=TheHash; 346end; 347 348Type 349 PPResourceStringRecord = ^PResourceStringRecord; 350 TResourceStringTableList = Packed Record 351 Count : sizeint; 352 Tables : Array[{$ifdef cpu16}Byte{$else cpu16}Word{$endif cpu16}] of record 353 TableStart, 354 TableEnd : {$ifdef ver3_0}PResourceStringRecord{$else}PPResourceStringRecord{$endif}; 355 end; 356 end; 357 PResourceStringTableList = ^TResourceStringTableList; 358 359{ Support for string constants initialized with resourcestrings } 360{$ifdef FPC_HAS_RESSTRINITS} 361 PResStrInitEntry = ^TResStrInitEntry; 362 TResStrInitEntry = record 363 Addr: PPointer; 364 Data: PResourceStringRecord; 365 end; 366 367 TResStrInitTable = packed record 368 Count: {$ifdef VER2_6}longint{$else}sizeint{$endif}; 369 Tables: packed array[1..{$ifdef cpu16}8191{$else cpu16}32767{$endif cpu16}] of PResStrInitEntry; 370 end; 371 PResStrInitTable = ^TResStrInitTable; 372 373var 374 ResStrInitTable : PResStrInitTable; external name '_FPC_ResStrInitTables'; 375 376procedure UpdateResourceStringRefs; 377var 378 i: integer; 379 ptable: PResStrInitEntry; 380begin 381 for i:=1 to ResStrInitTable^.Count do 382 begin 383 ptable:=ResStrInitTable^.Tables[i]; 384 while Assigned(ptable^.Addr) do 385 begin 386 AnsiString(ptable^.Addr^):=ptable^.Data^.CurrentValue; 387 Inc(ptable); 388 end; 389 end; 390end; 391{$endif FPC_HAS_RESSTRINITS} 392 393Var 394 ResourceStringTable : PResourceStringTableList; External Name '_FPC_ResourceStringTables'; 395 396Procedure SetResourceStrings (SetFunction : TResourceIterator;arg:pointer); 397Var 398 ResStr : PResourceStringRecord; 399 i : integer; 400 s : AnsiString; 401begin 402 With ResourceStringTable^ do 403 begin 404 For i:=0 to Count-1 do 405 begin 406 ResStr:=Tables[I].TableStart{$ifndef VER3_0}^{$endif}; 407 { Skip first entry (name of the Unit) } 408 inc(ResStr); 409 while ResStr<Tables[I].TableEnd{$ifndef VER3_0}^{$endif} do 410 begin 411 s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg); 412 if s<>'' then 413 ResStr^.CurrentValue:=s; 414 inc(ResStr); 415 end; 416 end; 417 end; 418{$ifdef FPC_HAS_RESSTRINITS} 419 UpdateResourceStringRefs; 420{$endif FPC_HAS_RESSTRINITS} 421end; 422 423 424Procedure SetUnitResourceStrings (const UnitName:string;SetFunction : TResourceIterator;arg:pointer); 425Var 426 ResStr : PResourceStringRecord; 427 i : integer; 428 s, 429 UpUnitName : AnsiString; 430begin 431 With ResourceStringTable^ do 432 begin 433 UpUnitName:=UpCase(UnitName); 434 For i:=0 to Count-1 do 435 begin 436 ResStr:=Tables[I].TableStart{$ifndef VER3_0}^{$endif}; 437 { Check name of the Unit } 438 if ResStr^.Name<>UpUnitName then 439 continue; 440 inc(ResStr); 441 while ResStr<Tables[I].TableEnd{$ifndef VER3_0}^{$endif} do 442 begin 443 s:=SetFunction(ResStr^.Name,ResStr^.DefaultValue,Longint(ResStr^.HashValue),arg); 444 if s<>'' then 445 ResStr^.CurrentValue:=s; 446 inc(ResStr); 447 end; 448 end; 449 end; 450{$ifdef FPC_HAS_RESSTRINITS} 451 { Resourcestrings of one unit may be referenced from other units, 452 so updating everything is the only option. } 453 UpdateResourceStringRefs; 454{$endif FPC_HAS_RESSTRINITS} 455end; 456 457 458Procedure ResetResourceTables; 459Var 460 ResStr : PResourceStringRecord; 461 i : integer; 462begin 463 With ResourceStringTable^ do 464 begin 465 For i:=0 to Count-1 do 466 begin 467 ResStr:=Tables[I].TableStart{$ifndef VER3_0}^{$endif}; 468 { Skip first entry (name of the Unit) } 469 inc(ResStr); 470 while ResStr<Tables[I].TableEnd{$ifndef VER3_0}^{$endif} do 471 begin 472 ResStr^.CurrentValue:=ResStr^.DefaultValue; 473 inc(ResStr); 474 end; 475 end; 476 end; 477end; 478 479 480Procedure FinalizeResourceTables; 481Var 482 ResStr : PResourceStringRecord; 483 i : integer; 484begin 485 With ResourceStringTable^ do 486 begin 487 For i:=0 to Count-1 do 488 begin 489 ResStr:=Tables[I].TableStart{$ifndef VER3_0}^{$endif}; 490 { Skip first entry (name of the Unit) } 491 inc(ResStr); 492 while ResStr<Tables[I].TableEnd{$ifndef VER3_0}^{$endif} do 493 begin 494 ResStr^.CurrentValue:=''; 495 inc(ResStr); 496 end; 497 end; 498 end; 499end; 500 501 502Function LoadResString(p:PResStringRec):AnsiString; 503begin 504 Result:=p^; 505end; 506{$endif FPC_HAS_FEATURE_RESOURCES} 507 508 509{$ifdef FPC_HAS_FEATURE_RESOURCES} 510Initialization 511{ ResetResourceTables;} 512finalization 513 FinalizeResourceTables; 514{$endif FPC_HAS_FEATURE_RESOURCES} 515end. 516