9

我正在使用 RemObjects(优秀)的 PascalScript 和 SynEdit 编辑器创建一个内置脚本引擎。使用 PascalScript 附带的 IDE 示例和 SynEdit 中的 IDE 示例几乎完成了 - 但是 - 我看不到如何询问 PascalScript 编号的源代码行是否“可执行”。(然后我可以使用它用“Delphi 蓝点”标记 SynEdit 排水沟)。我想我可能需要对 ROPS 输出进行反汇编?

这里有 PascalScript 专家吗?谢谢。布赖恩。

4

3 回答 3

9

查看Inno Setup的源代码。它确实在 SynEdit 装订线区域中显示了一个小点,用于表示具有可执行代码的行,灰色表示可执行但尚未执行的行,绿色表示已被命中至少一次的行。

可以在 中找到此代码CompForm.pas,查找TLineState类型。该信息是在iscbNotifySuccess编译器回调的状态下设置的,您可以在 IDE 中执行相同的操作。您可能需要调整代码以处理多个源文件,因为 Inno Setup 编译器仅处理单个源文件中的代码片段。

在 Pascal 脚本源中,您应该查看该TPSCustomDebugExec.TranslatePositionEx()方法 - 它也确实返回源文件的名称。

于 2009-06-26T21:34:17.297 回答
1

我不知道它到底是怎么做的,但是 PascalScript 包中的 IDE 项目(在 \samples\debug 下找到)能够提供 Step Into 和 Step Over(F7 和 F8)功能,所以从逻辑上讲它必须有一些将 PS 字节码与脚本代码行关联的方式。试着检查那个项目,看看它是如何做到的。作为奖励,它也使用 SynEdit,因此这些想法​​很容易适应您自己的系统。

于 2009-06-26T19:50:57.300 回答
1

我知道这是一个老问题,但我自己一直在做同样的事情,上面的建议并没有真正帮助。例如 Inno setup 不使用 Synedit,它使用 scintilla 编辑器。

TPSCustomDebugExec.TranslatePositionEx() 也与想要的相反,它从运行时代码位置提供源行号。

在闲逛了一段时间后,我得出结论,最简单的方法是在 Pascalscript 代码中添加一个函数。

新方法被添加到 uPSdebugger 单元中的 TPSCustomDebugExec 类中。

function TPSCustomDebugExec.HasCode(Filename:string; LineNo:integer):boolean;
var i,j:integer; fi:PFunctionInfo; pt:TIfList; r:PPositionData;
begin
  result:=false;
  for i := 0 to FDebugDataForProcs.Count -1 do
  begin
    fi := FDebugDataForProcs[i];
    pt := fi^.FPositionTable;
    for j := 0 to pt.Count -1 do
    begin
      r:=pt[j];
      result:= SameText(r^.FileName,Filename) and (r^.Row=LineNo);
      if result then exit
    end;
  end;
end;

主编辑器窗体中的油漆槽回调如下

procedure Teditor.PaintGutterGlyphs(ACanvas:TCanvas; AClip:TRect;
  FirstLine, LastLine: integer);
var a,b:boolean; LH,LH2,X,Y,ImgIndex:integer;
begin
  begin
    FirstLine := Ed.RowToLine(FirstLine);
    LastLine := Ed.RowToLine(LastLine);
    X := 14;
    LH := Ed.LineHeight;
    LH2:=(LH-imglGutterGlyphs.Height) div 2;
    while FirstLine <= LastLine do
    begin
      Y := LH2+LH*(Ed.LineToRow(FirstLine)-Ed.TopLine);
      a:= ce.HasBreakPoint(ce.MainFileName,FirstLine);
      b:= ce.Exec.HasCode(ce.MainFileName,FirstLine);
      if Factiveline=FirstLine then
      begin
        if a then
          ImgIndex := 2   //Blue arrow+red dot (breakpoint and execution point)
        else
          ImgIndex := 1;  //Blue arrow (current line execution point)
      end
      else
        if b then
        begin
          if a then
            ImgIndex := 3  //Valid Breakpoint marker
          else
            ImgIndex := 0; //blue dot  (has code)
        end
        else
        begin
          if a then
            ImgIndex := 4  //Invalid breakpoint (No code on this line)
          else
            ImgIndex := -1; //Empty (No code for line)
        end;
      if ImgIndex >= 0 then
        imglGutterGlyphs.Draw(ACanvas, X,Y,ImgIndex);
      Inc(FirstLine);
    end;
  end;
end;

带有行号、代码点、断点、书签和执行点的 Synedit 如下图所示

在此处输入图像描述

于 2015-11-05T22:52:18.490 回答