2016-05-31 19 views
3

Ich habe eine proc MYPROC, die von Slave-Interpreter (mit dem Namen MYPRO) mit Alias ​​und unbekannten Mechanismen aufgerufen wird.Invokationszeilennummer bei der Verwendung von Aliasen

#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; 
} 

Innenkörper MYPROC Ich brauche Zeilennummer MYPRO Aufruf (Ie Zeilennummer von „MYPRO {‚‘}“ in script2 die 3) erhalten

Hier eine Ausgabe dieser Probe ist

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) 

Hier gibt es keine jede Rahmeninformationen über MYPRO Aufruf Linie seit Bildzählwertes 2. auch von Fehlerspur ist interp1 Sie, dass proc und Zeileninformationen sehen können, ist für MYPRO fehlt {} Eintrag.

+0

Dies ist ein interessantes Problem, und nicht ganz trivial. _Kontext ist wichtig: _ Leser sollten sich darüber im Klaren sein, dass mehrere Interpreter im Einsatz sind und dass dies die Ergebnisse stark beeinflusst. –

Antwort

2

Das Problem (für Sie) ist, dass info frame nichts über Stapelrahmen in anderen Interpretern beschreibt. Dies ist beabsichtigt; Dolmetscher sind stark voneinander abgeschottet.

Ich habe Ihr Problem ohne C-Code reproduziert. Die Interpreter heißen foo und bar, aber Sie könnten diese Namen durch etwas anderes ersetzen.

% 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" 

Das scheint ordnungsgemäß zu funktionieren. (BTW ist info frame 0 nicht Nutzleistung hier;.. Es vom anderen Ende des Rahmens Stapel zählt schon, wie info level 0 nicht ich habe es entfernt)

Sie brauchen, um zu versuchen, die info frame Fragen in dem Dolmetscher zu stellen, die kann sie beantworten. Lassen Sie uns das tun (in diesem Fall einen Aliasnamen verwenden, aber ich denke, interp eval würde auch ein geeigneter Mechanismus sein):

% 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" 

Dort gehen wir, wir sind jetzt in der Lage, die richtige Liniennummer zu sehen. Ich nehme an, Sie werden die Dinge von dort aus ordnen können.

+0

Danke für die Antwort. Es löst mein Problem. – ArmanHunanyan