changeset 22898:9baa19102908

refactor display and disp functions (bug #49794) * pr-output.cc (Fdisp, Ffdisp): Tag with dispatch classes. (Fdisplay): New function. * ov-class.cc (octave_class::print_with_name): Simply call octave_base_value::print_with_name. * ov-classdef.cc (octave_classdef::print): Simply call print_raw. (octave_classdef::print_with_name): Simply call octave_base_value::print_with_name. * variables.cc (bind_ans): Call display function to print result. * pt-assign.cc (tree_simple_assignment::rvalue1, tree_multi_assignment::rvalue): Likewise. * pt-id.cc (tree_identifier::rvalue): Likewise. * display.m: Delete. * scripts/general/module.mk: Update.
author John W. Eaton <jwe@octave.org>
date Fri, 16 Dec 2016 00:10:27 -0500
parents 4090c32fccf8
children 31bd8a50d44c
files libinterp/corefcn/pr-output.cc libinterp/corefcn/variables.cc libinterp/octave-value/ov-class.cc libinterp/octave-value/ov-classdef.cc libinterp/parse-tree/pt-assign.cc libinterp/parse-tree/pt-id.cc scripts/general/display.m scripts/general/module.mk
diffstat 8 files changed, 106 insertions(+), 143 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/pr-output.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/corefcn/pr-output.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -53,6 +53,7 @@
 #include "oct-stream.h"
 #include "octave-preserve-stream-state.h"
 #include "pager.h"
+#include "parse.h"
 #include "pr-output.h"
 #include "sysdep.h"
 #include "unwind-prot.h"
@@ -3483,6 +3484,7 @@
 }
 
 DEFUN (disp, args, nargout,
+       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
        doc: /* -*- texinfo -*-
 @deftypefn {} {} disp (@var{x})
 Display the value of @var{x}.
@@ -3526,6 +3528,7 @@
 }
 
 DEFUN (fdisp, args, ,
+       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
        doc: /* -*- texinfo -*-
 @deftypefn {} {} fdisp (@var{fid}, @var{x})
 Display the value of @var{x} on the stream @var{fid}.
@@ -3592,6 +3595,82 @@
 %! endfor
 */
 
+DEFUN (display, args, ,
+       classes: cell char double function_handle int8 int16 int32 int64 logical single struct uint8 uint16 uint32 uint64
+       doc: /* -*- texinfo -*-
+@deftypefn {} {} display (@var{obj})
+Display the contents of the object @var{obj}.
+
+The Octave interpreter calls the @code{display} function whenever it needs
+to present a class on-screen.  Typically, this would be a statement which
+does not end in a semicolon to suppress output.  For example:
+
+@example
+myobj = myclass (@dots{})
+@end example
+
+User-defined classes should overload the @code{display} method so that
+something useful is printed for a class object.  Otherwise, Octave will
+report only that the object is an instance of its class.
+
+@example
+@group
+myobj = myclass (@dots{})
+  @result{} myobj = <class myclass>
+@end group
+@end example
+
+@seealso{class, subsref, subsasgn}
+@end deftypefn */)
+{
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+
+  std::string name;
+
+  if (nargin == 2)
+    name = args(1).xstring_value ("CALLER must be a string");
+  else
+    {
+      string_vector names = args.name_tags ();
+      std::string tmp = names(0);
+      name = valid_identifier (tmp) ? tmp : "ans";
+    }
+
+  // Only reason we got here is that there was no overloaded display
+  // function.  Rely on built-in functions to display whatever obj is.
+
+  octave_value value = args(0);
+  bool is_scalar = value.is_scalar_type ();
+
+  octave_stdout << name << (is_scalar ? " = " : " =\n\n");
+
+  // Use feval so that dispatch will also work for disp.
+
+  feval ("disp", ovl (value));
+
+  if (! is_scalar)
+    octave_stdout << std::endl;
+
+  return ovl ();
+}
+
+/*
+%!test
+%! str = evalc ("x = 1.1; display (x)");
+%! assert (str, "x =  1.1000\n");
+
+%!test
+%! str = evalc ("display (1.1)");
+%! assert (str, " 1.1000\n");
+
+## Test input validation
+%!error display ()
+%!error display (1,2)
+*/
+
 static void
 init_format_state (void)
 {
--- a/libinterp/corefcn/variables.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/corefcn/variables.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -1952,7 +1952,7 @@
           symbol_table::force_assign (ans, val);
 
           if (print)
-            val.print_with_name (octave_stdout, ans);
+            feval ("display", ovl (val, ans));
         }
     }
 }
--- a/libinterp/octave-value/ov-class.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/octave-value/ov-class.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -1010,31 +1010,9 @@
 
 void
 octave_class::print_with_name (std::ostream& os, const std::string& name,
-                               bool)
+                               bool print_padding)
 {
-  octave_value fcn = symbol_table::find_method ("display", class_name ());
-
-  if (fcn.is_defined ())
-    {
-      octave_value_list args;
-
-      count++;
-      args(0) = octave_value (this);
-
-      string_vector arg_names (1);
-
-      arg_names[0] = name;
-
-      args.stash_name_tags (arg_names);
-
-      feval (fcn.function_value (), args);
-    }
-  else
-    {
-      indent (os);
-      os << name << " = <class " << class_name () << ">";
-      newline (os);
-    }
+  octave_base_value::print_with_name (os, name, print_padding);
 }
 
 // Loading a class properly requires an exemplar map entry for success.
--- a/libinterp/octave-value/ov-classdef.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/octave-value/ov-classdef.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -943,24 +943,6 @@
 void
 octave_classdef::print (std::ostream& os, bool)
 {
-  if (! called_from_builtin ())
-    {
-      cdef_method meth = object.get_class ().find_method ("disp");
-
-      if (meth.ok ())
-        {
-          octave_value_list args;
-
-          count++;
-          args(0) = octave_value (this);
-
-          indent (os);
-          meth.execute (args, 0, true, "disp");
-
-          return;
-        }
-    }
-
   print_raw (os);
 }
 
@@ -986,25 +968,7 @@
 octave_classdef::print_with_name (std::ostream& os, const std::string& name,
                                   bool print_padding)
 {
-  cdef_method meth = object.get_class ().find_method ("display");
-
-  if (meth.ok ())
-    {
-      octave_value_list args;
-
-      count++;
-      args(0) = octave_value (this);
-
-      string_vector arg_names (1);
-
-      arg_names[0] = name;
-      args.stash_name_tags (arg_names);
-
-      indent (os);
-      meth.execute (args, 0, true, "display");
-    }
-  else
-    octave_base_value::print_with_name (os, name, print_padding);
+  octave_base_value::print_with_name (os, name, print_padding);
 }
 
 bool
--- a/libinterp/parse-tree/pt-assign.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/parse-tree/pt-assign.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -33,8 +33,9 @@
 #include "input.h"
 #include "ovl.h"
 #include "oct-lvalue.h"
+#include "ov.h"
 #include "pager.h"
-#include "ov.h"
+#include "parse.h"
 #include "pt-arg-list.h"
 #include "pt-bp.h"
 #include "pt-assign.h"
@@ -117,8 +118,12 @@
 
               octave_value lhs_val = ult.value ();
 
-              lhs_val.print_with_name (octave_stdout,
-                                       lhs->name ());
+              octave_value_list args = ovl (lhs_val, lhs->name ());
+              string_vector name_tags (2);
+              name_tags(0) = lhs->name ();
+              name_tags(1) = "name";
+              args.stash_name_tags (name_tags);
+              feval ("display", args);
             }
         }
       catch (octave::index_exception& e)
@@ -324,7 +329,12 @@
 
               octave_value lhs_val = ult.value ();
 
-              lhs_val.print_with_name (octave_stdout, lhs_elt->name ());
+              octave_value_list args = ovl (lhs_val, lhs_elt->name ());
+              string_vector name_tags (2);
+              name_tags(0) = lhs_elt->name ();
+              name_tags(1) = "name";
+              args.stash_name_tags (name_tags);
+              feval ("display", args);
             }
         }
 
--- a/libinterp/parse-tree/pt-id.cc	Thu Dec 15 22:04:11 2016 -0500
+++ b/libinterp/parse-tree/pt-id.cc	Fri Dec 16 00:10:27 2016 -0500
@@ -28,6 +28,7 @@
 #include "ovl.h"
 #include "oct-lvalue.h"
 #include "pager.h"
+#include "parse.h"
 #include "pt-bp.h"
 #include "pt-const.h"
 #include "pt-eval.h"
@@ -95,7 +96,14 @@
         {
           if (print_result () && nargout == 0
               && octave::tree_evaluator::statement_printing_enabled ())
-            val.print_with_name (octave_stdout, name ());
+            {
+              octave_value_list args = ovl (val, name ());
+              string_vector name_tags (2);
+              name_tags(0) = name ();
+              name_tags(1) = "name";
+              args.stash_name_tags (name_tags);
+              feval ("display", args);
+            }
 
           retval = val;
         }
--- a/scripts/general/display.m	Thu Dec 15 22:04:11 2016 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-## Copyright (C) 2008-2016 David Bateman
-##
-## This file is part of Octave.
-##
-## Octave 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.
-##
-## Octave 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 Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {} {} display (@var{obj})
-## Display the contents of the object @var{obj}.
-##
-## The Octave interpreter calls the @code{display} function whenever it needs
-## to present a class on-screen.  Typically, this would be a statement which
-## does not end in a semicolon to suppress output.  For example:
-##
-## @example
-## myobj = myclass (@dots{})
-## @end example
-##
-## User-defined classes should overload the @code{display} method so that
-## something useful is printed for a class object.  Otherwise, Octave will
-## report only that the object is an instance of its class.
-##
-## @example
-## @group
-## myobj = myclass (@dots{})
-##   @result{} myobj = <class myclass>
-## @end group
-## @end example
-##
-## @seealso{class, subsref, subsasgn}
-## @end deftypefn
-
-function display (obj)
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  ## Only reason we got here is that there was no overloaded display function.
-  ## Rely on built-in functions to display whatever obj is.
-
-  varname = inputname (1);
-  if (! isempty (varname))
-    evalin ("caller", varname);
-  else
-    disp (obj);
-  endif
-
-endfunction
-
-
-%!test
-%! str = evalc ("x = 1.1; display (x)");
-%! assert (str, "x =  1.1000\n");
-
-%!test
-%! str = evalc ("display (1.1)");
-%! assert (str, " 1.1000\n"); 
-
-## Test input validation
-%!error display ()
-%!error display (1,2)
-
--- a/scripts/general/module.mk	Thu Dec 15 22:04:11 2016 -0500
+++ b/scripts/general/module.mk	Fri Dec 16 00:10:27 2016 -0500
@@ -30,7 +30,6 @@
   scripts/general/deal.m \
   scripts/general/deg2rad.m \
   scripts/general/del2.m \
-  scripts/general/display.m \
   scripts/general/divergence.m \
   scripts/general/fieldnames.m \
   scripts/general/flip.m \