Tcl 使用别名时获取调用行号

Tcl 使用别名时获取调用行号,tcl,frame,interpreter,slave,Tcl,Frame,Interpreter,Slave,我有一个proc MYPROC,它是使用别名和未知机制从从属解释器(名为MYPRO)调用的 #include <tcl.h> #include <iostream> int main() { Tcl_Interp* interp0 = Tcl_CreateInterp(); Tcl_Interp* interp1 = Tcl_CreateSlave(interp0, "sl", false); const char* script1 =

我有一个proc MYPROC,它是使用别名和未知机制从从属解释器(名为MYPRO)调用的

#include <tcl.h>
#include <iostream>

int main()
{
    Tcl_Interp* interp0 = Tcl_CreateInterp();
    Tcl_Interp* interp1 = Tcl_CreateSlave(interp0, "sl", false);
    const char* script1 =
       "proc MYPROC {a} {                              \n"
       "    puts [info frame]                          \n"
       "    global tcl_version                         \n"
       "    if { $tcl_version >= \"8.5\" } {           \n"
       "        puts \"frame 0 [info frame 0]\"        \n"
       "        puts \"frame 1 [info frame 1]\"        \n"
       "        puts \"frame 2 [info frame 2]\"        \n"
       "        puts \"frame 3 [info frame 3]\"        \n"
       "    }                                          \n"
       "}                                              \n"
       "proc m_unknown {cmd args} {                    \n"
       "    ${cmd}C $args                              \n"
       "}                                              \n";

    Tcl_Eval(interp0, script1);

    Tcl_CreateAlias(interp1, "unknown", interp0, "m_unknown", NULL, NULL);
    const char* script2 =
       "set a 1       \n"
       "set b 2       \n"
       "MYPRO {""}    \n";

    if (Tcl_Eval(interp1, script2) == TCL_ERROR) {
        Tcl_Eval(interp1, "puts $errorInfo");
        Tcl_Eval(interp0, "puts $errorInfo");
    }

    return 0;
}
这里没有关于MYPRO调用行的任何帧信息,因为帧计数为2。另外,从interp1的错误跟踪中,您可以看到MYPRO{}条目缺少proc和行信息。

问题(对您而言)在于
info frame
没有描述其他解释器中的堆栈帧。这是故意的;口译员之间有很强的隔阂

我复制了你的问题没有任何C代码。口译员的名字是
foo
bar
,但是你可以用其他名字来代替这些名字

% interp create foo
foo
% interp eval foo {
  proc MYPROC {a} {
    puts [info frame]   
    global tcl_version
    if { $tcl_version >= "8.5" } {
      puts "frame 1 [info frame 1]"
      puts "frame 2 [info frame 2]"
      puts "frame 3 [info frame 3]"
    }
  }
  proc m_unknown {cmd args} {
    ${cmd}C {*}$args
  }
}
% interp create bar
bar
% interp alias  bar unknown  foo m_unknown
unknown
% interp eval bar {
  set a 1
  set b 2 
  MYPRO {""}
}
2
frame 1 type proc line -1 cmd {${cmd}C {*}$args} proc ::m_unknown level 1
frame 2 type proc line 7 cmd {info frame 2} proc ::MYPROC level 0
bad level "3"
这似乎运行正常。(顺便说一句,
info frame 0
在这里不是有用的输出;它从另一端开始计算帧堆栈,就像
info level 0
一样。我已经删除了它。)

您需要尝试在解释器中询问
信息框
可以回答的问题。让我们这样做(在本例中使用别名,但我认为
interp eval
也是一种合适的机制):


好了,我们现在可以看到正确的行号了。我想你可以从那里把事情整理出来。

这实际上是一个有趣的问题,而不是完全琐碎的问题。背景事项;读者应该意识到有多个口译员在使用,这对结果有很大影响。
% interp create foo
foo
% interp eval foo {
  proc MYPROC {a} {
    puts [info frame]   
    global tcl_version
    if { $tcl_version >= "8.5" } {
      puts "frame 1 [info frame 1]"
      puts "frame 2 [info frame 2]"
      puts "frame 3 [info frame 3]"
    }
  }
  proc m_unknown {cmd args} {
    ${cmd}C {*}$args
  }
}
% interp create bar
bar
% interp alias  bar unknown  foo m_unknown
unknown
% interp eval bar {
  set a 1
  set b 2 
  MYPRO {""}
}
2
frame 1 type proc line -1 cmd {${cmd}C {*}$args} proc ::m_unknown level 1
frame 2 type proc line 7 cmd {info frame 2} proc ::MYPROC level 0
bad level "3"
% interp alias  foo what  bar info frame
what
% interp eval foo {
  proc MYPROC {a} {
    puts [what]
    puts "frame 1 [what 1]"   
    puts "frame 2 [what 2]"
    puts "frame 3 [what 3]"
  }
}
% interp eval bar {
  set a 1
  set b 2
  MYPRO ""
}
1
frame 1 type eval line 4 cmd {MYPRO ""} level 0
bad level "2"