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