diff --git a/.gitignore b/.gitignore
index 4523933..9b20757 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-*.dcu
\ No newline at end of file
+*.dcu
+__history
\ No newline at end of file
diff --git a/Source/PascalScriptFCL.lpk b/Source/PascalScriptFCL.lpk
index 9907f4e..ae48905 100644
--- a/Source/PascalScriptFCL.lpk
+++ b/Source/PascalScriptFCL.lpk
@@ -51,7 +51,7 @@ Carlo Kok
RemObjects Software
"/>
-
+
@@ -152,6 +152,18 @@ RemObjects Software
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/PascalScriptFPC.inc b/Source/PascalScriptFPC.inc
index 387464d..7f65006 100644
--- a/Source/PascalScriptFPC.inc
+++ b/Source/PascalScriptFPC.inc
@@ -1,7 +1,9 @@
{$DEFINE PS_HAVEVARIANT}
{$DEFINE PS_DYNARRAY}
- {$DEFINE PS_NOIDISPATCH}
+ {$ifndef mswindows}
+ {$DEFINE PS_NOIDISPATCH}
+ {$endif}
{.$if (fpc_version=2) and (fpc_release>=3) and (fpc_patch>=1)}
{$if (fpc_version=2) and ((fpc_release=2) and (fpc_patch>=4)) or (fpc_release>2)}
{$UNDEF FPC_OLD_FIX}
@@ -9,6 +11,11 @@
{$UNDEF PS_FPCSTRINGWORKAROUND}
{$DEFINE PS_RESBEFOREPARAMETERS}
{$DEFINE x64_string_result_as_varparameter}
+ {$ifdef mswindows}
+ {$if (fpc_version=2) and (fpc_release>5)}
+ {$DEFINE PS_FPC_HAS_COM}
+ {$endif}
+ {$endif}
{FreePascal 2.3.1 and above has much Delphi compatibility bugs fixed}
{$else}
{$DEFINE FPC_OLD_FIX}
diff --git a/Source/PascalScript_Core_Reg.pas b/Source/PascalScript_Core_Reg.pas
index a076b77..cd87428 100644
--- a/Source/PascalScript_Core_Reg.pas
+++ b/Source/PascalScript_Core_Reg.pas
@@ -30,9 +30,7 @@ uses
uPSComponent,
uPSDebugger,
uPSComponent_Default,
- {$IFNDEF FPC}
uPSComponent_COM,
- {$ENDIF}
uPSComponent_DB,
uPSComponent_Forms,
uPSComponent_Controls,
@@ -45,9 +43,7 @@ begin
TPSDllPlugin,
TPSImport_Classes,
TPSImport_DateUtils,
- {$IFNDEF FPC}
TPSImport_ComObj,
- {$ENDIF}
TPSImport_DB,
TPSImport_Forms,
TPSImport_Controls,
diff --git a/Source/pascalscript.pas b/Source/pascalscript.pas
index d5bf447..fa37a2b 100644
--- a/Source/pascalscript.pas
+++ b/Source/pascalscript.pas
@@ -15,7 +15,7 @@ uses
uPSDisassembly, uPSPreProcessor, uPSR_buttons, uPSR_classes, uPSR_controls,
uPSR_dateutils, uPSR_DB, uPSR_dll, uPSR_extctrls, uPSR_forms,
uPSR_graphics, uPSR_menus, uPSR_std, uPSR_stdctrls, uPSUtils,
- LazarusPackageIntf;
+ uPSComponent_COM, uPSC_comobj, uPSR_comobj, LazarusPackageIntf;
implementation
diff --git a/Source/uPSC_comobj.pas b/Source/uPSC_comobj.pas
index b436468..4b4eb8b 100644
--- a/Source/uPSC_comobj.pas
+++ b/Source/uPSC_comobj.pas
@@ -21,6 +21,19 @@ implementation
procedure SIRegister_ComObj(cl: TPSPascalCompiler);
begin
+{$IFDEF FPC}
+ {$IFDEF PS_FPC_HAS_COM}
+ cl.AddTypeS('HResult', 'LongInt');
+ cl.AddTypeS('TGUID', 'record D1: LongWord; D2: Word; D3: Word; D4: array[0..7] of Byte; end;');
+ cl.AddTypeS('TCLSID', 'TGUID');
+ cl.AddTypeS('TIID', 'TGUID');
+ cl.AddDelphiFunction('procedure OleCheck(Result: HResult);');
+ cl.AddDelphiFunction('function StringToGUID(const S: string): TGUID;');
+ cl.AddDelphiFunction('function CreateComObject(const ClassID: TGUID): IUnknown;');
+ cl.AddDelphiFunction('function CreateOleObject(const ClassName: String): IDispatch;');
+ cl.AddDelphiFunction('function GetActiveOleObject(const ClassName: String): IDispatch;');
+ {$ENDIF}
+{$ELSE}
cl.AddTypeS('HResult', 'LongInt');
cl.AddTypeS('TGUID', 'record D1: LongWord; D2: Word; D3: Word; D4: array[0..7] of Byte; end;');
cl.AddTypeS('TCLSID', 'TGUID');
@@ -34,6 +47,7 @@ begin
{$ENDIF}
cl.AddDelphiFunction('function CreateOleObject(const ClassName: String): IDispatch;');
cl.AddDelphiFunction('function GetActiveOleObject(const ClassName: String): IDispatch;');
+{$ENDIF}
end;
end.
diff --git a/Source/uPSCompiler.pas b/Source/uPSCompiler.pas
index b59995e..0856b1b 100644
--- a/Source/uPSCompiler.pas
+++ b/Source/uPSCompiler.pas
@@ -923,6 +923,7 @@ type
FAllowNoBegin: Boolean;
FAllowNoEnd: Boolean;
FAllowUnit: Boolean;
+ FAllowDuplicateRegister : Boolean;
FBooleanShortCircuit: Boolean;
FDebugOutput: tbtString;
FOnExternalProc: TPSOnExternalProc;
@@ -1177,6 +1178,7 @@ type
property AllowNoEnd: Boolean read FAllowNoEnd write FAllowNoEnd;
+ property AllowDuplicateRegister : Boolean read FAllowDuplicateRegister write FAllowDuplicateRegister;
property BooleanShortCircuit: Boolean read FBooleanShortCircuit write FBooleanShortCircuit;
@@ -1724,7 +1726,7 @@ procedure DisposeVariant(p: PIfRVariant);
implementation
-uses {$IFDEF DELPHI5}ComObj, {$ENDIF}Classes, typInfo;
+uses {$IFDEF DELPHI5}ComObj, {$ENDIF}{$IFDEF PS_FPC_HAS_COM}ComObj, {$ENDIF}Classes, typInfo;
{$IFDEF DELPHI3UP}
resourceString
@@ -1804,7 +1806,6 @@ const
RPS_AbstractClass = 'Abstract Class Construction';
RPS_UnknownWarning = 'Unknown warning';
-
{$IFDEF DEBUG }
RPS_UnableToRegister = 'Unable to register %s';
{$ENDIF}
@@ -2383,6 +2384,9 @@ begin
raise EPSCompilerException.Create(RPS_OnUseEventOnly);
end;
+ if not(AllowDuplicateRegister) and IsDuplicate(FastUpperCase(Name),[dcTypes, dcProcs, dcVars]) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]);
+
case BaseType of
btProcPtr: Result := TPSProceduralType.Create;
BtTypeCopy: Result := TPSTypeLink.Create;
@@ -2908,8 +2912,8 @@ end;
function TPSPascalCompiler.GetUnicodeString(Src: PIfRVariant; var s: Boolean): tbtunicodestring;
begin
case Src.FType.BaseType of
- btChar: Result := Src^.tchar;
- btString: Result := tbtstring(src^.tstring);
+ btChar: Result := tbtunicodestring(Src^.tchar);
+ btString: Result := tbtunicodestring(tbtstring(src^.tstring));
btWideChar: Result := src^.twidechar;
btWideString: Result := tbtWideString(src^.twidestring);
btUnicodeString: result := tbtUnicodeString(src^.tunistring);
@@ -3564,12 +3568,12 @@ var
h, l: Longint;
x: TPSProcedure;
begin
- h := MakeHash(s);
if (s = 'RESULT') then
begin
Result := True;
exit;
end;
+ h := MakeHash(s);
if dcTypes in Check then
for l := FTypes.Count - 1 downto 0 do
begin
@@ -6035,7 +6039,7 @@ function TPSPascalCompiler.ProcessSub(BlockInfo: TPSBlockInfo): Boolean;
for i := 0 to arr.count -1 do
begin
mType := GetTypeNo(BlockInfo, arr.Item[i]);
- if mType <> SetType.SetType then
+ if (mType <> SetType.SetType) and not (IsIntType(mType.FBaseType) and IsIntType(SetType.SetType.BaseType)) then
begin
with MakeError('', ecTypeMismatch, '') do
begin
@@ -6055,6 +6059,18 @@ function TPSPascalCompiler.ProcessSub(BlockInfo: TPSBlockInfo): Boolean;
dataval.Free;
exit;
end;
+ if (c < Low(Byte)) or (c > High(Byte)) then
+ begin
+ with MakeError('', ecTypeMismatch, '') do
+ begin
+ FCol := arr.item[i].Col;
+ FRow := arr.item[i].Row;
+ FPosition := arr.item[i].Pos;
+ end;
+ DataVal.Free;
+ Result := False;
+ exit;
+ end;
Set_MakeMember(c, dataval.Data.tstring);
end else
begin
@@ -6140,9 +6156,9 @@ function TPSPascalCompiler.ProcessSub(BlockInfo: TPSBlockInfo): Boolean;
exit;
end;
if TPSType(FarrType).BaseType = btVariant then
- FArrType := FindAndAddType(self, '', 'array of variant');
+ FArrType := at2ut(FindAndAddType(self, '!OPENARRAYOFVARIANT', 'array of variant'));
if TPSType(FarrType).BaseType <> btArray then
- FArrType := FindAndAddType(self, '', 'array of variant');
+ FArrType := at2ut(FindAndAddType(self, '!OPENARRAYOFVARIANT', 'array of variant'));
tmpp := AllocStackReg(FArrType);
tmpc := AllocStackReg(FindBaseType(bts32));
@@ -12259,6 +12275,7 @@ begin
FParser.OnParserError := ParserError;
FAutoFreeList := TPSList.Create;
FOutput := '';
+ FAllowDuplicateRegister := true;
{$IFDEF PS_USESSUPPORT}
FAllowUnit := true;
{$ENDIF}
@@ -12407,6 +12424,10 @@ begin
FType := GetTypeCopyLink(FType);
if FType = nil then
Raise EPSCompilerException.CreateFmt(RPS_UnableToRegisterConst, [name]);
+
+ if not(AllowDuplicateRegister) and IsDuplicate(FastUpperCase(Name),[dcProcs, dcVars, dcConsts]) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]);
+
pc := TPSConstant.Create;
pc.OrgName := name;
pc.Name := FastUppercase(name);
@@ -13368,6 +13389,10 @@ begin
if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly);
Parser := TPSPascalParser.Create;
Parser.SetText(Decl);
+
+ if not(AllowDuplicateRegister) and (FindType(Name)<>nil) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]);
+
Result := ReadType(Name, Parser);
if Result<>nil then
begin
@@ -13475,6 +13500,9 @@ begin
if not ParseMethod(Self, '', Decl, DOrgName, pDecl, FT) then
Raise EPSCompilerException.CreateFmt(RPS_UnableToRegisterFunction, [Decl]);
+ if (FindProc(DOrgName)<>InvalidVal) and not(FAllowDuplicateRegister) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Decl]);
+
p := TPSRegProc.Create;
P.Name := FastUppercase(DOrgName);
p.OrgName := DOrgName;
@@ -13508,6 +13536,9 @@ var
begin
if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly);
f := FindType(Name);
+ if (f<>nil) and not(FAllowDuplicateRegister) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [Name]);
+
if (f <> nil) and (f is TPSInterfaceType) then
begin
result := TPSInterfaceType(f).Intf;
@@ -13544,7 +13575,8 @@ var
begin
if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly);
Result := FindClass(tbtstring(aClass.ClassName));
- if Result <> nil then exit;
+ if (Result<>nil) and not(FAllowDuplicateRegister) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [aClass.ClassName]);
f := AddType(tbtstring(aClass.ClassName), btClass);
Result := TPSCompileTimeClass.CreateC(aClass, Self, f);
Result.FInheritsFrom := InheritsFrom;
@@ -13559,6 +13591,8 @@ var
begin
if FProcs = nil then raise EPSCompilerException.Create(RPS_OnUseEventOnly);
Result := FindClass(aClass);
+ if (Result<>nil) and (Result.FInheritsFrom<>nil) and not(FAllowDuplicateRegister) then
+ Raise EPSCompilerException.CreateFmt(RPS_DuplicateIdent, [aClass]);
if Result <> nil then
begin
if InheritsFrom <> nil then
diff --git a/Source/uPSR_comobj.pas b/Source/uPSR_comobj.pas
index 3d354aa..73e1500 100644
--- a/Source/uPSR_comobj.pas
+++ b/Source/uPSR_comobj.pas
@@ -11,11 +11,16 @@ uses
procedure RIRegister_ComObj(cl: TPSExec);
implementation
-uses
-{$IFDEF DELPHI3UP}
- ComObj;
+{$IFDEF FPC}
+ {$IFDEF PS_FPC_HAS_COM}
+ uses SysUtils, ComObj;
+ {$ENDIF}
{$ELSE}
- SysUtils, Ole2;
+ {$IFDEF DELPHI3UP}
+ uses ComObj;
+ {$ELSE}
+ uses SysUtils, Ole2;
+ {$ENDIF}
{$ENDIF}
{$IFNDEF DELPHI3UP}
@@ -89,6 +94,15 @@ end;
procedure RIRegister_ComObj(cl: TPSExec);
begin
+{$IFDEF FPC}
+ {$IFDEF PS_FPC_HAS_COM}
+ cl.RegisterDelphiFunction(@OleCheck, 'OleCheck', cdRegister);
+ cl.RegisterDelphiFunction(@StringToGUID, 'StringToGUID', cdRegister);
+ cl.RegisterDelphiFunction(@CreateComObject, 'CreateComObject', cdRegister);
+ cl.RegisterDelphiFunction(@CreateOleObject, 'CREATEOLEOBJECT', cdRegister);
+ cl.RegisterDelphiFunction(@GetActiveOleObject, 'GETACTIVEOLEOBJECT', cdRegister);
+ {$ENDIF}
+{$ELSE}
cl.RegisterDelphiFunction(@OleCheck, 'OleCheck', cdRegister);
{$IFNDEF PS_NOINTERFACES}
{$IFDEF DELPHI3UP}
@@ -98,6 +112,7 @@ begin
{$ENDIF}
cl.RegisterDelphiFunction(@CreateOleObject, 'CREATEOLEOBJECT', cdRegister);
cl.RegisterDelphiFunction(@GetActiveOleObject, 'GETACTIVEOLEOBJECT', cdRegister);
+{$ENDIF}
end;
end.
diff --git a/Source/uPSRuntime.pas b/Source/uPSRuntime.pas
index 4b9794e..dc2bf1c 100644
--- a/Source/uPSRuntime.pas
+++ b/Source/uPSRuntime.pas
@@ -1101,7 +1101,7 @@ function IDispatchInvoke(Self: IDispatch; PropertySet: Boolean; const Name: tbtS
implementation
uses
- TypInfo {$IFDEF DELPHI3UP}{$IFNDEF FPC}{$IFNDEF KYLIX} , ComObj {$ENDIF}{$ENDIF}{$ENDIF};
+ TypInfo {$IFDEF DELPHI3UP}{$IFNDEF FPC}{$IFNDEF KYLIX} , ComObj {$ENDIF}{$ENDIF}{$ENDIF}{$IFDEF PS_FPC_HAS_COM}, ComObj{$ENDIF};
{$IFDEF DELPHI3UP }
resourceString
@@ -1822,15 +1822,15 @@ const
type
TDynArrayRecHeader = packed record
+ {$ifdef FPC}
+ refCnt : ptrint;
+ high : tdynarrayindex;
+ {$else}
{$ifdef CPUX64}
_Padding: LongInt; // Delphi XE2+ expects 16 byte align
{$endif}
/// dynamic array reference count (basic garbage memory mechanism)
refCnt: Longint;
- {$ifdef FPC}
- high: sizeint;
- function length: sizeint; inline;
- {$else}
/// length in element count
// - size in bytes = length*ElemSize
length: NativeInt;
@@ -3585,10 +3585,10 @@ begin
case aType.BaseType of
btU8: Result := chr(tbtu8(src^));
btU16: Result := widechar(src^);
- btChar: Result := tbtchar(Src^);
- btPchar: Result := pansichar(src^);
+ btChar: Result := tbtunicodestring(tbtchar(Src^));
+ btPchar: Result := tbtunicodestring(pansichar(src^));
btWideChar: Result := tbtwidechar(Src^);
- btString: Result := tbtstring(src^);
+ btString: Result := tbtunicodestring(tbtstring(src^));
btWideString: Result := tbtwidestring(src^);
btVariant: Result := Variant(src^);
btUnicodeString: result := tbtUnicodeString(src^);
@@ -4231,7 +4231,6 @@ begin
{$ENDIF CPUX64}
darr^.header.refCnt:=1;
{$IFDEF FPC}
- darr^.header.length := nil;
darr^.header.high := NewLength - 1;
{$ELSE}
darr^.header.length := NewLength;
@@ -9077,12 +9076,15 @@ var
arr: TPSVariantIFC;
begin
Arr := NewTPSVariantIFC(Stack[Stack.Count-2], True);
- if (arr.Dta = nil) or (arr.aType.BaseType <> btArray) then
+ if (arr.aType.BaseType <> btStaticArray) and ((arr.Dta = nil) or (arr.aType.BaseType <> btArray)) then
begin
Result := false;
exit;
end;
- Stack.SetInt(-1, PSDynArrayGetLength(Pointer(arr.Dta^), arr.aType));
+ if arr.aType.BaseType = btStaticArray then
+ Stack.SetInt(-1, TPSTypeRec_StaticArray(arr.aType).Size)
+ else
+ Stack.SetInt(-1, PSDynArrayGetLength(Pointer(arr.Dta^), arr.aType));
Result := True;
end;
@@ -9379,7 +9381,9 @@ begin
RegisterDelphiFunction(@VarIsEmpty, 'VARISEMPTY', cdRegister);
RegisterDelphiFunction(@Null, 'NULL', cdRegister);
RegisterDelphiFunction(@VarIsNull, 'VARISNULL', cdRegister);
+ {$IFNDEF FPC}
RegisterDelphiFunction(@VarType, 'VARTYPE', cdRegister);
+ {$ENDIF}
{$IFNDEF PS_NOIDISPATCH}
RegisterDelphiFunction(@IDispatchInvoke, 'IDISPATCHINVOKE', cdregister);
{$ENDIF}
@@ -12655,7 +12659,11 @@ begin
if not Succeeded(i) then
begin
if i = DISP_E_EXCEPTION then
+ {$IFDEF FPC}
+ raise Exception.Create(ExceptInfo.Source+': '+ExceptInfo.Description)
+ {$ELSE}
raise Exception.Create(ExceptInfo.bstrSource+': '+ExceptInfo.bstrDescription)
+ {$ENDIF}
else
raise Exception.Create(SysErrorMessage(i));
end;
diff --git a/Source/x64.inc b/Source/x64.inc
index 1e5b733..d52a5ad 100644
--- a/Source/x64.inc
+++ b/Source/x64.inc
@@ -610,6 +610,7 @@ begin
{$ENDIF}
btInterface, btArray, btVariant, btStaticArray:
GetPtr(res);
+ btRecord,
btSet:
begin
if res.aType.RealSize > PointerSize then GetPtr(res);
@@ -629,6 +630,7 @@ begin
{$ENDIF}
btInterface, btArray, btVariant, btStaticArray:
GetPtr(res);
+ btRecord,
btSet:
begin
if res.aType.RealSize > PointerSize then GetPtr(res);
@@ -666,7 +668,7 @@ begin
btu32,bts32: tbtu32(res.dta^) := _RAX;
btPChar: pansichar(res.dta^) := Pansichar(_RAX);
bts64: tbts64(res.dta^) := Int64(_RAX);
- btCurrency: tbtCurrency(res.Dta^) := Int64(_RAX);
+ btCurrency: tbts64(res.Dta^) := Int64(_RAX);
btInterface,
btVariant,
{$IFDEF x64_string_result_as_varparameter}