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