Program: bbtk
Module: $RCSfile: bbtkInterpreter.cxx,v $ $
Language: C++
- Date: $Date: 2008/01/22 15:02:00 $
- Version: $Revision: 1.1 $
+ Date: $Date: 2008/01/28 15:08:53 $
+ 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
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.
#define BBTK_USE_TERMIOS_BASED_PROMPT
#endif
+#include <string>
namespace bbtk
{
Interpreter* Interpreter::mGlobalInterpreter = NULL;
-
-
//=======================================================================
/**
*
bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
-
mGlobalInterpreter = this;
// mFactory = new bbtk::Factory();
info.help = "Executes the black box of name <box> (and connected boxes if needed). If the special keyword 'freeze' is given then freezes any further execution command. 'unfreeze' reverts to normal execution mode.";
mCommandDict[info.keyword] = info;
+ info.keyword = "package";
+ info.argmin = 1;
+ info.argmax = 1;
+ info.code = cPackage;
+ info.syntax = "package <name>";
+ info.help = "Begins the definition of a package.";
+ mCommandDict[info.keyword] = info;
+
+ info.keyword = "endpackage";
+ info.argmin = 0;
+ info.argmax = 0;
+ info.code = cEndPackage;
+ info.syntax = "endpackage";
+ info.help = "Ends the definition of a package.";
+ mCommandDict[info.keyword] = info;
+
info.keyword = "define";
info.argmin = 1;
info.argmax = 2;
std::cout << "* LINE : "<<mLine.back()<<std::endl;
}
}
-
+
CloseAllFiles();
bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
bbtkDecTab("Interpreter",9);
std::vector<std::string> words;
SplitLine(line,words);
-
+
// Empty line
if (words.size()<1)
{
bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
return;
}
-
+
// Command
CommandInfoType command;
InterpretCommand(words,command);
bbtkDebugMessage("Interpreter",9,
- "Command '"<<command.keyword
- <<" code="<<command.code<<std::endl);
+ "Command='"<<command.keyword
+ <<"' code="<<command.code<<std::endl);
int level=0;
std::string left,right,left2,right2;
std::string filename;
switch (command.code)
{
case cNew :
- mExecuter->Create(words[1],words[2]);
- break;
+ mExecuter->Create(words[1],words[2]);
+ break;
case cDelete :
- // TO DO !!
- // mExecuter->Remove(words[1]);
- break;
+ // TO DO !!
+ // mExecuter->Remove(words[1]);
+ break;
case cConnect :
- SplitAroundFirstDot(words[1],left,right);
- SplitAroundFirstDot(words[2],left2,right2);
- mExecuter->Connect(left,right,left2,right2);
- break;
+ Utilities::SplitAroundFirstDot(words[1],left,right);
+ Utilities::SplitAroundFirstDot(words[2],left2,right2);
+ mExecuter->Connect(left,right,left2,right2);
+ break;
+
+ case cPackage :
+ mExecuter->BeginPackage(words[1]);
+ break;
+
+ case cEndPackage :
+ mExecuter->EndPackage();
+ break;
case cDefine :
- if (mFileName.size()>0)
- {
- filename = Utilities::get_file_name(mFileName.back());
- }
- if (words.size()==2)
- {
- mExecuter->Define(words[1],"user",filename);
- }
- else
- {
- mExecuter->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;
+ mExecuter->Author(words[1]);
+ break;
case cDescription :
- mExecuter->Description(words[1]);
- break;
+ 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;
+ if (words.size()>1) // any param for config means verbose = true
+ verbose = true;
+ else
+ verbose = false;
+ Config(verbose);
+ break;
case cReset : // EED
- this->mExecuter->Reset();
- break;
+ this->mExecuter->Reset();
+ break;
case cInclude :
- if (mCommandLine)
- {
+ if (mCommandLine)
+ {
InterpretFile(words[1], true, verbose); // true : better pass use_config_file
- }
- else
- {
+ }
+ else
+ {
SwitchToFile(words[1], true, verbose); // true : better pass use_config_file
- }
- break;
+ }
+ break;
case cLoad:
- LoadPackage(words[1], true, verbose); // true : better pass use_config_file
- break;
+ LoadPackage(words[1], true, verbose); // 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);
bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
-
std::vector<std::string> chains;
std::string delimiters("$");
// is an output (between $$) : decode
std::string tok,box,output;
tok = str.substr(lastPos, pos - lastPos);
- SplitAroundFirstDot(tok,box,output);
+ Utilities::SplitAroundFirstDot(tok,box,output);
chains.push_back( mExecuter->Get(box,output) );
// std::cout << "outp='"<<chains.back()<<"'"<<std::endl;
}
*
*/
-
-// --> 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)
- {
- 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;
- }
-
-// ===================================================================================
-
- std::string Interpreter::ExpandLibName(const std::string &name, bool verbose)
- {
- // ----- Think of expanding path name ( ./ ../ ../../ )
-
- 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;
-
- if ( name[0] == '/' || name[0] == '\\' )
- {
- 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
- {
- // 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 ../
- }
- if (tooHigh)
- libname="";
- return (libname);
-
- } // ----- End of expanding path name ( ./ ../ ../../ )
-
- // To avoid warning
- return(""); // Will never get here!
- }
-
-
-// ===================================================================================
-
- 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;
- }
-
-// ===================================================================================
-
- 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);
-}
-
-
-// ===================================================================================
-
void Interpreter::SwitchToFile( const std::string& name,
bool use_configuration_file, bool verbose)
{
+ // 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: ...
+ //
bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
<<name<<"\")"<<std::endl);
-
+verbose = true;
std::vector<std::string> script_paths;
std::string libname; // full path library name
std::string pkgname; // e.g. <scriptname>.bbs
- pkgname = ExtractScriptName(name);
-
+ pkgname = Utilities::ExtractScriptName(name);
if (use_configuration_file)
{
if (verbose)
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 (false) //slash_position != std::string::npos)
+ { // ------------------------------------- check user supplied location
+ fullnameGiven = true;
+ libname = Utilities::ExpandLibName(name, verbose);
+
+ // allow user to always forget ".bbs"
+ int l = libname.size();
+ if (l>4)
+ {
+ if (libname.substr(l-4, 4) != ".bbs")
+ {
+ libname = libname + ".bbs";
+ }
+ }
+ else
+ {
+ libname = libname + ".bbs";
+ }
+
if (libname != "") {
- if (FileExists(libname))
+ if ( Utilities::FileExists(libname))
{
foundFile = true;
}
}
}
- else // ----------------------- iterate on the paths
+ else // ------------------------------------- iterate on the paths
{
- std::string path;
+ std::string path;
std::vector<std::string>::iterator i;
for (i=script_paths.begin();i!=script_paths.end();++i)
{
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);
-
+ libname = Utilities::MakePkgnameFromPath(path, name); //pkgname);
// Check if library exists
- if ( !FileExists(libname) )
+ if ( ! Utilities::FileExists(libname) )
{
+ // 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;
- continue; // try next path
+ continue; // try next path
}
foundFile = true;
break; // a script was found; we stop iterating
{
if (fullnameGiven)
if(libname == "")
- bbtkError("Path \""<<name<<"\" doesn't exist");
+ bbtkError("Path ["<<name<<"] doesn't exist");
else
- bbtkError("Script \""<<libname<<"\" not found");
+ bbtkError("Script ["<<libname<<"] not found");
else
- bbtkError("No \""<<pkgname<<".bbs\" script found");
+ bbtkError("No ["<<pkgname<<".bbs] script found");
return;
}
s->open(libname.c_str());
if (!s->good())
{
- bbtkError("Could not open file \""<<libname<<"\"");
+ bbtkError("Could not open file ["<<libname<<"]");
return;
}
bool insideComment = false; // for multiline comment
do
{
- try
+ try
{
std::string line;
GetLineFromPrompt(line);
}
catch (std::exception& e)
{
- std::cerr << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
+ std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
}
catch (...)
{
bbtkDebugDecTab("Interpreter",9);
}
- //=======================================================================
-
-
- //=======================================================================
- void Interpreter::SplitAroundFirstDot( const std::string& in,
- std::string& left,
- std::string& right)
- {
- bbtkDebugMessageInc("Interpreter",9,
- "Interpreter::SplitAroundFirstDot(\""
- <<in<<"\")"<<std::endl);
-
- std::string delimiter = ".";
- std::string::size_type pos = in.find_first_of(delimiter);
- if (std::string::npos != pos)
- {
- left = in.substr(0,pos);
- right = in.substr(pos+1,in.size());
- bbtkDebugMessage("Interpreter",9,
- "["<<left<<"] ["<<right<<"]"<<std::endl);
- }
- else
- {
- bbtkError(in<<" : expected 'a.b' format but no dot found");
- }
-
- bbtkDebugDecTab("Interpreter",9);
- }
- //=======================================================================
-
-
//=======================================================================
void Interpreter::Graph(const std::vector<std::string>& words)