changeset 115:00d19f71c9ca

Initial implementation of py oct-file * py.cc: Initial implementation of py oct function. * ax_octave.m4: Find and export path to mkoctfile. * Makefile.am (.cc.oct): Custom rule to build py.oct. (all-am): Depend on py.oct. * .hgignore: Include py.oct in the ignore list.
author Mike Miller <mtmiller@octave.org>
date Sun, 20 Sep 2015 15:12:47 +0200
parents f6fec9453ac9
children 3a35bb85ce52
files .hgignore Makefile.am m4/ax_octave.m4 py.cc
diffstat 4 files changed, 126 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Sep 20 02:57:31 2015 +0200
+++ b/.hgignore	Sun Sep 20 15:12:47 2015 +0200
@@ -26,6 +26,7 @@
 ^Makefile.in$
 ^missing$
 ^project-root.jam$
+^py\.oct$
 ^_pytave?la*$
 ^setup.py$
 ^stamp-h1$
--- a/Makefile.am	Sun Sep 20 02:57:31 2015 +0200
+++ b/Makefile.am	Sun Sep 20 15:12:47 2015 +0200
@@ -14,3 +14,10 @@
 _pytave_la_SOURCES = octave_to_python.cc pytave.cc python_to_octave.cc \
 arrayobjectdefs.h octave_to_python.h pytavedefs.h exceptions.h   \
 exceptions.cc python_to_octave.h config.h
+
+all-am: py.oct
+
+.cc.oct:
+	$(MKOCTFILE) $(DEFS) $(_pytave_la_CPPFLAGS) $< exceptions.cc octave_to_python.cc python_to_octave.cc -l$(BOOST_PYTHON_LIB) $(PYTHON_LIBS) -o $@
+
+SUFFIXES = .oct
--- a/m4/ax_octave.m4	Sun Sep 20 02:57:31 2015 +0200
+++ b/m4/ax_octave.m4	Sun Sep 20 15:12:47 2015 +0200
@@ -80,6 +80,8 @@
 	ax_octave_config="[$]$1"
 	ax_octave_ok=
 
+        AC_CHECK_TOOLS([MKOCTFILE], [mkoctfile])
+
 	AC_MSG_CHECKING([for octave-config filename])
 	AS_IF([test -z "$ax_octave_config"], [
 		AC_MSG_RESULT([determined from path])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/py.cc	Sun Sep 20 15:12:47 2015 +0200
@@ -0,0 +1,116 @@
+/*
+
+Copyright (C) 2015 Mike Miller
+
+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; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <boost/python.hpp>
+#include <boost/python/numeric.hpp>
+
+/* Both boost::python and octave define HAVE_STAT and HAVE_FSTAT.  Ideally,
+   they shouldn't expose their configuration in the header files, but they do.
+   This silences the compiler warning. */
+#undef HAVE_STAT
+#undef HAVE_FSTAT
+
+#include <oct.h>
+
+#define PYTAVE_DO_DECLARE_SYMBOL
+#include "pytavedefs.h"
+#include "arrayobjectdefs.h"
+#include "exceptions.h"
+#include "python_to_octave.h"
+
+using namespace boost::python;
+
+DEFUN_DLD (py, args, nargout,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} py (@var{func})\n\
+@enddeftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string module;
+  std::string func = args(0).string_value ();
+
+  size_t idx = func.rfind (".");
+  if (idx != std::string::npos)
+    {
+      module = func.substr (0, idx);
+    }
+
+  Py_Initialize ();
+
+  try
+    {
+      object main_module = import ("__main__");
+      object main_namespace = main_module.attr ("__dict__");
+
+      if (! module.empty ())
+        {
+          std::string cmd = "import " + module;
+          exec (cmd.c_str (), main_namespace, main_namespace);
+        }
+
+      object res = eval (func.c_str (), main_namespace, main_namespace);
+
+      if (! res.is_none ())
+        {
+          octave_value val;
+          pytave::pyobj_to_octvalue (val, res);
+          retval(0) = val;
+        }
+    }
+  catch (pytave::object_convert_exception const &)
+    {
+      error ("py: error in return value type conversion");
+    }
+  catch (error_already_set const &)
+    {
+      std::cerr << "in here" << std::endl;
+      PyObject *ptype, *pvalue, *ptraceback;
+      PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+
+      try
+        {
+          std::string message = extract<std::string> (pvalue);
+          error ("py: %s", message.c_str ());
+        }
+      catch (error_already_set const &)
+        {
+          PyErr_Restore (ptype, pvalue, ptraceback);
+          PyErr_Print ();
+        }
+    }
+
+  return retval;
+}
+