diff libinterp/interpfcn/load-path.h @ 16676:7368654f302f classdef

Initial support for (classdef) packages. * libinterp/interpfcn/load-path.h (class load_path::loader): New class. (load_path::default_loader, load_path::loader_map): New members. (load_path::load_path): Initialize them. (load_path::fcn_map, load_path::private_fcn_map, load_path::method_map): Move to class load_path::loader. (load_path::add_to_fcn_map, load_path::add_to_private_fcn_map, load_path::add_to_method_map, load_path::move_fcn_map, load_path::move_method_map, load_path::remove_fcn_map, load_path::remove_private_fcn_map, load_path::remove_method_map): Move to class load_path::loader. (load_path::move): Change signature. (load_path::do_move, load_path::remove, load_path::add, load_path::get_loader): New methods. (load_path::find_package, load_path::do_find_package): Likewise. (load_path::dir_info::package_dir_map): New member. (load_path::dir_info::dir_info, load_path::dir_info::operator=): Initialize/assign it. (load_path::dir_info::get_package_dir): New method. (load_path::do_find_fcn, load_path::do_find_private_fcn): Remove methods. (load_path::find_fcn, load_path::find_private_fcn, load_path::find_fcn_file, load_path::find_oct_file, load_path::find_mex_file): Rewrite using class load_path::loader. New argument for package name. *libinterp/interpfcn/load-path.cc (load_path::dir_info::initialize): Clear package_map_dir. (load_path::dir_info::get_package_dir): New method. (load_path::dir_info::get_files_list): Use it. (load_path::add_to_fcn_map, load_path::add_to_private_fcn_map, load_path::add_to_method_map, load_path::move_fcn_map, load_path::move_method_map, load_path::remove_fcn_map, load_path::remove_private_fcn_map, load_path::remove_method_map): Move to class load_path::loader. (load_path::move): Move implementation to do_move, rewrite using class load_path::loader. Signature change. (load_path::do_move, load_path::add, load_path::remove): New methods. (load_path::do_clear): Rewrite using class load_path::loader. (load_path::do_add): Use "do_move" and "add" methods. (load_path::do_remove): Rewrite using "remove" method. (load_path::do_update): Rewitre using class load_path::loader and "add" method. (load_path::do_find_method, load_path::do_methods, load_path::do_overloads, load_path::do_fcn_names, load_path::do_display): Move Implementation to class load_path::loader, without "do_" prefix. Rewrite original to redirect to appropriate loaders. (F__dump_load_path__): New debug function. * libinterp/interpfcn/symtab.h (symbol_table::package_name): New member. (symbol_table::symbol_table): Initialize it. (symbol_table::find): New scope argument. (symbol_table::alloc_package_scope): New method. (symbol_table::fcn_info::find, symbol_table::fcn_info::find_function, symbol_table::fcn_info::find_user_function, symbol_table::fcn_info::fcn_info_rep::xfind, symbol_table::fcn_info::fcn_info_rep::load_class_constructor, symbol_table::fcn_info::fcn_info_rep::find, symbol_table::fcn_info::fcn_info_rep::find_user_function): New argument for package name. (symbol_table::fcn_info::fcn_info_rep::package): New member. (symbol_table::fcn_info::fcn_info_rep::find_package, symbol_table::fcn_info::fcn_info_rep::clear_package): New methods. (symbol_table::fcn_info::fcn_info_rep::clear): Clear package. * libinterp/interpfcn/symtab.cc (symbol_table::fcn_info::fcn_info_rep::load_class_constructor, symbol_table::fcn_info::fcn_info_rep::find, symbol_table::fcn_info::fcn_info_rep::xfind, symbol_table::fcn_info::fcn_info_rep::find_user_function): New argument for package name. (symbol_table::fcn_info::fcn_info_rep::find_package): New method. (symbol_table::find): New scope argument. (symbol_table::do_find): Use package_name member. * libinterp/octave-value/ov-classdef.h (cdef_package::cdef_package_rep::scope): New member. (cdef_package::cdef_package_rep::~cdef_package_rep): New destructor. (cdef_package::cdef_package_rep::meta_subsref, cdef_package::cdef_package_rep::meta_release, cdef_package::cdef_package_rep::meta_is_postfix_index_handled, cdef_package::cdef_package_rep::find, cdef_package::cdef_package_rep::wrap): New methods. (cdef_package::find): New method. (cdef_manager::find_package, cdef_manager::do_find_package): New argument "load_if_not_found". (cdef_manager::find_package_symbol, cdef_manager::do_find_package_symbol): New methods. * libinterp/octave-value/ov-classdef.cc (cdef_manager::do_find_package_symbol): New method. (cdef_manager::do_find_package): New argument. Create package object if it is not loaded yet and the package exists in load_path. (cdef_manager::do_find_class): Handle class names with package. (cdef_package::cdef_package_rep::meta_subsref, cdef_package::cdef_package_rep::meta_release, cdef_package::cdef_package_rep::find): New methods. (cdef_class::make_meta_class): Handle package-scoped classes. (make_package): Assign correct name to the package object. * libinterp/parse-tree/pt-classdef.h (tree_classdef::pack_name): New member. (tree_classdef::tree_classdef): New argument. Initialize it. (tree_classdef::package_name): New accessor. * libinterp/parse-tree/parse.h (octave_base_parser::curr_package_name): New member. (octave_base_parser::octave_base_parser): Initialize it. (load_fcn_from_file): New argument for package name. * libinterp/parse-tree/oct-parse.in.yy (load_fcn_from_file): New argument for package name. Change callers. (parse_fcn_from_file): New argument for package name. Change callers. (octave_base_parser::make_classdef): Use curr_package_name to create the tree_classdef object. * libinterp/octave-value/ov-fcn-handle.cc (octave_fcn_handle::set_fcn): Adapt to new load_fcn_from_file signature. * libinterp/interp-core/ls-mat5.cc (read_mat5_binary_element): Adapt to new load_fcn_from_file signature.
author Michael Goffioul <michael.goffioul@gmail.com>
date Fri, 17 May 2013 23:17:25 -0400
parents 3cd80afc3509
children edbb123cbe3a
line wrap: on
line diff
--- a/libinterp/interpfcn/load-path.h	Sun May 12 21:47:57 2013 -0400
+++ b/libinterp/interpfcn/load-path.h	Fri May 17 23:17:25 2013 -0400
@@ -39,8 +39,7 @@
 protected:
 
   load_path (void)
-    : dir_info_list (), fcn_map (), private_fcn_map (), method_map (),
-      init_dirs () { }
+    : loader_map (), default_loader (), dir_info_list (), init_dirs () { }
 
 public:
 
@@ -99,7 +98,8 @@
                                   std::string& dir_name)
   {
     return instance_ok ()
-      ? instance->do_find_method (class_name, meth, dir_name) : std::string ();
+      ? instance->do_find_method (class_name, meth, dir_name)
+      : std::string ();
   }
 
   static std::string find_method (const std::string& class_name,
@@ -121,47 +121,64 @@
       ? instance->do_overloads (meth) : std::list<std::string> ();
   }
 
-  static std::string find_fcn (const std::string& fcn, std::string& dir_name)
+  static bool find_package (const std::string& package_name)
+  {
+    return instance_ok ()
+      ? instance->do_find_package (package_name) : false;
+  }
+
+  static std::string find_fcn (const std::string& fcn, std::string& dir_name,
+                               const std::string& pack_name = std::string ())
   {
     return instance_ok ()
-      ? instance->do_find_fcn (fcn, dir_name) : std::string ();
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name)
+      : std::string ();
   }
 
-  static std::string find_fcn (const std::string& fcn)
+  static std::string find_fcn (const std::string& fcn,
+                               const std::string& pack_name = std::string ())
   {
     std::string dir_name;
-    return find_fcn (fcn, dir_name);
+    return find_fcn (fcn, dir_name, pack_name);
   }
 
   static std::string find_private_fcn (const std::string& dir,
-                                       const std::string& fcn)
+                                       const std::string& fcn,
+                                       const std::string& pack_name = std::string ())
   {
     return instance_ok ()
-      ? instance->do_find_private_fcn (dir, fcn) : std::string ();
+      ? instance->get_loader (pack_name).find_private_fcn (dir, fcn)
+      : std::string ();
   }
 
-  static std::string find_fcn_file (const std::string& fcn)
+  static std::string find_fcn_file (const std::string& fcn,
+                                    const std::string& pack_name = std::string ())
   {
     std::string dir_name;
 
-    return instance_ok () ?
-      instance->do_find_fcn (fcn, dir_name, M_FILE) : std::string ();
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name, M_FILE)
+      : std::string ();
   }
 
-  static std::string find_oct_file (const std::string& fcn)
+  static std::string find_oct_file (const std::string& fcn,
+                                    const std::string& pack_name = std::string ())
   {
     std::string dir_name;
 
-    return instance_ok () ?
-      instance->do_find_fcn (fcn, dir_name, OCT_FILE) : std::string ();
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name, M_FILE)
+      : std::string ();
   }
 
-  static std::string find_mex_file (const std::string& fcn)
+  static std::string find_mex_file (const std::string& fcn,
+                                    const std::string& pack_name = std::string ())
   {
     std::string dir_name;
 
-    return instance_ok () ?
-      instance->do_find_fcn (fcn, dir_name, MEX_FILE) : std::string ();
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name, M_FILE)
+      : std::string ();
   }
 
   static std::string find_file (const std::string& file)
@@ -295,19 +312,27 @@
     typedef method_file_map_type::const_iterator const_method_file_map_iterator;
     typedef method_file_map_type::iterator method_file_map_iterator;
 
+    // <PACKAGE_NAME, DIR_INFO>
+    typedef std::map<std::string, dir_info> package_dir_map_type;
+
+    typedef package_dir_map_type::const_iterator const_package_dir_map_iterator;
+    typedef package_dir_map_type::iterator package_dir_map_iterator;
+
     // This default constructor is only provided so we can create a
     // std::map of dir_info objects.  You should not use this
     // constructor for any other purpose.
     dir_info (void)
       : dir_name (), abs_dir_name (), is_relative (false),
         dir_mtime (), dir_time_last_checked (),
-        all_files (), fcn_files (), private_file_map (), method_file_map ()
+        all_files (), fcn_files (), private_file_map (), method_file_map (),
+        package_dir_map ()
       { }
 
     dir_info (const std::string& d)
       : dir_name (d), abs_dir_name (), is_relative (false),
         dir_mtime (), dir_time_last_checked (),
-        all_files (), fcn_files (), private_file_map (), method_file_map ()
+        all_files (), fcn_files (), private_file_map (), method_file_map (),
+        package_dir_map ()
     {
       initialize ();
     }
@@ -319,7 +344,8 @@
         dir_time_last_checked (di.dir_time_last_checked),
         all_files (di.all_files), fcn_files (di.fcn_files),
         private_file_map (di.private_file_map),
-        method_file_map (di.method_file_map) { }
+        method_file_map (di.method_file_map),
+        package_dir_map (di.package_dir_map) { }
 
     ~dir_info (void) { }
 
@@ -336,6 +362,7 @@
           fcn_files = di.fcn_files;
           private_file_map = di.private_file_map;
           method_file_map = di.method_file_map;
+          package_dir_map = di.package_dir_map;
         }
 
       return *this;
@@ -352,6 +379,7 @@
     string_vector fcn_files;
     fcn_file_map_type private_file_map;
     method_file_map_type method_file_map;
+    package_dir_map_type package_dir_map;
 
   private:
 
@@ -364,6 +392,9 @@
     void get_method_file_map (const std::string& d,
                               const std::string& class_name);
 
+    void get_package_dir (const std::string& d,
+                          const std::string& package_name);
+
     friend fcn_file_map_type get_fcn_files (const std::string& d);
   };
 
@@ -439,13 +470,125 @@
   typedef method_map_type::const_iterator const_method_map_iterator;
   typedef method_map_type::iterator method_map_iterator;
 
-  mutable dir_info_list_type dir_info_list;
+  class loader
+  {
+  public:
+    loader (const std::string& pfx = std::string ())
+      : prefix (pfx), dir_list (), fcn_map (), private_fcn_map (),
+        method_map () { }
+
+    loader (const loader& l)
+      : prefix (l.prefix), dir_list (l.dir_list),
+        private_fcn_map (l.private_fcn_map), method_map (l.method_map) { }
+
+    ~loader (void) { }
+
+    loader& operator = (const loader& l)
+    {
+      if (&l != this)
+        {
+          prefix = l.prefix;
+          dir_list = l.dir_list;
+          fcn_map = l.fcn_map;
+          private_fcn_map = l.private_fcn_map;
+          method_map = l.method_map;
+        }
+
+      return *this;
+    }
 
-  mutable fcn_map_type fcn_map;
+    void add (const dir_info& di, bool at_end)
+    {
+      if (at_end)
+        dir_list.push_back (di.dir_name);
+      else
+        dir_list.push_front (di.dir_name);
+
+      add_to_fcn_map (di, at_end);
+
+      add_to_private_fcn_map (di);
+
+      add_to_method_map (di, at_end);
+    }
+
+    void move (const dir_info& di, bool at_end);
+
+    void remove (const dir_info& di);
+
+    void clear (void)
+      {
+        dir_list.clear ();
+
+        fcn_map.clear ();
+
+        private_fcn_map.clear ();
+
+        method_map.clear ();
+      }
+
+    void display (std::ostream& out) const;
 
-  mutable private_fcn_map_type private_fcn_map;
+    std::string find_fcn (const std::string& fcn,
+                          std::string& dir_name,
+                          int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+    std::string find_private_fcn (const std::string& dir,
+                                  const std::string& fcn,
+                                  int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+    std::string find_method (const std::string& class_name,
+                             const std::string& meth,
+                             std::string& dir_name,
+                             int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+    std::list<std::string> methods (const std::string& class_name) const;
+
+    void overloads (const std::string& meth, std::list<std::string>& l) const;
+
+    string_vector fcn_names (void) const;
+
+  private:
+    void add_to_fcn_map (const dir_info& di, bool at_end);
+
+    void add_to_private_fcn_map (const dir_info& di);
+
+    void add_to_method_map (const dir_info& di, bool at_end);
+
+    void move_fcn_map (const std::string& dir,
+                       const string_vector& fcn_files, bool at_end);
+
+    void move_method_map (const std::string& dir, bool at_end);
 
-  mutable method_map_type method_map;
+    void remove_fcn_map (const std::string& dir,
+                         const string_vector& fcn_files);
+
+    void remove_private_fcn_map (const std::string& dir);
+
+    void remove_method_map (const std::string& dir);
+
+  private:
+    std::string prefix;
+
+    std::list<std::string> dir_list;
+
+    fcn_map_type fcn_map;
+
+    private_fcn_map_type private_fcn_map;
+
+    method_map_type method_map;
+  };
+
+  // <PACKAGE_NAME, LOADER>
+  typedef std::map<std::string, loader> loader_map_type;
+
+  typedef loader_map_type::const_iterator const_loader_map_iterator;
+  typedef loader_map_type::iterator loader_map_iterator;
+
+  mutable loader_map_type loader_map;
+
+  mutable loader default_loader;
+
+  mutable dir_info_list_type dir_info_list;
 
   mutable std::set<std::string> init_dirs;
 
@@ -472,12 +615,13 @@
 
   bool do_contains_canonical (const std::string& dir) const;
 
-  void move_fcn_map (const std::string& dir,
-                     const string_vector& fcn_files, bool at_end);
+  void do_move (dir_info_list_iterator i, bool at_end);
 
-  void move_method_map (const std::string& dir, bool at_end);
+  void move (const dir_info& di, bool at_end,
+             const std::string& pname = std::string ());
 
-  void move (std::list<dir_info>::iterator i, bool at_end);
+  void remove (const dir_info& di,
+               const std::string& pname = std::string ());
 
   void do_initialize (bool set_initial_path);
 
@@ -491,12 +635,6 @@
 
   void do_add (const std::string& dir, bool at_end, bool warn);
 
-  void remove_fcn_map (const std::string& dir, const string_vector& fcn_files);
-
-  void remove_private_fcn_map (const std::string& dir);
-
-  void remove_method_map (const std::string& dir);
-
   bool do_remove (const std::string& dir);
 
   void do_update (void) const;
@@ -505,23 +643,35 @@
   check_file_type (std::string& fname, int type, int possible_types,
                    const std::string& fcn, const char *who);
 
-  std::string do_find_fcn (const std::string& fcn,
-                           std::string& dir_name,
-                           int type = M_FILE | OCT_FILE | MEX_FILE) const;
+  loader& get_loader (const std::string& name) const
+  {
+    if (! name.empty ())
+      {
+        loader_map_iterator l = loader_map.find (name);
 
-  std::string do_find_private_fcn (const std::string& dir,
-                                   const std::string& fcn,
-                                   int type = M_FILE | OCT_FILE | MEX_FILE) const;
+        if (l == loader_map.end ())
+          l = loader_map.insert (loader_map.end (),
+                                 loader_map_type::value_type (name, loader (name)));
+
+        return l->second;
+      }
+
+    return default_loader;
+  }
 
   std::string do_find_method (const std::string& class_name,
                               const std::string& meth,
-                              std::string& dir_name,
-                              int type = M_FILE | OCT_FILE | MEX_FILE) const;
+                              std::string& dir_name) const;
 
   std::list<std::string> do_methods (const std::string& class_name) const;
 
   std::list<std::string> do_overloads (const std::string& meth) const;
 
+  bool do_find_package (const std::string& package_name) const
+  {
+    return (loader_map.find (package_name) != loader_map.end ());
+  }
+
   std::string do_find_file (const std::string& file) const;
 
   std::string do_find_dir (const std::string& dir) const;
@@ -555,11 +705,8 @@
 
   std::string do_get_command_line_path (void) const { return command_line_path; }
 
-  void add_to_fcn_map (const dir_info& di, bool at_end) const;
-
-  void add_to_private_fcn_map (const dir_info& di) const;
-
-  void add_to_method_map (const dir_info& di, bool at_end) const;
+  void add (const dir_info& di, bool at_end,
+            const std::string& pname = std::string ()) const;
 
   friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d);
 };