]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkInterpreter.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkInterpreter.cxx
index f500e92fde9d125becaecee6a8ccbe9203c41779..ca1bd896e3d918bbc82a4f77c881c10f889fadb5 100644 (file)
@@ -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/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;
 
-
-
  //=======================================================================
  /**
    *  
@@ -51,7 +50,6 @@ 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();
@@ -101,6 +99,22 @@ Interpreter* Interpreter::mGlobalInterpreter = NULL;
     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;
@@ -327,7 +341,7 @@ Interpreter* Interpreter::mGlobalInterpreter = NULL;
           std::cout << "* LINE  : "<<mLine.back()<<std::endl;
       }    
     }
-    
+
     CloseAllFiles();
     bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
     bbtkDecTab("Interpreter",9);
@@ -350,7 +364,7 @@ void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
 
     std::vector<std::string> words;
     SplitLine(line,words);
-    
+
     // Empty line
     if (words.size()<1) 
     {
@@ -394,155 +408,166 @@ void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
        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);
@@ -642,7 +667,6 @@ void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>&
 
     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
 
-
     std::vector<std::string> chains;
     std::string delimiters("$");
 
@@ -667,7 +691,7 @@ void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>&
        // 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;
        }
@@ -695,182 +719,26 @@ void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>&
    *  
    */
 
-
-// --> 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)
@@ -881,21 +749,36 @@ bool Interpreter::FileExists(std::string strFilename) {
     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)
       {
@@ -905,18 +788,20 @@ bool Interpreter::FileExists(std::string strFilename) {
         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
@@ -930,11 +815,11 @@ bool Interpreter::FileExists(std::string strFilename) {
     {
        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;    
     }
 
@@ -944,7 +829,7 @@ bool Interpreter::FileExists(std::string strFilename) {
     s->open(libname.c_str());
     if (!s->good()) 
     {
-        bbtkError("Could not open file \""<<libname<<"\"");
+        bbtkError("Could not open file ["<<libname<<"]");
         return;     
     }
 
@@ -1469,7 +1354,7 @@ void Interpreter::Help(const std::vector<std::string>& words)
     bool insideComment = false; // for multiline comment  
     do 
     {
-      try 
+      try
       {
         std::string line;
         GetLineFromPrompt(line);
@@ -1485,7 +1370,7 @@ void Interpreter::Help(const std::vector<std::string>& words)
       }
         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 (...)
       {
@@ -1502,37 +1387,6 @@ void Interpreter::Help(const std::vector<std::string>& words)
     
     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)