changeset 20207:abf85f8cbd6c

Expand type() to work on command-line entered functions (bug #40462). * symtab.h (find_cmdline_function): New function. * symtab.cc (__get_cmdline_fcn_txt__): New function. * pt-pr-code.cc (tree_print_code::visit_octave_user_function): Don't decrement indent level. * pt-pr-code.cc (tree_print_code::visit_no_op_command): Decrement indent level if end of fcn_or_script reached. * pt-pr-code.cc (tree_print_code::visit_statement): Just print newline. * type.m: Check for command-line function and print string from __get_cmdline_fcn_txt__() if it is not empty.
author John W. Eaton <jwe@octave.org>
date Wed, 20 May 2015 08:01:10 -0700
parents 3c8260fd0837
children 29eb47fe8e8c
files libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h libinterp/parse-tree/pt-pr-code.cc scripts/help/type.m
diffstat 4 files changed, 65 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.cc	Tue May 19 13:49:21 2015 -0700
+++ b/libinterp/corefcn/symtab.cc	Wed May 20 08:01:10 2015 -0700
@@ -44,6 +44,7 @@
 #include "pager.h"
 #include "parse.h"
 #include "pt-arg-list.h"
+#include "pt-pr-code.h"
 #include "symtab.h"
 #include "unwind-prot.h"
 #include "utils.h"
@@ -1810,6 +1811,44 @@
   return retval;
 }
 
+DEFUN (__get_cmdline_fcn_txt__, args, ,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {} __get_cmdline_fcn_txt__ (@var{name})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+        {
+          octave_value ov = symbol_table::find_cmdline_function (name);
+
+          octave_user_function *f = ov.user_function_value ();
+
+          if (f)
+            {
+              std::ostringstream buf;
+
+              tree_print_code tpc (buf);
+
+              f->accept (tpc);
+
+              retval = buf.str ();
+            }
+        }
+      else
+        error ("__get_cmd_line_function_text__: expecting function name");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
 #if 0
 
 // FIXME: should we have functions like this in Octave?
--- a/libinterp/corefcn/symtab.h	Tue May 19 13:49:21 2015 -0700
+++ b/libinterp/corefcn/symtab.h	Wed May 20 08:01:10 2015 -0700
@@ -1548,6 +1548,14 @@
            ? p->second.find_user_function () : octave_value ();
   }
 
+  static octave_value find_cmdline_function (const std::string& name)
+  {
+    fcn_table_iterator p = fcn_table.find (name);
+
+    return (p != fcn_table.end ())
+           ? p->second.find_cmdline_function () : octave_value ();
+  }
+
   static void install_cmdline_function (const std::string& name,
                                         const octave_value& fcn)
   {
--- a/libinterp/parse-tree/pt-pr-code.cc	Tue May 19 13:49:21 2015 -0700
+++ b/libinterp/parse-tree/pt-pr-code.cc	Wed May 20 08:01:10 2015 -0700
@@ -329,7 +329,7 @@
 
       cmd_list->accept (*this);
 
-      decrement_indent_level ();
+      // endfunction will decrement the indent level.
     }
 
   visit_octave_user_function_trailer (fcn);
@@ -719,6 +719,9 @@
 void
 tree_print_code::visit_no_op_command (tree_no_op_command& cmd)
 {
+  if (cmd.is_end_of_fcn_or_script ())
+    decrement_indent_level ();
+
   indent ();
 
   os << cmd.original_command ();
@@ -873,13 +876,7 @@
     {
       cmd->accept (*this);
 
-      if (! stmt.print_result ())
-        {
-          os << ";";
-          newline (" ");
-        }
-      else
-        newline ();
+      newline ();
     }
   else
     {
--- a/scripts/help/type.m	Tue May 19 13:49:21 2015 -0700
+++ b/scripts/help/type.m	Wed May 20 08:01:10 2015 -0700
@@ -97,6 +97,19 @@
       txt = sprintf ("%s is a dynamically-linked function", name);
     elseif (e == 5)
       txt = sprintf ("%s is a built-in function", name);
+    elseif (e == 103)
+      contents = __get_cmdline_fcn_txt__ (name);
+      if (isempty (contents))
+        txt = sprintf ("%s is a command-line function with no definition",
+                       name);
+      else
+        if (quiet)
+          txt = contents;
+        else
+          txt = sprintf ("%s is the command-line function:\n\n%s",
+                         name, contents);
+        endif
+      endif
     elseif (any (strcmp (__operators__ (), name)))
       txt = sprintf ("%s is an operator", name);
     elseif (any (strcmp (__keywords__ (), name)))