changeset 12962:55c3da8f1c9a

Merge in Daniel's changes
author Jordi Gutiérrez Hermoso <jordigh@gmail.com>
date Sun, 14 Aug 2011 12:41:20 -0500
parents 0c86ae6f7c34 (diff) 8c64cc024e8c (current diff)
children 27e5f0e79f19
files
diffstat 10 files changed, 220 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/oop.txi
+++ b/doc/interpreter/oop.txi
@@ -578,8 +578,8 @@
 @item @tab a / b @tab mrdivide (a, b) @tab Matrix right division operator @tab
 @item @tab a .\ b @tab ldivide (a, b) @tab Element-wise left division operator @tab
 @item @tab a \ b @tab mldivide (a, b) @tab Matrix left division operator @tab
-@item @tab a .^ b @tab ldivide (a, b) @tab Element-wise power operator @tab
-@item @tab a ^ b @tab mldivide (a, b) @tab Matrix power operator @tab
+@item @tab a .^ b @tab power (a, b) @tab Element-wise power operator @tab
+@item @tab a ^ b @tab mpower (a, b) @tab Matrix power operator @tab
 @item @tab a < b @tab lt (a, b) @tab Less than operator @tab
 @item @tab a <= b @tab le (a, b) @tab Less than or equal to operator @tab
 @item @tab a > b @tab gt (a, b) @tab Greater than operator @tab
--- a/liboctave/chMatrix.cc
+++ b/liboctave/chMatrix.cc
@@ -74,8 +74,8 @@
     elem (0, i) = s[i];
 }
 
-charMatrix::charMatrix (const string_vector& s)
-  : Array<char> (dim_vector (s.length (), s.max_length ()), 0)
+charMatrix::charMatrix (const string_vector& s, char fill_value)
+  : Array<char> (dim_vector (s.length (), s.max_length ()), fill_value)
 {
   octave_idx_type nr = rows ();
 
--- a/liboctave/chMatrix.h
+++ b/liboctave/chMatrix.h
@@ -62,7 +62,7 @@
 
   charMatrix (const std::string& s);
 
-  charMatrix (const string_vector& s);
+  charMatrix (const string_vector& s, char fill_value = '\0');
 
   charMatrix& operator = (const charMatrix& a)
     {
--- a/scripts/miscellaneous/private/__xzip__.m
+++ b/scripts/miscellaneous/private/__xzip__.m
@@ -80,14 +80,16 @@
              commandname, status);
     endif
 
-    if (nargout > 0)
-      if (nargin == 5)
+    if (nargin == 5)
+      if (nargout > 0)
         entries = cellfun(
             @(x) fullfile (outdir, sprintf ("%s.%s", x, extension)),
             f, "uniformoutput", false);
-      else
-        movefile (cellfun(@(x) sprintf ("%s.%s", x, extension), f,
-                          "uniformoutput", false), cwd);
+      endif
+    else
+      movefile (cellfun(@(x) sprintf ("%s.%s", x, extension), f,
+                        "uniformoutput", false), cwd);
+      if (nargout > 0)
         ## FIXME this does not work when you try to compress directories
         entries  = cellfun(@(x) sprintf ("%s.%s", x, extension),
                            files, "uniformoutput", false);
--- a/scripts/miscellaneous/tar.m
+++ b/scripts/miscellaneous/tar.m
@@ -42,7 +42,7 @@
     files = cellstr (files);
   endif
 
-  if (ischar (tarfile) && iscellstr (files) && ischar (root))
+  if (! (ischar (tarfile) && iscellstr (files) && ischar (root)))
     error ("tar: all arguments must be character strings");
   endif
 
--- a/scripts/strings/str2num.m
+++ b/scripts/strings/str2num.m
@@ -17,7 +17,8 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} str2num (@var{s})
+## @deftypefn {Function File} {@var{x} =} str2num (@var{s})
+## @deftypefnx {Function File} {[@var{x}, @var{state}] =} str2num (@var{s})
 ## Convert the string (or character array) @var{s} to a number (or an
 ## array).  Examples:
 ##
@@ -33,6 +34,10 @@
 ## @end group
 ## @end example
 ##
+## The optional second output, @var{state}, is logically true when the
+## coversion is successful. If the conversion fails the numeric output,
+## @var{n}, is empty and @var{state} is false.
+##
 ## @strong{Caution:} As @code{str2num} uses the @code{eval} function
 ## to do the conversion, @code{str2num} will execute any code contained
 ## in the string @var{s}.  Use @code{str2double} instead if you want to
@@ -42,16 +47,18 @@
 
 ## Author: jwe
 
-function m = str2num (s)
+function [m, state] = str2num (s)
 
   if (nargin == 1 && ischar (s))
     [nr, nc] = size (s);
     sep = ";";
     sep = sep (ones (nr, 1), 1);
     s = sprintf ("m = [%s];", reshape ([s, sep]', 1, nr * (nc + 1)));
-    eval (s, "m = [];");
+    state = true;
+    eval (s, "m = []; state = false;");
     if (ischar (m))
       m = [];
+      state = false;
     endif
   else
     print_usage ();
@@ -65,3 +72,8 @@
 
 %!error str2num ("string", 1);
 
+%!test
+%! [x, state] = str2num ("pi");
+%! assert (state)
+%! [x, state] = str2num (tmpnam);
+%! assert (! state)
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -541,7 +541,7 @@
     ../libcruft/libcruft.la \
     ../libcruft/libranlib.la \
     ../libgnu/libgnu.la \
-    $(FFTW_XLDFLAGS) $(FFTW_XLIBS)
+    $(FFTW_XLDFLAGS) $(FFTW_XLIBS) \
     $(QHULL_LDFLAGS) $(QHULL_LIBS) \
     $(QRUPDATE_LDFLAGS) $(QRUPDATE_LIBS) \
     $(SPARSE_XLDFLAGS) $(SPARSE_XLIBS) \
--- a/src/genprops.awk
+++ b/src/genprops.awk
@@ -300,8 +300,9 @@
         emit_get_accessor(i, "graphics_handle", "handle_value");
       else if (type[i] == "string_property")
         emit_get_accessor(i, "std::string", "string_value");
-      else if (type[i] == "string_array_property")
-          emit_get_accessor(i, "octave_value", "get");
+      else if (type[i] == "string_array_property" \
+               || type[i] == "text_label_property")
+        emit_get_accessor(i, "octave_value", "get");
       else if (type[i] == "double_property")
         emit_get_accessor(i, "double", "double_value");
       else if (type[i] == "double_radio_property")
--- a/src/graphics.h.in
+++ b/src/graphics.h.in
@@ -33,6 +33,7 @@
 #include <list>
 #include <map>
 #include <set>
+#include <sstream>
 #include <string>
 
 #include "caseless-str.h"
@@ -692,6 +693,170 @@
 
 // ---------------------------------------------------------------------
 
+class text_label_property : public base_property
+{
+public:
+  enum type { char_t, cellstr_t };
+
+  text_label_property (const std::string& s, const graphics_handle& h,
+                       const std::string& val = "")
+    : base_property (s, h), value (val), stored_type (char_t)
+  { }
+
+  text_label_property (const std::string& s, const graphics_handle& h,
+                       const NDArray& nda)
+    : base_property (s, h), stored_type (char_t)
+  {
+    octave_idx_type nel = nda.numel ();
+
+    value.resize (nel);
+
+    for (octave_idx_type i = 0; i < nel; i++)
+      {
+        std::ostringstream buf;
+        buf << nda(i);
+        value[i] = buf.str ();
+      }
+  }
+
+  text_label_property (const std::string& s, const graphics_handle& h,
+                       const Cell& c)
+    : base_property (s, h), stored_type (cellstr_t)
+  {
+    octave_idx_type nel = c.numel ();
+
+    value.resize (nel);
+
+    for (octave_idx_type i = 0; i < nel; i++)
+      {
+        octave_value tmp = c(i);
+
+        if (tmp.is_string ())
+          value[i] = c(i).string_value ();
+        else
+          {
+            double d = c(i).double_value ();
+
+            if (! error_state)
+              {
+                std::ostringstream buf;
+                buf << d;
+                value[i] = buf.str ();
+              }
+            else
+              break;
+          }
+      }
+  }
+
+  text_label_property (const text_label_property& p)
+    : base_property (p), value (p.value), stored_type (p.stored_type)
+  { }
+
+  octave_value get (void) const
+  {
+    if (stored_type == char_t)
+      return octave_value (char_value ());
+    else
+      return octave_value (cell_value ());
+  }
+
+  std::string string_value (void) const
+  {
+    return value.empty () ? std::string () : value[0];
+  }
+
+  string_vector string_vector_value (void) const { return value; }
+
+  charMatrix char_value (void) const { return charMatrix (value, ' '); }
+
+  Cell cell_value (void) const {return Cell (value); }
+
+  text_label_property& operator = (const octave_value& val)
+  {
+    set (val);
+    return *this;
+  }
+
+  base_property* clone (void) const { return new text_label_property (*this); }
+
+protected:
+
+  bool do_set (const octave_value& val)
+  {
+    if (val.is_string ())
+      {
+        value = val.all_strings ();
+
+        stored_type = char_t;
+      }
+    else if (val.is_cell ())
+      {
+        Cell c = val.cell_value ();
+
+        octave_idx_type nel = c.numel ();
+
+        value.resize (nel);
+
+        for (octave_idx_type i = 0; i < nel; i++)
+          {
+            octave_value tmp = c(i);
+
+            if (tmp.is_string ())
+              value[i] = c(i).string_value ();
+            else
+              {
+                double d = c(i).double_value ();
+
+                if (! error_state)
+                  {
+                    std::ostringstream buf;
+                    buf << d;
+                    value[i] = buf.str ();
+                  }
+                else
+                  return false;
+              }
+          }
+      }
+    else
+      {
+        NDArray nda = val.array_value ();
+
+        if (! error_state)
+          {
+            octave_idx_type nel = nda.numel ();
+
+            value.resize (nel);
+
+            for (octave_idx_type i = 0; i < nel; i++)
+              {
+                std::ostringstream buf;
+                buf << nda(i);
+                value[i] = buf.str ();
+              }
+
+            stored_type = char_t;
+          }
+        else
+          {
+            error ("set: invalid string property value for \"%s\"",
+                   get_name ().c_str ());
+
+            return false;
+          }
+      }
+
+    return true;
+  }
+
+private:
+  string_vector value;
+  type stored_type;
+};
+
+// ---------------------------------------------------------------------
+
 class radio_values
 {
 public:
@@ -3686,7 +3851,7 @@
     // properties declarations.
 
     BEGIN_PROPERTIES (text)
-      string_property string u , ""
+      text_label_property string gu , ""
       radio_property units u , "{data}|pixels|normalized|inches|centimeters|points"
       array_property position mu , Matrix (1, 3, 0.0)
       double_property rotation mu , 0
@@ -3723,6 +3888,8 @@
       radio_property autopos_tag h , "{none}|xlabel|ylabel|zlabel|title"
     END_PROPERTIES
 
+    std::string get_string (void) const { return string.string_value (); }
+
     Matrix get_data_position (void) const;
     Matrix get_extent_matrix (void) const;
     const uint8NDArray& get_pixels (void) const { return pixels; }
--- a/src/oct-parse.yy
+++ b/src/oct-parse.yy
@@ -4215,12 +4215,26 @@
 @noindent\n\
 calls the function @code{acos} with the argument @samp{-1}.\n\
 \n\
-The function @code{feval} is necessary in order to be able to write\n\
-functions that call user-supplied functions, because Octave does not\n\
-have a way to declare a pointer to a function (like C) or to declare a\n\
-special kind of variable that can be used to hold the name of a function\n\
-(like @code{EXTERNAL} in Fortran).  Instead, you must refer to functions\n\
-by name, and use @code{feval} to call them.\n\
+The function @code{feval} can also be used with function handles of\n\
+any sort. @xref{Function Handles} Historically, @code{feval} was\n\
+the only way to call user-supplied functions in strings, but\n\
+function handles are now preferred due to the cleaner syntax they\n\
+offer. For example,\n\
+\n\
+@example\n\
+@group\n\
+@var{f} = @@exp;\n\
+feval (@var{f}, 1)\n\
+     @result{} 2.7183\n\
+@var{f} (1)\n\
+     @result{} 2.7183\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+are equivalent ways to call the function referred to by @var{f}. If it\n\
+cannot be predicted beforehand that @var{f} is a function handle or the\n\
+function name in a string, @code{feval} can be used instead.\n\
 @end deftypefn")
 {
   octave_value_list retval;