title: Getting the line number of executing code in TCL-Interpreter instantiated in C++
body: <p>I'm using CPPTCL to instantiate an instance of TCL interpreter in my C++ code. I can then execute scripts by use of "pTclInterpreter->eval(script);" Works as needed. I also define my own TCL functions as C++ functions and make them available for use in the TCL script by "pTclInterpreter->def("getValueCmd", getValueCmd);". Works fine, too.</p>
  
  <p>Now, for messaging (info/error) inside my C++ implemented TCL functions I need to know from what script line the function was called. I found the article: <a href="https://stackoverflow.com/questions/27834094/getting-the-line-number-of-executing-code-in-tcl">Getting the line number of executing code in TCL</a> and when I execute the TCL-Script in a standalone TCL shell I receive as expected:
  Global
  28
  proc A
  23
  proc B
  18
  proc C
  13
  proc D
  9</p>
  
  <p>But when I execute the very same script from within my C++ instantiated TCL interpreter I receive instead:
  Global
  28
  proc A
  3
  proc B
  3
  proc C
  3
  proc D
  3</p>
  
  <p>The Global call is correct at line 28. But for the function calls it is always "3", which seems to refer to being the third line in the called function - not the line in the complete script.</p>
  
  <p>This leaves me with two Questions:
  1.) How can I detect what TCL script line called my C++ function?
  2.) If the behavior of TCL script is different in this point - where else would I have to expect differences?</p>
  
  <p>In the folling my C++ code.</p>
  
  <pre><code>#include &lt;systemc.h&gt;
  #include "cpptcl.h"
  
  sc_event  go;
  
  Tcl::interpreter *pTclInterpreter;
  
  int MOD(std::string module, std::string cmd, int param1, int param2){
      /* 
          Function to simulate the execution of an IFS command.
      */
  
      /*
          Here we would have the code that creates the proper cmdObj
      */
      std::cout &lt;&lt; sc_time_stamp() &lt;&lt; ": creatingCmdObj(";
      std::cout &lt;&lt; module;
      std::cout &lt;&lt; ", " &lt;&lt; cmd;
      std::cout &lt;&lt; ", " &lt;&lt; param1;
      std::cout &lt;&lt; ", " &lt;&lt; param2;
      std::cout &lt;&lt; ")"  &lt;&lt; std::endl;
  
  //  pTclInterpreter-&gt;eval("puts [ dict get [info frame [info frame -1] ]  line ]");
  
      return 0;
  }
  
  int getValueCmd(){
      /*
          Function to simulate the execution of a getValue
      */
      std::cout &lt;&lt; sc_time_stamp() &lt;&lt; ": executing getValueCmd." &lt;&lt; std::endl;
      std::cout &lt;&lt; sc_time_stamp() &lt;&lt; ": TCL waiting for all TBMs to catch up." &lt;&lt; std::endl;
      wait(go);
      std::cout &lt;&lt; sc_time_stamp() &lt;&lt; ": TBMs in sync. TCL interpreter to continue." &lt;&lt; std::endl;
      return 0;
  }
  
  int read_trace(const int&amp; v, void *) {
    cout &lt;&lt; "read trace triggered: wait(10, SC_NS)" &lt;&lt; endl;
    wait(10, SC_NS);
    return v;
  }
  
  SC_MODULE (wait_example) {
  
    void tclInterpreter() {
  
      std::cout &lt;&lt; sc_time_stamp() &lt;&lt; ": Starting TCL interpreter!" &lt;&lt; std::endl;
  
      // new TCL
      pTclInterpreter = new(Tcl::interpreter);
  
      // register the C++ function to be called from TCL
      pTclInterpreter-&gt;def("MOD", MOD);
      pTclInterpreter-&gt;def("getValueCmd", getValueCmd);
      // register read trace for variable
      pTclInterpreter-&gt;def_read_trace("tracedVar", "read", read_trace);
  
      // load the script
      // ifstream script("helloworld.tcl");
      ifstream script("test.tcl");
  
      // run the script with the given arguments
      pTclInterpreter-&gt;eval(script);
  
      cout &lt;&lt; sc_time_stamp() &lt;&lt; ": Terminating Simulation." &lt;&lt; std::endl;
      sc_stop(); // sc_stop triggers end of simulation
    }
  
    void ifscontroller() {
      wait(100, SC_NS);
      go.notify();
    }
  
    SC_CTOR(wait_example) {
      SC_THREAD(tclInterpreter);
      SC_THREAD(ifscontroller);
    }
  }; 
  
  int sc_main (int argc, char* argv[]) {
  
    wait_example object("wait");
  
    sc_start(0, SC_NS); // First time called will init schedular
    sc_start();  // Run the simulation till sc_stop is encountered
    return 0;// Terminate simulation
  }
  </code></pre>
  
  <p>This also uses SystemC which I believe to be of no further importants here. As you see, I create a TCL interpreter instance and have the pointer pTclInterpreter reference it. I then use "pTclInterpreter->eval(script);" to execute the script from the reference. But results are different from doing this in a pure shell.</p>