changeset 10887:f10d0bc8f9cc

make isargout available to DEFUNs
author Jaroslav Hajek <highegg@gmail.com>
date Fri, 13 Aug 2010 10:14:52 +0200
parents 9993f1354713
children f4fdd8637762
files src/ChangeLog src/defun-int.h src/defun.cc src/ov-builtin.cc src/ov-builtin.h
diffstat 5 files changed, 106 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Aug 13 07:58:14 2010 +0200
+++ b/src/ChangeLog	Fri Aug 13 10:14:52 2010 +0200
@@ -1,3 +1,14 @@
+2010-08-13  Jaroslav Hajek  <highegg@gmail.com>
+
+	* ov-builtin.cc 
+	(octave_builtin::subsref (..., const std::list<octave_lvalue> *)
+	octave_builtin::do_multi_index_op (..., const std::list<octave_lvalue> *)): 
+	New methods. Move code here. Set curr_lvalue_list.
+	(octave_builtin::curr_lvalue_list): New static member.
+	* ov-fcn-handle.h: Declare them.
+	* defun.cc (defun_isargout): New overloaded function.
+	* defun-int.h: Declare it.
+
 2010-08-11  Jaroslav Hajek  <highegg@gmail.com>
 
 	* ov-lazy-idx.h (octave_lazy_index::subsasgn): Remove override. Leave
--- a/src/defun-int.h	Fri Aug 13 07:58:14 2010 +0200
+++ b/src/defun-int.h	Fri Aug 13 10:14:52 2010 +0200
@@ -72,6 +72,12 @@
     : octave_shlib (shl) { }
 };
 
+extern OCTINTERP_API bool
+defun_isargout (int, int);
+
+extern OCTINTERP_API void
+defun_isargout (int, int, bool *);
+
 #define DECLARE_FUNX(name, args_name, nargout_name) \
   OCTAVE_EXPORT octave_value_list \
   name (const octave_value_list& args_name, int nargout_name)
--- a/src/defun.cc	Fri Aug 13 07:58:14 2010 +0200
+++ b/src/defun.cc	Fri Aug 13 10:14:52 2010 +0200
@@ -40,6 +40,7 @@
 #include "ov-mex-fcn.h"
 #include "ov-usr-fcn.h"
 #include "oct-obj.h"
+#include "oct-lvalue.h"
 #include "pager.h"
 #include "symtab.h"
 #include "toplev.h"
@@ -145,3 +146,55 @@
 
   return retval;
 }
+
+bool defun_isargout (int nargout, int iout)
+{
+  const std::list<octave_lvalue> *lvalue_list = octave_builtin::curr_lvalue_list;
+  if (iout >= std::max (nargout, 1))
+    return false;
+  else if (lvalue_list)
+    {
+      int k = 0;
+      for (std::list<octave_lvalue>::const_iterator p = lvalue_list->begin ();
+           p != lvalue_list->end (); p++)
+        {
+          if (k == iout)
+            return ! p->is_black_hole ();
+          k += p->numel ();
+          if (k > iout)
+            break;
+        }
+
+      return true;
+    }
+  else
+    return true;
+}
+
+void defun_isargout (int nargout, int nout, bool *isargout)
+{
+  const std::list<octave_lvalue> *lvalue_list = octave_builtin::curr_lvalue_list;
+  if (lvalue_list)
+    {
+      int k = 0;
+      for (std::list<octave_lvalue>::const_iterator p = lvalue_list->begin ();
+           p != lvalue_list->end () && k < nout; p++)
+        {
+          if (p->is_black_hole ())
+            isargout[k++] = false;
+          else
+            {
+              int l = std::min (k + p->numel (), nout);
+              while (k < l)
+                isargout[k++] = true;
+            }
+        }
+    }
+  else
+    for (int i = 0; i < nout; i++)
+      isargout[i] = true;
+
+  for (int i = std::max(nargout, 1); i < nout; i++)
+    isargout[i] = false;
+}
+
--- a/src/ov-builtin.cc	Fri Aug 13 07:58:14 2010 +0200
+++ b/src/ov-builtin.cc	Fri Aug 13 10:14:52 2010 +0200
@@ -44,6 +44,14 @@
                          const std::list<octave_value_list>& idx,
                          int nargout)
 {
+  return octave_builtin::subsref (type, idx, nargout, 0);
+}
+
+octave_value_list
+octave_builtin::subsref (const std::string& type,
+                         const std::list<octave_value_list>& idx,
+                         int nargout, const std::list<octave_lvalue>* lvalue_list)
+{
   octave_value_list retval;
 
   switch (type[0])
@@ -52,7 +60,8 @@
       {
         int tmp_nargout = (type.length () > 1 && nargout == 0) ? 1 : nargout;
 
-        retval = do_multi_index_op (tmp_nargout, idx.front ());
+        retval = do_multi_index_op (tmp_nargout, idx.front (),
+                                    idx.size () == 1 ? lvalue_list : 0);
       }
       break;
 
@@ -87,6 +96,13 @@
 octave_value_list
 octave_builtin::do_multi_index_op (int nargout, const octave_value_list& args)
 {
+  return octave_builtin::do_multi_index_op (nargout, args, 0);
+}
+
+octave_value_list
+octave_builtin::do_multi_index_op (int nargout, const octave_value_list& args,
+                                   const std::list<octave_lvalue> *lvalue_list)
+{
   octave_value_list retval;
 
   if (error_state)
@@ -102,6 +118,12 @@
 
       frame.add_fcn (octave_call_stack::pop);
 
+      if (lvalue_list || curr_lvalue_list)
+        {
+          frame.protect_var (curr_lvalue_list);
+          curr_lvalue_list = lvalue_list;
+        }
+
       try
         {
           retval = (*f) (args, nargout);
@@ -125,3 +147,6 @@
 
   return retval;
 }
+
+
+const std::list<octave_lvalue> *octave_builtin::curr_lvalue_list = 0;
--- a/src/ov-builtin.h	Fri Aug 13 07:58:14 2010 +0200
+++ b/src/ov-builtin.h	Fri Aug 13 10:14:52 2010 +0200
@@ -61,6 +61,10 @@
                              const std::list<octave_value_list>& idx,
                              int nargout);
 
+  octave_value_list subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             int nargout, const std::list<octave_lvalue>* lvalue_list);
+
   octave_function *function_value (bool = false) { return this; }
 
   bool is_builtin_function (void) const { return true; }
@@ -68,6 +72,12 @@
   octave_value_list
   do_multi_index_op (int nargout, const octave_value_list& args);
 
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& args, 
+                     const std::list<octave_lvalue>* lvalue_list);
+
+  static const std::list<octave_lvalue> *curr_lvalue_list;
+
 protected:
 
   // A pointer to the actual function.