📄 qfrontend.cpp
字号:
// ------------------------------------------------------------------// qfrontend.cpp//// This file contains functions associated with the interface to// the front-end language. For this version of qfrontend, the// front-end language is Matlab. See qfrontend.h// ------------------------------------------------------------------// Author: Stephen A. Vavasis// Copyright (c) 1999 by Cornell University. All rights reserved.// // See the accompanying file 'Copyright' for authorship information,// the terms of the license governing this software, and disclaimers// concerning this software.// ------------------------------------------------------------------// This file is part of the QMG software. // Version 2.0 of QMG, release date September 3, 1999.// ------------------------------------------------------------------#ifdef _MSC_VER#if _MSC_VER == 1200#include "qmatvec.h"#endif#endif#include "qfrontend.h"#include "qbrep_constr.h"#include "qsimpcomp.h"#include "qmatvec.h"#include "string.h"namespace { using namespace QMG; using namespace QMG::FrontEnd; Object_Type_Code get_obj_type(const mxArray* obj) { if (strcmp(mxGetClassName(obj), "zba") != 0) return UNKNOWN; const mxArray* entries = mxGetFieldByNumber(obj,0,0); if (entries == 0) return UNKNOWN; const mxArray* typecode = mxGetCell(entries, 0); if (typecode == 0) return UNKNOWN; int lth1 = mxGetM(typecode) * mxGetN(typecode); if (lth1 != strlen(SimpComplex::io_header_code()) && lth1 != strlen(Brep::io_header_code())) return UNKNOWN; char buf[100]; if (mxGetString(typecode, buf, 99)) return UNKNOWN; if (compare_nocase(string(buf), string(Brep::io_header_code())) == 0) return BREP; else if (compare_nocase(string(buf), string(SimpComplex::io_header_code())) == 0) return SIMPCOMPLEX; else return UNKNOWN; } 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 MatlabStreambuf: public streambuf { private: void put_buffer(); void put_char(int); char my_buffer[STREAMBUF_BUFLEN]; int buffer_next; protected: int overflow(int); int underflow() { return 0; } int sync(); public: MatlabStreambuf(); ~MatlabStreambuf(); }; MatlabStreambuf::MatlabStreambuf(): streambuf() { setp(0,0); setg(0,0,0); buffer_next = 0; } MatlabStreambuf::~MatlabStreambuf() { sync(); } int MatlabStreambuf::overflow(int c) { put_buffer(); if (c != local_eof()) if (pbase() == epptr()) put_char(c); else sputc(c); return 0; } int MatlabStreambuf::sync() { put_buffer(); my_buffer[buffer_next] = 0; mexPrintf("%s", my_buffer); buffer_next = 0; return 0; } void MatlabStreambuf::put_char(int c) { my_buffer[buffer_next++] = c; if (buffer_next == STREAMBUF_BUFLEN - 1 || c == '\n' || c == 0) { my_buffer[buffer_next] = 0; mexPrintf("%s", my_buffer); buffer_next = 0; } } void MatlabStreambuf::put_buffer() { ptrdiff_t len = pptr() - pbase(); if (len != 0) { if (buffer_next + len + 2 > STREAMBUF_BUFLEN) { if (buffer_next > 0) { my_buffer[buffer_next] = 0; mexPrintf("%s", my_buffer); buffer_next = 0; } char* buf1 = new char[len + 1]; for (int j = 0; j < len; ++j) buf1[j] = pbase()[j]; buf1[len] = 0; mexPrintf("%s", buf1); delete[] buf1; } else { for (int j = 0; j < len; j++) my_buffer[buffer_next++] = pbase()[j]; } } setp(pbase(), epptr()); } void default_tol_errmsg1() { mexPrintf("An error has occurred accessing global variable GM_DEFAULT_TOL\n"); mexPrintf("This error may indicate that initialization routine 'startup.m' was not executed.\n"); mexPrintf("Please read the 'readme' file shipped with QMG for more information about startup.m.\n"); }} QMG::FrontEnd::ArgValType::ArgValType(int nrhs, const mxArray** prhs) { nrhs_ = nrhs; prhs_ = prhs;}QMG::FrontEnd::ArgValType::~ArgValType() {}void QMG::FrontEnd::ArgValType::verify_nargin(int narginmin, int narginmax, const char* routine_name) const { if (nrhs_ < narginmin || nrhs_ > narginmax) { ostringstream ostr; if (narginmin == narginmax) { ostr << "Routine expected " << narginmin << " argument"; if (narginmin != 1) ostr << "s"; } else { ostr << "Routine expected " << narginmin << " to " << narginmax << " arguments"; } ostr << " but " << nrhs_ << " were given"; throw_error(ostr.str()); }}int QMG::FrontEnd::ArgValType::nargin() const { return nrhs_;}QMG::string QMG::FrontEnd::ArgValType::get_string(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 1");#endif if (!mxIsChar(prhs_[argidx]) || mxIsSparse(prhs_[argidx]) || mxGetM(prhs_[argidx]) > 1) { ostringstream os; os << "Argument #" << argidx << " is supposed to be a string"; throw_error(os.str()); } int l = mxGetN(prhs_[argidx]); char* buf = new char[l + 2]; mxGetString(prhs_[argidx], buf, l + 1); string s(buf); delete[] buf; return s;}int QMG::FrontEnd::ArgValType::get_int(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 2");#endif if (!mxIsDouble(prhs_[argidx]) || mxIsSparse(prhs_[argidx]) || mxGetM(prhs_[argidx]) * mxGetN(prhs_[argidx]) != 1) { ostringstream os; os << "Argument #" << argidx << " is supposed to be an integer"; throw_error(os.str()); } double returnvald = *mxGetPr(prhs_[argidx]); int returnval = static_cast<int>(returnvald); if (returnvald != static_cast<double>(returnval)) { ostringstream os; os << "Argument #" << argidx << " is supposed to be an integer"; throw_error(os.str()); } return returnval;}double QMG::FrontEnd::ArgValType::get_double(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 2");#endif if (!mxIsDouble(prhs_[argidx]) || mxIsSparse(prhs_[argidx]) || mxGetM(prhs_[argidx]) * mxGetN(prhs_[argidx]) != 1) { ostringstream os; os << "Argument #" << argidx << " is supposed to be a scalar"; throw_error(os.str()); } return *mxGetPr(prhs_[argidx]);}QMG::Brep_From_FrontEndQMG::FrontEnd::ArgValType::get_brep(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 4");#endif return Brep_From_FrontEnd(prhs_[argidx]);}QMG::SimpComplex_From_FrontEndQMG::FrontEnd::ArgValType::get_simpcomp(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 4a");#endif return SimpComplex_From_FrontEnd(prhs_[argidx]);}QMG::Object_Type_Code QMG::FrontEnd::ArgValType::determine_argument_type(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 4b");#endif return get_obj_type(prhs_[argidx]);}boolQMG::FrontEnd::ArgValType::get_bool(int argidx) const { return get_int(argidx) != 0;}#ifndef BUG_IN_USINGusing QMG::vector;#endifvector<double>QMG::FrontEnd::ArgValType::get_vector_double(int argidx) const {#ifdef RANGECHECK if (argidx < 0 || argidx >= nrhs_) throw_error("Argidx range error 6");#endif if (!mxIsDouble(prhs_[argidx]) || mxIsSparse(prhs_[argidx]) || mxGetPi(prhs_[argidx]) || (mxGetN(prhs_[argidx]) > 1 && mxGetM(prhs_[argidx]) > 1)) { ostringstream ostr; ostr << "Argument #" << argidx << " is supposed to be a double vector"; throw_error(ostr.str()); } int sz = mxGetM(prhs_[argidx]) * mxGetN(prhs_[argidx]); vector<double> returnval(sz, 0.0); const double* pr = mxGetPr(prhs_[argidx]); for (int j = 0; j < sz; ++j) returnval[j] = pr[j];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -