qfrontend.cpp
来自「算断裂的」· C++ 代码 · 共 775 行 · 第 1/2 页
CPP
775 行
} QMG::FrontEnd::ReturnValType::ReturnValType() { nargout_ = -1;}QMG::FrontEnd::ReturnValType::~ReturnValType() { if (nargout_ >= 0) { for (int j = 0; j < nargout_; ++j) { if (returnvals_[j]) { Tcl_DecrRefCount(returnvals_[j]); } } delete[] returnvals_; }}void QMG::FrontEnd::ReturnValType::verify_nargout(int nargoutmin, int nargoutmax, const char* routine_name) { if (nargout_ != -1) throw_error("verify_nargout called twice"); nargout_ = nargoutmax; returnvals_ = new Tcl_Obj*[(nargout_ <= 0)? 1 : nargout_]; for (int j = 0; j < nargout_; ++j) returnvals_[j] = 0;}void QMG::FrontEnd::ReturnValType::checkarg_(int idx) { if (idx < 0 || idx >= nargout_) throw_error("returnval put called for index out of range"); if (returnvals_[idx] != 0) throw_error("put called twice for same argument");}int QMG::FrontEnd::ReturnValType::nargout() const { return nargout_;}void QMG::FrontEnd::ReturnValType::put_simpcomp(int argidx, SimpComplex_Under_Construction& sc) {#ifdef DEBUGGING checkarg_(argidx);#endif Cptc_MshDesc* mesh = sc.release(); Tcl_Obj* newobj = new_simpcomp_obj(mesh); returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_brep(int argidx, Brep_Under_Construction& b) {#ifdef DEBUGGING checkarg_(argidx);#endif Cptc_GeomDesc* geo = b.release(); Tcl_Obj* newobj = new_brep_obj(geo); returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_double(int argidx, double val) {#ifdef DEBUGGING checkarg_(argidx);#endif Tcl_Obj* newobj = Tcl_NewDoubleObj(val); returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_int(int argidx, int val) {#ifdef DEBUGGING checkarg_(argidx);#endif Tcl_Obj* newobj = Tcl_NewIntObj(val); returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_string(int argidx, const string& s) {#ifdef DEBUGGING checkarg_(argidx);#endif Tcl_Obj* newobj = Tcl_NewStringObj(const_cast<char*>(s.data()), s.length()); returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_matrix(int argidx, Matrix& m) {#ifdef DEBUGGING checkarg_(argidx);#endif int nr = m.numrows(); int nc = m.numcols(); Tcl_Obj** onerow = new Tcl_Obj*[nc]; Tcl_Obj** rowlist = new Tcl_Obj*[nr]; for (int i = 0; i < nr; ++i) { for (int j = 0; j < nc; ++j) onerow[j] = Tcl_NewDoubleObj(m(i,j)); rowlist[i] = Tcl_NewListObj(nc, onerow); } Tcl_Obj* newobj = Tcl_NewListObj(nr, rowlist); delete[] rowlist; delete[] onerow; returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_intmatrix(int argidx, IntMatrix& m) {#ifdef DEBUGGING checkarg_(argidx);#endif int nr = m.numrows(); int nc = m.numcols(); Tcl_Obj** onerow = new Tcl_Obj*[nc]; Tcl_Obj** rowlist = new Tcl_Obj*[nr]; for (int i = 0; i < nr; ++i) { for (int j = 0; j < nc; ++j) onerow[j] = Tcl_NewIntObj(m(i,j)); rowlist[i] = Tcl_NewListObj(nc, onerow); } Tcl_Obj* newobj = Tcl_NewListObj(nr, rowlist); delete[] rowlist; delete[] onerow; returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_intvector(int argidx, vector<int>& m) {#ifdef DEBUGGING checkarg_(argidx);#endif int nr = m.size(); Tcl_Obj** vec = new Tcl_Obj*[nr]; for (int i = 0; i < nr; ++i) { vec[i] = Tcl_NewIntObj(m[i]); } Tcl_Obj* newobj = Tcl_NewListObj(nr, vec); delete[] vec; returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::put_doublevector(int argidx, vector<double>& m) {#ifdef DEBUGGING checkarg_(argidx);#endif int nr = m.size(); Tcl_Obj** vec = new Tcl_Obj*[nr]; for (int i = 0; i < nr; ++i) { vec[i] = Tcl_NewDoubleObj(m[i]); } Tcl_Obj* newobj = Tcl_NewListObj(nr, vec); delete[] vec; returnvals_[argidx] = newobj; Tcl_IncrRefCount(newobj);}void QMG::FrontEnd::ReturnValType::set_result(Tcl_Interp* interp) {#ifdef DEBUGGING if (nargout_ < 0) throw_error("set_result called when nargout < 0"); for (int j = 0; j < nargout_; ++j) if (!returnvals_[j]) throw_error("set_result called with an unset return val");#endif if (nargout_ == 0) { } else if (nargout_ == 1) Tcl_SetObjResult(interp, returnvals_[0]); else { Tcl_Obj* listptr = Tcl_NewListObj(nargout_, returnvals_); Tcl_SetObjResult(interp, listptr); }}namespace { using namespace QMG; using namespace QMG::FrontEnd; using std::streambuf;#ifndef OLD_STYLE_STREAMBUF using std::char_traits; typedef char_traits<char> char_traits_char; int local_eof() { return char_traits_char::eof(); }#else int local_eof() { return EOF; }#endif const int STREAMBUF_BUFLEN = 100; class TclStreambuf: public streambuf { private: void put_buffer(); void put_char(int); Tcl_Interp* interp_; char my_buffer[STREAMBUF_BUFLEN]; int buffer_next; void print_buffer_(); bool channel_; Tcl_Obj* cmd1_[4]; Tcl_Obj* cmd2_[4]; Tcl_Obj* tmp1_; Tcl_Obj* tmp2_; Tcl_Obj* tmp3_; protected: int overflow(int); int underflow() { return 0; } int sync(); public: TclStreambuf(Tcl_Interp* interp, char* channel); ~TclStreambuf(); }; TclStreambuf::TclStreambuf(Tcl_Interp* interp, char* channel) : streambuf(), interp_(interp) { setp(0,0); setg(0,0,0); buffer_next = 0; tmp1_= Tcl_NewStringObj("puts", -1); Tcl_IncrRefCount(tmp1_); tmp2_ = Tcl_NewStringObj("-nonewline", -1); Tcl_IncrRefCount(tmp2_); if (channel) { channel_ = true; tmp3_ = Tcl_NewStringObj(channel, -1); Tcl_IncrRefCount(tmp3_); cmd1_[0] = tmp1_; cmd1_[1] = tmp3_; cmd2_[0] = tmp1_; cmd2_[1] = tmp2_; cmd2_[2] = tmp3_; } else { channel_ = false; tmp3_ = 0; cmd1_[0] = tmp1_; cmd2_[0] = tmp1_; cmd2_[1] = tmp2_; } } TclStreambuf::~TclStreambuf() { sync(); Tcl_DecrRefCount(tmp1_); Tcl_DecrRefCount(tmp2_); if (channel_) { Tcl_DecrRefCount(tmp3_); } } int TclStreambuf::overflow(int c) { put_buffer(); if (c != local_eof()) if (pbase() == epptr()) put_char(c); else sputc(c); return 0; } void TclStreambuf::print_buffer_() { my_buffer[buffer_next] = 0; Tcl_Obj* newcmd; if (buffer_next > 0 && my_buffer[buffer_next - 1] == '\n') { Tcl_Obj* strobj = Tcl_NewStringObj(my_buffer, buffer_next - 1); int p = (channel_)? 2 : 1; cmd1_[p] = strobj; newcmd = Tcl_NewListObj(p + 1, cmd1_); } else { Tcl_Obj* strobj = Tcl_NewStringObj(my_buffer, buffer_next); int p = (channel_)? 3 : 2; cmd2_[p] = strobj; newcmd = Tcl_NewListObj(p + 1, cmd2_); } Tcl_IncrRefCount(newcmd); Tcl_EvalObj(interp_, newcmd); Tcl_DecrRefCount(newcmd); buffer_next = 0; } int TclStreambuf::sync() { put_buffer(); print_buffer_(); return 0; } void TclStreambuf::put_char(int c) { my_buffer[buffer_next++] = c; if (buffer_next == STREAMBUF_BUFLEN - 1 || c == '\n' || c == 0) { print_buffer_(); } } void TclStreambuf::put_buffer() { ptrdiff_t len = pptr() - pbase(); if (len != 0) { if (buffer_next + len + 2 > STREAMBUF_BUFLEN) { if (buffer_next > 0) { print_buffer_(); } int p = (channel_)? 3 : 2; cmd2_[p] = Tcl_NewStringObj(pbase(), len); Tcl_Obj* newcmd = Tcl_NewListObj(p + 1, cmd2_); Tcl_IncrRefCount(newcmd); Tcl_EvalObj(interp_, newcmd); Tcl_DecrRefCount(newcmd); } else { for (int j = 0; j < len; j++) my_buffer[buffer_next++] = pbase()[j]; } } setp(pbase(), epptr()); }}QMG::FrontEnd::InterpOStream::InterpOStream(Interpreter& interp1) :sb_(0), os_(0) { Tcl_Interp* interp = interp1.get_interp(); Tcl_Obj* namePtr = Tcl_NewStringObj("gm_redirect_stdout", -1); Tcl_Obj* redirect = Tcl_ObjGetVar2(interp, namePtr, 0, 0); char* redirect_chan = (redirect)? Tcl_GetStringFromObj(redirect, 0) : 0; sb_ = new TclStreambuf(interp, redirect_chan); os_ = new QMG::ostream(sb_);}QMG::FrontEnd::InterpOStream::~InterpOStream() { if (os_) delete os_; if (sb_) delete sb_;}// ------------------------------------------------------------------// qmg_default_tol// get the default tolerance from global variable gm_default_tol// ------------------------------------------------------------------double QMG::FrontEnd::default_tol(Interpreter& interp1) { Tcl_Interp* interp = interp1.get_interp(); Tcl_Obj* namePtr = Tcl_NewStringObj("gm_default_tol", -1); Tcl_Obj* default1 = Tcl_ObjGetVar2(interp, namePtr, 0, TCL_GLOBAL_ONLY); if (!default1) { throw_error("gm_default_tol global variable absent"); } double x; int returncode = Tcl_GetDoubleFromObj(interp, default1, &x); if (returncode != TCL_OK || x <= 0 || x > 1) { throw_error("gm_default_tol not a number or out of range"); return 0; } return x;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?