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