]> Creatis software - bbtk.git/blob - kernel/src/bbtkInterpreter.cxx
no message
[bbtk.git] / kernel / src / bbtkInterpreter.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkInterpreter.cxx,v $
4   Language:  C++
5   Date:      $Date: 2010/09/17 15:56:51 $
6   Version:   $Revision: 1.90 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  *  \file 
33  *  \brief class Interpreter :
34  */
35
36 #include "bbtkInterpreter.h"
37 #include "bbtkExecuter.h"
38 #include "bbtkTranscriptor.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkConfigurationFile.h"
41 #include "bbtkUtilities.h"
42 #include "bbtkAtomicBlackBox.h"
43 #include "bbtkWxBlackBox.h"
44 #include <sys/stat.h>
45 #include <algorithm>
46 #ifdef CMAKE_HAVE_TERMIOS_H
47 #include <termios.h>
48 #define BBTK_USE_TERMIOS_BASED_PROMPT
49 #endif
50
51 #include <string>
52
53 namespace bbtk
54 {
55
56  //=======================================================================
57   Interpreter::Pointer Interpreter::New(const std::string& cpp_file) 
58   {
59     bbtkDebugMessage("kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
60     return MakePointer(new Interpreter(cpp_file));
61   }
62  //=======================================================================
63
64  //=======================================================================
65   Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e) 
66   {
67     bbtkDebugMessage("kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
68     return MakePointer(new Interpreter(e));
69   }
70  //=======================================================================
71
72  //=======================================================================
73   Interpreter::Interpreter(const std::string& cpp_file) 
74   {
75     bbtkDebugMessage("object",2,"==> Interpreter("<<cpp_file<<")"<<std::endl);
76     Init(VirtualExec::Pointer(), cpp_file);
77     bbtkDebugMessage("object",2,"<== Interpreter("<<cpp_file<<")"<<std::endl);
78   }
79   //=======================================================================
80
81  //=======================================================================
82   Interpreter::Interpreter(VirtualExec::Pointer e) 
83   {
84     bbtkDebugMessage("object",2,"==> Interpreter(VirtualExec)"<<std::endl);
85     Init(e,"");
86     bbtkDebugMessage("object",2,"<== Interpreter(VirtualExec)"<<std::endl);
87   }
88   //=======================================================================
89
90   //=======================================================================
91   void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file) 
92   {
93     if (e)
94       {
95         mVirtualExecuter = e;
96       }
97     else if (cpp_file.size()!=0)
98       {
99         mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
100       }
101     else 
102       {
103         bbtk::Executer::Pointer exe = bbtk::Executer::New();
104         mRealExecuter = exe;
105         mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
106       }
107
108           
109           
110     // Lock this pointer or will auto-destruct !!
111     if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
112
113           
114           bbtk::InterpreterVirtual::Init();
115   } 
116   //=======================================================================
117   
118   
119   
120   //=======================================================================  
121   /**
122    *  
123    */
124   Interpreter::~Interpreter()
125   {
126     bbtkDebugMessage("object",2,"==> ~Interpreter()" <<std::endl);
127     mVirtualExecuter = VirtualExec::Pointer();
128     bbtkDebugMessage("object",2,"<== ~Interpreter()" <<std::endl);
129   }
130   //=======================================================================
131
132 /*EED Borrame
133   //=======================================================================
134   InterpreterException::InterpreterException( const std::string& message,
135                                       bool in_script_file,
136                                       const std::string& script_file,
137                                       int script_line 
138                                       )
139     : Exception("interpreter",0,message),
140       mInScriptFile(in_script_file),
141       mScriptFile(script_file),
142       mScriptLine(script_line)
143   {
144   }
145   //=======================================================================
146   //=======================================================================
147   InterpreterException::InterpreterException( const Exception& excep,
148                       bool in_script_file,
149                       const std::string& script_file,
150                       int script_line 
151                       )
152     : Exception(excep),
153       mInScriptFile(in_script_file),
154       mScriptFile(script_file),
155       mScriptLine(script_line)
156   {
157   }
158   //=======================================================================
159 */
160
161   //=======================================================================
162   void Interpreter::CatchInterpreterException( const InterpreterException& e )
163   {
164     if (GetExecuter()->GetNoErrorMode()) 
165       {
166         bbtkWarning("ERROR :"<<e.GetErrorMessage()
167                     <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
168                     <<" skipped");
169
170         return;
171       }
172           
173           bbtk::InterpreterVirtual::CatchInterpreterException(  e );      
174   }
175   //=======================================================================
176
177   //=======================================================================
178   void Interpreter::CatchBbtkException( const bbtk::Exception& e )
179   {
180     if (GetExecuter()->GetNoErrorMode()) 
181       {
182         std::string file("?");
183         int line = 0;
184         if (mFileName.size()) {
185           file = mFileName.back();
186           line = mLine.back();
187         }    
188         bbtkWarning("ERROR '"<<e.GetErrorMessage()
189                     <<"' ("<<file<<":"<<line<<") skipped");
190         
191         return;
192       }
193           
194           bbtk::InterpreterVirtual::CatchBbtkException(  e );     
195   }
196   //=======================================================================
197   
198   //=======================================================================
199   void Interpreter::CatchStdException( const std::exception& e )
200   {  
201         if (GetExecuter()->GetNoErrorMode()) 
202         {
203                 std::string file("?");
204                 int line = 0;
205                 if (mFileName.size()) 
206                 {
207                         file = mFileName.back();
208                         line = mLine.back();
209                 }    
210                 bbtkWarning("ERROR '"<<e.what() <<"' ("<<file<<":"<<line<<") skipped");
211                 return;
212       }
213           bbtk::InterpreterVirtual::CatchStdException(  e );      
214   }
215   //=======================================================================
216
217   //=======================================================================
218   void Interpreter::CatchUnknownException()
219   {
220         if (GetExecuter()->GetNoErrorMode()) 
221         {
222                 std::string file("?");
223                 int line = 0;
224                 if (mFileName.size()) 
225                 {
226                         file = mFileName.back();
227                         line = mLine.back();
228                 }  
229                 bbtkWarning("UNDEFINED ERROR " <<"("<<file<<":"<<line<<") skipped");
230                 return;
231         }
232
233           bbtk::InterpreterVirtual::CatchUnknownException( );     
234   }
235   //=======================================================================
236
237   //=======================================================================
238   
239 #define CATCH_MACRO                                     \
240   catch (InterpreterException e)                        \
241     {                                                   \
242       CatchInterpreterException(e);                     \
243     }                                                   \
244   catch (bbtk::Exception e)                             \
245     {                                                   \
246       CatchBbtkException(e);                            \
247     }                                                   \
248   catch (std::exception& e)                             \
249     {                                                   \
250       CatchStdException(e);                             \
251     }                                                   \
252   catch (...)                                           \
253     {                                                   \
254       CatchUnknownException();                          \
255     }                                           
256   //=======================================================================
257    
258 /*EED Borrame
259   //=======================================================================
260   Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
261   {
262     bbtkDebugMessage("interpreter",4,"==> Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
263
264     bool exm = mCommandLine;
265     mCommandLine = false;
266
267     try 
268     {
269       mStatus = Interpreter_OK;
270       SwitchToFile(filename,source);
271       mInsideComment = false;
272       InterpretCurrentStreams();
273     } 
274     CATCH_MACRO;
275     
276     bbtkDebugMessage("interpreter",4,
277                      "<== Interpreter::InterpretFile(\""
278                      <<filename<<"\")"<<std::endl);
279
280
281     mCommandLine = exm;
282     
283     return mStatus;
284   }
285   //=======================================================================
286
287
288   //=======================================================================
289   Interpreter::ExitStatus 
290   Interpreter::InterpretBuffer( std::stringstream* buffer )
291   {
292     bbtkDebugMessage("interpreter",4,"==> Interpreter::InterpretBuffer()"<<std::endl);
293
294     bool exm = mCommandLine;
295     mCommandLine = false;
296
297     try 
298     {
299       mStatus = Interpreter_OK;
300       SwitchToStream(buffer);
301       mInsideComment = false;
302       InterpretCurrentStreams();
303     }
304     CATCH_MACRO;
305     
306     //    CloseAllFiles();
307     bbtkDebugMessage("interpreter",4,"<== Interpreter::InterpretBuffer()"<<std::endl);
308
309     
310     mCommandLine = exm;
311     return mStatus;
312   }
313   //=======================================================================
314
315   //=======================================================================
316   /// Interprets the currently open streams
317   Interpreter::ExitStatus Interpreter::InterpretCurrentStreams()
318   {
319     bbtkDebugMessage("interpreter",4,
320                      "==> Interpreter::InterpretCurrentStreams()"<<std::endl);
321
322     while (mFile.size()>0) 
323       {
324         while (!mFile.back()->eof()) {
325           mLine.back()++;
326           char buf[500];
327           mFile.back()->getline(buf,500);
328           std::string str(buf);
329           //size 0 JCP 21-09-2009
330           int size=str.length();
331           if(size != 0){
332                   if ( str[ size-1 ]==13  )
333             {
334               str.erase(size-1,1);
335             }
336                   try
337                         {
338                           DoInterpretLine(str);
339                         }
340                   CATCH_MACRO;
341           }
342           
343         } 
344         CloseCurrentFile();
345       }
346     bbtkDebugMessage("interpreter",4,
347                      "<== Interpreter::InterpretCurrentStreams()"<<std::endl);
348
349     return mStatus;
350   }
351   //=======================================================================
352
353   //=======================================================================
354   /// Runs the interpretation of a command
355   Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
356   {
357     bbtkDebugMessage("interpreter",5,"==> Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
358
359     try 
360     {
361       mStatus = Interpreter_OK;
362       mInsideComment = false;
363 //std::cout<<"JCP bbtkInterpreter.cxx Interpreter::InterpretLine("<<std::endl;
364       DoInterpretLine(line );
365     }
366     CATCH_MACRO;
367     
368     
369    bbtkDebugMessage("interpreter",5,"<== Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
370     
371     return mStatus;
372   }
373   //=======================================================================  
374 */
375         
376         
377         void Interpreter::commandNew(std::string boxType, std::string boxName)  //virtual
378     {
379                 mVirtualExecuter->Create(boxType,boxName);
380     }
381         
382         void Interpreter::commandDelete(std::string boxName)  //virtual
383     {
384                 mVirtualExecuter->Destroy(boxName);
385     }
386
387         void Interpreter::commandConnection(std::string nodeFrom, std::string outputLabel, std::string nodeTo, std::string inputLabel) //virtual
388     {
389                 mVirtualExecuter->Connect(nodeFrom,outputLabel,nodeTo,inputLabel);
390     }
391                 
392         void Interpreter::commandPackage(std::string packageName) //virtual
393     {
394                 mVirtualExecuter->BeginPackage(packageName);
395     }
396         
397         void Interpreter::commandEndPackage() //virtual
398     {
399                 mVirtualExecuter->EndPackage();
400     }
401         
402         void Interpreter::commandDefine(std::string name, std::string pack, std::string scriptfilename) //virtual
403     {
404                 mVirtualExecuter->Define(name,pack,scriptfilename);
405     }
406
407         void Interpreter::commandEndDefine() //virtual
408     {
409                 mVirtualExecuter->EndDefine();
410     }
411
412         void Interpreter::commandKind(std::string kind) //virtual
413     {
414                 mVirtualExecuter->Kind(kind);
415     }
416         
417         void Interpreter::commandPrint(std::string value) //virtual
418     {
419                 mVirtualExecuter->Print(value);
420     }
421         
422         
423         void Interpreter::commandExec(std::string word) //virtual
424     {
425                 if (word=="freeze") 
426                 {
427                         mVirtualExecuter->SetNoExecMode(true);
428                         mThrow = false;
429                 }
430                 else if (word=="freeze_no_error") 
431                 {
432                         mVirtualExecuter->SetNoExecMode(true);
433                         mVirtualExecuter->SetNoErrorMode(true);
434                         mThrow = false;
435                 }
436                 else if (word=="unfreeze") 
437                 {
438                         mVirtualExecuter->SetNoExecMode(false);
439                         mVirtualExecuter->SetNoErrorMode(false);
440                 }
441                 else
442                 {
443                         mVirtualExecuter->Execute(word);
444                 } // if
445     }
446         
447         
448         void Interpreter::commandInput(std::string name, std::string box, std::string input,std::string  help) //virtual
449     {
450                 mVirtualExecuter->DefineInput(name,box,input,help);
451     }
452         
453         void Interpreter::commandOutput(std::string name, std::string box, std::string output,std::string  help) //virtual
454     {
455                 mVirtualExecuter->DefineOutput(name,box,output,help);
456     }
457         
458         void Interpreter::commandSet(std::string box, std::string input, std::string value) //virtual
459     {
460                 mVirtualExecuter->Set(box,input,value);
461     }
462
463         void Interpreter::commandAuthor(std::string author) //virtual
464     {
465                 mVirtualExecuter->Author(author);
466     }
467
468         void Interpreter::commandCategory(std::string categorytype) //virtual
469     {
470                 mVirtualExecuter->Category(categorytype);
471     }
472         
473         void Interpreter::commandDescription(std::string description) //virtual
474     {
475                 mVirtualExecuter->Description(description);
476     }
477
478         
479         void Interpreter::commandClear() //virtual
480     {
481                 mVirtualExecuter->Clear();
482     }
483         
484         void Interpreter::commandInclude(std::string word, bool ok) //virtual
485     {
486                 // if 'source' was given (words.size()==3) then tell to set the 
487                 // source file name of the current complex box with the full file name included
488                 if (mCommandLine)
489                 {
490                         InterpretFile(word, ok ); 
491                 }
492                 else
493                 {
494                         SwitchToFile(word , ok );
495                 }
496     }
497         
498         
499         void Interpreter::commandLoad(std::string packageName) //virtual
500     {
501                 GetExecuter()->LoadPackage(packageName);
502     }
503
504         void Interpreter::commandUnload(std::string packageName) //virtual
505     {
506                 GetExecuter()->UnLoadPackage(packageName);
507     }
508         
509         void Interpreter::commandBreak() //virtual
510     {
511             /*
512                  std::cout << "BreakException(" 
513                  <<in_script<<","
514                  <<file<<","
515                  <<line<<")"<<std::endl;
516                  */
517                 bbtkError("break");//,in_script,file,line);
518             //      throw BreakException(in_script,file,line);
519     }
520         
521         void Interpreter::commandQuit() //virtual
522     {
523                 bbtkError("quit");//,in_script,file,line);
524                 //throw QuitException(in_script,file,line);
525     }
526         
527         void Interpreter::commandMessage() //virtual
528     {
529                 mVirtualExecuter->HelpMessages();
530     }
531         
532 //ups2 EED Borrame      
533         void Interpreter::commandMessage(std::string kind, std::string levelstr) //virtual
534     {
535                 int level=0;
536                 sscanf(levelstr.c_str(),"%d",&level);
537                 mVirtualExecuter->SetMessageLevel(kind,level);
538
539     }
540         
541         
542 /*EED Borrame   
543   //=======================================================================  
544   void Interpreter::DoInterpretLine( const std::string& line ) //virtual
545    {
546     bbtkDebugMessage("interpreter",6,"==> Interpreter::DoInterpretLine(\""
547                      <<line<<"\")"<<std::endl);
548     std::vector<std::string> words;
549     SplitLine(line,words);
550
551     // Empty line
552     if (words.size()<1) 
553     {
554        bbtkDebugDecTab("interpreter",9);
555        return;
556     }
557
558     // Single line comment : # or //
559     if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') ) 
560     {  
561        bbtkDebugDecTab("interpreter",9);
562        bbtkMessage("interpreter",9,"Comment"<<std::endl);
563        return;
564     }
565
566     // Multi line comment ( / * ... * / ) -delimiters on different lines !-   <<<<<<<  / *     * /
567     
568     if (words[0][0]=='/' && words[0][1]=='*') 
569     {  
570        bbtkDebugDecTab("interpreter",9);
571        bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
572        mInsideComment = true;
573        return;
574     }
575
576     if (words[0][0]=='*' && words[0][1]=='/') 
577     {  
578        bbtkDebugDecTab("interpreter",9);
579        bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
580        if ( !mInsideComment ) {
581           bbtkDebugDecTab("interpreter",9);
582           bbtkMessage("interpreter",9,"Comment mismatch : '* /' with no matching '/ *'"<<std::endl);        <<<<<<<<< * /       / * 
583        }
584        mInsideComment = false;
585        return;
586     }
587
588     if (mInsideComment) 
589     {  
590        bbtkDebugDecTab("interpreter",9);
591        bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
592        return;
593     }
594
595     // Command 
596     CommandInfoType command;
597     InterpretCommand(words,command);
598 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
599     bbtkDebugMessage("interpreter",9,
600                      "Command='"<<command.keyword
601                       <<"' code="<<command.code<<std::endl); 
602           
603     std::string left,right,left2,right2;
604     std::string filename;
605
606 //ups1 EED borrame        
607     // message command
608     if (command.code==cMessage)
609       {
610         if (words.size()<3)
611           {
612                   commandMessage();
613 //EED Borrame       mVirtualExecuter->HelpMessages();
614           }
615         else
616           {
617                 commandMessage(words[1],words[2]);
618 //EED Borrame           sscanf(words[2].c_str(),"%d",&level);
619 //EED Borrame       mVirtualExecuter->SetMessageLevel(words[1],level);
620           }
621         return;
622       }
623     else 
624       {
625         bbtkMessage("echo",2,line<<std::endl);
626       }
627
628     // break and quit commands
629     if ((command.code==cBreak) || (command.code==cQuit))
630       {
631         bool in_script = false;
632         std::string file("");
633         int line = 0;
634
635         if (mFileName.size()) 
636           {
637             std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
638             if (fs!=0) in_script = true;          
639             file = mFileName.back();
640             line = mLine.back();
641           } 
642         if (command.code==cBreak)
643           {
644 //          std::cout << "BreakException(" 
645 //                    <<in_script<<","
646 //                    <<file<<","
647 //                    <<line<<")"<<std::endl;
648                   commandBreak();
649 //EED Borrame       bbtkError("break");//,in_script,file,line);
650             //      throw BreakException(in_script,file,line);
651           }       
652         else 
653           {
654                   commandQuit();
655 //EED Borrame       bbtkError("quit");//,in_script,file,line);
656               //throw QuitException(in_script,file,line);
657           }
658         return;
659       }   
660 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
661     // other cammands
662
663     switch (command.code) 
664       {
665       case cNew :
666                 commandNew(words[1],words[2]);
667 //EED Borrame        mVirtualExecuter->Create(words[1],words[2]);
668         break;
669
670       case cDelete :
671                           commandDelete(words[1]);
672 //EED Borrame   mVirtualExecuter->Destroy(words[1]);
673         break;
674
675       case cConnect :
676         Utilities::SplitAroundFirstDot(words[1],left,right);
677         Utilities::SplitAroundFirstDot(words[2],left2,right2);      
678         commandConnection(left,right,left2,right2);
679 //EED Borrame        mVirtualExecuter->Connect(left,right,left2,right2);
680         break;
681
682       case cPackage :
683                           commandPackage(words[1]);
684 //EED Borrame                mVirtualExecuter->BeginPackage(words[1]);
685         break;
686
687       case cEndPackage :
688                           commandEndPackage();
689 //EED Borrame        mVirtualExecuter->EndPackage();
690         break;
691
692       case cDefine :
693         if (mFileName.size()>0) 
694         {
695 //???                   commandDefine(????);
696                    filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
697         }
698         if (words.size()==2) 
699         {
700                         commandDefine(words[1],"",filename);
701 //EED Borrame           mVirtualExecuter->Define(words[1],"",filename);
702         }
703         else
704         {
705                         commandDefine(words[1],words[2],filename);
706 //EED Borrame           mVirtualExecuter->Define(words[1],words[2],filename);
707         }
708         break;
709
710       case cEndDefine :
711                 commandEndDefine();
712 //EED Borrame        mVirtualExecuter->EndDefine();
713         break;
714
715       case cKind :
716                         commandKind(words[1]);
717 //EED Borrame        mVirtualExecuter->Kind(words[1]);
718         break;
719
720       case cPrint :
721                           commandPrint(words[1]);
722 //EED Borrame        mVirtualExecuter->Print(words[1]);
723         break;
724                           
725       case cExec :
726                           commandExec(words[1]);
727 //EED Borrame        if (words[1]=="freeze") 
728 //EED Borrame     {
729 //EED Borrame       mVirtualExecuter->SetNoExecMode(true);
730 //EED Borrame       mThrow = false;
731 //EED Borrame     }
732 //EED Borrame   else if (words[1]=="freeze_no_error") 
733 //EED Borrame     {
734 //EED Borrame       mVirtualExecuter->SetNoExecMode(true);
735 //EED Borrame       mVirtualExecuter->SetNoErrorMode(true);
736 //EED Borrame       mThrow = false;
737 //EED Borrame     }
738 //EED Borrame   else if (words[1]=="unfreeze") 
739 //EED Borrame     {
740 //EED Borrame       mVirtualExecuter->SetNoExecMode(false);
741 //EED Borrame       mVirtualExecuter->SetNoErrorMode(false);
742 //EED Borrame     }
743 //EED Borrame   else
744 //EED Borrame     {
745 //EED Borrame       mVirtualExecuter->Execute(words[1]);
746 //EED Borrame     }
747                           
748         break;
749
750       case cInput :
751         Utilities::SplitAroundFirstDot(words[2],left,right);
752                           commandInput(words[1],left,right,words[3]);
753 //EED Borrame        mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
754         break;
755
756       case cOutput :
757         Utilities::SplitAroundFirstDot(words[2],left,right);
758                 commandOutput(words[1],left,right,words[3]);
759 //EED Borrame         mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
760         break;
761
762       case cSet :
763         Utilities::SplitAroundFirstDot(words[1],left,right);
764                 commandSet(left,right,words[2]);
765 //EED Borrame        mVirtualExecuter->Set(left,right,words[2]);
766         break;
767
768       case cAuthor :
769                 commandAuthor(words[1]);
770 //EED Borrame        mVirtualExecuter->Author(words[1]);
771         break;
772
773       case cNewGUI :
774                 commandNewGUI(words[1],words[2]);
775         break;
776
777       case cCategory :
778                 commandCategory(words[1]);
779 //EED Borrame   mVirtualExecuter->Category(words[1]);
780         break;
781
782       case cIndex :
783         if (words.size()==1)
784                         commandIndex("tmp_index.html");
785         else if (words.size()==2)
786                         commandIndex(words[1]);
787         else if (words.size()==3)
788                         commandIndex(words[1],words[2]);
789         break;
790
791       case cDescription :
792                 commandDescription(words[1]);
793 //EED Borrame        mVirtualExecuter->Description(words[1]);
794         break;
795
796       case cHelp :
797         commandHelp(words);
798         break;
799
800
801       case cGraph :
802         commandGraph(words);
803         break;
804
805       case cConfig :
806         commandConfig();
807         break;
808
809       case cReset :  
810         commandReset();
811         break;
812         
813       case cClear :  
814                 commandClear();
815 //EED Borrame           mVirtualExecuter->Clear();
816         break;
817
818       case cInclude :
819                           commandInclude( words[1] , (words.size()==3) );
820 //EED Borrame           // if 'source' was given (words.size()==3) then tell to set the 
821 //EED Borrame           // source file name of the current complex box with the full file name included
822 //EED Borrame           if (mCommandLine)
823 //EED Borrame        {
824 //EED Borrame           InterpretFile(words[1],(words.size()==3)); 
825 //EED Borrame        } else{
826 //EED Borrame            SwitchToFile(words[1],(words.size()==3) );
827 //EED Borrame        }
828                 break;
829
830       case cLoad:
831                 commandLoad( words[1] );
832 //EED Borrame        GetExecuter()->LoadPackage(words[1]);
833         break;
834
835       case cUnload:
836                 commandUnload( words[1] );
837 //EED Borrame        GetExecuter()->UnLoadPackage(words[1]);
838         break;
839
840       case cDebug :
841                           if (words.size()==2) commandDebug(words[1]);
842                                 else commandDebug("");
843         break;
844                           
845         // obsolete
846     //  case cWorkspace :
847     //    if (words.size() == 2) 
848     //    {
849     //       if (words[1]=="freeze")        mVirtualExecuter->SetNoExecMode(true);
850     //       else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
851     //    }
852     //    else
853     //    {
854     //       mVirtualExecuter->SetWorkspaceName(words[2]);
855     //    }
856     //    break;
857
858                 default:
859         bbtkInternalError("should not reach here !!!");
860    }
861
862     bbtkDebugMessage("interpreter",6,"<== Interpreter::DoInterpretLine(\""
863                      <<line<<"\")"<<std::endl);
864     
865   }
866   //=======================================================================  
867
868
869
870
871   //=======================================================================
872   void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
873 {
874     bbtkDebugMessage("interpreter",9,"==> Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
875
876     std::string delimiters = "\"";
877     std::vector<std::string> quote;
878     Utilities::SplitString(str,delimiters,quote);
879
880     delimiters = " \t";
881     std::vector<std::string>::iterator i;
882     for (i=quote.begin(); i!=quote.end(); ) 
883     {
884        Utilities::SplitString(*i,delimiters,tokens);
885        ++i;
886        if (i!=quote.end()) 
887        {
888         //    bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
889           tokens.push_back(*i);
890           ++i;
891        }
892     }
893
894     for (i=tokens.begin(); i!=tokens.end(); ++i) 
895     {
896       bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
897     }
898     bbtkDebugMessage("interpreter",9,"<== Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
899
900  }
901   //=======================================================================
902 */
903
904
905   //=======================================================================
906   void Interpreter::commandReset()  // virtual
907   {
908     // Cannot close all files if the reset command is read from a file !
909     CloseAllFiles();
910     mFileNameHistory.clear();
911     this->mVirtualExecuter->Reset();
912   }
913   //=======================================================================
914
915   //=======================================================================
916   /**
917    *
918    */
919   /*
920   void Interpreter::Print( const std::string& str)
921   {
922     if (mVirtualExecuter->GetNoExecMode()) return;
923
924     bbtkDebugMessageInc("interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
925
926  // TO DO :
927  // InterpretLine ("load std")
928  // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande 
929  // InterpretLine("new Print _P_") 
930  // InterpretLine("connect _C_.Out _P_.In")
931  // int num = 1
932  
933
934     std::vector<std::string> chains;
935     std::string delimiters("$");
936
937     // Skip delimiters at beginning.
938     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
939     bool is_text = true;
940     if (lastPos>0) is_text = false;
941
942     // Find first delimiter.
943     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
944
945     while (std::string::npos != pos || std::string::npos != lastPos)
946     {
947        if (is_text) 
948        {
949           // Found a text token, add it to the vector.
950           chains.push_back(str.substr(lastPos, pos - lastPos));
951  // std::string token = str.substr(lastPos, pos - lastPos)
952  // InterpretLine("set _C_.In%num% %token%")
953  
954        }
955        else 
956        {
957
958        // is an output (between $$) : decode 
959          std::string tok,box,output;
960          tok = str.substr(lastPos, pos - lastPos);
961          Utilities::SplitAroundFirstDot(tok,box,output);
962          chains.push_back( mVirtualExecuter->Get(box,output) );
963
964 // InterpretLine("connect %tok% _C_.In%num%") 
965
966        }
967         // Skip delimiters.  Note the "not_of"
968        lastPos = str.find_first_not_of(delimiters, pos);
969         // Find next delimiter
970        pos = str.find_first_of(delimiters, lastPos);
971     //
972        is_text = !is_text;
973 // num ++;
974      }
975 // InterpretLine("exec _P_")
976 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
977
978      std::vector<std::string>::iterator i;
979      for (i= chains.begin(); i!=chains.end(); ++i) 
980      {
981
982        Utilities::SubsBackslashN(*i);
983        std::cout << *i;
984      }
985      std::cout << std::endl;
986      bbtkDebugDecTab("interpreter",9);
987  }
988 */
989
990   //=======================================================================
991   /**
992    *
993    */
994 /*EED Borrame
995   // =========================================================================
996   void Interpreter::SwitchToFile( const std::string& name , bool source )
997   {
998   // Note : in the following :
999   // name : the user supplied name 
1000   //      - abreviated name    e.g.       scr   scr.bbs
1001   //      - relative full name e.g.       ./scr.bbs   ../../scr.bbs 
1002   //      - absolute full name e.g.       /home/usrname/proj/dir/scr.bbs
1003   //          same for Windows, with      c:, d: ...
1004   //
1005   // use ./directory/subdir/scrname.bbs
1006   //
1007
1008     bbtkDebugMessage("interpreter",4,"==> Interpreter::SwitchToFile( \""
1009                      <<name<<"\")"<<std::endl);
1010
1011     std::vector<std::string> script_paths;
1012     std::string fullPathScriptName;  // full path script name
1013     std::string pkgname;             // e.g. <scriptname>.bbs
1014     std::vector<std::string> Filenames;
1015
1016     // The following is *NOT* a debug time message :
1017     // It's a user intended message.
1018     // Please don't remove it.
1019     bbtkMessage("interpreter",1,
1020         "look for : [" << name
1021         << "]" << std::endl);
1022
1023
1024     std::string upath;
1025     pkgname = Utilities::ExtractScriptName(name,upath);
1026
1027     bbtkMessage("interpreter",3,
1028                 "package name:[" << pkgname
1029                  << "] path:[" << upath << "]" << std::endl);
1030     bool fullnameGiven = false; 
1031     bool foundFile     = false;
1032
1033     // ==== "*" provided : load all scripts in given path 
1034     // relative (e.g. std/boxes/ *) or absolute      <<<<<<<< / *
1035     if (pkgname == "*") 
1036       {
1037
1038         std::stringstream* stream = new std::stringstream;
1039         //if (upath.size()!=0) // avoid troubles for "*"
1040         
1041         // ==== no path provided : look in root bbs path
1042         if (upath.size()==0)
1043           {
1044             //      bbtkMessage("interpreter",1,
1045             // LG : add all bbs path
1046             //  script_paths.push_back(  ConfigurationFile::GetInstance().Get_root_bbs_path() );
1047             std::vector<std::string>::const_iterator i;
1048             for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1049                  i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1050                  i++)
1051               {
1052                 script_paths.push_back(*i);
1053               }
1054           }
1055         // ==== absolute path provided 
1056         else if (upath[0]=='/' || upath[1] == ':' ) 
1057           {
1058             if ( Utilities::IsDirectory( upath ) )
1059               {
1060                 script_paths.push_back(upath);
1061               }
1062             else 
1063               {
1064                 bbtkError("'"<<upath<<"' : directory does not exist"); 
1065               }
1066           }
1067         // ==== relative path provided : search all bbs path appended with 
1068         // the relative path provided
1069         else
1070           {    
1071             std::vector<std::string>::const_iterator i;
1072             for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1073                  i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1074                  i++)
1075               {
1076                 std::string full_path(*i);
1077                 // we *really* want '.' to be the current working directory
1078                 if (full_path == ".") 
1079                   {
1080                     char buf[2048]; // for getcwd
1081                     char * currentDir = getcwd(buf, 2048);
1082                     std::string cwd(currentDir);
1083                     full_path = currentDir;
1084                   } // if full_path
1085                 
1086                 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1087                 full_path += upath;
1088                 
1089                 if ( Utilities::IsDirectory( full_path ) )
1090                   {
1091                     script_paths.push_back(full_path);
1092                   }
1093               } 
1094             if (script_paths.empty())
1095               {
1096                 bbtkError("no '"<<upath<<"' subdir found in search paths" 
1097                           << std::endl);
1098               }
1099           }
1100         
1101         
1102         // === search paths list complete : now explore it
1103         int nbBssFiles = 0;     
1104         // ==== relative name, iterate + load all .bbs/.bbp files
1105         std::vector<std::string>::iterator i;
1106         for (i=script_paths.begin();i!=script_paths.end();i++)
1107           {
1108             bbtkMessage("interpreter",1,
1109                         "--> Looking in '" << *i << "'" << std::endl);
1110             
1111             Filenames.clear();
1112             //int nbFiles = 
1113             Utilities::Explore(*i, false, Filenames);
1114             
1115             for (std::vector<std::string>::iterator j = Filenames.begin(); 
1116                  j!= Filenames.end(); ++j)
1117               {
1118                 int lgr = (*j).size();
1119                 if (lgr < 5) continue;  
1120                 // ignore non .bbp file
1121                 if ( (*j).substr(lgr-4, 4) != ".bbp") continue; 
1122                 
1123                 (*stream) << "include \"" << *j << "\"\n";
1124                 bbtkMessage("interpreter",2,"  --> Found '" << *j << "'" << std::endl);
1125                 
1126                 nbBssFiles++;
1127               } // for (std::vector...
1128           } // for (i=script_...
1129
1130         // === Result ...
1131         if (nbBssFiles==0)
1132           {
1133             bbtkMessage("interpreter",1,
1134                         "  --> No .bbp found"<< std::endl);
1135           } 
1136         else 
1137           {
1138             bbtkMessage("interpreter",1,
1139                         "  --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1140             SwitchToStream(stream);
1141           }
1142         return;
1143       }  
1144     //=============== end pkgname=="*" ===========
1145     
1146     
1147     // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1148     // (not only a plain script name)
1149     // we trust him, and try to expland the directory name
1150     // WARNING : starting from current local directory :  ./whatYouWant  (./ mandatory!)
1151
1152     if (name[0]=='/' || name[1] == ':' || name[0]=='.')  // absolute path (linux/windows) or relative path
1153     { 
1154
1155       // ===========================================================check user supplied location
1156       fullnameGiven = true;
1157
1158       fullPathScriptName =  Utilities::ExpandLibName(name, false);
1159
1160       // allow user to always forget ".bbs"
1161       int l = fullPathScriptName.size();
1162
1163       if (l!=0) 
1164           {
1165          if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1166                          (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1167          {
1168                         std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1169                         if ( Utilities::FileExists(tfullPathScriptName) )
1170                         {
1171                                 fullPathScriptName = tfullPathScriptName;
1172                                 foundFile = true;
1173                         }
1174                         else 
1175                         {
1176                                 tfullPathScriptName = fullPathScriptName + ".bbp";
1177                                 if ( Utilities::FileExists(tfullPathScriptName) )
1178                                 {
1179                                         fullPathScriptName = tfullPathScriptName;
1180                                         foundFile = true;
1181                                 }
1182                         }
1183                  }
1184                  else 
1185                  {
1186                         if ( Utilities::FileExists(fullPathScriptName) )
1187                         {
1188                                 foundFile = true;
1189                         }
1190                  }
1191           } // endif l != 0
1192   }
1193   else
1194   // =============================== iterate on the paths
1195   {
1196       script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1197       std::string path;
1198       std::vector<std::string>::iterator i;
1199       for (i=script_paths.begin();i!=script_paths.end();++i)
1200           {
1201                 path = *i;
1202                 // we *really* want '.' to be the current working directory
1203                 if (path == ".") 
1204                 {
1205                         char buf[2048]; // for getcwd
1206                         char * currentDir = getcwd(buf, 2048);
1207                         std::string cwd(currentDir);
1208                         path = currentDir;
1209                 }
1210           
1211                 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1212 //Addition JCP tfullPathScriptName.size()>=4 
1213                 if(tfullPathScriptName.size()>=4){
1214                         if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1215                         {
1216                           fullPathScriptName = tfullPathScriptName;
1217                                 if ( ! Utilities::FileExists(fullPathScriptName) )
1218                                 {
1219                                         // The following is *NOT* a debug time message :
1220                                         // It's a user intended message.
1221                                         // Please don't remove it.
1222                                         bbtkMessage("interpreter",2,
1223                                   "   [" <<fullPathScriptName <<"] : does not exist" 
1224                                   <<std::endl);
1225                                         continue;  // try next path
1226                                 }
1227                                 bbtkMessage("interpreter",2,
1228                                           "   [" <<fullPathScriptName 
1229                                           <<"] : found" <<std::endl);
1230                                 foundFile = true;
1231                                 break; // a script was found; we stop iterating
1232                         }
1233                         else 
1234                         {
1235                                 fullPathScriptName = tfullPathScriptName + ".bbs";
1236                                 // Check if library exists
1237                                 if ( ! Utilities::FileExists(fullPathScriptName) )
1238                                 {
1239                                         fullPathScriptName = tfullPathScriptName + ".bbp";
1240                                         if ( ! Utilities::FileExists(fullPathScriptName) )
1241                                         {
1242                                                 // The following is *NOT* a debug time message :
1243                                                 // It's a user intended message.
1244                                                 // Please don't remove it.
1245                                                 bbtkMessage("interpreter",2,
1246                                                 "   [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist" 
1247                                                 <<std::endl);
1248                                                 continue;  // try next path
1249                                         }
1250                                 }
1251                                 bbtkMessage("interpreter",2,
1252                                   "   [" <<fullPathScriptName 
1253                                   <<"] : found" <<std::endl);
1254                                 foundFile = true;
1255                                 break; // a script was found; we stop iterating
1256                         }
1257                 }               
1258         } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1259   }
1260
1261     if (!foundFile)
1262       {
1263         if (fullnameGiven)
1264           if(fullPathScriptName == "")
1265             bbtkError("Path ["<<upath<<"] doesn't exist");
1266           else
1267             bbtkError("Script ["<<fullPathScriptName<<"] not found");
1268         else
1269           bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1270         return;
1271       }
1272     else
1273         {
1274       LoadScript(fullPathScriptName,name);
1275           if (source) SetCurrentFileName(fullPathScriptName);
1276         }
1277     
1278     return;
1279   }
1280   //=======================================================================
1281 */
1282
1283         //=======================================================================
1284         void Interpreter::SetCurrentFileName(std::string fullPathScriptName)  // virtual 
1285         {
1286                 GetExecuter()->SetCurrentFileName(fullPathScriptName);
1287         }       
1288         //=======================================================================
1289         
1290 /*EED Borrame   
1291   //=======================================================================
1292 void Interpreter::SwitchToStream( std::stringstream* stream )
1293 {
1294   bbtkDebugMessage("interpreter",4,"==> Interpreter::SwitchToStream()"
1295                    <<std::endl);
1296    mFile.push_back(stream);
1297     std::ostringstream buffer_name;
1298     bufferNb++;
1299     buffer_name << "buffer_" ;
1300
1301     if (mFileName.size()>0 )
1302     {
1303        buffer_name << mFileName.back() << "_" << mLine.back();
1304     }
1305     mFileName.push_back(buffer_name.str());
1306     mIncludeFileName.push_back(buffer_name.str());
1307     mLine.push_back(0);
1308 }
1309   //=======================================================================
1310 */
1311         
1312 /*      
1313   //=======================================================================
1314   void Interpreter::LoadScript( std::string fullPathScriptName,
1315                                 std::string includeScriptName)
1316   {
1317     bbtkDebugMessage("interpreter",4,"==> Interpreter::LoadScript("
1318                      <<fullPathScriptName<<")"
1319                      <<std::endl);
1320
1321     Utilities::replace( fullPathScriptName , 
1322                          INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1323    
1324      if (find(mFileNameHistory.begin(),
1325               mFileNameHistory.end(),
1326               fullPathScriptName)!=mFileNameHistory.end())
1327      {
1328         return;
1329      }
1330
1331     std::ifstream* s;
1332     s = new std::ifstream;
1333     s->open(fullPathScriptName.c_str());
1334     if (!s->good())
1335     {
1336         bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1337         return;
1338     }
1339
1340     bbtkMessage("interpreter",1,"   -->[" << fullPathScriptName 
1341                 << "] found" << std::endl);
1342
1343     mFile.push_back(s);
1344     mFileName.push_back(fullPathScriptName);
1345     mFileNameHistory.push_back(fullPathScriptName);
1346     mIncludeFileName.push_back(includeScriptName);
1347     mLine.push_back(0);
1348
1349     return;
1350   }
1351   //=======================================================================
1352 */
1353
1354 /*EED Borrame
1355   //=======================================================================
1356   void Interpreter::CloseCurrentFile()
1357   {
1358     bbtkDebugMessage("interpreter",9,"==> Interpreter::CloseCurrentFile()"
1359                       <<std::endl);
1360
1361     if (mFile.size()==0)
1362     {
1363       bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1364       return;
1365     }
1366
1367     bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1368
1369     std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1370     if (file!=0) file->close();
1371
1372     delete mFile.back();
1373     mFile.pop_back();
1374     mFileName.pop_back();
1375     mIncludeFileName.pop_back();
1376     mLine.pop_back();
1377
1378     bbtkDebugMessage("interpreter",9," Remains "
1379                      <<mFile.size()
1380                      <<" open"<<std::endl);
1381     bbtkDebugMessage("interpreter",9,"<== Interpreter::CloseCurrentFile()"
1382                      <<std::endl);
1383   }
1384   //=======================================================================
1385
1386  //=======================================================================
1387   void Interpreter::CloseAllFiles()
1388   {
1389     bbtkDebugMessage("interpreter",9,"==> Interpreter::CloseAllFiles()"
1390                       <<std::endl);
1391
1392     while (mFile.size() != 0) 
1393     {
1394        CloseCurrentFile();
1395     }
1396     bbtkDebugMessage("interpreter",9,"<== Interpreter::CloseAllFiles()"
1397                       <<std::endl);
1398   }
1399   //=======================================================================
1400
1401
1402   //=======================================================================
1403   void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1404                                       CommandInfoType& info )
1405   {
1406     bbtkDebugMessage("interpreter",9,"==> Interpreter::InterpretCommand(...)"<<std::endl);
1407
1408     // searches the command keyword
1409     CommandDictType::iterator c;
1410     c = mCommandDict.find(words[0]);
1411     if ( c == mCommandDict.end() ) {
1412       bbtkError(words[0]<<" : unknown command");
1413     }
1414
1415     // tests the number of args 
1416     if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1417          ( ((int)words.size())-1 > c->second.argmax ) )
1418     {
1419        commandHelp(words[0]);
1420        bbtkError(words[0]<<" : wrong number of arguments");
1421     }
1422 //std::cout<<"Interpreter::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1423     info = c->second;
1424
1425     bbtkDebugMessage("interpreter",9,"<== Interpreter::InterpretCommand(...)"<<std::endl);
1426
1427   }
1428   //=======================================================================
1429  */
1430
1431
1432   //=======================================================================
1433   /// Displays help on all the commands
1434 void Interpreter::commandHelp(const std::vector<std::string>& words)
1435 {
1436     unsigned int nbarg = words.size()-1;
1437
1438     if (nbarg==0) 
1439     {
1440        HelpCommands();
1441     }
1442     else if (nbarg==1) 
1443     {
1444       if (words[1]=="packages") 
1445       {
1446          GetExecuter()->GetFactory()->PrintHelpListPackages(true);
1447          return;
1448       }
1449       try 
1450       {
1451           commandHelp(words[1]);
1452       }
1453       catch (bbtk::Exception e) 
1454       {
1455          try 
1456          {
1457             GetExecuter()->GetFactory()->PrintHelpPackage(words[1]);
1458             if ( mUser != 0 )
1459               {
1460                 std::string url = 
1461                   ConfigurationFile::GetInstance().Get_doc_path();
1462                 url += "/bbdoc/" + words[1] + "/index.html";
1463                 if (Utilities::FileExists(url)) 
1464                   {
1465                     mUser->InterpreterUserViewHtmlPage(url);
1466                   }
1467               }
1468          }
1469          catch (bbtk::Exception f) 
1470          {
1471            try 
1472              {
1473                std::string package;
1474                GetExecuter()->GetFactory()->PrintHelpDescriptor(words[1],
1475                                                                 package);
1476                if ( mUser != 0 )
1477                  {
1478                    std::string url = 
1479                      ConfigurationFile::GetInstance().Get_doc_path();
1480                    url += "/bbdoc/" + package + "/index.html";
1481                    if (Utilities::FileExists(url)) 
1482                      {
1483                        url += "#" + words[1];
1484                        mUser->InterpreterUserViewHtmlPage(url);
1485                      }
1486                  }
1487              }
1488            catch (bbtk::Exception g) 
1489              {
1490                try
1491                  {
1492                    GetExecuter()->PrintHelpBlackBox(words[1],"0","9999");
1493                  }
1494                catch (bbtk::Exception h){
1495                  bbtkError("\""<<words[1].c_str()
1496                            <<"\" is not a known command, package, black box type or black box name");
1497                }
1498              }
1499          }
1500       }
1501     }
1502     else if (nbarg==2) 
1503     {
1504       if (words[2]=="all")
1505       {
1506          if ( words[1]=="packages" )
1507          {
1508             GetExecuter()->GetFactory()->PrintHelpListPackages(true,true);
1509             return;
1510           }
1511          try 
1512          {
1513             GetExecuter()->GetFactory()->PrintHelpPackage(words[1],true);
1514          }
1515          catch (bbtk::Exception f) 
1516          {
1517          }
1518      }
1519      else 
1520      {
1521         commandHelp(words[0]);
1522         bbtkError(words[0]<<" : syntax error");
1523      }
1524   }
1525   else 
1526   {
1527      bbtkError("Should not reach here !!!");
1528   }
1529 }
1530   //=======================================================================
1531
1532    //===================================================================    
1533   /// Displays the Configuration
1534   void Interpreter::commandConfig() const
1535   {
1536     ConfigurationFile::GetInstance().GetHelp(1);
1537   }  
1538    //===================================================================    
1539
1540   //=======================================================================
1541   /// Displays help on all the commands
1542   void Interpreter::HelpCommands()
1543   {
1544     std::cout << "Available commands :" << std::endl;
1545     CommandDictType::iterator i;
1546     for ( i =  mCommandDict.begin();
1547           i != mCommandDict.end();
1548         ++i) {
1549               std::cout << " " << i->first << std::endl;
1550       //      std::cout << "   usage : " << i->second.syntax << std::endl;
1551       //     std::cout << "    " << i->second.help << std::endl;
1552
1553     }
1554   }
1555   //=======================================================================
1556
1557
1558         
1559   //=======================================================================
1560   /// Displays help on a particular commands
1561   void Interpreter::commandHelp(const std::string& s)
1562   {
1563     CommandDictType::iterator c;
1564     c = mCommandDict.find(s);
1565     if ( c == mCommandDict.end() ) {
1566       bbtkError(s<<" : Unknown command");
1567     }   
1568     //    std::cout << " " << s << " : "<<  std::endl;
1569     //    CommandParamDictType::iterator i;
1570     //    for ( i =  c->second.begin();
1571     //      i != c->second.end();
1572     //      ++i) {
1573     std::cout << " usage : " << c->second.syntax << std::endl;
1574     std::cout << "  " << c->second.help << std::endl;
1575
1576   }
1577   //=======================================================================
1578
1579 /*EED Borrame
1580   //=======================================================================
1581   /// Fills the vector commands with the commands which 
1582   /// have the first n chars of buf for prefix
1583   /// TODO : skip initial spaces in buf and also return the position of first
1584   /// non blank char in buf
1585   void Interpreter::FindCommandsWithPrefix( char* buf,
1586                                             int n,
1587                                             std::vector<std::string>& commands )
1588   {
1589     CommandDictType::const_iterator i;
1590     for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1591     {
1592       if ((i->first).find(buf,0,n) == 0) 
1593         commands.push_back(i->first);
1594     }
1595   }
1596   //=======================================================================
1597 */
1598  
1599
1600 /*EED Borrame
1601   //=======================================================================
1602 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1603   
1604   inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1605   inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1606   
1607   // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1608   // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1609   // E.G. STORE THIS IN bbtk_config.xml
1610 #define BBTK_UP_ARROW_KBCODE    0x00415B1B
1611 #define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
1612 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1613 #define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
1614 #define BBTK_BACKSPACE_KBCODE   0x00000008
1615 #define BBTK_DEL_KBCODE         0x0000007F
1616 #define BBTK_SPACE_KBCODE       0x00000020 
1617
1618   //=======================================================================
1619   void Interpreter::GetLineFromPrompt(std::string& s)
1620   {
1621     int c;
1622     unsigned int ind=0;
1623
1624     unsigned int MAX_LINE_SIZE = 160;
1625     unsigned int MAX_HISTORY_SIZE = 100;
1626
1627     char* newline = new char[MAX_LINE_SIZE];
1628     memset(newline,0,MAX_LINE_SIZE);
1629     char* histline = new char[MAX_LINE_SIZE];
1630     memset(histline,0,MAX_LINE_SIZE);
1631
1632     char* line = newline;
1633     unsigned int hist = mHistory.size();
1634
1635     write(1,"> ",2);
1636     while(1)
1637     {
1638        c=0;
1639        read ( STDIN_FILENO, &c, 4) ;
1640
1641        bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1642
1643        // Printable character
1644        if ( (ind<MAX_LINE_SIZE-1) &&
1645             ( c >= BBTK_SPACE_KBCODE ) && 
1646             ( c <  BBTK_DEL_KBCODE )) 
1647        {
1648           PrintChar(c);
1649           line[ind++]=c;
1650        }
1651       // CR
1652        else if (c=='\n')
1653        {
1654        // delete the unused line
1655           if (line==newline)
1656               delete histline;
1657           else
1658               delete newline;
1659    
1660     // empty lines are not stored in from history
1661           if (strlen(line)) 
1662           {
1663              // if history too long : delete oldest command
1664              if (mHistory.size()>MAX_HISTORY_SIZE) 
1665              {
1666                 delete mHistory.front();
1667                 mHistory.pop_front();
1668              }
1669              mHistory.push_back(line);
1670           }
1671           break;
1672         }
1673        // Backspace
1674         else if ( (ind>0) && 
1675                   ((c == BBTK_BACKSPACE_KBCODE) ||
1676                    (c == BBTK_DEL_KBCODE)) )
1677           {
1678             line[ind--]=' ';
1679             BackSpace();
1680           }
1681         // Tab 
1682         else if (c=='\t')
1683           {
1684             // TODO : Command completion  
1685             std::vector<std::string> commands;
1686             FindCommandsWithPrefix( line,ind,commands);
1687             if (commands.size()==1) 
1688               {
1689                 std::string com = *commands.begin();
1690                 for (; ind<com.size(); ++ind) 
1691                   {
1692                     PrintChar(com[ind]); 
1693                     line[ind]=com[ind];
1694                   }
1695                 PrintChar(' '); 
1696                 line[ind++]=' ';
1697               }
1698             else if (commands.size()>1) 
1699               {
1700                 std::vector<std::string>::iterator i;
1701                 write(1,"\n",1);
1702                 for (i=commands.begin();i!=commands.end();++i) 
1703                   {
1704                     write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1705                     PrintChar(' ');
1706                   }
1707                 write(STDOUT_FILENO,"\n> ",3);
1708                 //for (int j=0;j<ind;++j) 
1709                   //{
1710                     write(STDOUT_FILENO,line,ind); 
1711                     //  }
1712               }
1713           }
1714         // Arrow up : back in history
1715         else if (c==BBTK_UP_ARROW_KBCODE)
1716           {
1717             if (hist) 
1718               {
1719                 // erase current line
1720                 while (ind--) BackSpace();
1721                 // 
1722                 hist--;
1723                 // 
1724                 strcpy(histline,mHistory[hist]);
1725                 line = histline;
1726                 ind = strlen(line);
1727                 
1728                 write(STDOUT_FILENO,line,ind);
1729               }
1730           }
1731         // Arrow down : down in history
1732         else if (c==BBTK_DOWN_ARROW_KBCODE)
1733           {
1734             if (hist<mHistory.size()-1) 
1735               {
1736                 // erase current line
1737                 while (ind--) BackSpace();
1738                 // 
1739                 hist++;
1740                 // 
1741                 strcpy(histline,mHistory[hist]);
1742                 line = histline;
1743                 ind = strlen(line);
1744                 
1745                 write(STDOUT_FILENO,line,ind);
1746               }
1747             // end of history : switch back to newline
1748             else if (hist==mHistory.size()-1)
1749               {
1750                 // erase current line
1751                 while (ind--) BackSpace();
1752                 // 
1753                 hist++;
1754                 // 
1755                 line = newline;
1756                 ind = strlen(line);
1757                 
1758                 write(STDOUT_FILENO,line,ind);
1759               }
1760           }
1761         // Arrow right
1762         else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1763           {
1764             PrintChar(line[ind]);
1765             ind++;
1766           }
1767
1768         // Arrow left
1769         else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1770           {
1771             PrintChar('\b');
1772             ind--;
1773     
1774           }
1775
1776       }
1777     write(STDOUT_FILENO,"\n\r",2);
1778     
1779     
1780     s = line;
1781     
1782   }
1783 #else
1784
1785   //=======================================================================
1786   void Interpreter::GetLineFromPrompt(std::string& s)
1787   {  
1788     s.clear();
1789
1790     putchar('>');
1791     putchar(' ');
1792
1793     do 
1794     {
1795       char c = getchar();
1796       if (c=='\n') 
1797       {
1798         putchar('\n');
1799         break;
1800       }
1801       if (c=='\t') 
1802       {
1803         // putchar('T');
1804         continue;
1805       }
1806       // putchar(c);
1807       s += c;
1808     } 
1809     while (true);  
1810     
1811   }
1812   //=======================================================================  
1813
1814 #endif
1815 */
1816
1817         
1818         
1819         
1820         
1821         
1822 /*EED Borrame
1823   //=======================================================================
1824   void Interpreter::CommandLineInterpreter()
1825   {
1826     bbtkDebugMessageInc("interpreter",9,
1827                         "Interpreter::CommandLineInterpreter()"<<std::endl);
1828
1829 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
1830     // Initialise the tty in non canonical mode with no echo
1831     // oter remembers the previous settings to restore them after 
1832     struct termios ter,oter;
1833     tcgetattr(0,&ter);
1834     oter=ter;
1835     ter.c_lflag &= ~ECHO;
1836     ter.c_lflag &= ~ICANON;
1837     ter.c_cc[VMIN]=1;
1838     ter.c_cc[VTIME]=0;
1839     tcsetattr(0,TCSANOW,&ter);
1840 #endif
1841     
1842     mCommandLine = true;
1843     bool again = true;
1844     // bool insideComment = false; // for multiline comment  
1845     mInsideComment = false;
1846     do 
1847     {
1848       try
1849       {
1850         std::string line;
1851         GetLineFromPrompt(line);
1852         DoInterpretLine(line); //, insideComment);
1853       }
1854  //     catch (QuitException e)
1855  //     {
1856  //     bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
1857  //        again = false;
1858       }
1859       catch (bbtk::Exception e) 
1860       {
1861         e.Print();
1862       }
1863         catch (std::exception& e) 
1864       {
1865         std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1866       }
1867       catch (...)
1868       {
1869         std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1870       }
1871     }
1872     while (again);
1873
1874 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1875     tcsetattr(0,TCSANOW,&oter);
1876 #endif
1877
1878     std::cout << "Good bye !" << std::endl;
1879
1880     bbtkDebugDecTab("interpreter",9);
1881   }
1882 */
1883                   
1884 //=======================================================================
1885 void Interpreter::commandGraph(const std::vector<std::string>& words)
1886 {
1887   std::string page;
1888     bool system_display = true;
1889
1890     if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1891       system_display = false; 
1892  
1893     if (words.size()==1) 
1894     {
1895       page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1896     }
1897     else if (words.size()==2) 
1898     {
1899       page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1900     }
1901     else if (words.size()==3) 
1902     {
1903       page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1904     }
1905     else if (words.size()==4) 
1906     {
1907       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1908     } 
1909     else if (words.size()==5) 
1910     {
1911       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1912     } 
1913     else if (words.size()==6) 
1914     {
1915       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1916     } 
1917     else if (words.size()==7) 
1918       {
1919         page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1920       } 
1921     
1922     if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1923       mUser->InterpreterUserViewHtmlPage(page);
1924
1925   }
1926 //=======================================================================
1927
1928
1929 //=======================================================================
1930 void  Interpreter::commandIndex(const std::string& filename, 
1931                          const std::string& type)
1932 {
1933   Factory::IndexEntryType t;
1934   if (type=="Initials") t = Factory::Initials;
1935   else if (type=="Categories") t = Factory::Categories;
1936   else if (type=="Packages") t = Factory::Packages;
1937   else if (type=="Adaptors") t = Factory::Adaptors;
1938   
1939   GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1940 }
1941 //=======================================================================
1942
1943
1944 //=======================================================================
1945 void  Interpreter::commandNewGUI(const std::string& boxname,
1946                              const std::string& instanceName)
1947 {
1948   if (mRealExecuter.expired())
1949     {
1950       bbtkError("command 'newgui' cannot be compiled yet");
1951     }
1952
1953   std::string typeName = instanceName+"Type";
1954   std::stringstream* s = new std::stringstream;
1955   // create the complex box
1956   (*s) << "define "<<typeName<<std::endl;
1957   //  (*s) << "  description 'Automatically generated user interface for the box "
1958   //       << boxname << "'" <<std::endl;
1959   // create the Layout box
1960   (*s) << "  load wx"<<std::endl;
1961   (*s) << "  new LayoutLine layout"<<std::endl;
1962   // create the output 'Widget'
1963   (*s) << "  output Widget layout.Widget Widget"<<std::endl;
1964   // the box change output 
1965   (*s) << "  new MultipleInputs change"<<std::endl;
1966   (*s) << "  output BoxChange change.Out BoxChange"<<std::endl;
1967
1968   // Browse the inputs of the box in order to find which ones are not 
1969   // connected and can be adapted from a widget adaptor
1970   // vector which stores the list of inputs of the box which must be connected
1971   std::vector<std::string> in;
1972  
1973   Factory::Pointer F = mVirtualExecuter->GetFactory();
1974   /*
1975   Package::Pointer user = F->GetPackage("user");
1976   */
1977   ComplexBlackBoxDescriptor::Pointer workspace = 
1978     mRealExecuter.lock()->GetCurrentDescriptor();
1979
1980   if (workspace==0)
1981     {
1982       delete s;
1983       bbtkError("interpreter::CreateGUI : could not access the executer currently defined complex box");
1984     }
1985  
1986
1987   /*
1988     (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
1989   */
1990
1991   BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
1992   //  BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
1993   // int nb = 0;
1994   BlackBox::InputConnectorMapType::iterator i;
1995   for (i=box->bbGetInputConnectorMap().begin();
1996        i!=box->bbGetInputConnectorMap().end();
1997        ++i)
1998     {
1999       // If the input is connected : continue
2000       if (i->second->IsConnected()) continue;
2001       // Get the input descriptor 
2002       const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2003       // If it is a "system" input : skip it
2004 #ifdef USE_WXWIDGETS
2005       if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2006            ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2007         continue;
2008 #else
2009       if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) )
2010         continue;
2011 #endif
2012       bool widok = true;
2013       std::string widget,adaptor;
2014       // try to find a widget adaptor
2015       if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2016                                d->GetDataInfo(),
2017                                adaptor))
2018         {
2019           // command to create the adaptor
2020           (*s) << "  new "<<adaptor<<" "<<i->first<<std::endl;
2021           // Sets the label of the widget adaptor to the name of the input
2022           (*s) << "  set "<<i->first<<".Label "<<i->first<<std::endl;
2023           // Sets the initial value of the widget to the value of the input
2024           (*s) << "  set "<<i->first<<".In \" "
2025                <<box->bbGetInputAsString(i->first)<<"\""
2026                << std::endl;
2027           // store the input name
2028           in.push_back(i->first);
2029           (*s) << "  connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2030             //<i->first<<"'"<<std::endl;
2031           (*s) << "  connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2032         }
2033       // try to find a two pieces adaptor
2034       else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2035                                      d->GetDataInfo(),
2036                                      widget,adaptor) )
2037         {
2038           // command to create the widget
2039           (*s) << "  new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2040           // command to create the adaptor
2041           (*s) << "  new "<<adaptor<<" "<<i->first<<std::endl;
2042           // connect the two
2043           (*s) << "  connect "<<i->first<<"Widget.Out "
2044                <<i->first<<".In"<<std::endl;
2045           // Sets the label of the widget adaptor to the name of the input
2046           (*s) << "  set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2047           // Sets the initial value of the widget to the value of the input
2048           (*s) << "  set "<<i->first<<"Widget.In \" "
2049                <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2050           // store the input name
2051           in.push_back(i->first);
2052           (*s) << "  connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2053             //<i->first<<"'"<<std::endl;
2054           (*s) << "  connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2055
2056         }
2057       // try to find an adaptor from string 
2058       // If found then can create a text input which 
2059       // will be automatically adapted 
2060       else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2061                                d->GetDataInfo(),
2062                                adaptor))
2063         {
2064           // command to create the adaptor
2065           (*s) << "  new InputText "<<i->first<<std::endl;
2066           // Sets the label of the widget adaptor to the name of the input
2067           (*s) << "  set "<<i->first<<".Title "<<i->first<<std::endl;
2068           // Sets the initial value of the widget to the value of the input
2069           (*s) << "  set "<<i->first<<".In \" "
2070                <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2071           // store the input name
2072           in.push_back(i->first);
2073           (*s) << "  connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2074             //<i->first<<"'"<<std::endl;
2075           (*s) << "  connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2076
2077         }
2078       else 
2079         {
2080           widok = false;
2081         }
2082       if (widok)
2083         {
2084           // command to create the output
2085           (*s) << "  output "<<i->first<<" "
2086                <<i->first<<".Out "<<i->first<<std::endl;
2087             //         <<" Output of the widget which allows to set "
2088           
2089         }
2090     }   
2091   // Inputs for window properties
2092   (*s) << "  input WinTitle layout.WinTitle Title"<<std::endl;
2093   (*s) << "  input WinWidth layout.WinWidth Width"<<std::endl;
2094   (*s) << "  input WinHeight layout.WinHeight Height"<<std::endl;
2095   (*s) << "  input WinDialog layout.WinDialog Dialog"<<std::endl;
2096   (*s) << "  input WinHide layout.WinHide Hide"<<std::endl;
2097
2098   
2099   
2100   // Execute the box executes the layout
2101   (*s) << "  exec layout" << std::endl;
2102   (*s) << "endefine" << std::endl;
2103   // (*s) << "help "<< typeName<< std::endl;
2104   // instanciate the box and connect it
2105   (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2106   // connections
2107   std::vector<std::string>::iterator j;
2108   for (j=in.begin();j!=in.end();++j)
2109     {
2110       // connect
2111       (*s) << "connect "<<instanceName<<"."<<*j<<" "
2112            << boxname<<"."<<*j<<std::endl;
2113     }
2114   // That's all folks ! now execute the commands :
2115   SwitchToStream(s);
2116 }
2117 //=======================================================================
2118
2119
2120
2121  //==========================================================================
2122   void Interpreter::commandDebug(const std::string& name)
2123   {
2124     if ((name.length()==2)&&(name[0]=='-'))
2125       {
2126         if (name[1]=='D')
2127           {
2128             bbtk::StaticInitTime::PrintObjectListInfo = true;
2129           }
2130         if (name[1]=='C')
2131           {
2132             //      int o = MessageManager::GetMessageLevel("debug");
2133             //      if (o<2) MessageManager::SetMessageLevel("debug",2);
2134             mVirtualExecuter->GetFactory()->Check();
2135             //      MessageManager::SetMessageLevel("debug",o);
2136           }
2137       }
2138     else 
2139       {
2140         Object:: PrintObjectListInfo(name);
2141       }
2142   }
2143  //==========================================================================
2144
2145   /*
2146   //==========================================================================
2147   // Adds a callback when 'break' command issued
2148   void Interpreter::AddBreakObserver( BreakCallbackType c )
2149   {
2150     mBreakSignal.connect(c);
2151   }
2152  //==========================================================================
2153  */
2154
2155  //==========================================================================
2156   std::string Interpreter::GetObjectName() const
2157   {
2158     return std::string("Interpreter");
2159   }
2160   //==========================================================================
2161   
2162   //==========================================================================
2163   std::string  Interpreter::GetObjectInfo() const 
2164   {
2165     std::stringstream i;
2166     return i.str();
2167   }
2168   //==========================================================================
2169
2170   //==========================================================================
2171 size_t  Interpreter::GetObjectSize() const 
2172 {
2173   size_t s = Superclass::GetObjectSize();
2174   s += Interpreter::GetObjectInternalSize();
2175   return s;
2176   }
2177   //==========================================================================
2178   //==========================================================================
2179 size_t  Interpreter::GetObjectInternalSize() const 
2180 {
2181   size_t s = sizeof(Interpreter);
2182   return s;
2183   }
2184   //==========================================================================
2185   //==========================================================================
2186   size_t  Interpreter::GetObjectRecursiveSize() const 
2187   {
2188     size_t s = Superclass::GetObjectRecursiveSize();
2189     s += Interpreter::GetObjectInternalSize();
2190     s += mVirtualExecuter->GetObjectRecursiveSize();
2191     return s;
2192   }
2193   //==========================================================================
2194 }//namespace
2195
2196