#include #include #include #include #include "FrameUtil/AbsInterp.hh" #include "TclUtils/TclInterpManager.hh" TclInterpManager* TclInterpManager::_instance = 0; TclInterpManager::TclInterpManager() : _defaultShared(true), _lastDeletedInterp(0) { _sharedInterp = Tcl_CreateInterp(); _initialize(_sharedInterp); // Install the "ac++" command into AbsInterp char command[] = "proc ac++ {args} {catch {uplevel #0 $args} result ; if {[string length $result] > 0} {puts $result ; flush stdout} ; return}"; AbsInterp::instance()->simulateInput(std::string(command)); } TclInterpManager* TclInterpManager::instance() { if (_instance == 0) _instance = new TclInterpManager; return _instance; } Tcl_Interp * TclInterpManager::getInterp() { return getInterp(_defaultShared); } void TclInterpManager::setShared(bool trueOrFalse) { _defaultShared = trueOrFalse; } bool TclInterpManager::isShared() { return _defaultShared; } Tcl_Interp * TclInterpManager::getInterp(bool isShared) { if (isShared) { return _sharedInterp; } else { Tcl_Interp *interp = Tcl_CreateInterp(); _initialize(interp); return interp; } } void TclInterpManager::deleteInterp(Tcl_Interp *interp) { assert(interp); // Delayed deletion. Useful for classes which have Tcl // interpreters as members, e.g. TclModule. if (interp != _sharedInterp) { if (_lastDeletedInterp != interp) { if (_lastDeletedInterp) Tcl_DeleteInterp(_lastDeletedInterp); _lastDeletedInterp = interp; } } } void TclInterpManager::_initialize(Tcl_Interp *interp) { Tcl_Init(interp); Tcl_SetVar(interp, "tcl_interactive", const_cast(isatty(0) ? "1" : "0"), TCL_GLOBAL_ONLY); // Install the "ac++" command char command[] = "ac++"; Tcl_CreateCommand(interp, command, reinterpret_cast(_absInterpCommand), 0, 0); // Source the Tcl utility script char sourceutils[] = "set inifile_u $env(CDFSOFT2_DIR)/TclUtils/scripts/TclUtils.tcl\n" "if {[info exists env(SRT_LOCAL)]} {\n" "if {[string compare $env(SRT_LOCAL) \".\"]} {\n" "if {[file readable $env(SRT_LOCAL)/TclUtils/scripts/TclUtils.tcl]} {\n" "set inifile_u $env(SRT_LOCAL)/TclUtils/scripts/TclUtils.tcl\n" "}\n" "}\n" "}\n" "catch {source $inifile_u}\n" "unset inifile_u"; Tcl_GlobalEval(interp, sourceutils); // Reset the interpreter result Tcl_ResetResult(interp); } int TclInterpManager::_absInterpCommand(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { if (argc < 2) { Tcl_SetResult(interp, "wrong # of arguments", TCL_VOLATILE); return TCL_ERROR; } char *script = Tcl_Concat(argc, argv); AbsInterp::instance()->simulateInput(std::string(script)); Tcl_Free(script); return TCL_OK; }