X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=kernel%2Fsrc%2FbbtkInterpreter.cxx;h=09954ef4fe723b386243bcfb143ffb6a9b9a7211;hb=d73a7833a28e6111e1e805efae5df3ab18a240e2;hp=f500e92fde9d125becaecee6a8ccbe9203c41779;hpb=a26195c366a89795288009cf7e20f11afa494970;p=bbtk.git diff --git a/kernel/src/bbtkInterpreter.cxx b/kernel/src/bbtkInterpreter.cxx index f500e92..09954ef 100644 --- a/kernel/src/bbtkInterpreter.cxx +++ b/kernel/src/bbtkInterpreter.cxx @@ -3,13 +3,13 @@ Program: bbtk Module: $RCSfile: bbtkInterpreter.cxx,v $ $ Language: C++ - Date: $Date: 2008/01/22 15:02:00 $ - Version: $Revision: 1.1 $ + Date: $Date: 2008/02/05 11:39:32 $ + Version: $Revision: 1.23 $ 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. @@ -31,27 +31,25 @@ #define BBTK_USE_TERMIOS_BASED_PROMPT #endif +#include namespace bbtk { Interpreter* Interpreter::mGlobalInterpreter = NULL; - - //======================================================================= /** * */ Interpreter::Interpreter() : - mCommandLine(false), verbose(false) + mCommandLine(false) { bbtk::MessageManager::RegisterMessageType("Echo","Level>0 : Prints the 'echo' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1); bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0); bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <0) { @@ -327,7 +356,7 @@ Interpreter* Interpreter::mGlobalInterpreter = NULL; std::cout << "* LINE : "< words; SplitLine(line,words); - + // Empty line if (words.size()<1) { @@ -394,155 +423,174 @@ void Interpreter::InterpretLine( const std::string& line, bool &insideComment ) bbtkMessage("Interpreter",9,"Multiline Comment"<Define(words[1],words[2],filename); - } - break; + if (mFileName.size()>0) + { + filename = Utilities::get_file_name(mFileName.back()); + } + if (words.size()==2) + { + mExecuter->Define(words[1],"",filename); + } + else + { + mExecuter->Define(words[1],words[2],filename); + } + break; case cEndDefine : - mExecuter->EndDefine(); - break; + mExecuter->EndDefine(); + break; case cPrint : - Print(words[1]); - break; + Print(words[1]); /// \todo use mExecuter + break; case cExec : - if (words[1]=="freeze") mExecuter->SetNoExecMode(true); - else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false); - else mExecuter->Update(words[1]); - break; + if (words[1]=="freeze") + mExecuter->SetNoExecMode(true); + else if (words[1]=="unfreeze") + mExecuter->SetNoExecMode(false); + else + mExecuter->Update(words[1]); + break; case cInput : - SplitAroundFirstDot(words[2],left,right); - mExecuter->DefineInput(words[1],left,right,words[3]); - break; + Utilities::SplitAroundFirstDot(words[2],left,right); + mExecuter->DefineInput(words[1],left,right,words[3]); + break; case cOutput : - SplitAroundFirstDot(words[2],left,right); - mExecuter->DefineOutput(words[1],left,right,words[3]); - break; + Utilities::SplitAroundFirstDot(words[2],left,right); + mExecuter->DefineOutput(words[1],left,right,words[3]); + break; case cSet : - SplitAroundFirstDot(words[1],left,right); - mExecuter->Set(left,right,words[2]); - break; + Utilities::SplitAroundFirstDot(words[1],left,right); + mExecuter->Set(left,right,words[2]); + break; case cAuthor : - mExecuter->Author(words[1]); - break; - - case cDescription : - mExecuter->Description(words[1]); - break; + mExecuter->Author(words[1]); + break; + + case cKeyword : + mExecuter->Keyword(words[1]); + break; + + case cIndex : + if (words.size()==1) + Index("tmp_index.html"); + else if (words.size()==2) + Index(words[1]); + else if (words.size()==3) + Index(words[1],words[2]); + break; + case cDescription : + mExecuter->Description(words[1]); + break; case cHelp : - Help(words); - break; + Help(words); + break; case cMessage : - if (words.size()<3) - { + if (words.size()<3) + { bbtk::MessageManager::PrintInfo(); - } - else - { - sscanf(words[2].c_str(),"%d",&level); - bbtk::MessageManager::SetMessageLevel(words[1],level); - } - break; + } + else + { + sscanf(words[2].c_str(),"%d",&level); + bbtk::MessageManager::SetMessageLevel(words[1],level); + } + break; case cGraph : - Graph(words); - break; + Graph(words); + break; case cConfig : - if (words.size()>1) // any param for config means verbose = true - verbose = true; - else - verbose = false; - Config(verbose); - break; + Config(); + break; case cReset : // EED - this->mExecuter->Reset(); - break; + this->mExecuter->Reset(); + break; case cInclude : - if (mCommandLine) - { - InterpretFile(words[1], true, verbose); // true : better pass use_config_file - } - else - { - SwitchToFile(words[1], true, verbose); // true : better pass use_config_file - } - break; + if (mCommandLine) + { + InterpretFile(words[1], true ); // true : better pass use_config_file + } + else + { + SwitchToFile(words[1], true ); // true : better pass use_config_file + } + break; case cLoad: - LoadPackage(words[1], true, verbose); // true : better pass use_config_file - break; + LoadPackage(words[1], true ); // true : better pass use_config_file + break; case cUnload: - UnLoadPackage(words[1]); - break; + UnLoadPackage(words[1]); + break; case cQuit : - throw QuitException(); - break; + throw QuitException(); + break; - case cWorkspace : - if (words.size() == 2) - { - if (words[1]=="freeze") mExecuter->SetNoExecMode(true); - else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false); - } - else - { - mExecuter->SetWorkspaceName(words[2]); - } - break; + case cWorkspace : + if (words.size() == 2) + { + if (words[1]=="freeze") mExecuter->SetNoExecMode(true); + else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false); + } + else + { + mExecuter->SetWorkspaceName(words[2]); + } + break; default: - bbtkInternalError("should not reach here !!!"); + bbtkInternalError("should not reach here !!!"); } bbtkDecTab("Interpreter",9); @@ -551,28 +599,6 @@ void Interpreter::InterpretLine( const std::string& line, bool &insideComment ) - //======================================================================= - void SplitString ( const std::string& str, const std::string& delimiters, - std::vector& tokens) - { - // Skip delimiters at beginning. - std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); - // Find first delimiter. - std::string::size_type pos = str.find_first_of(delimiters, lastPos); - - while (std::string::npos != pos || std::string::npos != lastPos) - { - // Found a token, add it to the vector. - tokens.push_back(str.substr(lastPos, pos - lastPos)); - // Skip delimiters. Note the "not_of" - lastPos = str.find_first_not_of(delimiters, pos); - // Find next delimiter - pos = str.find_first_of(delimiters, lastPos); - } - - } - //======================================================================= - //======================================================================= @@ -585,13 +611,13 @@ void Interpreter::SplitLine ( const std::string& str, std::vector& std::string delimiters = "\""; std::vector quote; - SplitString(str,delimiters,quote); + Utilities::SplitString(str,delimiters,quote); delimiters = " \t"; std::vector::iterator i; for (i=quote.begin(); i!=quote.end(); ) { - SplitString(*i,delimiters,tokens); + Utilities::SplitString(*i,delimiters,tokens); ++i; if (i!=quote.end()) { @@ -616,18 +642,15 @@ void Interpreter::SplitLine ( const std::string& str, std::vector& // Replaces substrings "\\n" by a real carriage return "\n" void SubsBackslashN ( std::string& s ) { - // std::cout << "BEFORE=["<& bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""< chains; std::string delimiters("$"); @@ -660,16 +682,14 @@ void Interpreter::SplitLine ( const std::string& str, std::vector& { // Found a text token, add it to the vector. chains.push_back(str.substr(lastPos, pos - lastPos)); - // std::cout << "text='"<Get(box,output) ); - // std::cout << "outp='"<& // is_text = !is_text; } - // std::cout << "nb="<::iterator i; for (i= chains.begin(); i!=chains.end(); ++i) { @@ -695,270 +714,250 @@ void Interpreter::SplitLine ( const std::string& str, std::vector& * */ - -// --> usefull in many places (at least : ConfigurationFile, Factory, Interpreter) -// should be factorized ( "bbtk::Util class ?) -/* -bool Interpreter::FileExists(std::string strFilename) -bool Interpreter::IsAtRoot(std::string cwd) -std::string Interpreter::ExtractPackageName(const std::string &name) -std::string Interpreter::ExpandLibName(const std::string &name, bool verbose) -std::string Interpreter::MakeLibnameFromPath(std::string path, std::string pkgname) -*/ -// =================================================================================== - -// See : http://www.techbytes.ca/techbyte103.html for more O.S. -bool Interpreter::FileExists(std::string strFilename) { - struct stat stFileInfo; - bool blnReturn; - int intStat; - - // Attempt to get the file attributes - intStat = stat(strFilename.c_str(),&stFileInfo); - if(intStat == 0) { - // We were able to get the file attributes - // so the file obviously exists. - blnReturn = true; - } else { - // We were not able to get the file attributes. - // This may mean that we don't have permission to - // access the folder which contains this file. If you - // need to do that level of checking, lookup the - // return values of stat which will give you - // more details on why stat failed. - blnReturn = false; - } - - return(blnReturn); -} - // =================================================================================== - std::string Interpreter::ExtractScriptName(const std::string &name) + void Interpreter::SwitchToFile( const std::string& name, + bool use_configuration_file ) { - 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); - } else { - pkgname = name; - } - - // remove {.bbs } if any - std::string::size_type dot_position = pkgname.find_last_of('.'); - if (dot_position != std::string::npos){ - pkgname = pkgname.substr(0,dot_position); - } - return pkgname; - } + // Note : in the following : + // name : the user supplied name + // - abreviated name e.g. scr scr.bbs + // - relative full name e.g. ./scr.bbs ../../scr.bbs + // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs + // same for Windows, with c:, d: ... + // + // use ./directory/subdir/scrname.bbs + // -// =================================================================================== + bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \"" + < script_paths; + std::string fullPathScriptName; // full path script name + std::string pkgname; // e.g. .bbs + std::vector Filenames; + + if (use_configuration_file) + { + // The following is *NOT* a debug time message : + // It's a user intended message. + // Please don't remove it. + bbtkMessage("Interpreter",1, + "look for : [" << name + << "] (use_configuration_file == TRUE)" << std::endl); + script_paths = ConfigurationFile::GetInstance().Get_bbs_paths(); + } + std::string upath; + pkgname = Utilities::ExtractScriptName(name,upath); - char buf[2048]; // for getcwd - char * currentDir = getcwd(buf, 2048); - std::string cwd(currentDir); - std::string libname(name); - - // tooHigh : true is user supplies a library pathname with too many "../" - bool tooHigh = false; + bool fullnameGiven = false; + bool foundFile = false; - if ( name[0] == '/' || name[0] == '\\' ) + if(pkgname == "*") // =========================================== load all boxes (e.g. std/boxes/*) { - return(libname); - } - else if (name[0] == '.' && (name[1] == '/' || name[1] == '\\') ) - { - libname = cwd + ConfigurationFile::GetInstance().Get_file_separator () + name.substr(2, name.length()); - return(libname); - } - else if ( name[0] == '.' && name[1] == '.' && (name[2] == '/' || name[2] == '\\') ) - { - if ( IsAtRoot(cwd) ) // hope it gets / (for Linux), C: D: (for Windows) - { - // if we are already at / or c: --> hopeless - if (verbose) - std::cout << " File path [" << name << "] doesn't exist" << std::endl; - tooHigh = true; - } - else + int nbBssFiles; + + if (upath[0]=='/' || upath[1] == ':' ) // ==== absolute name, load all .bbs files { - // iterate on ../ and go up from the current working dir! - std::string a(name); - bool alreadyProcessRoot = false; - for(;;) - { - std::string::size_type slash_position = cwd.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ()); - if (slash_position != std::string::npos) { - if (slash_position == 0) - slash_position = 1; - cwd = cwd.substr(0,slash_position/*+1*/); - a = a.substr(3, name.length()); // remove ../ - if (a == "" || alreadyProcessRoot) - { - if (verbose) - std::cout << " File path [" << name << "] doesn't exist" << std::endl; - tooHigh = true; - break; - } - // std::string b = cwd + a; - libname = cwd; - char c = cwd[cwd.size()-1]; - if (c != '/' && c != '\\' ) - libname += ConfigurationFile::GetInstance().Get_file_separator (); - libname += a; - - if ( a[0] != '.' ) // if . (probabely ../), loop again - break; - - if (IsAtRoot(cwd)) - alreadyProcessRoot = true; - } - } // end iterating on ../ + int nbFiles = Utilities::Explore(upath, false, Filenames); + 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) + bbtkMessage("Interpreter",2, + "WARNING : No '.bbs' file found in [" + << upath << "]" << std::endl); + + return; } - if (tooHigh) - libname=""; - return (libname); - } // ----- End of expanding path name ( ./ ../ ../../ ) - - // To avoid warning - return(""); // Will never get here! - } - -// =================================================================================== + std::string path; + std::vector::iterator i; + std::string fullDirectoryName; + for (i=script_paths.begin();i!=script_paths.end();++i)// ==== relative name, iterate + load all .bbs files + { + path = *i; - std::string Interpreter::MakeLibnameFromPath(std::string path, std::string pkgname) - { - std::string libname = path; - char c = path[path.size()-1]; - if (c != '/' && c != '\\') - libname += ConfigurationFile::GetInstance().Get_file_separator (); - libname += pkgname; - libname += ".bbs"; - return libname; - } - -// =================================================================================== + // 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; + } - bool Interpreter::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); -} + fullDirectoryName = Utilities::MakePkgnameFromPath(path, upath, false); - -// =================================================================================== + // 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. + bbtkMessage("Interpreter",1," [" < script_paths; - std::string libname; // full path library name - std::string pkgname; // e.g. .bbs - - pkgname = ExtractScriptName(name); + nbBssFiles = 0; + for (std::vector::iterator i = Filenames.begin(); i!= Filenames.end(); ++i) + { - if (use_configuration_file) - { - if (verbose) - std::cout << "look for : [" << name << "] (use_configuration_file == TRUE)" << std::endl; - script_paths = ConfigurationFile::GetInstance().Get_bbs_paths(); + if ((*i).substr((*i).size()-4, 4) != ".bbs") + continue; // ignore non .bbs files + LoadScript(*i); + nbBssFiles++; + } + if (nbBssFiles==0) + bbtkMessage("Interpreter",1, + "WARNING : No '.bbs' file found in [" + << fullDirectoryName << "]" << std::endl); + + //break; // a directory was found; we stop iterating + // LG : No! We want all files included ! + } + return; } - bool fullnameGiven = false; - bool foundFile = false; - std::string::size_type slash_position = name.find_last_of("/\\"); - - if (slash_position != std::string::npos) - { - fullnameGiven = true; - libname = ExpandLibName(name, verbose); - if (libname != "") { - if (FileExists(libname)) + //std::string::size_type slash_position = name.find_last_of("/\\"); + + // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name + // (not only a plain script name) + // we trust him, and try to expland the directory name + // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!) + + if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path + { + + // ===========================================================check user supplied location + fullnameGiven = true; + + + fullPathScriptName = Utilities::ExpandLibName(name, false); + + // allow user to always forget ".bbs" + int l = fullPathScriptName.size(); + + if (l!=0) { + + if (l>4) + { + if (fullPathScriptName.substr(l-4, 4) != ".bbs") + { + fullPathScriptName = fullPathScriptName + ".bbs"; + } + } + else + { + fullPathScriptName = fullPathScriptName + ".bbs"; + } + + if ( Utilities::FileExists(fullPathScriptName)) { foundFile = true; } - } + } // endif l != 0 } - else // ----------------------- iterate on the paths - { - std::string path; + else + + // =============================================================== iterate on the paths + { + std::string path; std::vector::iterator i; for (i=script_paths.begin();i!=script_paths.end();++i) { - path = *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); + std::string cwd(currentDir); path = currentDir; } - libname = MakeLibnameFromPath(path, pkgname); + // fullPathScriptName = Utilities::MakePkgnameFromPath(path, name, true); //pkgname); - // Check if library exists - if ( !FileExists(libname) ) + fullPathScriptName = Utilities::MakePkgnameFromPath(path, name, true); + + + // Check if library exists + if ( ! Utilities::FileExists(fullPathScriptName) ) { - 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; + + bbtkMessage("Interpreter",1," -->[" << fullPathScriptName + << "] found" << std::endl); mFile.push_back(s); - mFileName.push_back(libname); + mFileName.push_back(fullPathScriptName); mLine.push_back(0); - } - - - //======================================================================= - + return; + } //======================================================================= /** @@ -1126,7 +1125,7 @@ void Interpreter::Help(const std::vector& words) //=================================================================== /// Displays the Configuration - void Interpreter::Config( bool verbose ) const + void Interpreter::Config() const { bbtkDebugMessageInc("Core",9,"Factory::Config"<& 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)) ) { @@ -1394,13 +1392,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--; - + } } @@ -1469,7 +1467,7 @@ void Interpreter::Help(const std::vector& words) bool insideComment = false; // for multiline comment do { - try + try { std::string line; GetLineFromPrompt(line); @@ -1485,7 +1483,7 @@ void Interpreter::Help(const std::vector& words) } catch (std::exception& e) { - std::cerr << "* ERROR : "<& words) bbtkDebugDecTab("Interpreter",9); } - //======================================================================= - - - //======================================================================= - void Interpreter::SplitAroundFirstDot( const std::string& in, - std::string& left, - std::string& right) - { - bbtkDebugMessageInc("Interpreter",9, - "Interpreter::SplitAroundFirstDot(\"" - <& words) - { - std::string page; +//======================================================================= +void Interpreter::Graph(const std::vector& words) +{ + std::string page; bool system_display = true; #ifdef _USE_WXWIDGETS_ @@ -1569,18 +1536,31 @@ void Interpreter::Help(const std::vector& words) page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display); } else if (words.size()==7) - { - page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display); - } - + { + page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display); + } + #ifdef _USE_WXWIDGETS_ if ( WxConsole::GetInstance() != 0 ) WxConsole::GetInstance()->ShowHtmlPage(page); #endif } - //======================================================================= +//======================================================================= +//======================================================================= +void Interpreter::Index(const std::string& filename, + const std::string& type) +{ + Factory::IndexEntryType t; + if (type=="Initials") t = Factory::Initials; + else if (type=="Categories") t = Factory::Categories; + else if (type=="Packages") t = Factory::Packages; + + GetGlobalFactory()->CreateHtmlIndex(t,filename); +} +//======================================================================= + }//namespace