Mercurial > pytave
view pytave.cc @ 18:7a5fbc15fc6e error-msgs
Improved error messages from Octave.
author | David Grundberg <c04dgg@cs.umu.se> |
---|---|
date | Mon, 17 Nov 2008 12:10:04 +0100 |
parents | 56254a2e18e3 |
children | 5641245dd9d2 |
line wrap: on
line source
/* * Copyright 2008 David Grundberg, HÃ¥kan Fors Nilsson * * This file is part of Pytave. * * Pytave is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pytave is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pytave. If not, see <http://www.gnu.org/licenses/>. */ #define PYTAVE_DO_DECLARE_SYMBOL #include "arrayobjectdefs.h" #include <boost/python.hpp> #include <boost/python/numeric.hpp> #undef HAVE_STAT /* Both boost.python and octave define HAVE_STAT... */ #include <octave/oct.h> #include <octave/oct-map.h> #include <octave/octave.h> #include <octave/ov.h> #include <octave/parse.h> #include <iostream> #include <sstream> #include <sys/types.h> #include "pytavedefs.h" #include "exceptions.h" #include "python_to_octave.h" #include "octave_to_python.h" using namespace boost::python; using namespace std; namespace pytave { /* {{{ */ void init() { if (!octave_error_exception::init() || !value_convert_exception::init() || !object_convert_exception::init()) { PyErr_SetString(PyExc_ImportError, "_pytave: init failed"); return; } // Initialize Octave. // Also print Octave startup message. char* argv[] = {"octave", "--no-line-editing", "--no-history", NULL}; octave_main(3, argv, 1); // Initialize Python Numeric Array // This is actually a macro that becomes a block expression. If an error // occurs, e.g. Numeric Array not installed, an exception is set. import_array() } boost::python::tuple get_exceptions() { return make_tuple(object(handle<PyObject>( octave_error_exception::excclass)), object(handle<PyObject>( value_convert_exception::excclass)), object(handle<PyObject>( object_convert_exception::excclass))); } boost::python::tuple func_eval(const int nargout, const std::string &funcname, const boost::python::tuple &arguments) { octave_value_list octave_args, retval; pytuple_to_octlist(octave_args, arguments); reset_error_handler(); buffer_error_messages++; Py_BEGIN_ALLOW_THREADS retval = feval(funcname, octave_args, nargout); Py_END_ALLOW_THREADS if (error_state != 0) { // error_state values: // -2 error without traceback // -1 traceback // 1 general error int parse_status = 0; reset_error_handler(); octave_value_list lasterror = eval_string("lasterror", true, parse_status, 1); if (!lasterror.empty() && lasterror(0).is_map()) { ostringstream exceptionmsg; Octave_map map = lasterror(0).map_value(); string message = map.stringfield("message", ""); string identifier = map.stringfield("identifier", ""); Cell stackCell = map.contents("stack"); // Trim trailing new lines message = message.substr(0, message.find_last_not_of("\r\n") + 1); if (!stackCell.is_empty() && stackCell(0).is_map()) { // The struct element is called "stack" but only contain // info about the top frame. Octave_map stack = stackCell(0).map_value(); string file = stack.stringfield("file", "d"); string name = stack.stringfield("name", "a"); int line = stack.intfield("line", 1); int column = stack.intfield("column", 2); exceptionmsg << file << ":" << line << ":" << column << ": "; if (!name.empty()) exceptionmsg << "in '" << name << "': "; } if (!identifier.empty()) { exceptionmsg << "(identifier: " << identifier << ") "; } exceptionmsg << message; throw octave_error_exception(exceptionmsg.str()); } else throw octave_error_exception("No Octave error available"); } if (nargout > 0) { boost::python::tuple pytuple; octlist_to_pytuple(pytuple, retval); return pytuple; } else { // Return () if nargout <= 0. return make_tuple(); } } } /* namespace pytave }}} */ BOOST_PYTHON_MODULE(_pytave) { /* {{{ */ using namespace boost::python; def("init", pytave::init); def("feval", pytave::func_eval); def("get_exceptions", pytave::get_exceptions); register_exception_translator<pytave::pytave_exception>( pytave::pytave_exception::translate_exception); register_exception_translator<pytave::octave_error_exception>( pytave::octave_error_exception::translate_exception); register_exception_translator<pytave::object_convert_exception>( pytave::object_convert_exception::translate_exception); register_exception_translator<pytave::value_convert_exception>( pytave::value_convert_exception::translate_exception); } /* }}} */ /* Emacs * Local Variables: * fill-column:79 * coding:utf-8 * indent-tabs-mode:nil * c-basic-offset:3 * End: * vim: set textwidth=79 expandtab shiftwidth=3 : */