changeset 23680:ef71711f6d64

rework __dump_symbol_table__ function * symtab.h, symtab.cc (F__dump_symtab_info__): Instead of printing results, return a struct containing all the info. (symbol_table::symbol_record::symbol_record_rep::dump, symbol_table::fcn_info::fcn_info_rep::dump, symbol_table::dump, symbol_table::scope::dump): Update interface. Create and return struct. (dump_container_map, symbol_table::dump_fcn_table_map, symbol_table::scope::dump_symbols_map): New functions. (fcn_file_name): Delete static function. (symbol_table::dump_global, symbol_table::dump_functions): Delete. * ov-usr-fcn.h, ov-usr-fcn.cc (octave_user_function::dump): Update interface. Create and return struct. (octave_user_function::ctor_type_str): New function. * ov-base.h, ov-base.cc (octave_base_value::dump): Update interface. Create and return struct. * ov.h (octave_value::dump): Update interface.
author John W. Eaton <jwe@octave.org>
date Thu, 22 Jun 2017 16:23:36 -0400
parents ece6f43304e5
children 8b5bc5e5f74b
files libinterp/corefcn/symtab.cc libinterp/corefcn/symtab.h libinterp/octave-value/ov-base.cc libinterp/octave-value/ov-base.h libinterp/octave-value/ov-usr-fcn.cc libinterp/octave-value/ov-usr-fcn.h libinterp/octave-value/ov.h
diffstat 7 files changed, 197 insertions(+), 251 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/symtab.cc	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/corefcn/symtab.cc	Thu Jun 22 16:23:36 2017 -0400
@@ -109,29 +109,25 @@
   return new symbol_record_rep (new_scope, name, varval (), storage_class);
 }
 
-void
-symbol_table::symbol_record::symbol_record_rep::dump
-  (std::ostream& os, const std::string& prefix) const
+octave_value
+symbol_table::symbol_record::symbol_record_rep::dump (void) const
 {
-  octave_value val = varval ();
+  std::map<std::string, octave_value> m
+    = {{"name", name},
+       {"local", octave_value (is_local ())},
+       {"automatic", octave_value (is_automatic ())},
+       {"formal", octave_value (is_formal ())},
+       {"hidden", octave_value (is_hidden ())},
+       {"inherited", octave_value (is_inherited ())},
+       {"global", octave_value (is_global ())},
+       {"persistent", octave_value (is_persistent ())}};
 
-  os << prefix << name;
+  octave_value val = varval ();
 
   if (val.is_defined ())
-    {
-      os << " ["
-         << (is_local () ? "l" : "")
-         << (is_automatic () ? "a" : "")
-         << (is_formal () ? "f" : "")
-         << (is_hidden () ? "h" : "")
-         << (is_inherited () ? "i" : "")
-         << (is_global () ? "g" : "")
-         << (is_persistent () ? "p" : "")
-         << "] ";
-      val.dump (os);
-    }
+    m["value"] = val;
 
-  os << "\n";
+  return octave_value (m);
 }
 
 octave_value&
@@ -1258,14 +1254,6 @@
   return (q != inferior_classes.end ());
 }
 
-static std::string
-fcn_file_name (const octave_value& fcn)
-{
-  const octave_function *f = fcn.function_value ();
-
-  return f ? f->fcn_file_name () : "";
-}
-
 void
 symbol_table::fcn_info::fcn_info_rep::install_built_in_dispatch (const std::string& klass)
 {
@@ -1287,54 +1275,41 @@
            name.c_str ());
 }
 
-void
-symbol_table::fcn_info::fcn_info_rep::dump (std::ostream& os,
-                                            const std::string& prefix) const
+static octave_value
+dump_function_map (const std::map<std::string, octave_value>& fcn_map)
 {
-  os << prefix << full_name ()
-     << " ["
-     << (cmdline_function.is_defined () ? "c" : "")
-     << (built_in_function.is_defined () ? "b" : "")
-     << (package.is_defined () ? "p" : "")
-     << "]\n";
-
-  std::string tprefix = prefix + "  ";
+  if (fcn_map.empty ())
+    return octave_value (Matrix ());
 
-  if (autoload_function.is_defined ())
-    os << tprefix << "autoload: "
-       << fcn_file_name (autoload_function) << "\n";
+  std::map<std::string, octave_value> info_map;
 
-  if (function_on_path.is_defined ())
-    os << tprefix << "function from path: "
-       << fcn_file_name (function_on_path) << "\n";
-
-  if (! local_functions.empty ())
+  for (const auto& nm_fcn : fcn_map)
     {
-      for (const auto& str_val : local_functions)
-        os << tprefix << "local: " << fcn_file_name (str_val.second)
-           << " [" << str_val.first << "]\n";
+      std::string nm = nm_fcn.first;
+      const octave_value& fcn = nm_fcn.second;
+      info_map[nm] = fcn.dump ();
     }
 
-  if (! private_functions.empty ())
-    {
-      for (const auto& str_val : private_functions)
-        os << tprefix << "private: " << fcn_file_name (str_val.second)
-           << " [" << str_val.first << "]\n";
-    }
+  return octave_value (info_map);
+}
 
-  if (! class_constructors.empty ())
-    {
-      for (const auto& str_val : class_constructors)
-        os << tprefix << "constructor: " << fcn_file_name (str_val.second)
-           << " [" << str_val.first << "]\n";
-    }
+octave_value
+symbol_table::fcn_info::fcn_info_rep::dump (void) const
+{
+  std::map<std::string, octave_value> m
+    = {{"name", octave_value (full_name ())},
+       {"refcount", octave_value (count.value ())},
+       {"package", package.dump ()},
+       {"local_functions", dump_function_map (local_functions)},
+       {"private_functions", dump_function_map (private_functions)},
+       {"class_methods", dump_function_map (class_methods)},
+       {"class_constructors", dump_function_map (class_constructors)},
+       {"cmdline_function", cmdline_function.dump ()},
+       {"autoload_function", autoload_function.dump ()},
+       {"function_on_path", function_on_path.dump ()},
+       {"built_in_function", built_in_function.dump ()}};
 
-  if (! class_methods.empty ())
-    {
-      for (const auto& str_val : class_methods)
-        os << tprefix << "method: " << fcn_file_name (str_val.second)
-           << " [" << str_val.first << "]\n";
-    }
+  return octave_value (m);
 }
 
 octave_value
@@ -1444,55 +1419,34 @@
   return fcn;
 }
 
-void
-symbol_table::dump (std::ostream& os, scope *sid)
+template <typename V, template <typename...> class C>
+static octave_value
+dump_container_map (const std::map<std::string, C<V>>& container_map)
 {
-  if (sid == m_global_scope)
-    dump_global (os);
-  else
+  if (container_map.empty ())
+    return octave_value (Matrix ());
+
+  std::map<std::string, octave_value> info_map;
+
+  for (const auto& nm_container : container_map)
     {
-      if (sid)
-        {
-          os << "*** dumping symbol table scope ("
-             << sid->name () << ")\n\n";
+      std::string nm = nm_container.first;
+      const C<V>& container = nm_container.second;
+      info_map[nm] = Cell (container);
+    }
 
-          sid->dump (os);
-        }
-    }
+  return octave_value (info_map);
 }
 
-void
-symbol_table::dump_global (std::ostream& os)
+octave_value
+symbol_table::dump (void) const
 {
-  if (! m_global_symbols.empty ())
-    {
-      os << "*** dumping global symbol table\n\n";
-
-      for (const auto& str_val : m_global_symbols)
-        {
-          std::string nm = str_val.first;
-          octave_value val = str_val.second;
+  std::map<std::string, octave_value> m
+    = {{"function_info", dump_fcn_table_map ()},
+       {"precedence_table", dump_container_map (m_class_precedence_table)},
+       {"parent_classes", dump_container_map (m_parent_map)}};
 
-          os << "  " << nm << " ";
-          val.dump (os);
-          os << "\n";
-        }
-    }
-}
-
-void
-symbol_table::dump_functions (std::ostream& os)
-{
-  if (! m_fcn_table.empty ())
-    {
-      os << "*** dumping globally visible functions from symbol table\n"
-         << "    (c=commandline, b=built-in)\n\n";
-
-      for (const auto& nm_fi : m_fcn_table)
-        nm_fi.second.dump (os, "  ");
-
-      os << "\n";
-    }
+  return octave_value (m);
 }
 
 void
@@ -1507,6 +1461,24 @@
 }
 
 octave_value
+symbol_table::dump_fcn_table_map (void) const
+{
+  if (m_fcn_table.empty ())
+    return octave_value (Matrix ());
+
+  std::map<std::string, octave_value> info_map;
+
+  for (const auto& nm_finfo : m_fcn_table)
+    {
+      std::string nm = nm_finfo.first;
+      const fcn_info& finfo = nm_finfo.second;
+      info_map[nm] = finfo.dump ();
+    }
+
+  return octave_value (info_map);
+}
+
+octave_value
 symbol_table::scope::find (const std::string& name,
                            const octave_value_list& args,
                            bool skip_variables, bool local_funcs)
@@ -1723,46 +1695,31 @@
   return retval;
 }
 
-void
-symbol_table::scope::dump (std::ostream& os)
+octave_value
+symbol_table::scope::dump (void) const
 {
-  if (! m_subfunctions.empty ())
+  std::map<std::string, octave_value> m
+    = {{"name", octave_value (m_name)},
+       {"symbols", dump_symbols_map ()},
+       {"persistent_variables", octave_value (m_persistent_symbols)},
+       {"subfunctions", dump_function_map (m_subfunctions)}};
+
+  return octave_value (m);
+}
+
+octave_value
+symbol_table::scope::dump_symbols_map (void) const
+{
+  std::map<std::string, octave_value> info_map;
+
+  for (const auto& nm_sr : m_symbols)
     {
-      os << "  subfunctions defined in this scope:\n";
-
-      for (const auto& nm_sf : m_subfunctions)
-        os << "    " << nm_sf.first << "\n";
-
-      os << "\n";
+      std::string nm = nm_sr.first;
+      const symbol_table::symbol_record& sr = nm_sr.second;
+      info_map[nm] = sr.dump ();
     }
 
-  if (! m_persistent_symbols.empty ())
-    {
-      os << "  persistent variables in this scope:\n\n";
-
-      for (const auto& nm_val : m_persistent_symbols)
-        {
-          std::string nm = nm_val.first;
-          octave_value val = nm_val.second;
-
-          os << "    " << nm << " ";
-          val.dump (os);
-          os << "\n";
-        }
-
-      os << "\n";
-    }
-
-  if (! m_symbols.empty ())
-    {
-      os << "  other symbols in this scope (l=local; a=auto; f=formal\n"
-         << "    h=hidden; i=inherited; g=global; p=persistent)\n\n";
-
-      for (const auto& nm_sr : m_symbols)
-        nm_sr.second.dump (os, "    ");
-
-      os << "\n";
-    }
+  return octave_value (info_map);
 }
 
 void
@@ -1968,9 +1925,7 @@
 DEFMETHOD (__dump_symtab_info__, interp, args, ,
            doc: /* -*- texinfo -*-
 @deftypefn  {} {} __dump_symtab_info__ ()
-@deftypefnx {} {} __dump_symtab_info__ (@var{scope})
-@deftypefnx {} {} __dump_symtab_info__ ("scopes")
-@deftypefnx {} {} __dump_symtab_info__ ("functions")
+@deftypefnx {} {} __dump_symtab_info__ (@var{function})
 Undocumented internal function.
 @seealso{__current_scope__}
 @end deftypefn */)
@@ -1980,67 +1935,21 @@
   if (nargin > 1)
     print_usage ();
 
-  octave_value retval;
-
   symbol_table& symtab = interp.get_symbol_table ();
 
   if (nargin == 0)
-    {
-      symtab.dump_functions (octave_stdout);
-
-      symtab.dump_global (octave_stdout);
-
-      // This won't work now...
-#if 0
-      std::list<symbol_table::scope*> lst = symtab.scopes ();
-
-      for (auto *scp : lst)
-        symtab.dump (octave_stdout, scp);
-#endif
-    }
+    return symtab.dump ();
   else
     {
-      octave_value arg = args(0);
-
-      if (arg.is_string ())
-        {
-          std::string s_arg = arg.string_value ();
-
-          if (s_arg == "scopes")
-            {
-              // This won't work now...
-#if 0
-              std::list<symbol_table::scope*> lst = symtab.scopes ();
-
-              RowVector v (lst.size ());
-
-              octave_idx_type k = 0;
-
-              for (auto *sid : lst)
-                v.xelem (k++) = sid;
+      std::string fname = args(0).xstring_value ("__dump_symtab_info__: argument must be a function name");
 
-              retval = v;
-#endif
-            }
-          else if (s_arg == "functions")
-            {
-              symtab.dump_functions (octave_stdout);
-            }
-          else
-            error ("__dump_symtab_info__: string argument must be \"functions\" or \"scopes\"");
-        }
-      else
-        {
-          // This won't work now...
-#if 0
-          int sid = arg.xint_value ("__dump_symtab_info__: first argument must be string or scope id");
+      symbol_table::fcn_info *finfo = symtab.get_fcn_info (fname);
 
-          symtab.dump (octave_stdout, sid);
-#endif
-        }
+      if (finfo)
+        return finfo->dump ();
     }
 
-  return retval;
+  return ovl ();
 }
 
 DEFMETHOD (__get_cmdline_fcn_txt__, interp, args, ,
--- a/libinterp/corefcn/symtab.h	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/corefcn/symtab.h	Thu Jun 22 16:23:36 2017 -0400
@@ -35,11 +35,11 @@
 
 #include "glob-match.h"
 #include "lo-regexp.h"
+#include "oct-refcount.h"
 
 class tree_argument_list;
 class octave_user_function;
 
-#include "oct-refcount.h"
 #include "ov.h"
 #include "ovl.h"
 #include "workspace-element.h"
@@ -288,7 +288,7 @@
 
       symbol_record_rep * dup (scope *new_scope) const;
 
-      void dump (std::ostream& os, const std::string& prefix) const;
+      octave_value dump (void) const;
 
       scope *m_decl_scope;
 
@@ -472,11 +472,7 @@
 
     void set_curr_fcn (octave_user_function *fcn) { rep->set_curr_fcn (fcn); }
 
-    void
-    dump (std::ostream& os, const std::string& prefix = "") const
-    {
-      rep->dump (os, prefix);
-    }
+    octave_value dump (void) const { return rep->dump (); }
 
     const symbol_record_rep *xrep (void) const { return rep; }
 
@@ -707,7 +703,7 @@
         clear_package ();
       }
 
-      void dump (std::ostream& os, const std::string& prefix) const;
+      octave_value dump (void) const;
 
       std::string full_name (void) const
       {
@@ -870,11 +866,7 @@
 
     void clear_mex_function (void) { rep->clear_mex_function (); }
 
-    void
-    dump (std::ostream& os, const std::string& prefix = "") const
-    {
-      rep->dump (os, prefix);
-    }
+    octave_value dump (void) const { return rep->dump (); }
 
   private:
 
@@ -1493,11 +1485,7 @@
     return retval;
   }
 
-  void dump (std::ostream& os, scope *sid);
-
-  void dump_global (std::ostream& os);
-
-  void dump_functions (std::ostream& os);
+  octave_value dump (void) const;
 
   void add_to_parent_map (const std::string& classname,
                           const std::list<std::string>& parent_list)
@@ -1537,6 +1525,12 @@
 
   void cleanup (void);
 
+  fcn_info * get_fcn_info (const std::string& name)
+  {
+    fcn_table_iterator p = m_fcn_table.find (name);
+    return p != m_fcn_table.end () ? &p->second : 0;
+  }
+
   class scope
   {
   public:
@@ -1556,9 +1550,9 @@
     typedef std::map<std::string, octave_value>::iterator subfunctions_iterator;
 
     scope (const std::string& name = "")
-      : m_name (name), m_symbols (), m_children (), m_subfunctions (),
-        m_parent (0), m_fcn (0), m_is_nested (false), m_is_static (false),
-        m_persistent_symbols (), m_context (0)
+      : m_name (name), m_symbols (), m_persistent_symbols (), m_subfunctions (),
+        m_fcn (0), m_parent (0), m_children (), m_is_nested (false),
+        m_is_static (false), m_context (0)
     { }
 
     // No copying!
@@ -2010,7 +2004,7 @@
 
     std::list<workspace_element> workspace_info (void) const;
 
-    void dump (std::ostream& os);
+    octave_value dump (void) const;
 
     std::string name (void) const { return m_name; }
 
@@ -2036,17 +2030,20 @@
     // Map from symbol names to symbol info.
     std::map<std::string, symbol_table::symbol_record> m_symbols;
 
-    // Child nested functions.
-    std::vector<scope*> m_children;
+    // Map from names of persistent variables to values.
+    std::map<std::string, octave_value> m_persistent_symbols;
 
     // Map from symbol names to subfunctions.
     std::map<std::string, octave_value> m_subfunctions;
 
+    // The associated user code (may be null).
+    octave_user_function *m_fcn;
+
     // Parent of nested function (may be null).
     scope *m_parent;
 
-    // The associated user code (may be null).
-    octave_user_function *m_fcn;
+    // Child nested functions.
+    std::vector<scope*> m_children;
 
     // If true, then this scope belongs to a nested function.
     bool m_is_nested;
@@ -2054,10 +2051,9 @@
     // If true then no variables can be added.
     bool m_is_static;
 
-    // Map from names of persistent variables to values.
-    std::map<std::string, octave_value> m_persistent_symbols;
-
     context_id m_context;
+
+    octave_value dump_symbols_map (void) const;
   };
 
 private:
@@ -2103,11 +2099,7 @@
 
   scope *m_current_scope;
 
-  fcn_info * get_fcn_info (const std::string& name)
-  {
-    fcn_table_iterator p = m_fcn_table.find (name);
-    return p != m_fcn_table.end () ? &p->second : 0;
-  }
+  octave_value dump_fcn_table_map (void) const;
 };
 
 extern bool out_of_date_check (octave_value& function,
--- a/libinterp/octave-value/ov-base.cc	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/octave-value/ov-base.cc	Thu Jun 22 16:23:36 2017 -0400
@@ -1165,14 +1165,15 @@
   err_wrong_type_arg ("octave_base_value::unlock ()", type_name ());
 }
 
-void
-octave_base_value::dump (std::ostream& os) const
+octave_value
+octave_base_value::dump (void) const
 {
-  dim_vector dv = this->dims ();
+  std::map<std::string, octave_value> m
+    = {{"class", octave_value (this->class_name ())},
+       {"type", octave_value (this->type_name ())},
+       {"dims", octave_value (this->dims().as_array ())}};
 
-  os << "class: " << this->class_name ()
-     << " type: " << this->type_name ()
-     << " dims: " << dv.str ();
+  return octave_value (m);
 }
 
 OCTAVE_NORETURN static
--- a/libinterp/octave-value/ov-base.h	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/octave-value/ov-base.h	Thu Jun 22 16:23:36 2017 -0400
@@ -687,7 +687,7 @@
 
   virtual bool islocked (void) const { return false; }
 
-  virtual void dump (std::ostream& os) const;
+  virtual octave_value dump (void) const;
 
   // Standard mappers.  Register new ones here.
   enum unary_mapper_t
--- a/libinterp/octave-value/ov-usr-fcn.cc	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Thu Jun 22 16:23:36 2017 -0400
@@ -648,16 +648,60 @@
   return retval;
 }
 
-#if 0
-void
-octave_user_function::print_symtab_info (std::ostream& os) const
+std::string
+octave_user_function::ctor_type_str (void) const
 {
-  symbol_table& symtab
-    = octave::__get_symbol_table__ ("octave_user_function::print_symtab_info");
+  std::string retval;
+
+  switch (class_constructor)
+    {
+    case none:
+      retval = "none";
+      break;
+
+    case legacy:
+      retval = "legacy";
+      break;
+
+    case classdef:
+      retval = "classdef";
+      break;
+
+    default:
+      retval = "unrecognized enum value";
+      break;
+    }
+
+  return retval;
+}
 
-  symtab.print_info (os, m_scope);
+octave_value
+octave_user_function::dump (void) const
+{
+  std::map<std::string, octave_value> m
+    = {{"file_name", octave_value (file_name)},
+       {"line", octave_value (location_line)},
+       {"col", octave_value (location_column)},
+       {"end_line", octave_value (end_location_line)},
+       {"end_col", octave_value (end_location_column)},
+       {"time_parsed", octave_value (t_parsed)},
+       {"time_checked", octave_value (t_checked)},
+       {"parent_name", octave_value (parent_name)},
+       {"system_fcn_file", octave_value (system_fcn_file)},
+       {"call_depth", octave_value (call_depth)},
+       {"num_named_args", octave_value (num_named_args)},
+       {"subfunction", octave_value (subfunction)},
+       {"inline_function", octave_value (inline_function)},
+       {"anonymous_function", octave_value (anonymous_function)},
+       {"nested_function", octave_value (nested_function)},
+       {"ctor_type", octave_value (ctor_type_str ())},
+       {"class_method", octave_value (class_method)},
+       {"parent_scope", octave_value (parent_scope
+                                      ? parent_scope->name () : "0x0")},
+       {"scope_info", m_scope ? m_scope->dump () : octave_value ("0x0")}};
+
+  return octave_value (m);
 }
-#endif
 
 void
 octave_user_function::print_code_function_header (void)
--- a/libinterp/octave-value/ov-usr-fcn.h	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/octave-value/ov-usr-fcn.h	Thu Jun 22 16:23:36 2017 -0400
@@ -382,9 +382,7 @@
   void stash_info (jit_function_info *info) { jit_info = info; }
 #endif
 
-#if 0
-  void print_symtab_info (std::ostream& os) const;
-#endif
+  octave_value dump (void) const;
 
 private:
 
@@ -395,6 +393,8 @@
     classdef
   };
 
+  std::string ctor_type_str (void) const;
+
   // Our symbol table scope.
   symbol_table::scope *m_scope;
 
--- a/libinterp/octave-value/ov.h	Thu Jun 22 15:20:46 2017 -0400
+++ b/libinterp/octave-value/ov.h	Thu Jun 22 16:23:36 2017 -0400
@@ -1370,7 +1370,7 @@
 
   bool islocked (void) const { return rep->islocked (); }
 
-  void dump (std::ostream& os) const { rep->dump (os); }
+  octave_value dump (void) const { return rep->dump (); }
 
 #define MAPPER_FORWARD(F) \
   octave_value F (void) const                           \