Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2019-07

Lazarus 2.0.2 EditorMacroScript error on first startup RPi4B

30 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I have just installed fpc 3.0.4 + Lazarus 2.0.2 from svn sources on a pristine Raspberry Pi4B with 4GB RAM.
All of the commands my script performs finished OK and the IDE is installed without errors.

But now (again) on a first ever start of the newly installed Lazarus I am greeted by a pop-up dialog:

Error in EditorMacroScript
The package EditorMacroScript (pascalscript macros) has detected a problem and was deactivated.
The package failed its selftest with the message:
"Replace All [Exp: True / Got: False]"
[OK]

It was a while now since I last installed on the bare metal from svn but still this problem pops up. It has done that every time I can remember and I even posted here back in 2016 about it.

Apparently nothing has been done, and I do not know what the pascalscript really does in the IDE so I cannot say if I will be hit with some unexplainable error down the road.

Can someone please explain what this is and how to stop the problem from happening? I think I am not alone having it appear...

And I know it will not show anymore, but I want to know what caused it and what is unavailable/not working now that it is deactivated.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 16 lines
I have just installed fpc 3.0.4 + Lazarus 2.0.2 from svn sources on a pristine Raspberry Pi4B with 4GB RAM. But now (again) on a first ever start of the newly installed Lazarus I am greeted by a pop-up dialog: Error in EditorMacroScript It was a while now since I last installed on the bare metal from svn but still this problem pops up. It has done that every time I can remember and I even posted here back in 2016 about it. Apparently nothing has been done, and I do not know what the pascalscript really does in the IDE so I cannot say if I will be hit with some unexplainable error down the road.

Yep nothing has been done since.... (Except for me hoping, that one day I have the time prioritized to install Laz on a RP myself....) Well the underlying PasScript was updated (not sure if in 2.0.x but in trunk). But that seems to have done little for arm.

The error happens once only, the result is stored and EMS disabled. There is an entry in the Tools > Options to enable it again (or check the xml files in your conf)

PasScript sometimes needs to call code from the project (i.e. binary code). For this it needs to pass params, in the correct registers/stack. Since that can change (calling convention), the IDE performs a selftest.

It finds that PS does not work on your platform.

There is an alternative calling mechanism. I did not test that yet. Compile the IDE with:
  -dPasMacroNoNativeCalls
Then enable the test again.

---------
Before you try that define, check if the following patch (currently applied) is actually needed
https://github.com/User4martin/pascalscript/commit/269faf94db7be08f243aa1b1f55b28624e0692d5

It is something that is not in the original. Not sure though if correct or not.

You can also test this patch (or its absence) by running the testcase in the PascalScript package.

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 47 lines
On 09/07/2019 19:03, Bo Berglund via lazarus wrote: > I have just installed fpc 3.0.4 + Lazarus 2.0.2 from svn sources on a > pristine Raspberry Pi4B with 4GB RAM. > > But now (again) on a first ever start of the newly installed Lazarus I > am greeted by a pop-up dialog: > > Error in EditorMacroScript > > It was a while now since I last installed on the bare metal from svn > but still this problem pops up. It has done that every time I can > remember and I even posted here back in 2016 about it. > > Apparently nothing has been done, and I do not know what the > pascalscript really does in the IDE so I cannot say if I will be hit > with some unexplainable error down the road. > Yep nothing has been done since.... (Except for me hoping, that one day I have the time prioritized to install Laz on a RP myself....) Well the underlying PasScript was updated (not sure if in 2.0.x but in trunk). But that seems to have done little for arm. The error happens once only, the result is stored and EMS disabled. There is an entry in the Tools > Options to enable it again (or check the xml files in your conf) PasScript sometimes needs to call code from the project (i.e. binary code). For this it needs to pass params, in the correct registers/stack. Since that can change (calling convention), the IDE performs a selftest. It finds that PS does not work on your platform. There is an alternative calling mechanism. I did not test that yet. Compile the IDE with:   -dPasMacroNoNativeCalls Then enable the test again. --------- Before you try that define, check if the following patch (currently applied) is actually needed https://github.com/User4martin/pascalscript/commit/269faf94db7be08f243aa1b1f55b28624e0692d5 It is something that is not in the original. Not sure though if correct or not. You can also test this patch (or its absence) by running the testcase in the PascalScript package.

Back to this issue again after installing the latest Lazarus 2.0.4 just released.
It does the same thing...
Is there really nothing one can do to stop it from happening? Yes, I know it just happend once on a new install, but still...

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 7 lines
Back to this issue again after installing the latest Lazarus 2.0.4 just released. It does the same thing... Is there really nothing one can do to stop it from happening? Yes, I know it just happend once on a new install, but still...

That is on a new install. Not on an update, correct? The default is on. SO it will test, and the test result will be shown.

It could be generally disabled on arm. Assuming that it really fails for everybody. Otherwise those for whom it does not fail, will not like it disabled.

You can copy the test result file into your config. It should have editormacros in the filename, and after the failed test, it should be in your primary conf folder.

Or fix PS for arm... Maybe it will work with that alternative compiler define. (I need to look it up, there are some ifdef in that code). If it does then that could be set for arm.
Actually at some point I want to set this for all platforms. But that needs changes to the self test (maybe), and testing on all targets.... And I currently have plenty other stuff to deal with. So I am not working on it.

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote
That is on a new install. Not on an update, correct?

It is a new x64 install on Windows 7-x64 using the official installer downloaded via the link in the release message. I installed a secondary installation so I can keep the old for a while.

Given I used the "official" installer it should contain "everything" needed for all enabled functions and yet it does not.

On Arm (Raspberry Pi units 2-3-4) I always use svn to get the sources and install using my established script for Linux. I did so a few days ago on an RPi4 I got a month ago.

But the same dialog on first start as always on RPi...

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 10 lines
On Fri, 16 Aug 2019 23:02:57 +0200, Martin Frb via lazarus wrote: > That is on a new install. Not on an update, correct? It is a new x64 install on Windows 7-x64 using the official installer downloaded via the link in the release message. I installed a secondary installation so I can keep the old for a while. Given I used the "official" installer it should contain "everything" needed for all enabled functions and yet it does not.

It looks I missed something? I got that you get an error on rasbi/arm.

I did not get what issue happens on win64? What is missing?

Show quoted text 6 lines
On Arm (Raspberry Pi units 2-3-4) I always use svn to get the sources and install using my established script for Linux. I did so a few days ago on an RPi4 I got a month ago. But the same dialog on first start as always on RPi...

I understand the frustration. But I currently cannot test myself on rasberry. And I don't know when I will have the time to change that.

I thought I had recently answered to a similar mail about rasbi, including some pointers. But I cannot find that mail....

So questions here again:

1)
Does editor macro work (self test passed / enabled in global options), if you remove the following changeset:
https://github.com/User4martin/pascalscript/commit/269faf94db7be08f243aa1b1f55b28624e0692d5

Ideally also run the testcase in the componet/pascalscript dir. But I leave that optional.

2) Does it work if the IDE (or relevant packages) are compiled with: -dPasMacroNoNativeCalls

(That does not affect the test in the pascalscript dir)

3) If both are applied?

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 24 lines
On 16/08/2019 23:34, Bo Berglund via lazarus wrote: > On Fri, 16 Aug 2019 23:02:57 +0200, Martin Frb via lazarus > wrote: > >> That is on a new install. Not on an update, correct? > It is a new x64 install on Windows 7-x64 using the official installer > downloaded via the link in the release message. I installed a > secondary installation so I can keep the old for a while. > > Given I used the "official" installer it should contain "everything" > needed for all enabled functions and yet it does not. It looks I missed something? I got that you get an error on rasbi/arm. I did not get what issue happens on win64? What is missing? > > On Arm (Raspberry Pi units 2-3-4) I always use svn to get the sources > and install using my established script for Linux. I did so a few days > ago on an RPi4 I got a month ago. > > But the same dialog on first start as always on RPi... I understand the frustration. But I currently cannot test myself on rasberry. And I don't know when I will have the time to change that.

It is really not a very big issue, since it goes away after first start of Lazarus after the installation. It does not show up after IDE rebuild following a package installation for example. And because of the disabling I have never ever used it, whatever it is.

But since I saw the pop-up again when dealing with 2.0.4 on both RPi and Windows I thought I would mention it....

On Windows I used the official installer and on RPi I used svn to get the sources and compiled myself. Same result.

I thought I had recently answered to a similar mail about rasbi, including some pointers. But I cannot find that mail....

Here is where the GMane news mirror of this mail list is so very useful. I have a complete archive starting Sept 2003 of the Lazarus and freepascal lists in my newsreader's cached data, so I can search and find anything without even being on-line....
Your reply a month ago below.

Show quoted text 16 lines
So questions here again: 1) Does editor macro work (self test passed / enabled in global options), if you remove the following changeset: https://github.com/User4martin/pascalscript/commit/269faf94db7be08f243aa1b1f55b28624e0692d5 Ideally also run the testcase in the componet/pascalscript dir. But I leave that optional. 2) Does it work if the IDE (or relevant packages) are compiled with: -dPasMacroNoNativeCalls (That does not affect the test in the pascalscript dir) 3) If both are applied?

I don't even know what the macro system is used for or how to invoke it since on *every* Lazarus install I have done I have encountered the dialog that disables it...
So I cannot test. But it seems I can program OK in the IDE without it.

Here is your first reply in this thread taken from my news archive: ------------------ 2019-07-09 -------------------------------------

Bo Berglund wrote 16 lines
I have just installed fpc 3.0.4 + Lazarus 2.0.2 from svn sources on a pristine Raspberry Pi4B with 4GB RAM. But now (again) on a first ever start of the newly installed Lazarus I am greeted by a pop-up dialog: Error in EditorMacroScript It was a while now since I last installed on the bare metal from svn but still this problem pops up. It has done that every time I can remember and I even posted here back in 2016 about it. Apparently nothing has been done, and I do not know what the pascalscript really does in the IDE so I cannot say if I will be hit with some unexplainable error down the road.

Yep nothing has been done since.... (Except for me hoping, that one day
I have the time prioritized to install Laz on a RP myself....) Well the underlying PasScript was updated (not sure if in 2.0.x but in trunk). But that seems to have done little for arm.

The error happens once only, the result is stored and EMS disabled. There is an entry in the Tools > Options to enable it again (or check the xml files in your conf)

PasScript sometimes needs to call code from the project (i.e. binary code).
For this it needs to pass params, in the correct registers/stack. Since
that can change (calling convention), the IDE performs a selftest.

It finds that PS does not work on your platform.

There is an alternative calling mechanism. I did not test that yet. Compile the IDE with:
  -dPasMacroNoNativeCalls
Then enable the test again.

---------
Before you try that define, check if the following patch (currently applied) is actually needed
https://github.com/User4martin/pascalscript/commit/269faf94db7be08f243aa1b1f55b28624e0692d5

It is something that is not in the original. Not sure though if correct
or not.

You can also test this patch (or its absence) by running the testcase in
the PascalScript package.

------------------------------------------------------------------

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 8 lines
On Fri, 16 Aug 2019 23:57:51 +0200, Martin Frb via lazarus wrote: > On 16/08/2019 23:34, Bo Berglund via lazarus wrote: >> Given I used the "official" installer it should contain "everything" >> needed for all enabled functions and yet it does not. > It looks I missed something? I got that you get an error on rasbi/arm. > > I did not get what issue happens on win64? What is missing?

I still do not know what error you get on win7/64 bit....

Show quoted text 21 lines
> So questions here again: > > 1) > Does editor macro work (self test passed / enabled in global options), > if you remove the following changeset: > https://github.com/User4martin/pascalscript/commit/269faf94db7be08f243aa1b1f55b28624e0692d5 > > Ideally also run the testcase in the componet/pascalscript dir. But I > leave that optional. > > 2) Does it work if the IDE (or relevant packages) are compiled with: > -dPasMacroNoNativeCalls > > (That does not affect the test in the pascalscript dir) > > 3) If both are applied? I don't even know what the macro system is used for or how to invoke it since on *every* Lazarus install I have done I have encountered the dialog that disables it... So I cannot test. But it seems I can program OK in the IDE without it.

You can record "EditorMacros" in the IDE. That is a series of commands to the Editor. And then replay it as often as needed. The basic macro work without PascalScript. So the basic will work for you: https://wiki.lazarus.freepascal.org/IDE_Window:_Editor_Macros

With PascalScript you can do more complex Macros.
https://wiki.lazarus.freepascal.org/Editor_Macros_PascalScript

As for "it works". It should work if it passes the self-test at IDE startup.
Tools > Options > Editor Macro Script > Status
If it says "Scripting active" then it passed the self test.

Here is your first reply in this thread taken from my news archive:

So that was the same/similar reply

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote
>> I did not get what issue happens on win64? What is missing? I still do not know what error you get on win7/64 bit....

Exactly the same as on RPi as I described on my first post in this thread back in July 9:

Error in EditorMacroScript
The package EditorMacroScript (pascalscript macros) has detected a problem and was deactivated.
The package failed its selftest with the message:
"Replace All [Exp: True / Got: False]"
[OK]

Upon starting the Lazarus IDE the first time this dialog box pops up saying the macro stuff will be deactivated.

It works the same on Raspbian and Windows.

If I remember correctly at first there is the dialog informing about the various parts of fpc it has found (sources etc), then the error dialog pops up.

Both will only show on the very first start after installation.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 16 lines
On Sat, 17 Aug 2019 11:41:01 +0200, Martin Frb via lazarus wrote: >>> I did not get what issue happens on win64? What is missing? > I still do not know what error you get on win7/64 bit.... Exactly the same as on RPi as I described on my first post in this thread back in July 9: Error in EditorMacroScript The package EditorMacroScript (pascalscript macros) has detected a problem and was deactivated. The package failed its selftest with the message: "Replace All [Exp: True / Got: False]" [OK]

Strange. I would expect it to be the same on win7/64 and win10/64.

Especially since you get it on first start, with the pre-build lazarus.exe, which is the same exe that I tested with (and it works for me/ win10)

Could you apply the following patch please:
https://github.com/User4martin/lazarus/commit/5fa7fac42bb55d23b9654984be1e2e1c08049709 (this can be applied to any 2.0.x)
Recompile the IDE, under Tools > Option > Editor Macro... >> "Test again", and restart the IDE.
You should get a more verbose error.

Thanks

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 6 lines
On 17/08/2019 14:00, Martin Frb via lazarus wrote: > > Could you apply the following patch please: > https://github.com/User4martin/lazarus/commit/5fa7fac42bb55d23b9654984be1e2e1c08049709 Or the patch/commit from latest trunk. Added the verbose to all tests

This is somehing I have never done...
Could you please explain what you mean I should do in order to "apply the patch"?
Step by step please.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 12 lines
On Sat, 17 Aug 2019 14:12:02 +0200, Martin Frb via lazarus wrote: > On 17/08/2019 14:00, Martin Frb via lazarus wrote: >> Could you apply the following patch please: >> https://github.com/User4martin/lazarus/commit/5fa7fac42bb55d23b9654984be1e2e1c08049709 > Or the patch/commit from latest trunk. Added the verbose to all tests This is somehing I have never done... Could you please explain what you mean I should do in order to "apply the patch"? Step by step please.

I attached a ready to go replacement file.
Make a copy of your original
  components/macroscript/emsselftest.pas
and then put the attached file into it.

Tools > Option > editor macro script : "Test again"    (this deletes/reset editormacroscript.xml from your primary conf, which is the file that stores the error)
Tools > Rebuild Lazarus IDE
Restart

The new error should be shown on IDE start.

--------

Applying patches (not needed for the above)
1)
If it is just a few lines, locate them in your source and edit them. githup shows the line number and changes

2)
Download as a patch. Now here is the thing: GitHUB (not git) is actually not as good as in is often praised. There seems to be no intuitive way to get an actual patch.
I assumed there would be a button. Sorry about that, but github is not normally my turf.

From what I found one has to append .diff to the url https://github.com/User4martin/lazarus/commit/5fa7fac42bb55d23b9654984be1e2e1c08049709.diff That can be saved, and then
  cd lazarus
  patch -p1 < the_file.patch

The -p1 strips one leading folder from

--- a/components/macroscript/emsselftest.pas
+++ b/components/macroscript/emsselftest.pas
In this case the "a/"

If you did
cd lazarus/components
and therefore you file was macroscript/emsselftest.pas then you would need -p2
and so on

you can do --dry-run

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20190817/c46e744e/attachment-0001.html> -------------- next part --------------
unit EMSSelfTest;

{$mode objfpc}{$H+}
interface
{$IFDEF darwin}
  {$DEFINE NeedTPointFix }
{$ENDIF}

uses
Classes, SysUtils, SynEdit, LazLoggerBase,
IDECommands, EMScriptClasses, EMScriptMacro, Clipbrd, Dialogs, Controls,

  uPSCompiler, uPSRuntime, uPSUtils;
type
  TEMScriptSelfTestException = Exception;
  { TEMSTPSTestExec }
  TEMSTPSTestExec = class(TEMSTPSExec)
  protected
    procedure AddFuncToExec; override;
  public
  end;
  { TEMSPSTestPascalCompiler }
  TEMSPSTestPascalCompiler = class(TEMSPSPascalCompiler)
  private
    FNextOnUses: TPSOnUses;
  public
    constructor Create;
  end;
  { TEMSelfTestEditorMacro }
  TEMSelfTestEditorMacro = class(TEMSEditorMacro)
  public
    constructor Create(aOwner: TComponent); override;
  end;
  function DoSelfTest: Boolean;
var
  SelfTestErrorMsg: String;
implementation
{$IFDEF NeedTPointFix}
type TPoint2 = record x,y,a,b,c: Longint; end;
{$ENDIF}

{%region RegisterSelfTests}

var
  {%H-}TestResultA: integer;
  TestResultInt1, TestResultInt2: integer;
  TestInputInt1, TestInputInt2: integer;
  TestResultBool1, TestResultBool2: boolean;
  TestInputBool1, TestInputBool2: boolean;
  TestResultStr1, TestResultStr2: String;
  TestInputStr1, TestInputStr2: String;
function test_ord_mt(AType: TMsgDlgType): Integer;
begin
  Result := ord(AType);
  TestResultA := Result;
end;
function test_ord_mb(ABtn: TMsgDlgBtn): Integer;
begin
  Result := ord(ABtn);
  TestResultA := Result;
end;
procedure test_int1(AValue: Integer);
begin
  TestResultInt1 := AValue;
end;
procedure test_int2(AValue: Integer);
begin
  TestResultInt2 := AValue;
end;
function test_getint1: Integer;
begin
  Result := TestInputInt1;
end;
function test_getint2: Integer;
begin
  Result := TestInputInt2;
end;
procedure test_varint1(var AValue: Integer);
begin
  TestResultInt1 := AValue;
  AValue := TestInputInt1;
end;
procedure test_bool1(AValue: boolean);
begin
  TestResultBool1 := AValue;
end;
procedure test_bool2(AValue: boolean);
begin
  TestResultBool2 := AValue;
end;
function test_getbool1: Boolean;
begin
  Result := TestInputBool1;
end;
function test_getbool2: Boolean;
begin
  Result := TestInputBool2;
end;
procedure test_point(AValue: TPoint);
begin
  TestResultInt1 := AValue.X;
  TestResultInt2 := AValue.Y;
end;
function test_getpoint: {$IFDEF NeedTPointFix}TPoint2{$ELSE}TPoint{$ENDIF};
begin
  Result.X := TestInputInt1;
  Result.Y := TestInputInt2;
end;
procedure test_varpoint(var AValue: TPoint);
begin
  TestResultInt1 := AValue.X;
  TestResultInt2 := AValue.Y;
  AValue.X := TestInputInt1;
  AValue.Y := TestInputInt2;
end;
procedure test_str1(AValue: String);
begin
  TestResultStr1 := AValue;
end;
procedure test_str2(AValue: String);
begin
  TestResultStr2 := AValue;
end;
function test_getstr1: String;
begin
  Result := TestInputStr1;
end;
function test_getstr2: String;
begin
  Result := TestInputStr2;
end;
procedure test_varstr1(var AValue: String);
begin
  TestResultStr1 := AValue;
  AValue := TestInputStr1;
end;
const
  Decltest_ord_mt   = 'function test_ord_mt(AType: TMsgDlgType): Integer;';
  Decltest_ord_mb   = 'function test_ord_mb(ABtn: TMsgDlgBtn): Integer;';
  Decltest_int1     = 'procedure test_int1(AValue: Integer);';
  Decltest_int2     = 'procedure test_int2(AValue: Integer);';
  Decltest_getint1  = 'function test_getint1: Integer;';
  Decltest_getint2  = 'function test_getint2: Integer;';
  Decltest_varint1  = 'procedure test_varint1(var AValue: Integer);';
  Decltest_bool1    = 'procedure test_bool1(AValue: Boolean);';
  Decltest_bool2    = 'procedure test_bool2(AValue: Boolean);';
  Decltest_getbool1 = 'function test_getbool1: Boolean;';
  Decltest_getbool2 = 'function test_getbool2: Boolean;';
  Decltest_point    = 'procedure test_point(AValue: TPoint);';
  Decltest_getpoint = 'function test_getpoint: TPoint;';
  Decltest_varpoint = 'procedure test_varpoint(var AValue: TPoint);';
  Decltest_str1     = 'procedure test_str1(AValue: String);';
  Decltest_str2     = 'procedure test_str2(AValue: String);';
  Decltest_getstr1  = 'function test_getstr1: String;';
  Decltest_getstr2  = 'function test_getstr2: String;';
  Decltest_varstr1  = 'procedure test_varstr1(var AValue: String);';
  Functest_ord_mt:    function(AType: TMsgDlgType): Integer = @test_ord_mt;
  Functest_ord_mb:    function(ABtn: TMsgDlgBtn): Integer = @test_ord_mb;
  Proctest_int1:      procedure (AValue: Integer) = @test_int1;
  Proctest_int2:      procedure (AValue: Integer) = @test_int2;
  Proctest_getint1:   function: Integer = @test_getint1;
  Proctest_getint2:   function: Integer = @test_getint2;
  Proctest_varint1:   procedure (var AValue: Integer) = @test_varint1;
  Proctest_bool1:     procedure (AValue: Boolean) = @test_bool1;
  Proctest_bool2:     procedure (AValue: Boolean) = @test_bool2;
  Proctest_getbool1:  function: Boolean = @test_getbool1;
  Proctest_getbool2:  function: Boolean = @test_getbool2;
  Proctest_point:     procedure (AValue: TPoint)  = @test_point;
  Proctest_getpoint:  function: {$IFDEF NeedTPointFix}TPoint2{$ELSE}TPoint{$ENDIF} = @test_getpoint;
  Proctest_varpoint:  procedure (var AValue: TPoint)  = @test_varpoint;
  Proctest_str1:      procedure (AValue: String)  = @test_str1;
  Proctest_str2:      procedure (AValue: String)  = @test_str2;
  Proctest_getstr1:   function: String = @test_getstr1;
  Proctest_getstr2:   function: String = @test_getstr2;
  Proctest_varstr1:   procedure (var AValue: String)  = @test_varstr1;
{$IFDEF PasMacroNoNativeCalls}
const
  Id_test_ord_mb    = 901;
  Id_test_ord_mt    = 902;
  Id_test_int1      = 910;
  Id_test_int2      = 911;
  Id_test_getint1   = 912;
  Id_test_getint2   = 913;
  Id_test_varint1   = 914;
  Id_test_bool1     = 920;
  Id_test_bool2     = 921;
  Id_test_getbool1  = 922;
  Id_test_getbool2  = 923;
  Id_test_point     = 930;
  Id_test_getpoint  = 931;
  Id_test_varpoint  = 932;
  Id_test_str1      = 940;
  Id_test_str2      = 941;
  Id_test_getstr1   = 942;
  Id_test_getstr2   = 943;
  Id_test_varstr1   = 944;
function ExecTestHandler({%H-}Caller: TPSExec; p: TPSExternalProcRec;
  {%H-}Global, Stack: TPSStack): Boolean;
var
  data: PPoint;
  i: integer;
  s: TbtString;
begin
  Result := True;
  case Longint(p.Ext1) of
    Id_test_ord_mb: begin // test_ord_mb(ABtn: TMsgDlgBtn): Integer;
        if Stack.Count < 2 then raise TEMScriptBadParamException.Create('Invalid param count for "test_ord_mb"');
        Stack.SetInt(-1, test_ord_mb(TMsgDlgBtn(Stack.GetUInt(-2))) );
      end;
    Id_test_ord_mt: begin // test_ord_mt(AType: TMsgDlgType): Integer;
        if Stack.Count < 2 then raise TEMScriptBadParamException.Create('Invalid param count for "test_ord_mt"');
        //  Stack[Stack.Count-2]^.FType.ExportName = 'TMSGDLGTYPE'
        Stack.SetInt(-1, test_ord_mt(TMsgDlgType(Stack.GetUInt(-2))) );
      end;
    Id_test_int1: begin // test_int1(AValue: Integer);
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_int1"');
        test_int1(Stack.GetUInt(-1));
      end;
    Id_test_int2: begin // test_int2(AValue: Integer);
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_int2"');
        test_int2(Stack.GetUInt(-1));
      end;
    Id_test_getint1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getint1"');
        Stack.SetInt(-1, test_getint1());
      end;
    Id_test_getint2: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getint2"');
        Stack.SetInt(-1, test_getint2());
      end;
    Id_test_varint1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_int1"');
        i := Stack.GetInt(-1);
        test_varint1(i);
        Stack.SetInt(-1, i);
      end;
    Id_test_bool1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_bool1()"');
        test_bool1(Stack.GetBool(-1));
      end;
    Id_test_bool2: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_bool2()"');
        test_bool2(Stack.GetBool(-1));
      end;
    Id_test_getbool1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getbool1"');
        Stack.SetBool(-1, test_getbool1());
      end;
    Id_test_getbool2: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getbool2"');
        Stack.SetBool(-1, test_getbool2());
      end;
    Id_test_point: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_point()"');
        test_point(GetPointFromStack(Stack, -1));
      end;
    Id_test_getpoint: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getpoint"');
        data := GetVarPointFromStack(Stack, -1);
        TPoint(data^) := test_getpoint;
      end;
    Id_test_varpoint: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getpoint"');
        data := GetVarPointFromStack(Stack, -1);
        test_varpoint(TPoint(data^));
      end;
    Id_test_str1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_str1()"');
        test_str1(Stack.GetAnsiString(-1));
      end;
    Id_test_str2: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_str2()"');
        test_str2(Stack.GetAnsiString(-1));
      end;
    Id_test_getstr1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getstr1"');
        Stack.SetAnsiString(-1, test_getstr1());
      end;
    Id_test_getstr2: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_getstr2"');
        Stack.SetAnsiString(-1, test_getstr2());
      end;
    Id_test_varstr1: begin
        if Stack.Count < 1 then raise TEMScriptBadParamException.Create('Invalid param count for "test_str1()"');
        s := Stack.GetAnsiString(-1);
        test_varstr1(s);
        Stack.SetAnsiString(-1, s);
      end;
    else
      Result := False;
  end;
end;
{$ENDIF}
procedure CompRegisterSelfTests(AComp: TPSPascalCompiler);
begin
  // for tests
  AComp.AddDelphiFunction(Decltest_ord_mb);
  AComp.AddDelphiFunction(Decltest_ord_mt);
  AComp.AddDelphiFunction(Decltest_int1);
  AComp.AddDelphiFunction(Decltest_int2);
  AComp.AddDelphiFunction(Decltest_getint1);
  AComp.AddDelphiFunction(Decltest_getint2);
  AComp.AddDelphiFunction(Decltest_varint1);
  AComp.AddDelphiFunction(Decltest_bool1);
  AComp.AddDelphiFunction(Decltest_bool2);
  AComp.AddDelphiFunction(Decltest_getbool1);
  AComp.AddDelphiFunction(Decltest_getbool2);
  AComp.AddDelphiFunction(Decltest_point);
  AComp.AddDelphiFunction(Decltest_getpoint);
  AComp.AddDelphiFunction(Decltest_varpoint);
  AComp.AddDelphiFunction(Decltest_str1);
  AComp.AddDelphiFunction(Decltest_str2);
  AComp.AddDelphiFunction(Decltest_getstr1);
  AComp.AddDelphiFunction(Decltest_getstr2);
  AComp.AddDelphiFunction(Decltest_varstr1);
end;
procedure ExecRegisterSelfTests(AExec: TEMSTPSExec);
begin
  // for tests
  {$IFnDEF PasMacroNoNativeCalls}
  AExec.RegisterDelphiFunction(Functest_ord_mb,    'test_ord_mb',   cdRegister);
  AExec.RegisterDelphiFunction(Functest_ord_mt,    'test_ord_mt',   cdRegister);
  AExec.RegisterDelphiFunction(Proctest_int1,      'test_int1',     cdRegister);
  AExec.RegisterDelphiFunction(Proctest_int2,      'test_int2',     cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getint1,   'test_getint1',  cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getint2,   'test_getint2',  cdRegister);
  AExec.RegisterDelphiFunction(Proctest_varint1,   'test_varint1',  cdRegister);
  AExec.RegisterDelphiFunction(Proctest_bool1,     'test_bool1',    cdRegister);
  AExec.RegisterDelphiFunction(Proctest_bool2,     'test_bool2',    cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getbool1,  'test_getbool1', cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getbool2,  'test_getbool2', cdRegister);
  AExec.RegisterDelphiFunction(Proctest_point,     'test_point',    cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getpoint,  'test_getpoint', cdRegister);
  AExec.RegisterDelphiFunction(Proctest_varpoint,  'test_varpoint', cdRegister);
  AExec.RegisterDelphiFunction(Proctest_str1,      'test_str1',     cdRegister);
  AExec.RegisterDelphiFunction(Proctest_str2,      'test_str2',     cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getstr1,   'test_getstr1',  cdRegister);
  AExec.RegisterDelphiFunction(Proctest_getstr2,   'test_getstr2',  cdRegister);
  AExec.RegisterDelphiFunction(Proctest_varstr1,   'test_varstr1',  cdRegister);
  {$ELSE}
  AExec.RegisterFunctionName('test_ord_mb',       @ExecTestHandler, Pointer(Id_test_ord_mb), nil);
  AExec.RegisterFunctionName('test_ord_mt',       @ExecTestHandler, Pointer(Id_test_ord_mt), nil);
  AExec.RegisterFunctionName('test_int1',         @ExecTestHandler, Pointer(Id_test_int1), nil);
  AExec.RegisterFunctionName('test_int2',         @ExecTestHandler, Pointer(Id_test_int2), nil);
  AExec.RegisterFunctionName('test_getint1',      @ExecTestHandler, Pointer(Id_test_getint1), nil);
  AExec.RegisterFunctionName('test_getint2',      @ExecTestHandler, Pointer(Id_test_getint2), nil);
  AExec.RegisterFunctionName('test_varint1',      @ExecTestHandler, Pointer(Id_test_varint1), nil);
  AExec.RegisterFunctionName('test_bool1',        @ExecTestHandler, Pointer(Id_test_bool1), nil);
  AExec.RegisterFunctionName('test_bool2',        @ExecTestHandler, Pointer(Id_test_bool2), nil);
  AExec.RegisterFunctionName('test_getbool1',     @ExecTestHandler, Pointer(Id_test_getbool1), nil);
  AExec.RegisterFunctionName('test_getbool2',     @ExecTestHandler, Pointer(Id_test_getbool2), nil);
  AExec.RegisterFunctionName('test_point',        @ExecTestHandler, Pointer(Id_test_point), nil);
  AExec.RegisterFunctionName('test_getpoint',     @ExecTestHandler, Pointer(Id_test_getpoint), nil);
  AExec.RegisterFunctionName('test_varpoint',     @ExecTestHandler, Pointer(Id_test_varpoint), nil);
  AExec.RegisterFunctionName('test_str1',         @ExecTestHandler, Pointer(Id_test_str1), nil);
  AExec.RegisterFunctionName('test_str2',         @ExecTestHandler, Pointer(Id_test_str2), nil);
  AExec.RegisterFunctionName('test_getstr1',      @ExecTestHandler, Pointer(Id_test_getstr1), nil);
  AExec.RegisterFunctionName('test_getstr2',      @ExecTestHandler, Pointer(Id_test_getstr2), nil);
  AExec.RegisterFunctionName('test_varstr1',      @ExecTestHandler, Pointer(Id_test_varstr1), nil);
  {$ENDIF}
end;

{%endregion RegisterSelfTests}

{ TEMSPSTestPascalCompiler }

function CompilerOnUses(Sender: TPSPascalCompiler; const Name: TbtString): Boolean;
var
  S: TEMSPSTestPascalCompiler;
begin
  S :=  (Sender as TEMSPSTestPascalCompiler);
  Result := assigned(S.FNextOnUses) and S.FNextOnUses(Sender, Name);
  if Result and (Name = 'SYSTEM') then
  begin
    CompRegisterSelfTests(S);
    Result := True;
  end;
end;
constructor TEMSPSTestPascalCompiler.Create;
begin
  inherited Create;
  FNextOnUses := OnUses;
  OnUses := @CompilerOnUses;
end;

{ TEMSTPSTestExec }

procedure TEMSTPSTestExec.AddFuncToExec;
begin
  inherited AddFuncToExec;
  ExecRegisterSelfTests(Self);
end;

{ TEMSelfTestEditorMacro }

constructor TEMSelfTestEditorMacro.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);
  Compiler := TEMSPSTestPascalCompiler.Create;
  Exec := TEMSTPSTestExec.Create;
end;
type THackTEMSEditorMacro = class(TEMSEditorMacro) end;
function DoSelfTest: Boolean;
var
  m: TEMSEditorMacro;
  syn: TSynEdit;
  procedure RunMacro(AText: String);
  begin
    m.SetFromSource(AText);
    m.PlaybackMacro(syn);
  end;
  procedure AssertEQ(Msg: String; Exp, Got: String); overload;
  begin
    if not(Got = Exp) then
      raise TEMScriptSelfTestException.Create(Format('%s [Exp: "%s" / Got: "%s" / Info: %s / SynTxt: %s]', [Msg, Exp, Got, dbgs(m.IsInvalid) + ' ' + THackTEMSEditorMacro(m).GetErrorMsg, syn.Text]));
  end;
  procedure AssertEQ(Msg: String; Exp, Got: Integer); overload;
  begin
    if not(Got = Exp) then
      raise TEMScriptSelfTestException.Create(Format('%s [Exp: %d / Got: %d / Info: %s / SynTxt: %s]', [Msg, Exp, Got, dbgs(m.IsInvalid) + ' ' + THackTEMSEditorMacro(m).GetErrorMsg, syn.Text]));
  end;
  procedure AssertEQ(Msg: String; Exp, Got: Boolean); overload;
  begin
    if not(Got = Exp) then
      raise TEMScriptSelfTestException.Create(Format('%s [Exp: %s / Got: %s / Info: %s / SynTxt: %s]', [Msg, dbgs(Exp), dbgs(Got), dbgs(m.IsInvalid) + ' ' + THackTEMSEditorMacro(m).GetErrorMsg, syn.Text]));
  end;
  procedure TestInt(Msg, AText: String; Exp: Integer);
  begin
    TestResultInt1 := 0;
    RunMacro(AText);
    AssertEQ(Msg + '(init: 0)', Exp, TestResultInt1);
    TestResultInt1 := -1;
    RunMacro(AText);
    AssertEQ(Msg + '(init: -1)', Exp, TestResultInt1);
    TestResultInt1 := 99919;
    RunMacro(AText);
    AssertEQ(Msg + '(init: 99919)', Exp, TestResultInt1);
  end;
  procedure TestBool(Msg, AText: String; Exp: Boolean);
  begin
    TestResultBool1 := False;
    RunMacro(AText);
    AssertEQ(Msg + '(init: F)', Exp, TestResultBool1);
    TestResultBool1 := True;
    RunMacro(AText);
    AssertEQ(Msg + '(init: T)', Exp, TestResultBool1);
  end;
  procedure TestBool(Msg, AText: String; Exp, Exp2: Boolean);
  begin
    TestResultBool1 := False;
    TestResultBool2 := False;
    RunMacro(AText);
    AssertEQ(Msg + '(init: F,F)', Exp, TestResultBool1);
    AssertEQ(Msg + '(init: F,F)', Exp2, TestResultBool2);
    TestResultBool1 := True;
    TestResultBool2 := True;
    RunMacro(AText);
    AssertEQ(Msg + '(init: T,T)', Exp, TestResultBool1);
    AssertEQ(Msg + '(init: T,T)', Exp2, TestResultBool2);
    TestResultBool1 := True;
    TestResultBool2 := False;
    RunMacro(AText);
    AssertEQ(Msg + '(init: T,F)', Exp, TestResultBool1);
    AssertEQ(Msg + '(init: T,F)', Exp2, TestResultBool2);
    TestResultBool1 := False;
    TestResultBool2 := True;
    RunMacro(AText);
    AssertEQ(Msg + '(init: F,T)', Exp, TestResultBool1);
    AssertEQ(Msg + '(init: F,T)', Exp2, TestResultBool2);
  end;
  procedure TestSyn(Msg, AText: String; Exp: String);
  begin
    syn.ClearAll;
    RunMacro(AText);
    AssertEQ(Msg , True, pos(Exp, syn.Text) > 0);
  end;
  procedure TestSyn(Msg, AInit, AText: String; Exp: String);
  begin
    syn.ClearAll;
    syn.Text := AInit;
    RunMacro(AText);
    AssertEQ(Msg , True, pos(Exp, syn.Text) > 0);
  end;
begin
  Result := False;
  SelfTestErrorMsg := '';
  try
    try
    m := TEMSelfTestEditorMacro.Create(nil);
    syn := TSynEdit.Create(nil);
    {%region calling convention}
    // test_int1
    TestResultInt1 := 99;
    TestInt('test_int1(42)',
            'begin' +
            '  test_int1(42);' +
            'end.',
            42);
    TestInt('test_int1(-3)',
            'begin' +
            '  test_int1(-3);' +
            'end.',
            -3);
    TestInputInt1 := 1001;
    TestInputInt2 := 2002;
    RunMacro('var i: Integer;' +
             'begin' +
             '  i := test_getint1' +
             '  test_int1(i);' +
             '  test_int2(test_getint2);' +
             'end.');
    AssertEQ('Failed getint1', 1001, TestResultInt1);
    AssertEQ('Failed getint2', 2002, TestResultInt2);
    TestInputInt1 := 2001;
    TestResultInt1 := -1;
    TestResultInt2 := -1;
    RunMacro('var i: Integer;' +
             'begin' +
             '  i := 1002' +
             '  test_varint1(i);' +
             '  test_int2(i);' +
             'end.');
    AssertEQ('Failed varint a', 1002, TestResultInt1);
    AssertEQ('Failed varint b', 2001, TestResultInt2);
    // test_bool
    TestBool('test_bool(F,F)',
             'begin' +
             '  test_bool1(False);' +
             '  test_bool2(False);' +
             'end.',
             False, False);
    TestBool('test_bool(T,T)',
             'begin' +
             '  test_bool1(True);' +
             '  test_bool2(True);' +
             'end.',
             True, True);
    TestBool('test_bool(T,F)',
             'begin' +
             '  test_bool1(True);' +
             '  test_bool2(False);' +
             'end.',
             True, False);
    TestInputBool1 := True;
    TestInputBool2 := False;
    RunMacro('var i: Boolean;' +
             'begin' +
             '  i := test_getbool1' +
             '  test_bool1(i);' +
             '  test_bool2(test_getbool2);' +
             'end.');
    AssertEQ('Failed getbool1', True, TestResultBool1);
    AssertEQ('Failed getbool2', False, TestResultBool2);
    // size_of(point)
    TestResultInt1 := -1;
    RunMacro('var p: TPoint;' +
             'begin' +
             '  test_int1(SizeOf(p));' +
             'end.');
    AssertEQ('Failed int param (SizeOf(TPoint))', SizeOf(TPoint), TestResultInt1);
    // TPoint
    TestResultInt1 := -1;
    TestResultInt2 := -1;
    RunMacro('var p: TPoint;' +
             'begin' +
             '  p := point(1001, 2002);' +
             '  test_point(p);' +
             'end.');
    AssertEQ('Failed point param X', 1001, TestResultInt1);
    AssertEQ('Failed point param Y', 2002, TestResultInt2);
    TestInputInt1 := 3001;
    TestInputInt2 := 4002;
    RunMacro('var p: TPoint;' +
             'begin' +
             '  p := test_getpoint' +
             '  test_point(p);' +
             'end.');
    AssertEQ('Failed getpoint param X', 3001, TestResultInt1);
    AssertEQ('Failed getpoint param Y', 4002, TestResultInt2);
    TestInputInt1 := 5001;
    TestInputInt2 := 6002;
    RunMacro('begin' +
             '  test_point(test_getpoint);' +
             'end.');
    AssertEQ('Failed getpoint(2) param X', 5001, TestResultInt1);
    AssertEQ('Failed getpoint(2) param Y', 6002, TestResultInt2);
    TestResultInt1 := -1;
    TestResultInt2 := -1;
    TestResultBool1 := False;
    TestInputInt1 := 1005;
    TestInputInt2 := 1006;
    RunMacro('var p: TPoint;' +
             'begin' +
             '  p := point(990, 991);' +
             '  test_varpoint(p);' +
             '  test_bool1((p.x =  1005) and (p.y = 1006));' +
             'end.');
    AssertEQ('Failed varpoint x', 990, TestResultInt1);
    AssertEQ('Failed varpoint y', 991, TestResultInt2);
    AssertEQ('Failed varpoint new', True, TestResultBool1);
    // string
    TestResultStr1 := 'no no';
    TestResultStr2 := TestResultStr1;
    RunMacro('var s: String;' +
             'begin' +
             '  s := ''abc'';' +
             '  test_str1(''123'');' +
             '  test_str2(s);' +
             'end.');
    AssertEQ('Failed str1 param', '123', TestResultStr1);
    AssertEQ('Failed str1 param', 'abc', TestResultStr2);
    TestInputStr1 := '123';
    TestInputStr2 := '456';
    RunMacro('var s: String;' +
             'begin' +
             '  s := test_getstr1' +
             '  test_str1(s);' +
             '  test_str2(test_getstr2);' +
             'end.');
    AssertEQ('Failed getstr1', '123', TestResultStr1);
    AssertEQ('Failed getstr2', '456', TestResultStr2);
    TestInputStr1 := '123';
    TestResultStr1 := '';
    TestResultStr2 := '';
    TestResultBool1 := False;
    RunMacro('var s: String;' +
             'begin' +
             '  s := ''aaa''' +
             '  test_varstr1(s);' +
             '  test_bool1(s = ''123'');' +
             '  test_str2(s);' +
             'end.');
    AssertEQ('Failed varstr1', 'aaa', TestResultStr1);
    AssertEQ('Failed varstr2', '123', TestResultStr2);
    AssertEQ('Failed varstr3',True, TestResultBool1);
    {%endregion calling convention}
    {%region }
    TestBool('mrNone',
             'begin' +
             '  test_bool1(mrNone = ' +IntToStr(mrNone) + ');' +
             'end.',
             True
             );
    TestBool('mrOk',
             'begin' +
             '  test_bool1(mrOk = ' +IntToStr(mrOk) + ');' +
             'end.',
             True
             );
    TestBool('mtWarning',
             'begin' +
             '  test_bool1(test_ord_mt(mtWarning) = ' +IntToStr(ord(mtWarning)) + ');' +
             'end.',
             True
             );
    TestBool('mtConfirmation',
             'begin' +
             '  test_bool1(test_ord_mt(mtConfirmation) = ' +IntToStr(ord(mtConfirmation)) + ');' +
             'end.',
             True
             );
    TestBool('mbYes',
             'begin' +
             '  test_bool1(test_ord_mb(mbYes) = ' +IntToStr(ord(mbYes)) + ');' +
             'end.',
             True
             );
    TestBool('mbCancel',
             'begin' +
             '  test_bool1(test_ord_mb(mbCancel) = ' +IntToStr(ord(mbCancel)) + ');' +
             'end.',
             True
             );
    {%endregion }
    TestSyn('ecChar',
            'begin ecChar(''C''); end.',
            'C'
            );
    TestSyn('InsertTextAtCaret',
            'begin Caller.InsertTextAtCaret(''Foo'', scamEnd); end.',
            'Foo');
    TestSyn('TextBetweenPoints',
            '123456',
            'begin Caller.TextBetweenPoints[Point(3,1), point(5,1)] :=  ''ng''; end.',
            '12ng56');
    TestSyn('Replace All',   'Test abc abcde 123',
            'begin Caller.SearchReplace(''abc'', ''XYZ'', [ssoReplaceAll]); end.',
            'Test XYZ XYZde 123'
            );
      Result := True;
    finally
      FreeAndNil(m);
      FreeAndNil(syn);
    end;
  except
    on E: Exception do begin
        SelfTestErrorMsg := E.Message;
        Result := False;
      end;
  end;
end;
end.

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote
I attached a ready to go replacement file. Make a copy of your original   components/macroscript/emsselftest.pas and then put the attached file into it.

Done!

Tools > Option > editor macro script : "Test again"

This button is disabled, cannot click it.
Do I need to replace the file as above with Lazarus closed? I did it while it was running.

So could not complete past this step.

   (this deletes/reset editormacroscript.xml from your primary conf, which is the file that stores the error) Tools > Rebuild Lazarus IDE Restart

Will Lazarus not automatically Restart following a rebuild?

The new error should be shown on IDE start.
Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 11 lines
On Sat, 17 Aug 2019 16:43:38 +0200, Martin Frb via lazarus wrote: > I attached a ready to go replacement file. > Make a copy of your original >   components/macroscript/emsselftest.pas > and then put the attached file into it. Done! > Tools > Option > editor macro script : "Test again" This button is disabled, cannot click it.

Then it should say "scripting active"?

That means, that this install of Lazarus has either not yet encountered the error, or that the "editormacroscript.xml" was deleted/reset (i.e. error removed from content).
( editormacroscript.xml is in your primary config path. You can find where that is from the menu: View > IDE Internals > About IDE )

If you get the error again (with or without the changed unit), then check for
1) the "test again" button
2) the editormacroscript.xml file

Anyway if scripting is active, then the self test runs at every start of your IDE. And that leaves the question why it does not report the error anymore. (and when the editormacroscript.xml was deleted/reset)

Do I need to replace the file as above with Lazarus closed? I did it while it was running.

Lazarus usually detects changed files while running. Though I do not know if a package will be marked for rebuild in that case.... But save is to do so when closed. Or to choose "clean all" as then the file will be rebuild no matter what
But the changes in the file do not affect the button.

Show quoted text 7 lines
So could not complete past this step. >    (this deletes/reset editormacroscript.xml from your primary conf, > which is the file that stores the error) > Tools > Rebuild Lazarus IDE > Restart Will Lazarus not automatically Restart following a rebuild?

That is the default setting, it can be changed though

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 13 lines
On 17/08/2019 18:23, Bo Berglund via lazarus wrote: > On Sat, 17 Aug 2019 16:43:38 +0200, Martin Frb via lazarus > wrote: > >> I attached a ready to go replacement file. >> Make a copy of your original >>   components/macroscript/emsselftest.pas >> and then put the attached file into it. > Done! > >> Tools > Option > editor macro script : "Test again" > This button is disabled, cannot click it. Then it should say "scripting active"?

Yes it does...

That means, that this install of Lazarus has either not yet encountered the error, or that the "editormacroscript.xml" was deleted/reset (i.e. error removed from content).

Could not the actions reported on first start do just that and this is what causes the message not to reappear?

( editormacroscript.xml is in your primary config path. You can find where that is from the menu: View > IDE Internals > About IDE )

I found it and it contains basically nothing:

<?xml version="1.0" encoding="UTF-8"?>
<CONFIG/>

If you get the error again (with or without the changed unit), then check for 1) the "test again" button 2) the editormacroscript.xml file

It will probably only happen wenever I get Lazarus 2.0.6 on board then...

Anyway if scripting is active, then the self test runs at every start of your IDE. And that leaves the question why it does not report the error anymore. (and when the editormacroscript.xml was deleted/reset)

Yes, why?

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 8 lines
On Sat, 17 Aug 2019 18:43:01 +0200, Martin Frb via lazarus wrote: > That means, that this install of Lazarus has either not yet encountered > the error, or that the "editormacroscript.xml" was deleted/reset (i.e. > error removed from content). Could not the actions reported on first start do just that and this is what causes the message not to reappear?

If it displays an error, it should create the xml file, and put the error into it. That will then stop it from testing again, and therefore the error does not happen again.

When you start a newly installed IDE, do you rebuild it (to get your packages back?) Then maybe the rebuild on works.
But that would still leave me wonder, what removed the error from the file.

Show quoted text 6 lines
> ( editormacroscript.xml is in your primary config path. You can find > where that is from the menu: View > IDE Internals > About IDE ) I found it and it contains basically nothing: <?xml version="1.0" encoding="UTF-8"?> <CONFIG/>

Which means no error...

Show quoted text 5 lines
> Anyway if scripting is active, then the self test runs at every start of > your IDE. And that leaves the question why it does not report the error > anymore. (and when the editormacroscript.xml was deleted/reset) Yes, why?

PascalScript can (and needs to) interact with compiled code. For example the instance of a SourceEDitor SynEdit (with limited access) is passed to any macro. The macro can call functions on this SynEdit and interact with it.

Because PascalScript is compiled without knowing of all the method signatures it may have to deal with, it actually has no code to call them. Methods are they need to be called, PS manually builds the stack (and cpu registers) that the called method would expect. This must match exactly what fpc would have done at compiletime.
(there is a 2nd callling method / awaits more testing)

If that goes wrong (maybe fpc changed....), then the behaviour will be undefined. the code is called with trashed data.... To avoid happening that while working in the IDE, there is a selftest at startup.

Before the selftest starts, it will write that to the xml file. So if the test crashes, never finishes, then the file says "I am in testing".
If at start the xml is found to be "in testing", then this is reported as "last test failed" and disables PS.

So your IDE did not crash, as the file is not "in testing" and you said you did not use the reset button.

If the test fails, it is reported and written to the XML. If it succeeds the xml is updated to have nothing in it.

So the self test runs on each start up (since the IDE could have been recompiled).
The only way for it not to run, is if it failed or crashed.

Reply by email

Martin Frb
to Martin Frb
Martin Frb wrote 8 lines
>> ( editormacroscript.xml is in your primary config path. You can find >> where that is from the menu: View > IDE Internals > About IDE ) > I found it and it contains basically nothing: > > <?xml version="1.0" encoding="UTF-8"?> > <CONFIG/> Which means no error...

Just to be sure: editormacroscript.xml

NOT: editormacros.xml

The latter contains your macros, if you have any.

Reply by email

Martin Frb
to Bo Berglund: On Sat, 17 Aug 2019 18:43:01 +0200, Martin Frb via lazarus Yes it does... Could not the…
Bo Berglund wrote
It will probably only happen wenever I get Lazarus 2.0.6 on board then...

I build an installer for 2.0.5 (which does include the extra verbosity) / 64 bit only

https://sourceforge.net/projects/lazarus-snapshots/files/test/ lazarus-2.0.5-61719-fpc-3.0.4-20190817-win64.exe

https://sourceforge.net/projects/lazarus-snapshots/files/test/lazarus-2.0.5-61719-fpc-3.0.4-20190817-win64.exe/download

It contains the following fixes over 2.0.4
https://wiki.lazarus.freepascal.org/index.php?title=Lazarus_2.0_fixes_branch&oldid=126476#Merged_revisions_for_2.0.6

So if you want to, you can try this.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20190818/e27f0fec/attachment.html>

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 6 lines
I build an installer for 2.0.5 (which does include the extra verbosity) / 64 bit only https://sourceforge.net/projects/lazarus-snapshots/files/test/ lazarus-2.0.5-61719-fpc-3.0.4-20190817-win64.exe

Downloaded and installed this 2.0.5 test version as a separate installation (like I always do) on my Windows 7 x64 workstation.

Then:
- Start Lazarus from installed shortcut
- Configure Lazarus IDE - [Start IDE]
- Now NO pop-up complaint about missing script
- config/editormacroscript.xml is empty (no data)
- "Tools/Options/Editor Macro Script/Test again" button is disabled and above there is a "Scripting active" message.

So this Lazarus installer successfully deposits a working Lazarus *without* the initial message about disabling the pascal scripting.

And Lazarus options seems to be exactly like the 2.0.4 I installed previously.
So the message I previously saw about deactivating scripting seems to be an *installer* bug when in fact the installation has succeeded all the time...

Now gone in any case!
Thanks!

Bo Berglund Developer in Sweden

Reply by email

Bo Berglund
to Martin Frb: I attached a ready to go replacement file. Make a copy of your original  …
Martin Frb wrote 13 lines
I attached a ready to go replacement file. Make a copy of your original   components/macroscript/emsselftest.pas and then put the attached file into it. Tools > Option > editor macro script : "Test again"    (this deletes/reset editormacroscript.xml from your primary conf, which is the file that stores the error) Tools > Rebuild Lazarus IDE Restart The new error should be shown on IDE start.

Now after getting 2.0.5 working in Win7 I returned to the RPi4 uinstallation of 2.0.4 and replaced the emsselftest.pas file as described above, then rebuilt the IDE and opened Lazarus and clicked the "test again" button. Closed and started Lazarus and received the message again.

The editormacroscript.xml now contains this:

<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<EMS>
<Settings SelfTestError="Replace All [Exp: True / Got: False / Info: False / SynTxt: Test abc abcde 123
]" SelfTestFailed="1"/>
</EMS>
</CONFIG>

Does this explain what is wrong on the RPi4 installation?

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 8 lines
So this Lazarus installer successfully deposits a working Lazarus *without* the initial message about disabling the pascal scripting. And Lazarus options seems to be exactly like the 2.0.4 I installed previously. So the message I previously saw about deactivating scripting seems to be an *installer* bug when in fact the installation has succeeded all the time...

I doubt it. Nothing was fixed that could have triggered this. Most likely some condition changed. Maybe simple because of the code grew a few bytes....
Something like this normally points to incorrect mem access. But running in valgrind revealed nothing.

Of course PascalScript has different code for each target CPU and OS. (linux vs win // but not diff version of win afaik).

Show quoted text 14 lines
Now after getting 2.0.5 working in Win7 I returned to the RPi4 The editormacroscript.xml now contains this: <?xml version="1.0" encoding="UTF-8"?> <CONFIG> <EMS> <Settings SelfTestError="Replace All [Exp: True / Got: False / Info: False / SynTxt: Test abc abcde 123 ]" SelfTestFailed="1"/> </EMS> </CONFIG> Does this explain what is wrong on the RPi4 installation?

Unfortunately not. This will require deeper debugging. Potentially quite a lot.

I do not have access to an RP at the moment.  I planed to set one up (or get QEMU to work) for more than 2 years now... But didn't find the time. So that may still be a long time before I get to it.

If you want to go on trying to see if we can find anything, then please open
  components\macroscript\emscriptclasses.pas
around line 555
replace TEmsSynWrapper.EMS_SearchReplace
with:

function TEmsSynWrapper.EMS_SearchReplace(ASearch, AReplace: string;
   AOptions: TSynSearchOptions): integer;
begin
debugln(['*** EMS_SearchReplace ASearch ', ord(ssoReplaceAll), ' / ',
integer([ssoReplaceAll])]);
debugln(['*** EMS_SearchReplace ', Pointer(ASearch), ' / ',
Pointer(AReplace), ' / ', integer(AOptions), ' / ', Pointer(self)]);
debugln(['*** EMS_SearchReplace ASearch ', ASearch, ' / ', AReplace]);
debugln(['*** EMS_SearchReplace ASearch ', length(ASearch), ' / ',
length(AReplace)]);
debugln(['*** EMS_SearchReplace ASearch ', RawByteString(ASearch), ' /
', RawByteString(AReplace)]);
debugln(['*** EMS_SearchReplace ASearch ', StringCodePage((ASearch)), '
/ ', StringCodePage((AReplace))]);
debugln(['*** EMS_SearchReplace ASearch ',
StringCodePage(RawByteString(ASearch)), ' / ',
StringCodePage(RawByteString(AReplace))]);
debugln(['*** EMS_SearchReplace ASearch ', self.Text, ' / ',
dbgs(CaretXY)]);
   Result := SearchReplace(ASearch, AReplace, AOptions);
debugln(['*** EMS_SearchReplace ASearch ', Result]);
debugln(['*** EMS_SearchReplace ASearch ', self.Text, ' / ',
dbgs(CaretXY)]);
end;

Start lazarus from console, so you can get the output. Copy the output. The output only matters, if the error occurs. So self-testing must be re-enabled.

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 35 lines
If you want to go on trying to see if we can find anything, then please open   components\macroscript\emscriptclasses.pas around line 555 replace TEmsSynWrapper.EMS_SearchReplace with: function TEmsSynWrapper.EMS_SearchReplace(ASearch, AReplace: string;   AOptions: TSynSearchOptions): integer; begin debugln(['*** EMS_SearchReplace ASearch ', ord(ssoReplaceAll), ' / ', integer([ssoReplaceAll])]); debugln(['*** EMS_SearchReplace ', Pointer(ASearch), ' / ', Pointer(AReplace), ' / ', integer(AOptions), ' / ', Pointer(self)]); debugln(['*** EMS_SearchReplace ASearch ', ASearch, ' / ', AReplace]); debugln(['*** EMS_SearchReplace ASearch ', length(ASearch), ' / ', length(AReplace)]); debugln(['*** EMS_SearchReplace ASearch ', RawByteString(ASearch), ' / ', RawByteString(AReplace)]); debugln(['*** EMS_SearchReplace ASearch ', StringCodePage((ASearch)), ' / ', StringCodePage((AReplace))]); debugln(['*** EMS_SearchReplace ASearch ', StringCodePage(RawByteString(ASearch)), ' / ', StringCodePage(RawByteString(AReplace))]); debugln(['*** EMS_SearchReplace ASearch ', self.Text, ' / ', dbgs(CaretXY)]);   Result := SearchReplace(ASearch, AReplace, AOptions); debugln(['*** EMS_SearchReplace ASearch ', Result]); debugln(['*** EMS_SearchReplace ASearch ', self.Text, ' / ', dbgs(CaretXY)]); end; Start lazarus from console, so you can get the output. Copy the output. The output only matters, if the error occurs. So self-testing must be re-enabled.

I have done this on my RPi4 with Lazarus 2.0.4.
The result after enabling the test and starting again from the console is this sequence (line breaks added by news reader):

pi at rpi4-test:~ $ /home/pi/dev/lazarus/2.0.4/startlazarus --pcp=/home/pi/.lazarus_2.0.4
Adding "--pcp=/home/pi/.lazarus_2.0.4" as a parameter is a file
SetPrimaryConfigPath NewValue="/home/pi/.lazarus_2.0.4" -> "/home/pi/.lazarus_2.0.4"
TLazarusManager.Run starting /home/pi/dev/lazarus/2.0.4/lazarus ... SetPrimaryConfigPath NewValue="/home/pi/.lazarus_2.0.4" -> "/home/pi/.lazarus_2.0.4"
Hint: (lazarus) [TMainIDE.ParseCmdLineOptions]
PrimaryConfigPath="/home/pi/.lazarus_2.0.4"
Hint: (lazarus) [TMainIDE.ParseCmdLineOptions]
SecondaryConfigPath="/etc/lazarus"
Hint: (lazarus) [TBuildManager.SetBuildTarget] Old=arm-linux-gtk2 New=arm-linux-gtk2 Changed: OS/CPU=True LCL=False
Parameter type not implemented!

---Here the error message is shown and it waits for the Start IDE button to be clicked. -----

[WARNING] SetImageList called without handle for
lbMacroView(TListView)
[WARNING] SetImageList called without handle for
lbMacroView(TListView)
[WARNING] SetImageList called without handle for
lbMacroView(TListView)

--- Here is where the IDE has started and can be used --- --- Now close the Lazarus IDE ---

LAZARUS END - cleaning up ...
Hint: (lazarus) [TMainIDE.Destroy] B -> inherited Destroy... TMainIDE Hint: (lazarus) [TMainIDE.Destroy] END

--- Lazarus IDE closed ---

I just copied the command line found in the GUI menu and ran it inside the terminal, except I removed the trailing %f since I had no file to pass in.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote
Parameter type not implemented!

So on arm that explains the error.
It does not implement passing a set as param (must be set, since string worked in other tests).

I have to see, if there are any options.
Otherwise I will disable it for arm (since it does not currently work for anyone, it would not be a regression)

As for what happened on windows, no idea.

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 7 lines
On 18/08/2019 21:19, Bo Berglund via lazarus wrote: > > Parameter type not implemented! > So on arm that explains the error. It does not implement passing a set as param (must be set, since string worked in other tests).

Does this mean that FPC on Arm is not generating the expected code like it does on Windows? So the cross-platform operation is somewhat broken?

Show quoted text 5 lines
I have to see, if there are any options. Otherwise I will disable it for arm (since it does not currently work for anyone, it would not be a regression) As for what happened on windows, no idea.

I know that on RPi Arm I had to figure out what build essentials to install every time I needed to put FPC + Lazarus on a new system. I had to retrieve sources via svn and build on the system so I had to figure out all that was needed to succeed.
I put all of this into an installation script I use every time nowadays (I have been doing this for 6-7 years now). It assumes nothing but a pristine out-of-the-box Raspbian installation which needs some more packages in order to work with s/w development. So the script installs that for me.

And it has worked every time except once when the RPi went from arm6 to arm7 and a flag had to be added into the fpc build commands in the script.

I think I have seen the same first start error for a long time on the RPi. It is quite possible that I don't have the complete set of required packages listed for installation in my script and this is what breaks it. But that is provided that it is not an fpc deviation for arm of course.

On Windows I have yet to build a dev system myself, I always use the "official" installers there.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 12 lines
On Sun, 18 Aug 2019 22:51:31 +0200, Martin Frb via lazarus wrote: > On 18/08/2019 21:19, Bo Berglund via lazarus wrote: >> Parameter type not implemented! >> > So on arm that explains the error. > It does not implement passing a set as param (must be set, since string > worked in other tests). Does this mean that FPC on Arm is not generating the expected code like it does on Windows? So the cross-platform operation is somewhat broken?

No, it means PascalScript is not fully implemented

Show quoted text 13 lines
> I have to see, if there are any options. > Otherwise I will disable it for arm (since it does not currently work > for anyone, it would not be a regression) > > As for what happened on windows, no idea. I think I have seen the same first start error for a long time on the RPi. It is quite possible that I don't have the complete set of required packages listed for installation in my script and this is what breaks it. But that is provided that it is not an fpc deviation for arm of course. On Windows I have yet to build a dev system myself, I always use the "official" installers there.

It is not a missing package.
All the code is compiled into the IDE.

PascalScript is a 3rd party package. It includes some asm code that differs for each platform (cpu and general type of OS).

The OS type only matters because the calling convention differs. That is fpc (following the rules for each platform) uses different registers to store function param.
But there is no diff between win7 (64bit) and win10 (64bit). So if it works on w10 for me, I have no idea why it fails for you (win 7).

Arm/linux (raspi) has different code in PS. And apparently that is incomplete. But that only affects RPI.

Also on either system. After the error happens once, that is stored in the config. Unless you remove your config each time that you install, you should never see the error again.
To verify that, you can (after the error) check the XML file. That xml file should stay there forever.

As I said, I will decide (soon / hopefully sometime before the next release) what to do on arm. Maybe disable it for arm. Then there wont be an error.
Maybe I find a work around. Then I would have to ask you to test (since I cant currently).

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 5 lines
Also on either system. After the error happens once, that is stored in the config. Unless you remove your config each time that you install, you should never see the error again. To verify that, you can (after the error) check the XML file. That xml file should stay there forever.

I always make a separate config dir for each installation so a new install starts out with an empty config. I use the --pcp= flag in the start command on Linux to specify this dir.
On Windows the installer fixes this during install when I check the "separate installation" flag.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund

Can you please retest with
Revision: 61896
Date: 17 September 2019 22:21:38
EditorMacroScript: Use "internal" (none-native) calling for object methods

Making sure you remove your editormacroscript.xml file, or re-request the self-test from the options page, please.

Bo Berglund wrote 15 lines
On Mon, 19 Aug 2019 00:46:18 +0200, Martin Frb via lazarus wrote: > Also on either system. After the error happens once, that is stored in > the config. Unless you remove your config each time that you install, > you should never see the error again. > To verify that, you can (after the error) check the XML file. That xml > file should stay there forever. I always make a separate config dir for each installation so a new install starts out with an empty config. I use the --pcp= flag in the start command on Linux to specify this dir. On Windows the installer fixes this during install when I check the "separate installation" flag.

Reply by email

Bo Berglund
to Martin Frb
Martin Frb wrote 7 lines
Can you please retest with Revision: 61896 Date: 17 September 2019 22:21:38 EditorMacroScript: Use "internal" (none-native) calling for object methods Making sure you remove your editormacroscript.xml file, or re-request the self-test from the options page, please.

I just installed Lazarus 2.0.6 from sources and when I started it on Raspbian Buster I did get the dialog again. I assume your change is in 2.0.6? Help/About reports revision 62151.

On Lazarus startup it created the file and following starts are OK. If I remove the file the error box re-appears (once) on Lazarus start.

Bo Berglund Developer in Sweden

Reply by email

Martin Frb
to Bo Berglund
Bo Berglund wrote 5 lines
I just installed Lazarus 2.0.6 from sources and when I started it on Raspbian Buster I did get the dialog again. I assume your change is in 2.0.6? Help/About reports revision 62151.

No, the change was a bigger change, which will only be in 2.2

Reply by email