2016-05-31 3 views
3

У меня есть proc MYPROC, который вызывается из подчиненного интерпретатора (с именем MYPRO) с использованием псевдонимов и неизвестных механизмов.Получение номера строки inviki при использовании псевдонимов

#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 вызова (Ie номер строки «MYPRO {„“}» в Скрипт2, который является 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 {} запись.

+0

Это интересная проблема на самом деле, а не совсем тривиальная. _Контекст имеет значение; _ читатели должны знать, что используются несколько интерпретаторов, и что это сильно влияет на результаты. –

ответ

2

Проблема (для вас) заключается в том, что 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" 

Там мы идем, мы теперь можем видеть правильный номер строки. Я предполагаю, что вы сможете разобраться с этим.

+0

Спасибо за ответ. Это решает мою проблему. – ArmanHunanyan