changeset 12956:332a97ea63ba

Merge in Daniel's changes
author Jordi Gutiérrez Hermoso <jordigh@gmail.com>
date Thu, 11 Aug 2011 21:12:56 -0500
parents 05941540287c (current diff) 5a5cb2a4b71d (diff)
children ae88a81e5d5c 43d78e103984
files
diffstat 3 files changed, 73 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/container.txi	Thu Aug 11 21:12:15 2011 -0500
+++ b/doc/interpreter/container.txi	Thu Aug 11 21:12:56 2011 -0500
@@ -563,16 +563,11 @@
 @example
 @group
 c@{1:2@}
+     @result{} ans = a string
      @result{} ans =
           
-          (,
-            [1] = a string
-            [2] =
-          
                0.593993   0.627732
                0.377037   0.033643
-          
-          ,)
 @end group
 @end example
 
--- a/src/DLD-FUNCTIONS/cellfun.cc	Thu Aug 11 21:12:15 2011 -0500
+++ b/src/DLD-FUNCTIONS/cellfun.cc	Thu Aug 11 21:12:56 2011 -0500
@@ -58,6 +58,8 @@
 #include "ov-uint32.h"
 #include "ov-uint64.h"
 
+#include "ov-fcn-handle.h"
+
 static octave_value_list
 get_output_list (octave_idx_type count, octave_idx_type nargout,
                  const octave_value_list& inputlist,
@@ -222,6 +224,7 @@
     }
 
   octave_value func = args(0);
+  bool symbol_table_lookup = false;
 
   if (! args(1).is_cell ())
     {
@@ -339,6 +342,8 @@
               func = symbol_table::find_function (name);
               if (func.is_undefined ())
                 error ("cellfun: invalid function NAME: %s", name.c_str ());
+
+              symbol_table_lookup = true;
             }
         }
     }
@@ -349,6 +354,30 @@
   if (func.is_function_handle () || func.is_inline_function ()
       || func.is_function ())
     {
+
+      // The following is an optimisation because the symbol table can
+      // give a more specific function class, so this can result in
+      // fewer polymorphic function calls as the function gets called
+      // for each value of the array.
+      if (! symbol_table_lookup )
+        {
+          if (func.is_function_handle ())
+            {
+              octave_fcn_handle* f = func.fcn_handle_value ();
+
+              // Overloaded function handles need to check the type of
+              // the arguments for each element of the array, so they
+              // cannot be optimised this way.
+              if (f -> is_overloaded ())
+                goto nevermind;
+            }
+          octave_value f = symbol_table::find_function (func.function_value ()
+                                                         -> name ());
+          if (f.is_defined ())
+            func = f;
+        }
+      nevermind:
+
       unwind_protect frame;
       frame.protect_var (buffer_error_messages);
 
--- a/src/oct-stream.cc	Thu Aug 11 21:12:15 2011 -0500
+++ b/src/oct-stream.cc	Thu Aug 11 21:12:56 2011 -0500
@@ -2860,38 +2860,60 @@
     {
       clearerr ();
 
+      // Find current position so we can return to it if needed.
+
       long orig_pos = rep->tell ();
 
-      status = rep->seek (offset, origin);
+      // Move to end of file.  If successful, find the offset of the end.
+
+      status = rep->seek (0, SEEK_END);
 
       if (status == 0)
         {
-          long save_pos = rep->tell ();
-
-          rep->seek (0, SEEK_END);
-
-          long pos_eof = rep->tell ();
-
-          // I don't think save_pos can be less than zero, but we'll
-          // check anyway...
-
-          if (save_pos > pos_eof || save_pos < 0)
+          long eof_pos = rep->tell ();
+
+          if (origin == SEEK_CUR)
+            {
+              // Move back to original position, otherwise we will be
+              // seeking from the end of file which is probably not the
+              // original location.
+
+              rep->seek (orig_pos, SEEK_SET);
+            }
+
+          // Attempt to move to desired position; may be outside bounds
+          // of existing file.
+
+          status = rep->seek (offset, origin);
+
+          if (status == 0)
             {
-              // Seek outside bounds of file.  Failure should leave
-              // position unchanged.
+              // Where are we after moving to desired position?
+
+              long desired_pos = rep->tell ();
+
+              // I don't think save_pos can be less than zero, but we'll
+              // check anyway...
+
+              if (desired_pos > eof_pos || desired_pos < 0)
+                {
+                  // Seek outside bounds of file.  Failure should leave
+                  // position unchanged.
+
+                  rep->seek (orig_pos, SEEK_SET);
+
+                  status = -1;
+                }
+            }
+          else
+            {
+              // Seeking to the desired position failed.  Move back to
+              // original position and return failure status.
 
               rep->seek (orig_pos, SEEK_SET);
 
               status = -1;
             }
-          else
-            {
-              // Is it possible for this to fail?  We are just
-              // returning to a position after the first successful
-              // seek.
-
-              rep->seek (save_pos, SEEK_SET);
-            }
         }
     }