]> Creatis software - bbtk.git/commitdiff
We can now use absolute/realtive path for scripts, as well as the '* notation'
authorjean-pierre roux <jean-pierre.roux@creatis.insa-lyon.fr>
Tue, 29 Jan 2008 10:12:45 +0000 (10:12 +0000)
committerjean-pierre roux <jean-pierre.roux@creatis.insa-lyon.fr>
Tue, 29 Jan 2008 10:12:45 +0000 (10:12 +0000)
e.g. std/boxes/*

kernel/src/bbtkFactory.cxx
kernel/src/bbtkInterpreter.cxx
kernel/src/bbtkInterpreter.h
kernel/src/bbtkUtilities.h

index 2a633d32c7bcd6a4c37fcb4c7c0e7e8272f80765..61b7e3266a3f92b3d9ecbd2b0141d61177e072d4 100644 (file)
@@ -4,8 +4,8 @@ Program:   bbtk
 Module:    $RCSfile: bbtkFactory.cxx,v $
 Language:  C++
 
-Date:      $Date: 2008/01/28 09:12:49 $
-Version:   $Revision: 1.3 $
+Date:      $Date: 2008/01/29 10:12:45 $
+Version:   $Revision: 1.4 $
                                                                                 
 
 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
@@ -315,8 +315,14 @@ namespace bbtk
     // push it into vector of paths
     if (upath.length()>0)   // ------------------------------------- check user supplied location
     {
+       if (name[0] != '.' && name[0] != '/' && name[1]!= ':')
+       {
+          bbtkError("Use absolute or relative path name! ["<<name<<"] is an illegal name");
+          return;
+       }
+       
       // std::string path = Utilities::ExpandLibName(upath, verbose);
-      std::string path = Utilities::ExpandLibName(name, verbose); // keep last item, here.
+       std::string path = Utilities::ExpandLibName(name, verbose); // keep last item, here.
        if (path != "")
        {
           std::string p2;
index 775ae989d66f26dc42536ddf5f30aba91bb3d055..a6101a5a2881f678cc33247ad30dfa9165f0fab9 100644 (file)
@@ -3,8 +3,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkInterpreter.cxx,v $ $
   Language:  C++
-  Date:      $Date: 2008/01/28 15:28:15 $
-  Version:   $Revision: 1.7 $
+  Date:      $Date: 2008/01/29 10:12:45 $
+  Version:   $Revision: 1.8 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
@@ -731,64 +731,128 @@ void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>&
   //      - absolute full name e.g.       /home/usrname/proj/dir/scr.bbs
   //          same for Windows, with      c:, d: ...
   //
+  // expression like directory/subdir/scrname.bbs is FORBIDDEN (*)
+  // use ./directory/subdir/scrname.bbs
+  //
+  //   (*) except when using packagename/boxes/*
+  
     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
                          <<name<<"\")"<<std::endl);
+
+// to be remove in final version
+// use : Config v
 verbose = true;
     std::vector<std::string> script_paths;
-    std::string libname;  // full path library name
-    std::string pkgname;  // e.g. <scriptname>.bbs
-     
-    // Add the void path to handle absolute paths
-    script_paths.push_back("");
-    // Add the "." path to handle paths relative to current directory
-    script_paths.push_back(".");
-
-    pkgname = Utilities::ExtractScriptName(name);
+    std::string fullPathScriptName;  // full path script name
+    std::string pkgname;             // e.g. <scriptname>.bbs
+
     if (use_configuration_file)
     {
+        // The following is *NOT* a debug time message :
+        // It's a user intended message.
+        // Please don't remove it.
       if (verbose)
          std::cout << "look for : [" << name << "] (use_configuration_file == TRUE)"  << std::endl;
-      std::vector<std::string> paths = 
-       ConfigurationFile::GetInstance().Get_bbs_paths();
-      std::vector<std::string>::iterator i;
-      for (i=paths.begin();i!=paths.end();++i)
-       {
-         script_paths.push_back(*i); 
-       }
-  
+      script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
     }
-
+    std::string upath;
+    pkgname = Utilities::ExtractScriptName(name,upath);
+    
     bool fullnameGiven = false; 
     bool foundFile     = false;
+
+    if(pkgname == "*") // =========================================== load all boxes (e.g. std/boxes/*)
+    {
+      std::string path;
+      std::vector<std::string>::iterator i;
+      std::string fullDirectoryName;
+      for (i=script_paths.begin();i!=script_paths.end();++i)
+      {
+        path = *i;
+
+       // we *really* want '.' to be the current working directory
+        if (path == ".") {
+          char buf[2048]; // for getcwd
+          char * currentDir = getcwd(buf, 2048);
+          std::string cwd(currentDir);
+          path = currentDir;
+        }
+
+        fullDirectoryName = Utilities::MakePkgnameFromPath(path, upath, false);
+//std::cout <<"fullpath [" <<   fullDirectoryName << "]" <<std::endl;
+      // Check if library exists           
+        if ( ! Utilities::IsDirectory(fullDirectoryName) )
+        {
+        // The following is *NOT* a debug time message :
+        // It's a user intended message.
+        // Please don't remove it.
+          if (verbose)
+            std::cout <<"   [" <<fullDirectoryName <<"] : doesn't exist" <<std::endl;
+          continue;  // try next path
+        }
+        foundFile = true;
+
+        std::cout << "recherche tous les .bbs du directory" << std::endl;
+        std::cout << "pour chacun, LoadScript" << std::endl; 
+
+        std::vector<std::string> Filenames;
+        int nbFiles = Utilities::Explore(fullDirectoryName, false, Filenames);
+// std::cout << "=================nbFiles " << nbFiles << std::endl;
+        int nbBssFiles = 0;
+        for (std::vector<std::string>::iterator i = Filenames.begin(); i!=Filenames.end(); ++i)
+        {
+           if ((*i).substr((*i).size()-4, 4) != ".bbs")
+              continue;      // ignore non .bbs files
+           LoadScript(*i);
+           nbBssFiles++;
+        }
+        if (nbBssFiles==0)
+           if (verbose)
+              std::cout << "WARNING : No '.bbs' file found in [" << fullDirectoryName << "]" << std::endl;
+           
+        break; // a directory was found; we stop iterating
+       }
+       return;
+    }
+
     std::string::size_type slash_position = name.find_last_of("/\\");
-            
-    if (false) //slash_position != std::string::npos)
-    {       // ------------------------------------- check user supplied location 
-      fullnameGiven = true;
-      libname =  Utilities::ExpandLibName(name, verbose);
 
+    // if name contains a slash (anywhere), user is assumed to have passed a relative/absolute name
+    // (not only a plain script name)
+    // we trust him, and try to explade the directory name
+    // WARNING : starting from current local directory :  ./whatYouWant  (./ mandatory!)
+    
+    if (slash_position != std::string::npos)
+    {       // ===========================================================check user supplied location
+      fullnameGiven = true;
+      
+      fullPathScriptName =  Utilities::ExpandLibName(name, verbose);
+      
       // allow user to always forget ".bbs"
-      int l = libname.size();
-      if (l>4) 
-      {       
-         if (libname.substr(l-4, 4) != ".bbs")
+      int l = fullPathScriptName.size();
+      if (l!=0) {
+      
+      if (l>4)
+      {
+         if (fullPathScriptName.substr(l-4, 4) != ".bbs")
          {
-            libname = libname + ".bbs";    
+            fullPathScriptName = fullPathScriptName + ".bbs";
          }
       }
       else
       {
-         libname = libname + ".bbs";
+         fullPathScriptName = fullPathScriptName + ".bbs";   
       }
 
-      if (libname != "") {
-        if ( Utilities::FileExists(libname))
+      //if (fullPathScriptName != "") {
+        if ( Utilities::FileExists(fullPathScriptName))
         {
           foundFile = true;
         }
-      }
+      //}
+      } // endif l != 0
     }
-    else    // ------------------------------------- iterate on the paths
+    else    // =============================================================== iterate on the paths
     {
       std::string path;
       std::vector<std::string>::iterator i;
@@ -804,15 +868,16 @@ verbose = true;
           path = currentDir;
         }
 
-        libname = Utilities::MakePkgnameFromPath(path, name); //pkgname);
-      // Check if library exists           
-        if ( ! Utilities::FileExists(libname) )
+       // fullPathScriptName = Utilities::MakePkgnameFromPath(path, name, true); //pkgname);
+       fullPathScriptName = Utilities::MakePkgnameFromPath(path, pkgname, true);
+      // Check if library exists
+        if ( ! Utilities::FileExists(fullPathScriptName) )
         {
         // The following is *NOT* a debug time message :
         // It's a user intended message.
         // Please don't remove it.
           if (verbose)
-            std::cout <<"   [" <<libname <<"] : doesn't exist" <<std::endl;
+            std::cout <<"   [" <<fullPathScriptName <<"] : doesn't exist" <<std::endl;
           continue;  // try next path
         }
         foundFile = true;
@@ -821,41 +886,47 @@ verbose = true;
       } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
     }
 
-    std::ifstream* s;
-
     if (!foundFile)
     {
        if (fullnameGiven)
-         if(libname == "")
-            bbtkError("Path ["<<name<<"] doesn't exist");
+         if(fullPathScriptName == "")
+            bbtkError("Path ["<<upath<<"] doesn't exist");
          else
-            bbtkError("Script ["<<libname<<"] not found");
+            bbtkError("Script ["<<fullPathScriptName<<"] not found");
        else
           bbtkError("No ["<<pkgname<<".bbs] script found");
        return;    
     }
+    else
+       LoadScript(fullPathScriptName);
 
-    bbtkMessage("Interpreter",1,pkgname<<" loaded"<<std::endl);
-    
+    return;
+  }   
+   
+
+  //=======================================================================
+
+  void Interpreter::LoadScript( std::string fullPathScriptName)
+  {
+    bbtkMessage("Interpreter",1,fullPathScriptName<<" found"<<std::endl);
+
+    std::ifstream* s;      
     s = new std::ifstream;
-    s->open(libname.c_str());
+    s->open(fullPathScriptName.c_str());
     if (!s->good()) 
     {
-        bbtkError("Could not open file ["<<libname<<"]");
+        bbtkError("Could not open file ["<<fullPathScriptName<<"]");
         return;     
     }
-
+    
     if (verbose)
-       std::cout << "   -->[" << libname << "] found" << std::endl;
+       std::cout << "   -->[" << fullPathScriptName << "] found" << std::endl;
 
     mFile.push_back(s);
-    mFileName.push_back(libname);
+    mFileName.push_back(fullPathScriptName);
     mLine.push_back(0);
-  }   
-   
-
-  //=======================================================================
-
+    return;  
+  }
 
   //=======================================================================
   /**
@@ -1186,19 +1257,18 @@ void Interpreter::Help(const std::vector<std::string>& words)
     // empty lines are not stored in from history
           if (strlen(line)) 
           {
-               // if history too long : delete oldest command
-               if (mHistory.size()>MAX_HISTORY_SIZE) 
-                 {
-                   delete mHistory.front();
-                   mHistory.pop_front();
-                 }
-               mHistory.push_back(line);
+             // if history too long : delete oldest command
+             if (mHistory.size()>MAX_HISTORY_SIZE) 
+             {
+                delete mHistory.front();
+                mHistory.pop_front();
+             }
+             mHistory.push_back(line);
           }
-    
           break;
         }
-       // Backspace
-       else if ( (ind>0) && 
+       // Backspace
+        else if ( (ind>0) && 
                  ((c == BBTK_BACKSPACE_KBCODE) ||
                   (c == BBTK_DEL_KBCODE)) )
          {
@@ -1291,13 +1361,13 @@ void Interpreter::Help(const std::vector<std::string>& words)
            PrintChar(line[ind]);
            ind++;
          }
-       
+
        // Arrow left
        else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
          {
            PrintChar('\b');
            ind--;
-           
+    
          }
 
       }
index 52ec57496f1c5131332ceefb147df20a14dfbe1e..732e8f725144e0aff6683f102b7749b1c337729f 100644 (file)
@@ -1,19 +1,19 @@
 /*=========================================================================
-                                                                                
+
   Program:   bbtk
   Module:    $RCSfile: bbtkInterpreter.h,v $ $
   Language:  C++
-  Date:      $Date: 2008/01/28 15:08:53 $
-  Version:   $Revision: 1.4 $
-                                                                                
+  Date:      $Date: 2008/01/29 10:12:45 $
+  Version:   $Revision: 1.5 $
+
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See Doc/License.txt or
   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
-                                                                                
+
      This software is distributed WITHOUT ANY WARRANTY; without even
      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
      PURPOSE.  See the above copyright notices for more information.
-                                                                                
+
 =========================================================================*/
 /**
  *  \file 
@@ -23,7 +23,7 @@
  *  \class bbtk::Interpreter 
  *  \brief The bbtk language interpreter
  */
-  
+
 #ifndef __bbtkInterpreter_h__
 #define __bbtkInterpreter_h__
 
@@ -40,11 +40,11 @@ namespace bbtk
   {
 
   private:
-    
+
     /// The enumeration of command codes == Command name
-    typedef enum 
+    typedef enum
     {
-      cNew, 
+      cNew,
       cDelete,
       cConnect,
       cExec,
@@ -67,7 +67,7 @@ namespace bbtk
       cUnload,
       cGraph,
       cPrint,
-      cWorkspace // LG 
+      cWorkspace // LG
     } CommandCodeType;
 
     /// The structure storing the informations on a command 
@@ -86,25 +86,25 @@ namespace bbtk
   public:
     /// Constructor
     Interpreter();
+
     /// Destructor
     ~Interpreter();
-      
+
    static Interpreter* mGlobalInterpreter;
 
     /// Launches a command line interpreter (with a prompt)
     void CommandLineInterpreter();
-    
-    /// Sets the inputs of the workspace : 
+
+    /// Sets the inputs of the workspace :
     /// the map is passed as is to the Executer
     void SetInputs(const std::map<std::string,std::string>& m)
     { mExecuter->SetInputs(m); }
-    /// Puts the executer in "no exec" mode, 
+
+    /// Puts the executer in "no exec" mode,
     /// which creates but does not execute pipelines.
     void SetNoExecMode(bool b) { mExecuter->SetNoExecMode(b); }
 
-    /// 
+    ///
     //typedef Executer::DialogModeType DialogModeType;
     typedef VirtualExec::DialogModeType DialogModeType;
 
@@ -123,31 +123,31 @@ namespace bbtk
     void SplitLine ( const std::string& line,
                      std::vector<std::string>& words );
 
-    /// Executes the right action depending on the command name  
-    void InterpretCommand( const std::vector<std::string>& words, 
+    /// Executes the right action depending on the command name
+    void InterpretCommand( const std::vector<std::string>& words,
                            CommandInfoType& info );
-    
+
     /// Switch to the interpretation of a file
     void SwitchToFile( const std::string& filename, bool use_configuration_file=true, bool verbose=false );
-    
+
     /// Closes the currently open file
     void CloseCurrentFile();
-    
+
     /// Closes all open files
     void CloseAllFiles();
 
     /// Displays help (entry point of any help)
     void Help(const std::vector<std::string>& words);
-    
+
     /// Displays help on all the commands
     void HelpCommands();
-    
+
     /// Displays help on a particular command 
     void HelpCommand( const std::string& command );
-    
+
     ///
     void Graph(const std::vector<std::string>& words);
-    
+
     ///
     void Config(bool verbose) const; // JPR
     /// 
@@ -161,7 +161,9 @@ namespace bbtk
     /// Sets the bool that indicates wether we are in command line context
     void SetCommandLine(bool v = true) { mCommandLine = v; }
 
-  private: 
+  private:
+
+  void LoadScript( std::string fullPathScriptName);
 
   private:
 
index 0a184b756c39a1c1028717c8d33de88829df9662..da5bba8df4ccb44e2e518f5a64980d349d738ee8 100644 (file)
@@ -3,8 +3,8 @@
   Program:   bbtk
   Module:    $RCSfile: bbtkUtilities.h,v $
   Language:  C++
-  Date:      $Date: 2008/01/28 15:08:53 $
-  Version:   $Revision: 1.5 $
+  Date:      $Date: 2008/01/29 10:12:45 $
+  Version:   $Revision: 1.6 $
                                                                                 
   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
   l'Image). All rights reserved. See doc/license.txt or
@@ -26,7 +26,7 @@
  * \class bbtk::Utilities
  * \brief various usefull methods 
  */
+
 #ifndef __bbtkUtilities_h_INCLUDED__
 #define __bbtkUtilities_h_INCLUDED__
 
 #define BBTK_USE_TERMIOS_BASED_PROMPT
 #endif
 
+#ifdef _MSC_VER
+   #include <windows.h> 
+   #include <direct.h>
+#else
+   #include <dirent.h>   
+   #include <sys/types.h>
+#endif
+
 //#include "bbtkMessageManager.h"
 
 namespace bbtk
@@ -46,10 +54,9 @@ namespace bbtk
   /// Holds various usefull methods 
   struct BBTK_EXPORT Utilities
   {
-  
 
 // ===================================================================================
+
    // See : http://www.techbytes.ca/techbyte103.html for more O.S.
    static inline bool FileExists(std::string strFilename) 
    {
@@ -137,13 +144,15 @@ namespace bbtk
 
 // ===================================================================================
 
-  static std::string ExtractScriptName(const std::string  &name)
+  static std::string ExtractScriptName(const std::string &name,
+                                         std::string& path)
   {
     std::string pkgname;
 
     std::string::size_type slash_position = name.find_last_of("/\\");
     if (slash_position != std::string::npos) {
       pkgname =name.substr(slash_position+1,std::string::npos);
+         path = name.substr(0,slash_position);      
     } else {
       pkgname = name;
     }
@@ -279,35 +288,59 @@ namespace bbtk
 
 // ===================================================================================
 
-  static inline std::string MakePkgnameFromPath(std::string path, std::string pkgname)
+  static inline std::string MakePkgnameFromPath(std::string path, std::string pkgname, bool addExt)
   {
     std::string libname = path;
-         char c = path[path.size()-1];
-         if (c != '/' && c != '\\')
-            libname +=  ConfigurationFile::GetInstance().Get_file_separator ();
-         libname += pkgname;
-    int l = libname.size();
-      if (l>4) 
-      {       
-         if (libname.substr(l-4, 4) != ".bbs")
-         {
-            libname = libname + ".bbs";    
-         }
-}
+    char c = path[path.size()-1];
+    if (c != '/' && c != '\\')
+    {
+       libname +=  ConfigurationFile::GetInstance().Get_file_separator ();
+    }
+    libname += pkgname;
+    if (addExt)
+    {
+       int l = libname.size();
+       if (l>4)
+       {
+          if (libname.substr(l-4, 4) != ".bbs")
+          {
+               libname = libname + ".bbs";
+          }
+       }
+    }
     return libname;
   }
 
 // ===================================================================================
 
  static inline  bool IsAtRoot(std::string cwd)
 {
+ {
     if ( cwd == "/"                             // hope it gets /     (for Linux)
         || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
       return (true);
     else
       return(false);
-}
+ }
 
+// ===================================================================================
+
+static bool IsDirectory(std::string const &dirName)
+{
+   struct stat fs;
+
+   if ( stat(dirName.c_str(), &fs) == 0 )
+   {
+#if _WIN32
+      return ((fs.st_mode & _S_IFDIR) != 0);
+#else
+      return S_ISDIR(fs.st_mode);
+#endif
+   }
+   else
+   {
+      return false;
+   }
+}
 
 // ===================================================================================
 
@@ -345,7 +378,114 @@ namespace bbtk
         return s;
       }
     }
+    
+// ===================================================================================
+/**
+ * \brief   Explore a directory with possibility of recursion
+ *          return number of files read
+ * @param  dirpath   directory to explore
+ * @param  recursive whether we want recursion or not
+ */
+static int Explore(std::string const &dirpath, bool recursive, std::vector<std::string> &Filenames)
+{
+   int numberOfFiles = 0;
+   std::string fileName;
+   
+   std::string dirName = dirpath;
+   
+#ifdef _MSC_VER
+   WIN32_FIND_DATA fileData;
+   HANDLE hFile = FindFirstFile((dirName+"*").c_str(), &fileData);
+
+   for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
+       b = FindNextFile(hFile, &fileData))
+   {
+      fileName = fileData.cFileName;
+      if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+      {
+         // Need to check for . and .. to avoid infinite loop
+         if ( fileName != "." && fileName != ".." && recursive )
+         {
+            numberOfFiles += Explore(dirName+ "\\"+fileName,recursive,Filenames);
+         }
+      }
+      else
+      {
+         Filenames.push_back(dirName+fileName);
+         numberOfFiles++;
+      }
+   }
+   DWORD dwError = GetLastError();
+   if (hFile != INVALID_HANDLE_VALUE) 
+      FindClose(hFile);
+   if (dwError != ERROR_NO_MORE_FILES) 
+   {
+      LPVOID lpMsgBuf;
+      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
+                    FORMAT_MESSAGE_FROM_SYSTEM|
+                    FORMAT_MESSAGE_IGNORE_INSERTS,
+                    NULL,GetLastError(),
+                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+                    (LPTSTR) &lpMsgBuf,0,NULL);
+
+     // ErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
+     //             <<" for the directory : "<<dirName);
+      
+      return 0;
+   }
 
+#else
+  // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
+  // work on debian for example
+//std::cout <<"in Explor dirname[" << dirName << "]" << std::endl; 
+   DIR* dir = opendir(dirName.c_str());
+   if (!dir)
+   {
+      return 0;
+   }
+//std::cout <<"Open OK" << std::endl; 
+   // According to POSIX, the dirent structure contains a field char d_name[]
+   // of unspecified size, with at most NAME_MAX characters preceeding the
+   // terminating null character. Use of other fields will harm the  porta-
+   // bility of your programs.
+
+   struct stat buf;
+   dirent *d;
+   for (d = readdir(dir); d; d = readdir(dir))
+   {
+      fileName = dirName + "/" + d->d_name;
+//std::cout <<"in Explor filename[" << fileName << "]" << std::endl;      
+      if( stat(fileName.c_str(), &buf) != 0 )
+      {
+         //ErrorMacro( strerror(errno) );
+      }
+      if ( S_ISREG(buf.st_mode) )    //is it a regular file?
+      {
+         Filenames.push_back( fileName );
+         numberOfFiles++;
+      }
+      else if ( S_ISDIR(buf.st_mode) ) //directory?
+      {
+         if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
+         {
+            numberOfFiles += Explore( fileName, recursive, Filenames);
+         }
+      }
+      else
+      {
+         //ErrorMacro( "Unexpected error" );
+         return -1;
+      }
+   }
+   if( closedir(dir) != 0 )
+   {
+     // ErrorMacro( strerror(errno) );
+   }
+#endif
+
+  return numberOfFiles;
+
+}
 
   //========================================================================
   // Usefull functions for html generation