From 61911bf3a8cb3775f3604cdb81d3b76a51df331d Mon Sep 17 00:00:00 2001
From: Thomas Moulard <thomas.moulard@gmail.com>
Date: Fri, 31 Dec 2010 19:02:51 +0100
Subject: [PATCH] Enhance import to avoid importing a module twice.

---
 include/dynamic-graph/fwd.hh   |  2 ++
 include/dynamic-graph/import.h | 22 +++++++++++++++++++++-
 src/dgraph/import.cpp          | 26 +++++++++++---------------
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/include/dynamic-graph/fwd.hh b/include/dynamic-graph/fwd.hh
index fe34dc2..b1ee9e5 100644
--- a/include/dynamic-graph/fwd.hh
+++ b/include/dynamic-graph/fwd.hh
@@ -37,6 +37,8 @@ namespace dynamicgraph
 
   template<class Time>
   class SignalArray;
+
+  class Interpreter;
 } // end of namespace dynamicgraph.
 
 #endif //! DYNAMIC_GRAPH_FWD_HH
diff --git a/include/dynamic-graph/import.h b/include/dynamic-graph/import.h
index 8566df4..a194be7 100644
--- a/include/dynamic-graph/import.h
+++ b/include/dynamic-graph/import.h
@@ -23,9 +23,10 @@
 
 # include <boost/filesystem/path.hpp>
 
+# include <dynamic-graph/fwd.hh>
+
 namespace dynamicgraph
 {
-  class Interpreter;
   namespace command
   {
     namespace
@@ -36,7 +37,26 @@ namespace dynamicgraph
       /// will look for scripts or plug-ins.
       typedef std::vector<boost::filesystem::path> paths_t;
 
+      /// \brief Import paths list.
+      ///
+      /// This vector of string is similar to Unix variables such as
+      /// PATH. It contains all paths that are used to search when
+      /// importing a script.
+      ///
+      /// The look-up is made from right to left:
+      ///
+      /// On Unix:
+      ///  importPaths = A:B:C
+      /// On Microsoft Windows:
+      ///  importPaths = A;B;C
+      ///
+      /// When typing "import foo", C will be searched first then B
+      /// and A. The search stops when the file is found.
       extern paths_t importPaths;
+
+      /// \brief Already imported paths to avoid multiple inclusion.
+      extern paths_t alreadyImportedPaths;
+
     } // end of anonymous namespace.
 
     /// \brief Implement sot interpretor import command.
diff --git a/src/dgraph/import.cpp b/src/dgraph/import.cpp
index e345057..9f93fb7 100644
--- a/src/dgraph/import.cpp
+++ b/src/dgraph/import.cpp
@@ -68,22 +68,8 @@ namespace dynamicgraph
       /// Initialize import paths list (called during static initialization).
       paths_t initializePaths ();
 
-      /// \brief Import paths list.
-      ///
-      /// This vector of string is similar to Unix variables such as
-      /// PATH. It contains all paths that are used to search when
-      /// importing a script.
-      ///
-      /// The look-up is made from right to left:
-      ///
-      /// On Unix:
-      /// importPaths = A:B:C
-      /// On Microsoft Windows:
-      /// importPaths = A;B;C
-      ///
-      /// When typing ``import foo'', C will be searched first then B
-      /// and A. The search stops when the file is found.
       paths_t importPaths = initializePaths ();
+      paths_t alreadyImportedPaths;
 
       /// Search for a module.
       ///
@@ -268,6 +254,7 @@ namespace dynamicgraph
       // Get the absolute path of the module.
       boost::filesystem::path path = searchModule (module);
 
+      // Check that the module can be opened.
       std::ifstream file (path.file_string ().c_str ());
       if (!boost::filesystem::is_regular_file (path)
 	  || !file.is_open () || !file.good ())
@@ -296,11 +283,20 @@ namespace dynamicgraph
 	  return;
 	}
 
+      // If the module has already been imported, do not import it
+      // again.
+      if (std::find (alreadyImportedPaths.begin (),
+		     alreadyImportedPaths.end (),
+		     path) != alreadyImportedPaths.end ())
+	return;
+
       if (path.extension () != SHARED_LIBRARY_EXT)
 	importScript (interpreter, path, file, os);
       else
 	importPlugin (interpreter, path, os);
 
+      alreadyImportedPaths.push_back (path);
+
       dgDEBUGOUT(15);
     }
 
-- 
GitLab