使用别名时获取调用行号
Getting invokation line number when using aliases
我有一个 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;
}
在 MYPROC 的主体中,我需要获取 MYPRO 调用的行号(即脚本 2 中“MYPRO {""}”的行号为 3)
这是这个示例的输出
2
frame 0 type proc line 5 cmd {info frame 0} proc ::MYPROC level 0
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"
while executing
"info frame 3"
(procedure "MYPROC" line 8)
invoked from within
"${cmd}C $args "
(procedure "m_unknown" line 2)
invoked from within
"MYPRO {} "
bad level "3"
while executing
"info frame 3"
(procedure "MYPROC" line 8)
invoked from within
"${cmd}C $args "
(procedure "m_unknown" line 2)
这里没有关于 MYPRO 调用行的任何帧信息,因为帧数是 2。另外,从 interp1 的错误跟踪中,您可以看到 MYPRO 的过程和行信息丢失{}条目。
问题(对你来说)是 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
一样。我已经删除了它。)
您需要尝试在可以回答的口译员中询问 info frame
问题。让我们这样做(在这种情况下使用别名,但我认为 interp eval
也是一种合适的机制):
% 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"
好了,我们现在可以看到正确的行号了。我想您可以从那里解决问题。
我有一个 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;
}
在 MYPROC 的主体中,我需要获取 MYPRO 调用的行号(即脚本 2 中“MYPRO {""}”的行号为 3)
这是这个示例的输出
2
frame 0 type proc line 5 cmd {info frame 0} proc ::MYPROC level 0
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"
while executing
"info frame 3"
(procedure "MYPROC" line 8)
invoked from within
"${cmd}C $args "
(procedure "m_unknown" line 2)
invoked from within
"MYPRO {} "
bad level "3"
while executing
"info frame 3"
(procedure "MYPROC" line 8)
invoked from within
"${cmd}C $args "
(procedure "m_unknown" line 2)
这里没有关于 MYPRO 调用行的任何帧信息,因为帧数是 2。另外,从 interp1 的错误跟踪中,您可以看到 MYPRO 的过程和行信息丢失{}条目。
问题(对你来说)是 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
一样。我已经删除了它。)
您需要尝试在可以回答的口译员中询问 info frame
问题。让我们这样做(在这种情况下使用别名,但我认为 interp eval
也是一种合适的机制):
% 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"
好了,我们现在可以看到正确的行号了。我想您可以从那里解决问题。