From cadbc7f9439327013dfbefa9415ad7c8680fb351 Mon Sep 17 00:00:00 2001 From: jean-pierre roux Date: Tue, 29 Jan 2008 10:12:45 +0000 Subject: [PATCH] We can now use absolute/realtive path for scripts, as well as the '* notation' e.g. std/boxes/* --- kernel/src/bbtkFactory.cxx | 12 +- kernel/src/bbtkInterpreter.cxx | 206 ++++++++++++++++++++++----------- kernel/src/bbtkInterpreter.h | 58 +++++----- kernel/src/bbtkUtilities.h | 182 +++++++++++++++++++++++++---- 4 files changed, 338 insertions(+), 120 deletions(-) diff --git a/kernel/src/bbtkFactory.cxx b/kernel/src/bbtkFactory.cxx index 2a633d3..61b7e32 100644 --- a/kernel/src/bbtkFactory.cxx +++ b/kernel/src/bbtkFactory.cxx @@ -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! ["<& // - 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( \"" < script_paths; - std::string libname; // full path library name - std::string pkgname; // e.g. .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. .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 paths = - ConfigurationFile::GetInstance().Get_bbs_paths(); - std::vector::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::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 << "]" < Filenames; + int nbFiles = Utilities::Explore(fullDirectoryName, false, Filenames); +// std::cout << "=================nbFiles " << nbFiles << std::endl; + int nbBssFiles = 0; + for (std::vector::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::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 <<" [" <open(libname.c_str()); + s->open(fullPathScriptName.c_str()); if (!s->good()) { - bbtkError("Could not open file ["<[" << 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& 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& words) PrintChar(line[ind]); ind++; } - + // Arrow left else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE) { PrintChar('\b'); ind--; - + } } diff --git a/kernel/src/bbtkInterpreter.h b/kernel/src/bbtkInterpreter.h index 52ec574..732e8f7 100644 --- a/kernel/src/bbtkInterpreter.h +++ b/kernel/src/bbtkInterpreter.h @@ -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& 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& words ); - /// Executes the right action depending on the command name - void InterpretCommand( const std::vector& words, + /// Executes the right action depending on the command name + void InterpretCommand( const std::vector& 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& 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& 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: diff --git a/kernel/src/bbtkUtilities.h b/kernel/src/bbtkUtilities.h index 0a184b7..da5bba8 100644 --- a/kernel/src/bbtkUtilities.h +++ b/kernel/src/bbtkUtilities.h @@ -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__ @@ -39,6 +39,14 @@ #define BBTK_USE_TERMIOS_BASED_PROMPT #endif +#ifdef _MSC_VER + #include + #include +#else + #include + #include +#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 &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 : "<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 -- 2.45.1