⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpptcl.cc

📁 cpptcl library for ns2
💻 CC
📖 第 1 页 / 共 2 页
字号:
//// Copyright (C) 2004-2006, Maciej Sobczak//// Permission to copy, use, modify, sell and distribute this software// is granted provided this copyright notice appears in all copies.// This software is provided "as is" without express or implied// warranty, and with no claim as to its suitability for any purpose.//#include "cpptcl.h"#include <map>#include <sstream>#include <iterator>using namespace Tcl;using namespace Tcl::details;using namespace std;using namespace boost;result::result(Tcl_Interp *interp) : interp_(interp) {}result::operator bool() const{     Tcl_Obj *obj = Tcl_GetObjResult(interp_);          int val, cc;     cc = Tcl_GetBooleanFromObj(interp_, obj, &val);     if (cc != TCL_OK)     {          throw tcl_error(interp_);     }          return static_cast<bool>(val);}result::operator double() const{     Tcl_Obj *obj = Tcl_GetObjResult(interp_);          double val;     int cc = Tcl_GetDoubleFromObj(interp_, obj, &val);     if (cc != TCL_OK)     {          throw tcl_error(interp_);     }          return val;}result::operator int() const{     Tcl_Obj *obj = Tcl_GetObjResult(interp_);          int val, cc;     cc = Tcl_GetIntFromObj(interp_, obj, &val);     if (cc != TCL_OK)     {          throw tcl_error(interp_);     }          return val;}result::operator long() const{     Tcl_Obj *obj = Tcl_GetObjResult(interp_);          long val;     int cc;     cc = Tcl_GetLongFromObj(interp_, obj, &val);     if (cc != TCL_OK)     {          throw tcl_error(interp_);     }          return val;}result::operator string() const{     Tcl_Obj *obj = Tcl_GetObjResult(interp_);     return Tcl_GetString(obj);}result::operator object() const{     return object(Tcl_GetObjResult(interp_));}void details::set_result(Tcl_Interp *interp, bool b){     Tcl_SetObjResult(interp, Tcl_NewBooleanObj(b));}void details::set_result(Tcl_Interp *interp, int i){     Tcl_SetObjResult(interp, Tcl_NewIntObj(i));}void details::set_result(Tcl_Interp *interp, long i){     Tcl_SetObjResult(interp, Tcl_NewLongObj(i));}void details::set_result(Tcl_Interp *interp, double d){     Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d));}void details::set_result(Tcl_Interp *interp, string const &s){     Tcl_SetObjResult(interp,          Tcl_NewStringObj(s.data(), static_cast<int>(s.size())));}void details::set_result(Tcl_Interp *interp, void *p){     ostringstream ss;     ss << 'p' << p;     string s(ss.str());     Tcl_SetObjResult(interp,          Tcl_NewStringObj(s.data(), static_cast<int>(s.size())));}void details::set_result(Tcl_Interp *interp, object const &o){     Tcl_SetObjResult(interp, o.get_object());}void details::check_params_no(int objc, int required){     if (objc < required)     {          throw tcl_error("Too few arguments.");     }}object details::get_var_params(Tcl_Interp *interp,     int objc, Tcl_Obj * CONST objv[],     int from, policies const &pol){     object o;     if (pol.variadic_)     {          check_params_no(objc, from);          o.assign(objv + from, objv + objc);     }     else     {          check_params_no(objc, from + 1);          o.assign(objv[from]);     }     o.set_interp(interp);     return o;}namespace // anonymous{// map of polymorphic callbackstypedef map<string, shared_ptr<callback_base> > callback_interp_map;typedef map<Tcl_Interp *, callback_interp_map> callback_map;callback_map callbacks;callback_map constructors;// map of call policiestypedef map<string, policies> policies_interp_map;typedef map<Tcl_Interp *, policies_interp_map> policies_map;policies_map call_policies;// map of object handlerstypedef map<string, shared_ptr<class_handler_base> > class_interp_map;typedef map<Tcl_Interp *, class_interp_map> class_handlers_map;class_handlers_map class_handlers;// helper for finding call policies - returns true when foundbool find_policies(Tcl_Interp *interp, string const &cmdName,     policies_interp_map::iterator &piti){     policies_map::iterator pit = call_policies.find(interp);     if (pit == call_policies.end())     {          return false;     }          piti = pit->second.find(cmdName);     return piti != pit->second.end();}extern "C"int object_handler(ClientData cd, Tcl_Interp *interp,     int objc, Tcl_Obj * CONST objv[]);// helper function for post-processing call policies// for both free functions (isMethod == false)// and class methods (isMethod == true)void post_process_policies(Tcl_Interp *interp, policies &pol,     Tcl_Obj * CONST objv[], bool isMethod){     // check if it is a factory     if (!pol.factory_.empty())     {          class_handlers_map::iterator it = class_handlers.find(interp);          if (it == class_handlers.end())          {               throw tcl_error(                    "Factory was registered for unknown class.");          }          class_interp_map::iterator oit = it->second.find(pol.factory_);          if (oit == it->second.end())          {               throw tcl_error(                    "Factory was registered for unknown class.");          }          class_handler_base *chb = oit->second.get();          // register a new command for the object returned          // by this factory function          // if everything went OK, the result is the address of the          // new object in the 'pXXX' form          // - the new command will be created with this name          Tcl_CreateObjCommand(interp,               Tcl_GetString(Tcl_GetObjResult(interp)),               object_handler, static_cast<ClientData>(chb), 0);     }     // process all declared sinks     // - unregister all object commands that envelopes the pointers     for (vector<int>::iterator s = pol.sinks_.begin();          s != pol.sinks_.end(); ++s)     {          if (isMethod == false)          {               // example: if there is a declared sink at parameter 3,               // and the Tcl command was:               // % fun par1 par2 PAR3 par4               // then the index 3 correctly points into the objv array               int index = *s;               Tcl_DeleteCommand(interp, Tcl_GetString(objv[index]));          }          else          {               // example: if there is a declared sink at parameter 3,               // and the Tcl command was:               // % $p method par1 par2 PAR3 par4               // then the index 3 needs to be incremented               // in order correctly point into the 4th index of objv array               int index = *s + 1;               Tcl_DeleteCommand(interp, Tcl_GetString(objv[index]));          }     }}// actual functions handling various callbacks// generic callback handlerextern "C"int callback_handler(ClientData, Tcl_Interp *interp,     int objc, Tcl_Obj * CONST objv[]){     callback_map::iterator it = callbacks.find(interp);     if (it == callbacks.end())     {          Tcl_SetResult(interp,               "Trying to invoke non-existent callback (wrong interpreter?)",               TCL_STATIC);          return TCL_ERROR;     }          string cmdName(Tcl_GetString(objv[0]));     callback_interp_map::iterator iti = it->second.find(cmdName);     if (iti == it->second.end())     {          Tcl_SetResult(interp,               "Trying to invoke non-existent callback (wrong cmd name?)",               TCL_STATIC);          return TCL_ERROR;     }          policies_map::iterator pit = call_policies.find(interp);     if (pit == call_policies.end())     {          Tcl_SetResult(interp,               "Trying to invoke callback with no known policies",               TCL_STATIC);          return TCL_ERROR;     }          policies_interp_map::iterator piti;     if (find_policies(interp, cmdName, piti) == false)     {          Tcl_SetResult(interp,               "Trying to invoke callback with no known policies",               TCL_STATIC);          return TCL_ERROR;     }     policies &pol = piti->second;          try     {          iti->second->invoke(interp, objc, objv, pol);          post_process_policies(interp, pol, objv, false);     }     catch (exception const &e)     {          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);          return TCL_ERROR;     }     catch (...)     {          Tcl_SetResult(interp, "Unknown error.", TCL_STATIC);          return TCL_ERROR;     }          return TCL_OK;}// generic "object" command handlerextern "C"int object_handler(ClientData cd, Tcl_Interp *interp,     int objc, Tcl_Obj * CONST objv[]){     // here, client data points to the singleton object     // which is responsible for managing commands for     // objects of a given type     class_handler_base *chb = reinterpret_cast<class_handler_base*>(cd);     // the command name has the form 'pXXX' where XXX is the address     // of the "this" object     string const str(Tcl_GetString(objv[0]));     istringstream ss(str);     char dummy;     void *p;     ss >> dummy >> p;     try     {          string methodName(Tcl_GetString(objv[1]));          policies &pol = chb->get_policies(methodName);          chb->invoke(p, interp, objc, objv, pol);          post_process_policies(interp, pol, objv, true);     }     catch (exception const &e)     {          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);          return TCL_ERROR;     }     catch (...)     {          Tcl_SetResult(interp, "Unknown error.", TCL_STATIC);          return TCL_ERROR;     }     return TCL_OK;}// generic "constructor" commandextern "C"int constructor_handler(ClientData cd, Tcl_Interp *interp,     int objc, Tcl_Obj * CONST objv[]){     // here, client data points to the singleton object     // which is responsible for managing commands for     // objects of a given type     class_handler_base *chb = reinterpret_cast<class_handler_base*>(cd);     callback_map::iterator it = constructors.find(interp);     if (it == constructors.end())     {          Tcl_SetResult(interp,               "Trying to invoke non-existent callback (wrong interpreter?)",               TCL_STATIC);          return TCL_ERROR;     }          string className(Tcl_GetString(objv[0]));     callback_interp_map::iterator iti = it->second.find(className);     if (iti == it->second.end())     {          Tcl_SetResult(interp,               "Trying to invoke non-existent callback (wrong class name?)",               TCL_STATIC);          return TCL_ERROR;     }          policies_interp_map::iterator piti;     if (find_policies(interp, className, piti) == false)     {          Tcl_SetResult(interp,               "Trying to invoke callback with no known policies",               TCL_STATIC);          return TCL_ERROR;     }     policies &pol = piti->second;     try     {          iti->second->invoke(interp, objc, objv, pol);          // if everything went OK, the result is the address of the          // new object in the 'pXXX' form          // - we can create a new command with this name          Tcl_CreateObjCommand(interp,               Tcl_GetString(Tcl_GetObjResult(interp)),               object_handler, static_cast<ClientData>(chb), 0);     }     catch (exception const &e)     {          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);          return TCL_ERROR;     }     catch (...)     {          Tcl_SetResult(interp, "Unknown error.", TCL_STATIC);          return TCL_ERROR;     }     return TCL_OK;}} // namespace anonymousTcl::details::no_init_type Tcl::no_init;policies & policies::factory(string const &name){     factory_ = name;     return *this;}policies & policies::sink(int index){     sinks_.push_back(index);     return *this;}policies & policies::variadic(){     variadic_ = true;     return *this;}policies Tcl::factory(string const &name){     return policies().factory(name);}policies Tcl::sink(int index){     return policies().sink(index);}policies Tcl::variadic(){     return policies().variadic();}class_handler_base::class_handler_base(){     // default policies for the -delete command     policies_["-delete"] = policies();}void class_handler_base::register_method(string const &name,     shared_ptr<object_cmd_base> ocb, policies const &p){     methods_[name] = ocb;     policies_[name] = p;}policies & class_handler_base::get_policies(string const &name){     policies_map_type::iterator it = policies_.find(name);     if (it == policies_.end())     {          throw tcl_error("Trying to use non-existent policy: " + name);     }     return it->second;}object::object()     : interp_(0){     obj_ = Tcl_NewObj();     Tcl_IncrRefCount(obj_);}object::object(bool b)     : interp_(0){     obj_ = Tcl_NewBooleanObj(b);     Tcl_IncrRefCount(obj_);}object::object(char const *buf, size_t size)     : interp_(0){     obj_ = Tcl_NewByteArrayObj(          reinterpret_cast<unsigned char const *>(buf),          static_cast<int>(size));     Tcl_IncrRefCount(obj_);}object::object(double d)     : interp_(0){     obj_ = Tcl_NewDoubleObj(d);     Tcl_IncrRefCount(obj_);}object::object(int i)     : interp_(0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -