]> Creatis software - bbtk.git/blobdiff - kernel/src/bbtkInterpreterVirtual.cxx
no message
[bbtk.git] / kernel / src / bbtkInterpreterVirtual.cxx
diff --git a/kernel/src/bbtkInterpreterVirtual.cxx b/kernel/src/bbtkInterpreterVirtual.cxx
new file mode 100644 (file)
index 0000000..85354e6
--- /dev/null
@@ -0,0 +1,2078 @@
+/*=========================================================================                                                                               
+  Program:   bbtk
+  Module:    $RCSfile: bbtkInterpreter.cxx,v $
+  Language:  C++
+  Date:      $Date: 2010/09/14 07:18:46 $
+  Version:   $Revision: 1.88 $
+=========================================================================*/
+
+/* ---------------------------------------------------------------------
+
+* Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
+* Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
+*
+*  This software is governed by the CeCILL-B license under French law and 
+*  abiding by the rules of distribution of free software. You can  use, 
+*  modify and/ or redistribute the software under the terms of the CeCILL-B 
+*  license as circulated by CEA, CNRS and INRIA at the following URL 
+*  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
+*  or in the file LICENSE.txt.
+*
+*  As a counterpart to the access to the source code and  rights to copy,
+*  modify and redistribute granted by the license, users are provided only
+*  with a limited warranty  and the software's author,  the holder of the
+*  economic rights,  and the successive licensors  have only  limited
+*  liability. 
+*
+*  The fact that you are presently reading this means that you have had
+*  knowledge of the CeCILL-B license and that you accept its terms.
+* ------------------------------------------------------------------------ */                                                                         
+
+/**
+ *  \file 
+ *  \brief class Interpreter :
+ */
+
+#include "bbtkInterpreterVirtual.h"
+//#include "bbtkTranscriptor.h"
+#include "bbtkConfigurationFile.h"
+#include "bbtkUtilities.h"
+//#include "bbtkAtomicBlackBox.h"
+//#include "bbtkWxBlackBox.h"
+#include <sys/stat.h>
+#include <algorithm>
+#ifdef CMAKE_HAVE_TERMIOS_H
+#include <termios.h>
+#define BBTK_USE_TERMIOS_BASED_PROMPT
+#endif
+
+#include <string>
+
+namespace bbtk
+{
+
+ //=======================================================================
+       InterpreterVirtual::Pointer InterpreterVirtual::New() 
+  {
+    bbtkDebugMessage("kernel",9,"InterpreterVirtual::New()"<<std::endl);
+    return MakePointer( new InterpreterVirtual() );
+  }
+ //=======================================================================
+
+ //=======================================================================
+  InterpreterVirtual::InterpreterVirtual() 
+  {
+    Init();
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  void InterpreterVirtual::Init() 
+  {
+    mUser                      = 0;
+    mCommandLine       = false;
+    mThrow                     = false;
+    bufferNb           = 0;  
+    bbtk::MessageManager::RegisterMessageType("echo","Level>0 : Prints the output of the 'print' 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,"InterpreterVirtual::Interpreter()" <<std::endl);
+
+    // For the time being, comment out previous line, and
+    // uncomment next line to check Transcriptor
+
+    //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
+
+    // Builds the commands dict
+    CommandInfoType info;
+   
+    info.keyword = "new";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cNew;
+    info.syntax = "new <type> <name>";
+    info.help = "Creates a new black box of type <type> with name <name>";
+    mCommandDict[info.keyword] = info;
+    
+    info.keyword = "delete";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cDelete;
+    info.syntax = "delete <box>";
+    info.help = "Deletes the black box of name <box>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "clear";
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cClear;
+    info.syntax = "clear";
+    info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "break";
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cBreak;
+    info.syntax = "break";
+    info.help = "Breaks the current execution";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "newgui";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cNewGUI;
+    info.syntax = "newgui <box> <name>";
+    info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "connect";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cConnect;
+    info.syntax = "connect <box1.output> <box2.input>";
+    info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "print";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cPrint;
+    info.syntax = "print <string>";
+    info.help = "Prints the string. Substitutes any token of the form '$box.output$' by the string adaptation of the output of the box (requires the right adaptor). No carriage return is issued at the end, use '\\n' to add carriage returns. The level of 'echo' messages must be greater than 1 (see the command 'message').";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "exec";
+    info.argmin = 1;
+    info.argmax = 2;
+    info.code = cExec;
+    info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
+    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. 'freeze_no_error' is like freeze but also skips any error.";
+    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;
+    info.code = cDefine;
+    info.syntax = "define <type> [<package>]";
+    info.help = "Begins the definition of a new type of complex black box called <type>. If <package> is provided will create it in the given package.";
+    mCommandDict[info.keyword] = info;
+    
+    info.keyword = "endefine";
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cEndDefine;
+    info.syntax = "endefine";
+    info.help = "Ends the definition of a new type of complex black box";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "kind";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cKind;
+    info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|GUI|DEFAULT_GUI>";
+    info.help = "Sets the kind of the currently defined complex black box";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "input";
+    info.argmin = 3;
+    info.argmax = 3;
+    info.code = cInput;
+    info.syntax = "input <name> <box.input> <help>";
+    info.help = "Defines the input <name> of the current working black box as being an alias for the input <input> of the black box <box>. <help> defines the help string for the newly created input";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "output";
+    info.argmin = 3;
+    info.argmax = 3;
+    info.code = cOutput;
+    info.syntax = "output <name> <box.output> <help>";
+    info.help = "Defines the output <name> of the current working black box as being an alias for the output <output> of the black box <box>. <help> defines the help string for the newly created output";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "set";
+    info.argmin = 2;
+    info.argmax = 2;
+    info.code = cSet;
+    info.syntax = "set <box.input> <value>";
+    info.help = "Sets the value of the input <input> of the black box <box> to <value>. There must exist a string to the value type adaptor";
+    mCommandDict[info.keyword] = info;
+   
+    info.keyword = "config";  // JPR
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cConfig;
+    info.syntax = "config";
+    info.help = "Prints the value of all configuration parameters";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "index";  // LG
+    info.argmin = 0;
+    info.argmax = 2;
+    info.code = cIndex;
+
+    info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
+    info.help = "Creates an html index of known boxes. If filename is provided then save it to the file 'filename'. The default index entries are the initial letters of the names of the boxes. If 'Packages' or 'Categories' is provided then the entries are either the packages names or the categories. If 'Adaptors' is provided then an alphabetical index of all adaptors is created.";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "reset";  
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cReset;
+    info.syntax = "reset";
+    info.help = "Deletes all boxes and unloads all packages (reset to start state)";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "author";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cAuthor;
+    info.syntax = "author <string>";
+    info.help = "Adds the string <string> to the author information of the black box being defined";
+    mCommandDict[info.keyword] = info;
+    
+    info.keyword = "category"; //JP
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cCategory;
+    info.syntax = "category <list of items, separated by ;>";
+    info.help = "Adds the string <string> to the category information of the black box being defined";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "description";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cDescription;
+    info.syntax = "description <string>";
+    info.help = "Adds the string <string> to the descriptive information of the black box being defined";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "help";
+    info.argmin = 0;
+    info.argmax = 2;
+    info.code = cHelp;
+    info.syntax = "help";
+    info.syntax = "\n         (1) help \n         (2) help <command name> \n         (3) help packages [all]\n         (4) help <package name> [all]\n         (5) help <black box type> \n         (6) help <black box name>";
+    info.help = "Effect :\n         (1) Lists all available commands;\n         (2) Prints help on a particular command; \n         (3) Lists the packages loaded and their black boxes.\n             Add 'all' to list adaptors; \n         (4) Prints short help on the black boxes of a package.\n             Add 'all' to include adaptors; \n         (5) Prints full help on a black box type; \n         (6) Prints information on the inputs, outputs and connections of a black box instance.";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "message";
+    info.argmin = 0;
+    info.argmax = 2;
+    info.code = cMessage;
+    info.syntax = "message <kind> <level>";
+    info.help = "Sets the level of the kind of messages <kind> to <level>.\n  If kind='All' then sets the level for all kinds. If no kind nor level is passed then prints info on available kinds of messages and their current level.";  
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "include";
+    info.argmin = 1;
+    info.argmax = 2;
+    info.code = cInclude;
+    info.syntax = "include <filename> [source]";
+    info.help = "Includes the file <filename>.\n  'source' : If the keyword 'source' is provided then informs the interpreter that the included file is the source of the current box definition (Advanced; used to get the right 'Include' field in html doc of packages 'appli' scripts).";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "quit";
+    info.argmin = 0;
+    info.argmax = 0;
+    info.code = cQuit;
+    info.syntax = "quit";
+    info.help = "Quits the program (during script execution it stops the complete execution)";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "load";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cLoad;
+    info.syntax = "load <packagename>";
+    info.help = "Loads the black box package <packagename>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "unload";
+    info.argmin = 1;
+    info.argmax = 1;
+    info.code = cUnload;
+    info.syntax = "unload <packagename>";
+    info.help = "Unloads the black box package <packagename>";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "graph";
+    info.argmin = 0;
+    info.argmax = 6;
+    info.code = cGraph;
+    info.syntax = "graph [ BlackBoxName [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]] \n         graph [ BlackBoxNameType [ Detail 0..1 [ Level 0..99999 [ Output html file [ Custom header [ Custom title ]]]]]]";
+    info.help = "Shows a graphical view of a bbtk pipeline.\n- BlackBoxName : name of the box to view. Default '.' : current box.\n- BlackBoxNameType : name of the type of box to view, ex : 'workspace')";
+    mCommandDict[info.keyword] = info;
+
+    info.keyword = "debug";
+    info.argmin = 0;
+    info.argmax = 1;
+    info.code = cDebug;
+    info.syntax = "debug [expr|-C|-D]";
+    info.help = "Prints debug info on living bbtk objects containing the string 'expr' (default expr=''). -C checks the factory integrity. -D turns on objects debug info after main ends";
+    mCommandDict[info.keyword] = info;
+
+    /*
+    info.keyword = "workspace";
+    info.argmin = 1;
+    info.argmax = 2;
+    info.code = cWorkspace;
+    info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
+    info.help = "Configures the workspace.\n        'freeze' allows to block execution commands while keeping definition commands active. 'unfreeze' turns back the worspace in 'normal' mode.\n      'rename' allow to set a new name to the workspace.";
+    mCommandDict[info.keyword] = info;
+    */
+
+
+
+  } 
+  //=======================================================================
+  
+  
+  
+  //=======================================================================  
+  /**
+   *  
+   */
+  InterpreterVirtual::~InterpreterVirtual()
+  {
+    bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  InterpreterException::InterpreterException( const std::string& message,
+                                     bool in_script_file,
+                                     const std::string& script_file,
+                                     int script_line 
+                                     )
+    : Exception("interpreter",0,message),
+      mInScriptFile(in_script_file),
+      mScriptFile(script_file),
+      mScriptLine(script_line)
+  {
+  }
+  //=======================================================================
+  //=======================================================================
+  InterpreterException::InterpreterException( const Exception& excep,
+                     bool in_script_file,
+                     const std::string& script_file,
+                     int script_line 
+                     )
+    : Exception(excep),
+      mInScriptFile(in_script_file),
+      mScriptFile(script_file),
+      mScriptLine(script_line)
+  {
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  void InterpreterVirtual::CatchInterpreterException( const InterpreterException& e )
+  {
+//EED Borrame     if (GetExecuter()->GetNoErrorMode()) 
+//EED Borrame       {
+//EED Borrame        bbtkWarning("ERROR :"<<e.GetErrorMessage()
+//EED Borrame              <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
+//EED Borrame              <<" skipped");
+//EED Borrame  return;
+//EED Borrame       }
+         if (mThrow) 
+      {
+                 if (e.GetErrorMessage()!="break")
+                 {
+                         mStatus = Interpreter_ERROR;         
+                         CloseAllFiles();
+                 }
+                 throw InterpreterException(e);
+      } else {
+                 std::stringstream mess;
+                 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
+                 if (e.IsInScriptFile())
+                 {
+                         mess << "* FILE  : \""<<e.GetScriptFile()<<"\""<<std::endl;
+                         mess << "* LINE  : "<<e.GetScriptLine()<<std::endl;
+                 }
+                 CloseAllFiles();
+                 std::cerr << mess.str();
+      } // if
+  }
+  //=======================================================================
+
+  //=======================================================================
+  void InterpreterVirtual::CatchBbtkException( const bbtk::Exception& e )
+  {
+//EED Borrame     if (GetExecuter()->GetNoErrorMode()) 
+//EED Borrame       {
+//EED Borrame  std::string file("?");
+//EED Borrame  int line = 0;
+//EED Borrame  if (mFileName.size()) {
+//EED Borrame    file = mFileName.back();
+//EED Borrame    line = mLine.back();
+//EED Borrame  }    
+//EED Borrame  bbtkWarning("ERROR '"<<e.GetErrorMessage()
+//EED Borrame              <<"' ("<<file<<":"<<line<<") skipped");
+//EED Borrame  return;
+//EED Borrame      }
+         
+    mStatus = Interpreter_ERROR;              
+    if (mThrow) 
+       {
+               bool in_script = false;
+               std::string file("");
+               int line = 0;
+               if (mFileName.size()) 
+               {
+                       std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
+                       if (fs!=0) in_script = true;      
+                       file = mFileName.back();
+                       line = mLine.back();
+               }   
+               if (e.GetErrorMessage()!="break")
+                       CloseAllFiles();
+               throw InterpreterException(e,in_script,file,line);
+       } else {
+               std::stringstream mess;
+               mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
+               if (mFileName.size()) 
+               {
+                       mess << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
+                       mess << "* LINE  : "<<mLine.back()<<std::endl;
+               }    
+               CloseAllFiles();
+               std::cerr << mess.str();
+       } // if
+  }
+  //=======================================================================
+  
+  //=======================================================================
+  void InterpreterVirtual::CatchStdException( const std::exception& e )
+  {  
+//EED Borrame   if (GetExecuter()->GetNoErrorMode()) 
+//EED Borrame      {
+//EED Borrame  std::string file("?");
+//EED Borrame  int line = 0;
+//EED Borrame  if (mFileName.size()) {
+//EED Borrame    file = mFileName.back();
+//EED Borrame    line = mLine.back();
+//EED Borrame  }    
+//EED Borrame  bbtkWarning("ERROR '"<<e.what()
+//EED Borrame              <<"' ("<<file<<":"<<line<<") skipped");
+//EED Borrame  return;
+//EED Borrame      }
+         
+    mStatus = Interpreter_ERROR;              
+       if (mThrow) 
+       {
+               bool in_script = false;
+               std::string file("");
+               int line = 0;
+               if (mFileName.size()) {
+                       std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
+                       if (fs!=0) in_script = true;      
+                       file = mFileName.back();
+                       line = mLine.back();
+               }    
+               CloseAllFiles();
+               throw InterpreterException(e.what(),in_script,file,line);
+       } else {
+               std::stringstream mess;
+               mess << "* ERROR : "<<e.what()<<std::endl;
+               if (mFileName.size()) 
+               {
+                       mess << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
+                       mess << "* LINE  : "<<mLine.back()<<std::endl;
+               }    
+               CloseAllFiles();
+               std::cerr << mess.str();
+       }
+  }
+       
+  //=======================================================================
+
+  //=======================================================================
+  void InterpreterVirtual::CatchUnknownException()
+  {
+//EED Borrame   if (GetExecuter()->GetNoErrorMode()) 
+//EED Borrame       {
+//EED Borrame  std::string file("?");
+//EED Borrame  int line = 0;
+//EED Borrame  if (mFileName.size()) {
+//EED Borrame    file = mFileName.back();
+//EED Borrame    line = mLine.back();
+//EED Borrame  }
+//EED Borrame          bbtkWarning("UNDEFINED ERROR "
+//EED Borrame                      <<"("<<file<<":"<<line<<") skipped");
+//EED Borrame          return;
+//EED Borrame        }
+    mStatus = Interpreter_ERROR;              
+    if (mThrow) 
+      {
+       bool in_script = false;
+       std::string file("");
+       int line = 0;
+       if (mFileName.size()) {
+         std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
+         if (fs!=0) in_script = true;    
+         file = mFileName.back();
+         line = mLine.back();
+       }    
+       CloseAllFiles();
+       throw InterpreterException("Unknown exception caught",
+                                  in_script,file,line);
+      }
+    else
+      {
+       std::stringstream mess;
+       mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)" 
+            << std::endl;
+       if (mFileName.size()) {
+         mess << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
+         mess << "* LINE  : "<<mLine.back()<<std::endl;
+       }    
+       CloseAllFiles();
+       std::cerr << mess.str();
+      }
+  }
+  //=======================================================================
+
+  //=======================================================================
+  
+#define CATCH_MACRO                                    \
+  catch (InterpreterException e)                       \
+    {                                                  \
+      CatchInterpreterException(e);                    \
+    }                                                  \
+  catch (bbtk::Exception e)                            \
+    {                                                  \
+      CatchBbtkException(e);                           \
+    }                                                  \
+  catch (std::exception& e)                            \
+    {                                                  \
+      CatchStdException(e);                            \
+    }                                                  \
+  catch (...)                                          \
+    {                                                  \
+      CatchUnknownException();                         \
+    }                                          
+  //=======================================================================
+   
+
+  //=======================================================================
+  InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretFile( const std::string& filename, bool source )
+  {
+    bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretFile(\""<<filename<<"\")"<<std::endl);
+
+    bool exm = mCommandLine;
+    mCommandLine = false;
+
+    try 
+    {
+      mStatus = Interpreter_OK;
+      SwitchToFile(filename,source);
+      mInsideComment = false;
+      InterpretCurrentStreams();
+    } 
+    CATCH_MACRO;
+    
+    bbtkDebugMessage("interpreter",4,
+                    "<== InterpreterVirtual::InterpretFile(\""
+                    <<filename<<"\")"<<std::endl);
+
+
+    mCommandLine = exm;
+    
+    return mStatus;
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  InterpreterVirtual::ExitStatus 
+  InterpreterVirtual::InterpretBuffer( std::stringstream* buffer )
+  {
+    bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::InterpretBuffer()"<<std::endl);
+
+    bool exm = mCommandLine;
+    mCommandLine = false;
+
+    try 
+    {
+      mStatus = Interpreter_OK;
+      SwitchToStream(buffer);
+      mInsideComment = false;
+      InterpretCurrentStreams();
+    }
+    CATCH_MACRO;
+    
+    //    CloseAllFiles();
+    bbtkDebugMessage("interpreter",4,"<== InterpreterVirtual::InterpretBuffer()"<<std::endl);
+
+    
+    mCommandLine = exm;
+    return mStatus;
+  }
+  //=======================================================================
+
+  //=======================================================================
+  /// Interprets the currently open streams
+  InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretCurrentStreams()
+  {
+    bbtkDebugMessage("interpreter",4,
+                    "==> InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
+
+    while (mFile.size()>0) 
+      {
+       while (!mFile.back()->eof()) {
+         mLine.back()++;
+         char buf[500];
+         mFile.back()->getline(buf,500);
+         std::string str(buf);
+         //size 0 JCP 21-09-2009
+         int size=str.length();
+         if(size != 0){
+                 if ( str[ size-1 ]==13  )
+            {
+             str.erase(size-1,1);
+            }
+                 try
+                       {
+                         DoInterpretLine(str);
+                       }
+                 CATCH_MACRO;
+         }
+         
+       } 
+       CloseCurrentFile();
+      }
+    bbtkDebugMessage("interpreter",4,
+                    "<== InterpreterVirtual::InterpretCurrentStreams()"<<std::endl);
+
+    return mStatus;
+  }
+  //=======================================================================
+
+  //=======================================================================
+  /// Runs the interpretation of a command
+  InterpreterVirtual::ExitStatus InterpreterVirtual::InterpretLine( const std::string& line )
+  {
+    bbtkDebugMessage("interpreter",5,"==> InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
+
+    try 
+    {
+      mStatus = Interpreter_OK;
+      mInsideComment = false;
+//std::cout<<"JCP bbtkInterpreter.cxx InterpreterVirtual::InterpretLine("<<std::endl;
+      DoInterpretLine(line );
+    }
+    CATCH_MACRO;
+    
+    
+   bbtkDebugMessage("interpreter",5,"<== InterpreterVirtual::InterpretLine('"<<line<<"')"<<std::endl);
+    
+    return mStatus;
+  }
+  //=======================================================================  
+  
+       void InterpreterVirtual::commandNew(std::string boxType, std::string boxName)
+    {
+    }
+       
+       void InterpreterVirtual::commandDelete(std::string boxName)
+    {
+    }
+
+       void InterpreterVirtual::commandConnection(std::string nodeFrom, std::string outputLabel, std::string nodeTo, std::string inputLabel)
+    {
+    }
+               
+       void InterpreterVirtual::commandPackage(std::string packageName)
+    {
+    }
+       
+       void InterpreterVirtual::commandEndPackage()
+    {
+    }
+       
+       void InterpreterVirtual::commandDefine(std::string name, std::string pack, std::string scriptfilename)
+    {
+    }
+
+       void InterpreterVirtual::commandEndDefine()
+    {
+    }
+
+       void InterpreterVirtual::commandKind(std::string kind)
+    {
+    }
+       
+       void InterpreterVirtual::commandPrint(std::string value)
+    {
+    }
+       
+       
+       void InterpreterVirtual::commandExec(std::string word)
+    {
+    }
+       
+       
+       void InterpreterVirtual::commandInput(std::string name, std::string box, std::string input,std::string  help)
+    {
+    }
+       
+       void InterpreterVirtual::commandOutput(std::string name, std::string box, std::string output,std::string  help)
+    {
+    }
+       
+       void InterpreterVirtual::commandSet(std::string box, std::string input, std::string value)
+    {
+    }
+
+       void InterpreterVirtual::commandAuthor(std::string author)
+    {
+    }
+
+       void InterpreterVirtual::commandCategory(std::string categorytype)
+    {
+    }
+       
+       
+       
+       void InterpreterVirtual::commandDescription(std::string description)
+    {
+    }
+
+       
+       void InterpreterVirtual::commandClear()
+    {
+    }
+       
+       void InterpreterVirtual::commandInclude(std::string word, bool ok)
+    {
+    }
+       
+       
+       void InterpreterVirtual::commandLoad(std::string packageName)
+    {
+    }
+
+       void InterpreterVirtual::commandUnload(std::string packageName)
+    {
+    }
+       
+       void InterpreterVirtual::commandBreak()
+    {
+    }
+       
+       void InterpreterVirtual::commandQuit()
+    {
+    }
+       
+       void InterpreterVirtual::commandMessage()
+    {
+    }
+       
+//ups2 EED Borrame     
+       void InterpreterVirtual::commandMessage(std::string kind, std::string levelstr)
+    {
+    }
+       
+       
+       
+  //=======================================================================  
+  void InterpreterVirtual::DoInterpretLine( const std::string& line )
+  {
+    bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
+                    <<line<<"\")"<<std::endl);
+    std::vector<std::string> words;
+    SplitLine(line,words);
+
+    // Empty line
+    if (words.size()<1) 
+    {
+       bbtkDebugDecTab("interpreter",9);
+       return;
+    }
+
+    // Single line comment : # or //
+    if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') ) 
+    {  
+       bbtkDebugDecTab("interpreter",9);
+       bbtkMessage("interpreter",9,"Comment"<<std::endl);
+       return;
+    }
+
+    // Multi line comment ( /* ... */ ) -delimiters on different lines !-
+    
+    if (words[0][0]=='/' && words[0][1]=='*') 
+    {  
+       bbtkDebugDecTab("interpreter",9);
+       bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
+       mInsideComment = true;
+       return;
+    }
+
+    if (words[0][0]=='*' && words[0][1]=='/') 
+    {  
+       bbtkDebugDecTab("interpreter",9);
+       bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
+       if ( !mInsideComment ) {
+          bbtkDebugDecTab("interpreter",9);
+          bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);       
+       }
+       mInsideComment = false;
+       return;
+    }
+
+    if (mInsideComment) 
+    {  
+       bbtkDebugDecTab("interpreter",9);
+       bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
+       return;
+    }
+
+    // Command 
+    CommandInfoType command;
+    InterpretCommand(words,command);
+//std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
+    bbtkDebugMessage("interpreter",9,
+                     "Command='"<<command.keyword
+                      <<"' code="<<command.code<<std::endl); 
+         
+    std::string left,right,left2,right2;
+    std::string filename;
+
+//ups1 EED borrame       
+    // message command
+    if (command.code==cMessage)
+      {
+       if (words.size()<3)
+         {
+                 commandMessage();
+//EED Borrame      mVirtualExecuter->HelpMessages();
+         }
+        else
+         {
+               commandMessage(words[1],words[2]);
+//EED Borrame          sscanf(words[2].c_str(),"%d",&level);
+//EED Borrame      mVirtualExecuter->SetMessageLevel(words[1],level);
+         }
+       return;
+      }
+    else 
+      {
+       bbtkMessage("echo",2,line<<std::endl);
+      }
+
+    // break and quit commands
+    if ((command.code==cBreak) || (command.code==cQuit))
+      {
+       bool in_script = false;
+       std::string file("");
+       int line = 0;
+
+       if (mFileName.size()) 
+         {
+           std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
+           if (fs!=0) in_script = true;          
+           file = mFileName.back();
+           line = mLine.back();
+         } 
+       if (command.code==cBreak)
+         {
+           /*
+           std::cout << "BreakException(" 
+                     <<in_script<<","
+                     <<file<<","
+                     <<line<<")"<<std::endl;
+           */
+                 commandBreak();
+//EED Borrame      bbtkError("break");//,in_script,file,line);
+           //      throw BreakException(in_script,file,line);
+         }       
+       else 
+         {
+                 commandQuit();
+//EED Borrame      bbtkError("quit");//,in_script,file,line);
+             //throw QuitException(in_script,file,line);
+         }
+       return;
+      }   
+//std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
+    // other cammands
+
+    switch (command.code) 
+      {
+      case cNew :
+               commandNew(words[1],words[2]);
+//EED Borrame        mVirtualExecuter->Create(words[1],words[2]);
+        break;
+
+      case cDelete :
+                         commandDelete(words[1]);
+//EED Borrame  mVirtualExecuter->Destroy(words[1]);
+        break;
+
+      case cConnect :
+        Utilities::SplitAroundFirstDot(words[1],left,right);
+        Utilities::SplitAroundFirstDot(words[2],left2,right2);      
+        commandConnection(left,right,left2,right2);
+//EED Borrame        mVirtualExecuter->Connect(left,right,left2,right2);
+        break;
+
+      case cPackage :
+                         commandPackage(words[1]);
+//EED Borrame                mVirtualExecuter->BeginPackage(words[1]);
+        break;
+
+      case cEndPackage :
+                         commandEndPackage();
+//EED Borrame        mVirtualExecuter->EndPackage();
+        break;
+
+      case cDefine :
+        if (mFileName.size()>0) 
+        {
+//???                  commandDefine(????);
+                  filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
+        }
+        if (words.size()==2) 
+        {
+                       commandDefine(words[1],"",filename);
+//EED Borrame           mVirtualExecuter->Define(words[1],"",filename);
+        }
+        else
+        {
+                       commandDefine(words[1],words[2],filename);
+//EED Borrame           mVirtualExecuter->Define(words[1],words[2],filename);
+        }
+        break;
+
+      case cEndDefine :
+               commandEndDefine();
+//EED Borrame        mVirtualExecuter->EndDefine();
+        break;
+
+      case cKind :
+                       commandKind(words[1]);
+//EED Borrame        mVirtualExecuter->Kind(words[1]);
+        break;
+
+      case cPrint :
+                         commandPrint(words[1]);
+//EED Borrame        mVirtualExecuter->Print(words[1]);
+        break;
+                         
+      case cExec :
+                         commandExec(words[1]);
+//EED Borrame        if (words[1]=="freeze") 
+//EED Borrame    {
+//EED Borrame      mVirtualExecuter->SetNoExecMode(true);
+//EED Borrame      mThrow = false;
+//EED Borrame    }
+//EED Borrame  else if (words[1]=="freeze_no_error") 
+//EED Borrame    {
+//EED Borrame      mVirtualExecuter->SetNoExecMode(true);
+//EED Borrame      mVirtualExecuter->SetNoErrorMode(true);
+//EED Borrame      mThrow = false;
+//EED Borrame    }
+//EED Borrame  else if (words[1]=="unfreeze") 
+//EED Borrame    {
+//EED Borrame      mVirtualExecuter->SetNoExecMode(false);
+//EED Borrame      mVirtualExecuter->SetNoErrorMode(false);
+//EED Borrame    }
+//EED Borrame  else
+//EED Borrame    {
+//EED Borrame      mVirtualExecuter->Execute(words[1]);
+//EED Borrame    }
+                         
+        break;
+
+      case cInput :
+        Utilities::SplitAroundFirstDot(words[2],left,right);
+                         commandInput(words[1],left,right,words[3]);
+//EED Borrame        mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
+        break;
+
+      case cOutput :
+        Utilities::SplitAroundFirstDot(words[2],left,right);
+               commandOutput(words[1],left,right,words[3]);
+//EED Borrame         mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
+        break;
+
+      case cSet :
+        Utilities::SplitAroundFirstDot(words[1],left,right);
+               commandSet(left,right,words[2]);
+//EED Borrame        mVirtualExecuter->Set(left,right,words[2]);
+        break;
+
+      case cAuthor :
+               commandAuthor(words[1]);
+//EED Borrame        mVirtualExecuter->Author(words[1]);
+        break;
+
+      case cNewGUI :
+               commandNewGUI(words[1],words[2]);
+        break;
+
+      case cCategory :
+               commandCategory(words[1]);
+//EED Borrame   mVirtualExecuter->Category(words[1]);
+        break;
+
+      case cIndex :
+        if (words.size()==1)
+                       commandIndex("tmp_index.html");
+        else if (words.size()==2)
+                       commandIndex(words[1]);
+        else if (words.size()==3)
+                       commandIndex(words[1],words[2]);
+        break;
+
+      case cDescription :
+               commandDescription(words[1]);
+//EED Borrame        mVirtualExecuter->Description(words[1]);
+        break;
+
+      case cHelp :
+        commandHelp(words);
+        break;
+
+
+      case cGraph :
+        commandGraph(words);
+        break;
+
+      case cConfig :
+        commandConfig();
+        break;
+
+      case cReset :  
+       commandReset();
+        break;
+       
+      case cClear :  
+               commandClear();
+//EED Borrame          mVirtualExecuter->Clear();
+        break;
+
+      case cInclude :
+                         commandInclude( words[1] , (words.size()==3) );
+//EED Borrame          // if 'source' was given (words.size()==3) then tell to set the 
+//EED Borrame          // source file name of the current complex box with the full file name included
+//EED Borrame                  if (mCommandLine)
+//EED Borrame        {
+//EED Borrame           InterpretFile(words[1],(words.size()==3)); 
+//EED Borrame        } else{
+//EED Borrame            SwitchToFile(words[1],(words.size()==3) );
+//EED Borrame        }
+               break;
+
+      case cLoad:
+               commandLoad( words[1] );
+//EED Borrame        GetExecuter()->LoadPackage(words[1]);
+        break;
+
+      case cUnload:
+               commandUnload( words[1] );
+//EED Borrame        GetExecuter()->UnLoadPackage(words[1]);
+        break;
+
+      case cDebug :
+                         if (words.size()==2) commandDebug(words[1]);
+                               else commandDebug("");
+        break;
+                         
+       /* obsolete
+      case cWorkspace :
+        if (words.size() == 2) 
+        {
+           if (words[1]=="freeze")        mVirtualExecuter->SetNoExecMode(true);
+           else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
+        }
+        else
+        {
+           mVirtualExecuter->SetWorkspaceName(words[2]);
+        }
+        break;
+        */
+      default:
+        bbtkInternalError("should not reach here !!!");
+   }
+
+    bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
+                    <<line<<"\")"<<std::endl);
+    
+  }
+  //=======================================================================  
+
+
+
+
+
+  //=======================================================================
+  void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
+{
+    bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
+
+    std::string delimiters = "\"";
+    std::vector<std::string> quote;
+    Utilities::SplitString(str,delimiters,quote);
+
+    delimiters = " \t";
+    std::vector<std::string>::iterator i;
+    for (i=quote.begin(); i!=quote.end(); ) 
+    {
+       Utilities::SplitString(*i,delimiters,tokens);
+       ++i;
+       if (i!=quote.end()) 
+       {
+        //    bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
+          tokens.push_back(*i);
+          ++i;
+       }
+    }
+
+    for (i=tokens.begin(); i!=tokens.end(); ++i) 
+    {
+      bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
+    }
+    bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
+
+ }
+  //=======================================================================
+
+
+  //=======================================================================
+  void InterpreterVirtual::commandReset()
+  {
+  }
+  //=======================================================================
+
+  //=======================================================================
+  /**
+   *
+   */
+  /*
+  void InterpreterVirtual::Print( const std::string& str)
+  {
+    if (mVirtualExecuter->GetNoExecMode()) return;
+
+    bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
+
+ // TO DO :
+ // InterpretLine ("load std")
+ // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande 
+ // InterpretLine("new Print _P_") 
+ // InterpretLine("connect _C_.Out _P_.In")
+ // int num = 1
+
+    std::vector<std::string> chains;
+    std::string delimiters("$");
+
+    // Skip delimiters at beginning.
+    std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
+    bool is_text = true;
+    if (lastPos>0) is_text = false;
+
+    // Find first delimiter.
+    std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
+
+    while (std::string::npos != pos || std::string::npos != lastPos)
+    {
+       if (is_text) 
+       {
+          // Found a text token, add it to the vector.
+          chains.push_back(str.substr(lastPos, pos - lastPos));
+ // std::string token = str.substr(lastPos, pos - lastPos)
+ // InterpretLine("set _C_.In%num% %token%")
+       }
+       else 
+       {
+
+       // is an output (between $$) : decode 
+         std::string tok,box,output;
+         tok = str.substr(lastPos, pos - lastPos);
+         Utilities::SplitAroundFirstDot(tok,box,output);
+         chains.push_back( mVirtualExecuter->Get(box,output) );
+
+// InterpretLine("connect %tok% _C_.In%num%") 
+
+       }
+        // Skip delimiters.  Note the "not_of"
+       lastPos = str.find_first_not_of(delimiters, pos);
+        // Find next delimiter
+       pos = str.find_first_of(delimiters, lastPos);
+    //
+       is_text = !is_text;
+// num ++;
+     }
+// InterpretLine("exec _P_")
+// if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
+
+     std::vector<std::string>::iterator i;
+     for (i= chains.begin(); i!=chains.end(); ++i) 
+     {
+
+       Utilities::SubsBackslashN(*i);
+       std::cout << *i;
+     }
+     std::cout << std::endl;
+     bbtkDebugDecTab("interpreter",9);
+ }
+*/
+
+  //=======================================================================
+  /**
+   *
+   */
+
+  // =========================================================================
+  void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
+  {
+  // 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
+  //
+
+    bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
+                    <<name<<"\")"<<std::endl);
+
+    std::vector<std::string> script_paths;
+    std::string fullPathScriptName;  // full path script name
+    std::string pkgname;             // e.g. <scriptname>.bbs
+    std::vector<std::string> Filenames;
+
+    // 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
+        << "]" << std::endl);
+
+
+    std::string upath;
+    pkgname = Utilities::ExtractScriptName(name,upath);
+
+    bbtkMessage("interpreter",3,
+               "package name:[" << pkgname
+                << "] path:[" << upath << "]" << std::endl);
+    bool fullnameGiven = false; 
+    bool foundFile     = false;
+
+    // ==== "*" provided : load all scripts in given path 
+    // relative (e.g. std/boxes/*) or absolute 
+    if (pkgname == "*") 
+      {
+
+       std::stringstream* stream = new std::stringstream;
+       //if (upath.size()!=0) // avoid troubles for "*"
+       
+       // ==== no path provided : look in root bbs path
+       if (upath.size()==0)
+         {
+           //      bbtkMessage("interpreter",1,
+           // LG : add all bbs path
+           //  script_paths.push_back(  ConfigurationFile::GetInstance().Get_root_bbs_path() );
+           std::vector<std::string>::const_iterator i;
+           for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
+                i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
+                i++)
+             {
+               script_paths.push_back(*i);
+             }
+         }
+       // ==== absolute path provided 
+       else if (upath[0]=='/' || upath[1] == ':' ) 
+         {
+           if ( Utilities::IsDirectory( upath ) )
+             {
+               script_paths.push_back(upath);
+             }
+           else 
+             {
+               bbtkError("'"<<upath<<"' : directory does not exist"); 
+             }
+         }
+       // ==== relative path provided : search all bbs path appended with 
+       // the relative path provided
+       else
+         {    
+           std::vector<std::string>::const_iterator i;
+           for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
+                i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
+                i++)
+             {
+               std::string full_path(*i);
+               // we *really* want '.' to be the current working directory
+               if (full_path == ".") 
+                 {
+                   char buf[2048]; // for getcwd
+                   char * currentDir = getcwd(buf, 2048);
+                   std::string cwd(currentDir);
+                   full_path = currentDir;
+                 } // if full_path
+               
+               full_path += ConfigurationFile::GetInstance().Get_file_separator();
+               full_path += upath;
+               
+               if ( Utilities::IsDirectory( full_path ) )
+                 {
+                   script_paths.push_back(full_path);
+                 }
+             } 
+           if (script_paths.empty())
+             {
+               bbtkError("no '"<<upath<<"' subdir found in search paths" 
+                         << std::endl);
+             }
+         }
+       
+       
+       // === search paths list complete : now explore it
+       int nbBssFiles = 0;     
+       // ==== relative name, iterate + load all .bbs/.bbp files
+       std::vector<std::string>::iterator i;
+       for (i=script_paths.begin();i!=script_paths.end();i++)
+         {
+           bbtkMessage("interpreter",1,
+                       "--> Looking in '" << *i << "'" << std::endl);
+           
+           Filenames.clear();
+           //int nbFiles = 
+           Utilities::Explore(*i, false, Filenames);
+           
+           for (std::vector<std::string>::iterator j = Filenames.begin(); 
+                j!= Filenames.end(); ++j)
+             {
+               int lgr = (*j).size();
+               if (lgr < 5) continue;  
+               // ignore non .bbp file
+               if ( (*j).substr(lgr-4, 4) != ".bbp") continue; 
+               
+               (*stream) << "include \"" << *j << "\"\n";
+               bbtkMessage("interpreter",2,"  --> Found '" << *j << "'" << std::endl);
+               
+               nbBssFiles++;
+             } // for (std::vector...
+         } // for (i=script_...
+
+       // === Result ...
+       if (nbBssFiles==0)
+         {
+           bbtkMessage("interpreter",1,
+                       "  --> No .bbp found"<< std::endl);
+         } 
+       else 
+         {
+           bbtkMessage("interpreter",1,
+                       "  --> "<<nbBssFiles<<" .bbp found"<< std::endl);
+           SwitchToStream(stream);
+         }
+       return;
+      }  
+    //=============== end pkgname=="*" ===========
+    
+    
+    // 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 ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
+                        (fullPathScriptName.substr(l-4, 4) != ".bbp"))
+         {
+                       std::string tfullPathScriptName = fullPathScriptName + ".bbs";
+                       if ( Utilities::FileExists(tfullPathScriptName) )
+                       {
+                               fullPathScriptName = tfullPathScriptName;
+                               foundFile = true;
+                       }
+                       else 
+                       {
+                               tfullPathScriptName = fullPathScriptName + ".bbp";
+                               if ( Utilities::FileExists(tfullPathScriptName) )
+                               {
+                                       fullPathScriptName = tfullPathScriptName;
+                                       foundFile = true;
+                               }
+                       }
+                }
+                else 
+                {
+                       if ( Utilities::FileExists(fullPathScriptName) )
+                       {
+                               foundFile = true;
+                       }
+                }
+         } // endif l != 0
+  }
+  else
+  // =============================== iterate on the paths
+  {
+      script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
+      std::string path;
+      std::vector<std::string>::iterator i;
+      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;
+               }
+         
+               std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
+//Addition JCP tfullPathScriptName.size()>=4 
+               if(tfullPathScriptName.size()>=4){
+                       if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
+                       {
+                         fullPathScriptName = tfullPathScriptName;
+                               if ( ! Utilities::FileExists(fullPathScriptName) )
+                               {
+                                       // The following is *NOT* a debug time message :
+                                       // It's a user intended message.
+                                       // Please don't remove it.
+                                       bbtkMessage("interpreter",2,
+                                 "   [" <<fullPathScriptName <<"] : does not exist" 
+                                 <<std::endl);
+                                       continue;  // try next path
+                               }
+                               bbtkMessage("interpreter",2,
+                                         "   [" <<fullPathScriptName 
+                                         <<"] : found" <<std::endl);
+                               foundFile = true;
+                               break; // a script was found; we stop iterating
+                       }
+                       else 
+                       {
+                               fullPathScriptName = tfullPathScriptName + ".bbs";
+                               // Check if library exists
+                               if ( ! Utilities::FileExists(fullPathScriptName) )
+                               {
+                                       fullPathScriptName = tfullPathScriptName + ".bbp";
+                                       if ( ! Utilities::FileExists(fullPathScriptName) )
+                                       {
+                                               // The following is *NOT* a debug time message :
+                                               // It's a user intended message.
+                                               // Please don't remove it.
+                                               bbtkMessage("interpreter",2,
+                                               "   [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist" 
+                                               <<std::endl);
+                                               continue;  // try next path
+                                       }
+                               }
+                               bbtkMessage("interpreter",2,
+                                 "   [" <<fullPathScriptName 
+                                 <<"] : found" <<std::endl);
+                               foundFile = true;
+                               break; // a script was found; we stop iterating
+                       }
+               }               
+       } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
+  }
+
+    if (!foundFile)
+      {
+       if (fullnameGiven)
+         if(fullPathScriptName == "")
+            bbtkError("Path ["<<upath<<"] doesn't exist");
+         else
+            bbtkError("Script ["<<fullPathScriptName<<"] not found");
+       else
+          bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
+       return;
+      } else {
+               LoadScript(fullPathScriptName,name);
+//EED Borrame    if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
+               if (source) SetCurrentFileName(fullPathScriptName);
+       }    
+    return;
+  }
+  //=======================================================================
+
+       //=======================================================================
+       void InterpreterVirtual::SetCurrentFileName(std::string fullPathScriptName)  // virtual 
+       {
+       }       
+       //=======================================================================
+       
+  //=======================================================================
+void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
+{
+  bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
+                  <<std::endl);
+   mFile.push_back(stream);
+    std::ostringstream buffer_name;
+    bufferNb++;
+    buffer_name << "buffer_" ;
+
+    if (mFileName.size()>0 )
+    {
+       buffer_name << mFileName.back() << "_" << mLine.back();
+    }
+    mFileName.push_back(buffer_name.str());
+    mIncludeFileName.push_back(buffer_name.str());
+    mLine.push_back(0);
+}
+  //=======================================================================
+
+  //=======================================================================
+
+  void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
+                               std::string includeScriptName)
+  {
+    bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
+                    <<fullPathScriptName<<")"
+                    <<std::endl);
+
+    Utilities::replace( fullPathScriptName , 
+                        INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
+   
+     if (find(mFileNameHistory.begin(),
+             mFileNameHistory.end(),
+             fullPathScriptName)!=mFileNameHistory.end())
+     {
+        return;
+     }
+
+    std::ifstream* s;
+    s = new std::ifstream;
+    s->open(fullPathScriptName.c_str());
+    if (!s->good())
+    {
+        bbtkError("Could not open file ["<<fullPathScriptName<<"]");
+        return;
+    }
+
+    bbtkMessage("interpreter",1,"   -->[" << fullPathScriptName 
+               << "] found" << std::endl);
+
+    mFile.push_back(s);
+    mFileName.push_back(fullPathScriptName);
+    mFileNameHistory.push_back(fullPathScriptName);
+    mIncludeFileName.push_back(includeScriptName);
+    mLine.push_back(0);
+
+    return;
+  }
+  //=======================================================================
+
+  //=======================================================================
+  void InterpreterVirtual::CloseCurrentFile()
+  {
+    bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
+                      <<std::endl);
+
+    if (mFile.size()==0)
+    {
+      bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
+      return;
+    }
+
+    bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
+
+    std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
+    if (file!=0) file->close();
+
+    delete mFile.back();
+    mFile.pop_back();
+    mFileName.pop_back();
+    mIncludeFileName.pop_back();
+    mLine.pop_back();
+
+    bbtkDebugMessage("interpreter",9," Remains "
+                     <<mFile.size()
+                     <<" open"<<std::endl);
+    bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
+                     <<std::endl);
+  }
+  //=======================================================================
+
+ //=======================================================================
+  void InterpreterVirtual::CloseAllFiles()
+  {
+    bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
+                      <<std::endl);
+
+    while (mFile.size() != 0) 
+    {
+       CloseCurrentFile();
+    }
+    bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
+                      <<std::endl);
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================
+  void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
+                                      CommandInfoType& info )
+  {
+    bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
+
+    // searches the command keyword
+    CommandDictType::iterator c;
+    c = mCommandDict.find(words[0]);
+    if ( c == mCommandDict.end() ) {
+      bbtkError(words[0]<<" : unknown command");
+    }
+
+    // tests the number of args 
+    if ( ( ((int)words.size())-1 < c->second.argmin ) ||
+         ( ((int)words.size())-1 > c->second.argmax ) )
+    {
+               
+//EED       HelpCommand(words[0]);
+               commandHelp(words[0]);
+               
+       bbtkError(words[0]<<" : wrong number of arguments");
+    }
+//std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
+    info = c->second;
+
+    bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
+
+  }
+  //=======================================================================
+
+
+  //=======================================================================
+  /// Displays help on all the commands
+  void InterpreterVirtual::commandHelp(const std::vector<std::string>& words) 
+  { 
+  }
+  //=======================================================================
+  void InterpreterVirtual::commandHelp(const std::string words) 
+  {  
+  }
+       //=======================================================================
+       
+   //===================================================================    
+  /// Displays the Configuration
+  void InterpreterVirtual::commandConfig() const
+  {
+  }  
+   //===================================================================    
+
+
+
+  //=======================================================================
+  /// Fills the vector commands with the commands which 
+  /// have the first n chars of buf for prefix
+  /// TODO : skip initial spaces in buf and also return the position of first
+  /// non blank char in buf
+  void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
+                                            int n,
+                                            std::vector<std::string>& commands )
+  {
+    CommandDictType::const_iterator i;
+    for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
+    {
+      if ((i->first).find(buf,0,n) == 0) 
+        commands.push_back(i->first);
+    }
+  }
+  //=======================================================================
+
+
+
+  //=======================================================================
+#ifdef BBTK_USE_TERMIOS_BASED_PROMPT
+  
+  inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
+  inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
+  
+  // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
+  // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
+  // E.G. STORE THIS IN bbtk_config.xml
+#define BBTK_UP_ARROW_KBCODE    0x00415B1B
+#define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
+#define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
+#define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
+#define BBTK_BACKSPACE_KBCODE   0x00000008
+#define BBTK_DEL_KBCODE         0x0000007F
+#define BBTK_SPACE_KBCODE       0x00000020 
+
+  //=======================================================================
+  void InterpreterVirtual::GetLineFromPrompt(std::string& s)
+  {
+    int c;
+    unsigned int ind=0;
+
+    unsigned int MAX_LINE_SIZE = 160;
+    unsigned int MAX_HISTORY_SIZE = 100;
+
+    char* newline = new char[MAX_LINE_SIZE];
+    memset(newline,0,MAX_LINE_SIZE);
+    char* histline = new char[MAX_LINE_SIZE];
+    memset(histline,0,MAX_LINE_SIZE);
+
+    char* line = newline;
+    unsigned int hist = mHistory.size();
+
+    write(1,"> ",2);
+    while(1)
+    {
+       c=0;
+       read ( STDIN_FILENO, &c, 4) ;
+
+       bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
+
+       // Printable character
+       if ( (ind<MAX_LINE_SIZE-1) &&
+            ( c >= BBTK_SPACE_KBCODE ) && 
+            ( c <  BBTK_DEL_KBCODE )) 
+       {
+          PrintChar(c);
+          line[ind++]=c;
+       }
+      // CR
+       else if (c=='\n')
+       {
+       // delete the unused line
+          if (line==newline)
+              delete histline;
+          else
+              delete newline;
+   
+    // 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);
+          }
+          break;
+        }
+       // Backspace
+        else if ( (ind>0) && 
+                 ((c == BBTK_BACKSPACE_KBCODE) ||
+                  (c == BBTK_DEL_KBCODE)) )
+         {
+           line[ind--]=' ';
+           BackSpace();
+         }
+       // Tab 
+       else if (c=='\t')
+         {
+           // TODO : Command completion  
+           std::vector<std::string> commands;
+           FindCommandsWithPrefix( line,ind,commands);
+           if (commands.size()==1) 
+             {
+               std::string com = *commands.begin();
+               for (; ind<com.size(); ++ind) 
+                 {
+                   PrintChar(com[ind]); 
+                   line[ind]=com[ind];
+                 }
+               PrintChar(' '); 
+               line[ind++]=' ';
+             }
+           else if (commands.size()>1) 
+             {
+               std::vector<std::string>::iterator i;
+               write(1,"\n",1);
+               for (i=commands.begin();i!=commands.end();++i) 
+                 {
+                   write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
+                   PrintChar(' ');
+                 }
+               write(STDOUT_FILENO,"\n> ",3);
+               //for (int j=0;j<ind;++j) 
+                 //{
+                   write(STDOUT_FILENO,line,ind); 
+                   //  }
+             }
+         }
+       // Arrow up : back in history
+       else if (c==BBTK_UP_ARROW_KBCODE)
+         {
+           if (hist) 
+             {
+               // erase current line
+               while (ind--) BackSpace();
+               // 
+               hist--;
+               // 
+               strcpy(histline,mHistory[hist]);
+               line = histline;
+               ind = strlen(line);
+               
+               write(STDOUT_FILENO,line,ind);
+             }
+         }
+       // Arrow down : down in history
+       else if (c==BBTK_DOWN_ARROW_KBCODE)
+         {
+           if (hist<mHistory.size()-1) 
+             {
+               // erase current line
+               while (ind--) BackSpace();
+               // 
+               hist++;
+               // 
+               strcpy(histline,mHistory[hist]);
+               line = histline;
+               ind = strlen(line);
+               
+               write(STDOUT_FILENO,line,ind);
+             }
+           // end of history : switch back to newline
+           else if (hist==mHistory.size()-1)
+             {
+               // erase current line
+               while (ind--) BackSpace();
+               // 
+               hist++;
+               // 
+               line = newline;
+               ind = strlen(line);
+               
+               write(STDOUT_FILENO,line,ind);
+             }
+         }
+       // Arrow right
+       else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
+         {
+           PrintChar(line[ind]);
+           ind++;
+         }
+
+       // Arrow left
+       else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
+         {
+           PrintChar('\b');
+           ind--;
+    
+         }
+
+      }
+    write(STDOUT_FILENO,"\n\r",2);
+    
+    
+    s = line;
+    
+  }
+#else
+
+  //=======================================================================
+  void InterpreterVirtual::GetLineFromPrompt(std::string& s)
+  {  
+    s.clear();
+
+    putchar('>');
+    putchar(' ');
+
+    do 
+    {
+      char c = getchar();
+      if (c=='\n') 
+      {
+        putchar('\n');
+        break;
+      }
+      if (c=='\t') 
+      {
+        // putchar('T');
+        continue;
+      }
+      // putchar(c);
+      s += c;
+    } 
+    while (true);  
+    
+  }
+  //=======================================================================  
+
+#endif
+
+
+
+  //=======================================================================
+  void InterpreterVirtual::CommandLineInterpreter()
+  {
+    bbtkDebugMessageInc("interpreter",9,
+                        "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
+
+#ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
+    // Initialise the tty in non canonical mode with no echo
+    // oter remembers the previous settings to restore them after 
+    struct termios ter,oter;
+    tcgetattr(0,&ter);
+    oter=ter;
+    ter.c_lflag &= ~ECHO;
+    ter.c_lflag &= ~ICANON;
+    ter.c_cc[VMIN]=1;
+    ter.c_cc[VTIME]=0;
+    tcsetattr(0,TCSANOW,&ter);
+#endif
+    
+    mCommandLine = true;
+    bool again = true;
+    // bool insideComment = false; // for multiline comment  
+    mInsideComment = false;
+    do 
+    {
+      try
+      {
+        std::string line;
+        GetLineFromPrompt(line);
+        DoInterpretLine(line); //, insideComment);
+      }
+      /*
+      catch (QuitException e)
+      {
+       bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
+        again = false;
+      }
+      */
+      catch (bbtk::Exception e) 
+      {
+        e.Print();
+      }
+        catch (std::exception& e) 
+      {
+        std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
+      }
+      catch (...)
+      {
+        std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
+      }
+    }
+    while (again);
+
+#ifdef BBTK_USE_TERMIOS_BASED_PROMPT
+    tcsetattr(0,TCSANOW,&oter);
+#endif
+
+    std::cout << "Good bye !" << std::endl;
+
+    bbtkDebugDecTab("interpreter",9);
+  }
+
+//=======================================================================
+void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
+{
+}
+//=======================================================================
+
+
+//=======================================================================
+void  InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
+{
+}
+//=======================================================================
+
+
+//=======================================================================
+void  InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
+{
+}
+//=======================================================================
+
+
+
+ //==========================================================================
+  void InterpreterVirtual::commandDebug(const std::string& name)
+  {
+  }
+ //==========================================================================
+
+  /*
+  //==========================================================================
+  // Adds a callback when 'break' command issued
+  void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
+  {
+    mBreakSignal.connect(c);
+  }
+ //==========================================================================
+ */
+
+ //==========================================================================
+  std::string InterpreterVirtual::GetObjectName() const
+  {
+    return std::string("InterpreterVirtual");
+  }
+  //==========================================================================
+  
+  //==========================================================================
+  std::string  InterpreterVirtual::GetObjectInfo() const 
+  {
+    std::stringstream i;
+    return i.str();
+  }
+  //==========================================================================
+
+  //==========================================================================
+size_t  InterpreterVirtual::GetObjectSize() const 
+{
+  size_t s = Superclass::GetObjectSize();
+  s += InterpreterVirtual::GetObjectInternalSize();
+  return s;
+  }
+  //==========================================================================
+  //==========================================================================
+size_t  InterpreterVirtual::GetObjectInternalSize() const 
+{
+  size_t s = sizeof(InterpreterVirtual);
+  return s;
+  }
+  //==========================================================================
+  //==========================================================================
+  size_t  InterpreterVirtual::GetObjectRecursiveSize() const 
+  {
+    size_t s = Superclass::GetObjectRecursiveSize();
+    s += InterpreterVirtual::GetObjectInternalSize();
+    return s;
+  }
+  //==========================================================================
+}//namespace
+
+