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