Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

src/aclvis/InterpTcl.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 #include "aclvis/InterpTcl.h"
00027 #ifdef IPPL_USE_STANDARD_HEADERS
00028 #include <iostream>
00029 #include <fstream>
00030 using namespace std;
00031 #else
00032 #include <iostream.h>
00033 #include <fstream.h>
00034 #endif
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 #include <string.h>
00039 #include <tcl.h>
00040 
00041 
00043 // the callback function used by all tcl commands, which will call the
00044 // the virtual function "process" in the proper InterpCmd object
00045 int TclCallback(ClientData data, Tcl_Interp *interp, int argc, char *argv[]) {
00046   // recast the clientdata back to an InterpCmd, which it must be
00047   InterpCmd *cmd = static_cast<InterpCmd *>(data);
00048 
00049   // invoke the virtual function 'process' in this InterpCmd, which will
00050   // then do the actual work for this command.  Give it the argc, argv, and
00051   // an integer status variable.  It should return a pointer to a string
00052   // with the return value for the command.
00053   bool status;
00054   char *infobuf = cmd->process(argc, argv, status);
00055 
00056   // since this is Tcl, put this return information in Tcl structures.
00057   if (infobuf != 0 && *infobuf != 0) {
00058     cout << infobuf << endl;
00059     Tcl_SetResult(interp, infobuf, TCL_STATIC);
00060   }
00061 
00062   // and then return the proper error code
00063   return (status ? TCL_OK : TCL_ERROR);
00064 }
00065 
00066 
00068 // constructor
00069 InterpTcl::InterpTcl(const char *nm) : Interp(nm) {
00070   // create a new TCL interpreter context
00071   interp = Tcl_CreateInterp();
00072 }
00073 
00074 
00076 // destructor
00077 InterpTcl::~InterpTcl() {
00078   // shut down the interpreter
00079   Tcl_DeleteInterp(interp);
00080 }
00081 
00082 
00084 // Add a new command callback to the interpreter, by providing a InterpCmd.
00085 void InterpTcl::addCommand(InterpCmd &cmd) { 
00086   // create a new command - set the callback to TclCallback, and the
00087   // clientdata to the given cmd, so that when the callback is called,
00088   // it can find the context for this new command
00089   Tcl_CreateCommand(interp, cmd.name(), TclCallback,
00090                     static_cast<ClientData>(&cmd), 0);
00091 }
00092 
00093 
00095 // Take the given string and have the interpreter evaluate it as a command.
00096 // Return true if OK, false if an error occurred.
00097 bool InterpTcl::evalCommand(const char *cmdstr) {
00098   // make sure we have something to do
00099   if (cmdstr == 0 || *cmdstr == 0)
00100     return true;
00101 
00102   // evaluate the command string using TCL
00103   char *buf = new char[strlen(cmdstr) + 1];
00104   strcpy(buf, cmdstr);
00105   int code = Tcl_Eval(interp, buf);
00106 
00107   // print out the result, if possible
00108   if (*(interp->result) != 0)
00109     cout << interp->result << endl;
00110 
00111   // and return if there was an error
00112   delete [] buf;
00113   return (code == TCL_OK);
00114 }
00115 
00116 
00118 // Bind a given variable to the given string variable name ... modifying
00119 // the interpreter variable should then modify the bound variable.
00120 // This is available for integer and double variables.
00121 void InterpTcl::bindVar(const char *cmdstr, int &myvar) {
00122   Tcl_LinkVar(interp, const_cast<char *>(cmdstr) ,
00123               reinterpret_cast<char *>(&myvar), TCL_LINK_INT);
00124 }
00125 
00126 
00128 // Bind a given variable to the given string variable name ... modifying
00129 // the interpreter variable should then modify the bound variable.
00130 // This is available for integer and double variables.
00131 void InterpTcl::bindVar(const char *cmdstr, double &myvar) {
00132   Tcl_LinkVar(interp, const_cast<char *>(cmdstr) ,
00133               reinterpret_cast<char *>(&myvar), TCL_LINK_DOUBLE);
00134 }
00135 
00136 
00137 /***************************************************************************
00138  * $RCSfile: InterpTcl.cpp,v $   $Author: adelmann $
00139  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:34 $
00140  * IPPL_VERSION_ID: $Id: InterpTcl.cpp,v 1.1.1.1 2003/01/23 07:40:34 adelmann Exp $ 
00141  ***************************************************************************/

Generated on Fri Nov 2 01:25:53 2007 for IPPL by doxygen 1.3.5