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