]> Creatis software - bbtk.git/blob - kernel/src/bbtkInterpreter.cxx
fc5f3f18638104b9d3046cc162c02de60a6c5259
[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:11:21 $
6   Version:   $Revision: 1.79 $
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     bbtkMessage("echo",2,line<<std::endl);
688
689     std::vector<std::string> words;
690     SplitLine(line,words);
691
692     // Empty line
693     if (words.size()<1) 
694     {
695        bbtkDebugDecTab("Interpreter",9);
696        return;
697     }
698
699     // Single line comment : # or //
700     if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') ) 
701     {  
702        bbtkDebugDecTab("Interpreter",9);
703        bbtkMessage("Interpreter",9,"Comment"<<std::endl);
704        return;
705     }
706
707     // Multi line comment ( /* ... */ ) -delimiters on different lines !-
708     
709     if (words[0][0]=='/' && words[0][1]=='*') 
710     {  
711        bbtkDebugDecTab("Interpreter",9);
712        bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
713        insideComment = true;
714        return;
715     }
716
717     if (words[0][0]=='*' && words[0][1]=='/') 
718     {  
719        bbtkDebugDecTab("Interpreter",9);
720        bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
721        if ( !insideComment ) {
722           bbtkDebugDecTab("Interpreter",9);
723           bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);       
724        }
725        insideComment = false;
726        return;
727     }
728
729     if (insideComment) 
730     {  
731        bbtkDebugDecTab("Interpreter",9);
732        bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
733        return;
734     }
735
736     // Command 
737     CommandInfoType command;
738     InterpretCommand(words,command);
739
740     bbtkDebugMessage("Interpreter",9,
741                      "Command='"<<command.keyword
742                       <<"' code="<<command.code<<std::endl); 
743     int level=0;
744     std::string left,right,left2,right2;
745     std::string filename;
746     switch (command.code) 
747     {
748       case cNew :
749         mVirtualExecuter->Create(words[1],words[2]);
750         break;
751
752       case cDelete :
753         mVirtualExecuter->Destroy(words[1]);
754         break;
755
756       case cConnect :
757         Utilities::SplitAroundFirstDot(words[1],left,right);
758         Utilities::SplitAroundFirstDot(words[2],left2,right2);      
759         mVirtualExecuter->Connect(left,right,left2,right2);
760         break;
761
762       case cPackage :
763         mVirtualExecuter->BeginPackage(words[1]);
764         break;
765
766       case cEndPackage :
767         mVirtualExecuter->EndPackage();
768         break;
769
770       case cDefine :
771         if (mFileName.size()>0) 
772         {
773                    filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
774         }
775         if (words.size()==2) 
776         {
777            mVirtualExecuter->Define(words[1],"",filename);
778         }
779         else
780         {
781            mVirtualExecuter->Define(words[1],words[2],filename);
782         }
783         break;
784
785       case cEndDefine :
786         mVirtualExecuter->EndDefine();
787         break;
788
789       case cKind :
790         mVirtualExecuter->Kind(words[1]);
791         break;
792
793       case cPrint :
794         mVirtualExecuter->Print(words[1]);
795         break;
796         
797       case cExec :
798         if (words[1]=="freeze") 
799           {
800             mVirtualExecuter->SetNoExecMode(true);
801             mThrow = false;
802           }
803         else if (words[1]=="freeze_no_error ") 
804           {
805             mVirtualExecuter->SetNoExecMode(true);
806             mVirtualExecuter->SetNoErrorMode(true);
807             mThrow = false;
808           }
809         else if (words[1]=="unfreeze") 
810           {
811             mVirtualExecuter->SetNoExecMode(false);
812             mVirtualExecuter->SetNoErrorMode(false);
813           }
814         else
815           {
816             mVirtualExecuter->Execute(words[1]);
817           }
818         break;
819
820       case cInput :
821         Utilities::SplitAroundFirstDot(words[2],left,right);
822         mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
823         break;
824
825       case cOutput :
826         Utilities::SplitAroundFirstDot(words[2],left,right);
827         mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
828         break;
829
830       case cSet :
831         Utilities::SplitAroundFirstDot(words[1],left,right);
832         mVirtualExecuter->Set(left,right,words[2]);
833         break;
834
835       case cAuthor :
836         mVirtualExecuter->Author(words[1]);
837         break;
838
839       case cNewGUI :
840         NewGUI(words[1],words[2]);
841         break;
842
843       case cCategory :
844         mVirtualExecuter->Category(words[1]);
845         break;
846
847       case cIndex :
848         if (words.size()==1)
849              Index("tmp_index.html");
850         else if (words.size()==2)
851              Index(words[1]);
852         else if (words.size()==3)
853              Index(words[1],words[2]);
854         break;
855
856       case cDescription :
857         mVirtualExecuter->Description(words[1]);
858         break;
859
860       case cHelp :
861         Help(words);
862         break;
863
864       case cMessage : 
865         if (words.size()<3)
866         {
867           mVirtualExecuter->HelpMessages();
868         }
869         else
870         {
871           sscanf(words[2].c_str(),"%d",&level);
872           mVirtualExecuter->SetMessageLevel(words[1],level);
873         }
874         break;
875
876       case cGraph :
877         Graph(words);
878         break;
879
880       case cConfig :
881         Config();
882         break;
883
884       case cReset :  
885         Reset();
886         break;
887
888      case cClear :  
889         mVirtualExecuter->Clear();
890         break;
891
892       case cInclude :
893                 // if 'source' was given (words.size()==3) then tell to set the 
894                 // source file name of the current complex box with the full file name included
895                 if (mCommandLine)
896         {
897            InterpretFile(words[1],(words.size()==3)); 
898         }
899         else
900         {
901             SwitchToFile(words[1],(words.size()==3) );
902         }
903                 break;
904
905       case cLoad:
906         GetExecuter()->LoadPackage(words[1]);
907         break;
908
909       case cUnload:
910         GetExecuter()->UnLoadPackage(words[1]);
911         break;
912
913       case cQuit :
914         throw QuitException();
915         break;
916
917       case cDebug :
918         if (words.size()==2) Debug(words[1]);
919         else Debug("");
920         break;
921         /* obsolete
922       case cWorkspace :
923         if (words.size() == 2) 
924         {
925            if (words[1]=="freeze")        mVirtualExecuter->SetNoExecMode(true);
926            else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
927         }
928         else
929         {
930            mVirtualExecuter->SetWorkspaceName(words[2]);
931         }
932         break;
933         */
934       default:
935         bbtkInternalError("should not reach here !!!");
936    }
937
938    bbtkDecTab("Interpreter",9);
939 }
940   //=======================================================================  
941
942
943
944
945
946   //=======================================================================
947   /**
948    *
949    */
950 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
951 {
952     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
953
954     std::string delimiters = "\"";
955     std::vector<std::string> quote;
956     Utilities::SplitString(str,delimiters,quote);
957
958     delimiters = " \t";
959     std::vector<std::string>::iterator i;
960     for (i=quote.begin(); i!=quote.end(); ) 
961     {
962        Utilities::SplitString(*i,delimiters,tokens);
963        ++i;
964        if (i!=quote.end()) 
965        {
966         //    bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
967           tokens.push_back(*i);
968           ++i;
969        }
970     }
971
972     for (i=tokens.begin(); i!=tokens.end(); ++i) 
973     {
974        bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
975     }
976     bbtkDebugMessageCont("Interpreter",9,std::endl);
977
978     bbtkDebugDecTab("Interpreter",9);
979  }
980   //=======================================================================
981
982
983   //=======================================================================
984   void Interpreter::Reset()
985   {
986     // Cannot close all files if the reset command is read from a file !
987     //    CloseAllFiles();
988     mFileNameHistory.clear();
989     this->mVirtualExecuter->Reset();
990   }
991   //=======================================================================
992
993   //=======================================================================
994   /**
995    *
996    */
997   /*
998   void Interpreter::Print( const std::string& str)
999   {
1000     if (mVirtualExecuter->GetNoExecMode()) return;
1001
1002     bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
1003
1004  // TO DO :
1005  // InterpretLine ("load std")
1006  // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande 
1007  // InterpretLine("new Print _P_") 
1008  // InterpretLine("connect _C_.Out _P_.In")
1009  // int num = 1
1010  
1011
1012     std::vector<std::string> chains;
1013     std::string delimiters("$");
1014
1015     // Skip delimiters at beginning.
1016     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1017     bool is_text = true;
1018     if (lastPos>0) is_text = false;
1019
1020     // Find first delimiter.
1021     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
1022
1023     while (std::string::npos != pos || std::string::npos != lastPos)
1024     {
1025        if (is_text) 
1026        {
1027           // Found a text token, add it to the vector.
1028           chains.push_back(str.substr(lastPos, pos - lastPos));
1029  // std::string token = str.substr(lastPos, pos - lastPos)
1030  // InterpretLine("set _C_.In%num% %token%")
1031  
1032        }
1033        else 
1034        {
1035
1036        // is an output (between $$) : decode 
1037          std::string tok,box,output;
1038          tok = str.substr(lastPos, pos - lastPos);
1039          Utilities::SplitAroundFirstDot(tok,box,output);
1040          chains.push_back( mVirtualExecuter->Get(box,output) );
1041
1042 // InterpretLine("connect %tok% _C_.In%num%") 
1043
1044        }
1045         // Skip delimiters.  Note the "not_of"
1046        lastPos = str.find_first_not_of(delimiters, pos);
1047         // Find next delimiter
1048        pos = str.find_first_of(delimiters, lastPos);
1049     //
1050        is_text = !is_text;
1051 // num ++;
1052      }
1053 // InterpretLine("exec _P_")
1054 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1055
1056      std::vector<std::string>::iterator i;
1057      for (i= chains.begin(); i!=chains.end(); ++i) 
1058      {
1059
1060        Utilities::SubsBackslashN(*i);
1061        std::cout << *i;
1062      }
1063      std::cout << std::endl;
1064      bbtkDebugDecTab("Interpreter",9);
1065  }
1066 */
1067
1068   //=======================================================================
1069   /**
1070    *
1071    */
1072
1073   // =========================================================================
1074   void Interpreter::SwitchToFile( const std::string& name , bool source )
1075   {
1076   // Note : in the following :
1077   // name : the user supplied name 
1078   //      - abreviated name    e.g.       scr   scr.bbs
1079   //      - relative full name e.g.       ./scr.bbs   ../../scr.bbs 
1080   //      - absolute full name e.g.       /home/usrname/proj/dir/scr.bbs
1081   //          same for Windows, with      c:, d: ...
1082   //
1083   // use ./directory/subdir/scrname.bbs
1084   //
1085
1086     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1087                          <<name<<"\")"<<std::endl);
1088
1089     std::vector<std::string> script_paths;
1090     std::string fullPathScriptName;  // full path script name
1091     std::string pkgname;             // e.g. <scriptname>.bbs
1092     std::vector<std::string> Filenames;
1093
1094     // The following is *NOT* a debug time message :
1095     // It's a user intended message.
1096     // Please don't remove it.
1097     bbtkMessage("Interpreter",1,
1098         "look for : [" << name
1099         << "]" << std::endl);
1100
1101
1102     std::string upath;
1103     pkgname = Utilities::ExtractScriptName(name,upath);
1104
1105     bbtkMessage("Interpreter",3,
1106                 "package name:[" << pkgname
1107                  << "] path:[" << upath << "]" << std::endl);
1108     bool fullnameGiven = false; 
1109     bool foundFile     = false;
1110
1111     // ==== "*" provided : load all scripts in given path 
1112     // relative (e.g. std/boxes/*) or absolute 
1113     if (pkgname == "*") 
1114       {
1115
1116         std::stringstream* stream = new std::stringstream;
1117         //if (upath.size()!=0) // avoid troubles for "*"
1118         
1119         // ==== no path provided : look in root bbs path
1120         if (upath.size()==0)
1121           {
1122             //      bbtkMessage("Interpreter",1,
1123             // LG : add all bbs path
1124             //  script_paths.push_back(  ConfigurationFile::GetInstance().Get_root_bbs_path() );
1125             std::vector<std::string>::const_iterator i;
1126             for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1127                  i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1128                  i++)
1129               {
1130                 script_paths.push_back(*i);
1131               }
1132           }
1133         // ==== absolute path provided 
1134         else if (upath[0]=='/' || upath[1] == ':' ) 
1135           {
1136             if ( Utilities::IsDirectory( upath ) )
1137               {
1138                 script_paths.push_back(upath);
1139               }
1140             else 
1141               {
1142                 bbtkError("'"<<upath<<"' : directory does not exist"); 
1143               }
1144           }
1145         // ==== relative path provided : search all bbs path appended with 
1146         // the relative path provided
1147         else
1148           {    
1149             std::vector<std::string>::const_iterator i;
1150             for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1151                  i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1152                  i++)
1153               {
1154                 std::string full_path(*i);
1155                 // we *really* want '.' to be the current working directory
1156                 if (full_path == ".") 
1157                   {
1158                     char buf[2048]; // for getcwd
1159                     char * currentDir = getcwd(buf, 2048);
1160                     std::string cwd(currentDir);
1161                     full_path = currentDir;
1162                   } // if full_path
1163                 
1164                 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1165                 full_path += upath;
1166                 
1167                 if ( Utilities::IsDirectory( full_path ) )
1168                   {
1169                     script_paths.push_back(full_path);
1170                   }
1171               } 
1172             if (script_paths.empty())
1173               {
1174                 bbtkError("no '"<<upath<<"' subdir found in search paths" 
1175                           << std::endl);
1176               }
1177           }
1178         
1179         
1180         // === search paths list complete : now explore it
1181         int nbBssFiles = 0;     
1182         // ==== relative name, iterate + load all .bbs/.bbp files
1183         std::vector<std::string>::iterator i;
1184         for (i=script_paths.begin();i!=script_paths.end();i++)
1185           {
1186             bbtkMessage("Interpreter",1,
1187                         "--> Looking in '" << *i << "'" << std::endl);
1188             
1189             Filenames.clear();
1190             //int nbFiles = 
1191             Utilities::Explore(*i, false, Filenames);
1192             
1193             for (std::vector<std::string>::iterator j = Filenames.begin(); 
1194                  j!= Filenames.end(); ++j)
1195               {
1196                 int lgr = (*j).size();
1197                 if (lgr < 5) continue;  
1198                 // ignore non .bbp file
1199                 if ( (*j).substr(lgr-4, 4) != ".bbp") continue; 
1200                 
1201                 (*stream) << "include \"" << *j << "\"\n";
1202                 bbtkMessage("Interpreter",2,"  --> Found '" << *j << "'" << std::endl);
1203                 
1204                 nbBssFiles++;
1205               } // for (std::vector...
1206           } // for (i=script_...
1207
1208         // === Result ...
1209         if (nbBssFiles==0)
1210           {
1211             bbtkMessage("Interpreter",1,
1212                         "  --> No .bbp found"<< std::endl);
1213           } 
1214         else 
1215           {
1216             bbtkMessage("Interpreter",1,
1217                         "  --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1218             SwitchToStream(stream);
1219           }
1220         return;
1221       }  
1222     //=============== end pkgname=="*" ===========
1223     
1224     
1225     // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1226     // (not only a plain script name)
1227     // we trust him, and try to expland the directory name
1228     // WARNING : starting from current local directory :  ./whatYouWant  (./ mandatory!)
1229
1230     if (name[0]=='/' || name[1] == ':' || name[0]=='.')  // absolute path (linux/windows) or relative path
1231     { 
1232
1233       // ===========================================================check user supplied location
1234       fullnameGiven = true;
1235
1236       fullPathScriptName =  Utilities::ExpandLibName(name, false);
1237
1238       // allow user to always forget ".bbs"
1239       int l = fullPathScriptName.size();
1240
1241       if (l!=0) 
1242           {
1243          if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1244                          (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1245          {
1246                         std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1247                         if ( Utilities::FileExists(tfullPathScriptName) )
1248                         {
1249                                 fullPathScriptName = tfullPathScriptName;
1250                                 foundFile = true;
1251                         }
1252                         else 
1253                         {
1254                                 tfullPathScriptName = fullPathScriptName + ".bbp";
1255                                 if ( Utilities::FileExists(tfullPathScriptName) )
1256                                 {
1257                                         fullPathScriptName = tfullPathScriptName;
1258                                         foundFile = true;
1259                                 }
1260                         }
1261                  }
1262                  else 
1263                  {
1264                         if ( Utilities::FileExists(fullPathScriptName) )
1265                         {
1266                                 foundFile = true;
1267                         }
1268                  }
1269           } // endif l != 0
1270   }
1271   else
1272   // =============================== iterate on the paths
1273   {
1274       script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1275       std::string path;
1276       std::vector<std::string>::iterator i;
1277       for (i=script_paths.begin();i!=script_paths.end();++i)
1278           {
1279                 path = *i;
1280                 // we *really* want '.' to be the current working directory
1281                 if (path == ".") 
1282                 {
1283                         char buf[2048]; // for getcwd
1284                         char * currentDir = getcwd(buf, 2048);
1285                         std::string cwd(currentDir);
1286                         path = currentDir;
1287                 }
1288           
1289                 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1290                 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1291                 {
1292                   fullPathScriptName = tfullPathScriptName;
1293                         if ( ! Utilities::FileExists(fullPathScriptName) )
1294                         {
1295                                 // The following is *NOT* a debug time message :
1296                                 // It's a user intended message.
1297                                 // Please don't remove it.
1298                                 bbtkMessage("Interpreter",2,
1299                           "   [" <<fullPathScriptName <<"] : does not exist" 
1300                           <<std::endl);
1301                                 continue;  // try next path
1302                         }
1303                         bbtkMessage("Interpreter",2,
1304                               "   [" <<fullPathScriptName 
1305                                   <<"] : found" <<std::endl);
1306                         foundFile = true;
1307                         break; // a script was found; we stop iterating
1308                 }
1309                 else 
1310                 {
1311                         fullPathScriptName = tfullPathScriptName + ".bbs";
1312                         // Check if library exists
1313                         if ( ! Utilities::FileExists(fullPathScriptName) )
1314                         {
1315                                 fullPathScriptName = tfullPathScriptName + ".bbp";
1316                                 if ( ! Utilities::FileExists(fullPathScriptName) )
1317                                 {
1318                                         // The following is *NOT* a debug time message :
1319                                         // It's a user intended message.
1320                                         // Please don't remove it.
1321                                         bbtkMessage("Interpreter",2,
1322                                         "   [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist" 
1323                                         <<std::endl);
1324                                         continue;  // try next path
1325                                 }
1326                         }
1327                         bbtkMessage("Interpreter",2,
1328                       "   [" <<fullPathScriptName 
1329                       <<"] : found" <<std::endl);
1330                         foundFile = true;
1331                         break; // a script was found; we stop iterating
1332                 }
1333         } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1334   }
1335
1336     if (!foundFile)
1337       {
1338         if (fullnameGiven)
1339           if(fullPathScriptName == "")
1340             bbtkError("Path ["<<upath<<"] doesn't exist");
1341           else
1342             bbtkError("Script ["<<fullPathScriptName<<"] not found");
1343         else
1344           bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1345         return;
1346       }
1347     else
1348         {
1349       LoadScript(fullPathScriptName,name);
1350           if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1351         }
1352     
1353     return;
1354   }
1355   //=======================================================================
1356
1357
1358   //=======================================================================
1359 void Interpreter::SwitchToStream( std::stringstream* stream )
1360 {
1361     mFile.push_back(stream);
1362     std::ostringstream buffer_name;
1363     bufferNb++;
1364     buffer_name << "buffer_" ;
1365
1366     if (mFileName.size()>0 )
1367     {
1368        buffer_name << mFileName.back() << "_" << mLine.back();
1369     }
1370     mFileName.push_back(buffer_name.str());
1371     mIncludeFileName.push_back(buffer_name.str());
1372     mLine.push_back(0);
1373 }
1374   //=======================================================================
1375
1376   //=======================================================================
1377
1378   void Interpreter::LoadScript( std::string fullPathScriptName,
1379                                 std::string includeScriptName)
1380   {
1381      Utilities::replace( fullPathScriptName , 
1382                          INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1383    
1384      if (find(mFileNameHistory.begin(),
1385               mFileNameHistory.end(),
1386               fullPathScriptName)!=mFileNameHistory.end())
1387      {
1388         return;
1389      }
1390
1391     std::ifstream* s;
1392     s = new std::ifstream;
1393     s->open(fullPathScriptName.c_str());
1394     if (!s->good())
1395     {
1396         bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1397         return;
1398     }
1399
1400     bbtkMessage("Interpreter",1,"   -->[" << fullPathScriptName 
1401                 << "] found" << std::endl);
1402
1403     mFile.push_back(s);
1404     mFileName.push_back(fullPathScriptName);
1405     mFileNameHistory.push_back(fullPathScriptName);
1406     mIncludeFileName.push_back(includeScriptName);
1407     mLine.push_back(0);
1408
1409         return;
1410   }
1411
1412   //=======================================================================
1413   /**
1414    *  
1415    */
1416   void Interpreter::CloseCurrentFile()
1417   {
1418     bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1419                       <<std::endl);
1420
1421     if (mFile.size()==0)
1422     {
1423       bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1424       return;
1425     }
1426
1427     bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1428
1429     std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1430     if (file!=0) file->close();
1431
1432     delete mFile.back();
1433     mFile.pop_back();
1434     mFileName.pop_back();
1435     mIncludeFileName.pop_back();
1436     mLine.pop_back();
1437
1438     bbtkDebugMessage("Interpreter",9," Remains "
1439                      <<mFile.size()
1440                      <<" open"<<std::endl);
1441     bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1442                      <<std::endl);
1443   }
1444   //=======================================================================
1445
1446  //=======================================================================
1447   /**
1448    *  
1449    */
1450   void Interpreter::CloseAllFiles()
1451   {
1452     bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1453                       <<std::endl);
1454
1455     while (mFile.size() != 0) 
1456     {
1457        CloseCurrentFile();
1458     }
1459     bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1460                       <<std::endl);
1461   }
1462   //=======================================================================
1463
1464
1465
1466   //=======================================================================
1467   /**
1468    *  
1469    */
1470   void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1471                                       CommandInfoType& info )
1472   {
1473     bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1474
1475     // searches the command keyword
1476     CommandDictType::iterator c;
1477     c = mCommandDict.find(words[0]);
1478     if ( c == mCommandDict.end() ) {
1479       bbtkError(words[0]<<" : unknown command");
1480     }
1481
1482     // tests the number of args 
1483     if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1484          ( ((int)words.size())-1 > c->second.argmax ) )
1485     {
1486        HelpCommand(words[0]);
1487        bbtkError(words[0]<<" : wrong number of arguments");
1488     }
1489
1490     info = c->second;
1491     bbtkDecTab("Interpreter",9);
1492   }
1493   //=======================================================================
1494
1495
1496   //=======================================================================
1497   /// Displays help on all the commands
1498 void Interpreter::Help(const std::vector<std::string>& words)
1499 {
1500     unsigned int nbarg = words.size()-1;
1501
1502     if (nbarg==0) 
1503     {
1504        HelpCommands();
1505     }
1506     else if (nbarg==1) 
1507     {
1508       if (words[1]=="packages") 
1509       {
1510          GetExecuter()->GetFactory()->PrintPackages(true);
1511          return;
1512       }
1513       try 
1514       {
1515           HelpCommand(words[1]);
1516       }
1517       catch (bbtk::Exception e) 
1518       {
1519          try 
1520          {
1521             GetExecuter()->GetFactory()->HelpPackage(words[1]);
1522             if ( mUser != 0 )
1523               {
1524                 std::string url = 
1525                   ConfigurationFile::GetInstance().Get_doc_path();
1526                 url += "/bbdoc/" + words[1] + "/index.html";
1527                 if (Utilities::FileExists(url)) 
1528                   {
1529                     mUser->InterpreterUserViewHtmlPage(url);
1530                   }
1531               }
1532          }
1533          catch (bbtk::Exception f) 
1534          {
1535            try 
1536              {
1537                std::string package;
1538                GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1539                if ( mUser != 0 )
1540                  {
1541                    std::string url = 
1542                      ConfigurationFile::GetInstance().Get_doc_path();
1543                    url += "/bbdoc/" + package + "/index.html";
1544                    if (Utilities::FileExists(url)) 
1545                      {
1546                        url += "#" + words[1];
1547                        mUser->InterpreterUserViewHtmlPage(url);
1548                      }
1549                  }
1550              }
1551            catch (bbtk::Exception g) 
1552              {
1553                try
1554                  {
1555                    GetExecuter()->ShowRelations(words[1],"0","9999");
1556                  }
1557                catch (bbtk::Exception h){
1558                  bbtkError("\""<<words[1].c_str()
1559                            <<"\" is not a known command, package, black box type or black box name");
1560                }
1561              }
1562          }
1563       }
1564     }
1565     else if (nbarg==2) 
1566     {
1567       if (words[2]=="all")
1568       {
1569          if ( words[1]=="packages" )
1570          {
1571             GetExecuter()->GetFactory()->PrintPackages(true,true);
1572             return;
1573           }
1574          try 
1575          {
1576             GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1577          }
1578          catch (bbtk::Exception f) 
1579          {
1580          }
1581      }
1582      else 
1583      {
1584         HelpCommand(words[0]);
1585         bbtkError(words[0]<<" : syntax error");
1586      }
1587   }
1588   else 
1589   {
1590      bbtkError("Should not reach here !!!");
1591   }
1592 }
1593   //=======================================================================
1594
1595    //===================================================================    
1596   /// Displays the Configuration
1597   void Interpreter::Config() const
1598   {
1599     ConfigurationFile::GetInstance().GetHelp(1);
1600   }  
1601    //===================================================================    
1602
1603   //=======================================================================
1604   /// Displays help on all the commands
1605   void Interpreter::HelpCommands()
1606   {
1607     std::cout << "Available commands :" << std::endl;
1608     CommandDictType::iterator i;
1609     for ( i =  mCommandDict.begin();
1610           i != mCommandDict.end();
1611         ++i) {
1612               std::cout << " " << i->first << std::endl;
1613       //      std::cout << "   usage : " << i->second.syntax << std::endl;
1614       //     std::cout << "    " << i->second.help << std::endl;
1615
1616     }
1617   }
1618   //=======================================================================
1619
1620
1621   //=======================================================================
1622   /// Displays help on a particular commands
1623   void Interpreter::HelpCommand(const std::string& s)
1624   {
1625     CommandDictType::iterator c;
1626     c = mCommandDict.find(s);
1627     if ( c == mCommandDict.end() ) {
1628       bbtkError(s<<" : Unknown command");
1629     }   
1630     //    std::cout << " " << s << " : "<<  std::endl;
1631     //    CommandParamDictType::iterator i;
1632     //    for ( i =  c->second.begin();
1633     //      i != c->second.end();
1634     //      ++i) {
1635     std::cout << " usage : " << c->second.syntax << std::endl;
1636     std::cout << "  " << c->second.help << std::endl;
1637
1638   }
1639   //=======================================================================
1640
1641
1642   //=======================================================================
1643   /// Fills the vector commands with the commands which 
1644   /// have the first n chars of buf for prefix
1645   /// TODO : skip initial spaces in buf and also return the position of first
1646   /// non blank char in buf
1647   void Interpreter::FindCommandsWithPrefix( char* buf,
1648                                             int n,
1649                                             std::vector<std::string>& commands )
1650   {
1651     CommandDictType::const_iterator i;
1652     for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1653     {
1654       if ((i->first).find(buf,0,n) == 0) 
1655         commands.push_back(i->first);
1656     }
1657   }
1658   //=======================================================================
1659
1660
1661
1662   //=======================================================================
1663 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1664   
1665   inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1666   inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1667   
1668   // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1669   // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1670   // E.G. STORE THIS IN bbtk_config.xml
1671 #define BBTK_UP_ARROW_KBCODE    0x00415B1B
1672 #define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
1673 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1674 #define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
1675 #define BBTK_BACKSPACE_KBCODE   0x00000008
1676 #define BBTK_DEL_KBCODE         0x0000007F
1677 #define BBTK_SPACE_KBCODE       0x00000020 
1678
1679   //=======================================================================
1680   void Interpreter::GetLineFromPrompt(std::string& s)
1681   {
1682     int c;
1683     unsigned int ind=0;
1684
1685     unsigned int MAX_LINE_SIZE = 160;
1686     unsigned int MAX_HISTORY_SIZE = 100;
1687
1688     char* newline = new char[MAX_LINE_SIZE];
1689     memset(newline,0,MAX_LINE_SIZE);
1690     char* histline = new char[MAX_LINE_SIZE];
1691     memset(histline,0,MAX_LINE_SIZE);
1692
1693     char* line = newline;
1694     unsigned int hist = mHistory.size();
1695
1696     write(1,"> ",2);
1697     while(1)
1698     {
1699        c=0;
1700        read ( STDIN_FILENO, &c, 4) ;
1701
1702        bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1703
1704        // Printable character
1705        if ( (ind<MAX_LINE_SIZE-1) &&
1706             ( c >= BBTK_SPACE_KBCODE ) && 
1707             ( c <  BBTK_DEL_KBCODE )) 
1708        {
1709           PrintChar(c);
1710           line[ind++]=c;
1711        }
1712       // CR
1713        else if (c=='\n')
1714        {
1715        // delete the unused line
1716           if (line==newline)
1717               delete histline;
1718           else
1719               delete newline;
1720    
1721     // empty lines are not stored in from history
1722           if (strlen(line)) 
1723           {
1724              // if history too long : delete oldest command
1725              if (mHistory.size()>MAX_HISTORY_SIZE) 
1726              {
1727                 delete mHistory.front();
1728                 mHistory.pop_front();
1729              }
1730              mHistory.push_back(line);
1731           }
1732           break;
1733         }
1734        // Backspace
1735         else if ( (ind>0) && 
1736                   ((c == BBTK_BACKSPACE_KBCODE) ||
1737                    (c == BBTK_DEL_KBCODE)) )
1738           {
1739             line[ind--]=' ';
1740             BackSpace();
1741           }
1742         // Tab 
1743         else if (c=='\t')
1744           {
1745             // TODO : Command completion  
1746             std::vector<std::string> commands;
1747             FindCommandsWithPrefix( line,ind,commands);
1748             if (commands.size()==1) 
1749               {
1750                 std::string com = *commands.begin();
1751                 for (; ind<com.size(); ++ind) 
1752                   {
1753                     PrintChar(com[ind]); 
1754                     line[ind]=com[ind];
1755                   }
1756                 PrintChar(' '); 
1757                 line[ind++]=' ';
1758               }
1759             else if (commands.size()>1) 
1760               {
1761                 std::vector<std::string>::iterator i;
1762                 write(1,"\n",1);
1763                 for (i=commands.begin();i!=commands.end();++i) 
1764                   {
1765                     write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1766                     PrintChar(' ');
1767                   }
1768                 write(STDOUT_FILENO,"\n> ",3);
1769                 //for (int j=0;j<ind;++j) 
1770                   //{
1771                     write(STDOUT_FILENO,line,ind); 
1772                     //  }
1773               }
1774           }
1775         // Arrow up : back in history
1776         else if (c==BBTK_UP_ARROW_KBCODE)
1777           {
1778             if (hist) 
1779               {
1780                 // erase current line
1781                 while (ind--) BackSpace();
1782                 // 
1783                 hist--;
1784                 // 
1785                 strcpy(histline,mHistory[hist]);
1786                 line = histline;
1787                 ind = strlen(line);
1788                 
1789                 write(STDOUT_FILENO,line,ind);
1790               }
1791           }
1792         // Arrow down : down in history
1793         else if (c==BBTK_DOWN_ARROW_KBCODE)
1794           {
1795             if (hist<mHistory.size()-1) 
1796               {
1797                 // erase current line
1798                 while (ind--) BackSpace();
1799                 // 
1800                 hist++;
1801                 // 
1802                 strcpy(histline,mHistory[hist]);
1803                 line = histline;
1804                 ind = strlen(line);
1805                 
1806                 write(STDOUT_FILENO,line,ind);
1807               }
1808             // end of history : switch back to newline
1809             else if (hist==mHistory.size()-1)
1810               {
1811                 // erase current line
1812                 while (ind--) BackSpace();
1813                 // 
1814                 hist++;
1815                 // 
1816                 line = newline;
1817                 ind = strlen(line);
1818                 
1819                 write(STDOUT_FILENO,line,ind);
1820               }
1821           }
1822         // Arrow right
1823         else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1824           {
1825             PrintChar(line[ind]);
1826             ind++;
1827           }
1828
1829         // Arrow left
1830         else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1831           {
1832             PrintChar('\b');
1833             ind--;
1834     
1835           }
1836
1837       }
1838     write(STDOUT_FILENO,"\n\r",2);
1839     
1840     
1841     s = line;
1842     
1843   }
1844 #else
1845
1846   //=======================================================================
1847   void Interpreter::GetLineFromPrompt(std::string& s)
1848   {  
1849     s.clear();
1850
1851     putchar('>');
1852     putchar(' ');
1853
1854     do 
1855     {
1856       char c = getchar();
1857       if (c=='\n') 
1858       {
1859         putchar('\n');
1860         break;
1861       }
1862       if (c=='\t') 
1863       {
1864         // putchar('T');
1865         continue;
1866       }
1867       // putchar(c);
1868       s += c;
1869     } 
1870     while (true);  
1871     
1872   }
1873   //=======================================================================  
1874
1875 #endif
1876
1877
1878
1879   //=======================================================================
1880   void Interpreter::CommandLineInterpreter()
1881   {
1882     bbtkDebugMessageInc("Interpreter",9,
1883                         "Interpreter::CommandLineInterpreter()"<<std::endl);
1884
1885 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
1886     // Initialise the tty in non canonical mode with no echo
1887     // oter remembers the previous settings to restore them after 
1888     struct termios ter,oter;
1889     tcgetattr(0,&ter);
1890     oter=ter;
1891     ter.c_lflag &= ~ECHO;
1892     ter.c_lflag &= ~ICANON;
1893     ter.c_cc[VMIN]=1;
1894     ter.c_cc[VTIME]=0;
1895     tcsetattr(0,TCSANOW,&ter);
1896 #endif
1897     
1898     mCommandLine = true;
1899     bool again = true;
1900     bool insideComment = false; // for multiline comment  
1901     do 
1902     {
1903       try
1904       {
1905         std::string line;
1906         GetLineFromPrompt(line);
1907         InterpretLine(line, insideComment);
1908       }
1909       catch (QuitException e)
1910       {
1911         bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1912         again = false;
1913       }
1914       catch (bbtk::Exception e) 
1915       {
1916         e.Print();
1917       }
1918         catch (std::exception& e) 
1919       {
1920         std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1921       }
1922       catch (...)
1923       {
1924         std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1925       }
1926     }
1927     while (again);
1928
1929 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1930     tcsetattr(0,TCSANOW,&oter);
1931 #endif
1932
1933     std::cout << "Good bye !" << std::endl;
1934
1935     bbtkDebugDecTab("Interpreter",9);
1936   }
1937
1938 //=======================================================================
1939 void Interpreter::Graph(const std::vector<std::string>& words)
1940 {
1941   std::string page;
1942     bool system_display = true;
1943
1944     if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1945       system_display = false; 
1946  
1947     if (words.size()==1) 
1948     {
1949       page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1950     }
1951     else if (words.size()==2) 
1952     {
1953       page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1954     }
1955     else if (words.size()==3) 
1956     {
1957       page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1958     }
1959     else if (words.size()==4) 
1960     {
1961       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1962     } 
1963     else if (words.size()==5) 
1964     {
1965       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1966     } 
1967     else if (words.size()==6) 
1968     {
1969       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1970     } 
1971     else if (words.size()==7) 
1972       {
1973         page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1974       } 
1975     
1976     if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1977       mUser->InterpreterUserViewHtmlPage(page);
1978
1979   }
1980 //=======================================================================
1981
1982
1983 //=======================================================================
1984 void  Interpreter::Index(const std::string& filename, 
1985                          const std::string& type)
1986 {
1987   Factory::IndexEntryType t;
1988   if (type=="Initials") t = Factory::Initials;
1989   else if (type=="Categories") t = Factory::Categories;
1990   else if (type=="Packages") t = Factory::Packages;
1991   else if (type=="Adaptors") t = Factory::Adaptors;
1992   
1993   GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1994 }
1995 //=======================================================================
1996
1997
1998 //=======================================================================
1999 void  Interpreter::NewGUI(const std::string& boxname,
2000                              const std::string& instanceName)
2001 {
2002   if (mRealExecuter.expired())
2003     {
2004       bbtkError("command 'newgui' cannot be compiled yet");
2005     }
2006
2007   std::string typeName = instanceName+"Type";
2008   std::stringstream* s = new std::stringstream;
2009   // create the complex box
2010   (*s) << "define "<<typeName<<std::endl;
2011   //  (*s) << "  description 'Automatically generated user interface for the box "
2012   //       << boxname << "'" <<std::endl;
2013   // create the Layout box
2014   (*s) << "  load wx"<<std::endl;
2015   (*s) << "  new LayoutLine layout"<<std::endl;
2016   // create the output 'Widget'
2017   (*s) << "  output Widget layout.Widget Widget"<<std::endl;
2018   // the box change output 
2019   (*s) << "  new MultipleInputs change"<<std::endl;
2020   (*s) << "  output BoxChange change.Out BoxChange"<<std::endl;
2021
2022   // Browse the inputs of the box in order to find which ones are not 
2023   // connected and can be adapted from a widget adaptor
2024   // vector which stores the list of inputs of the box which must be connected
2025   std::vector<std::string> in;
2026  
2027   Factory::Pointer F = mVirtualExecuter->GetFactory();
2028   /*
2029   Package::Pointer user = F->GetPackage("user");
2030   */
2031   ComplexBlackBoxDescriptor::Pointer workspace = 
2032     mRealExecuter.lock()->GetCurrentDescriptor();
2033
2034   if (workspace==0)
2035     {
2036       delete s;
2037       bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2038     }
2039  
2040
2041   /*
2042     (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2043   */
2044
2045   BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2046   //  BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2047   // int nb = 0;
2048   BlackBox::InputConnectorMapType::iterator i;
2049   for (i=box->bbGetInputConnectorMap().begin();
2050        i!=box->bbGetInputConnectorMap().end();
2051        ++i)
2052     {
2053       // If the input is connected : continue
2054       if (i->second->IsConnected()) continue;
2055       // Get the input descriptor 
2056       const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2057       // If it is a "system" input : skip it
2058       if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2059            ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2060         continue;
2061       bool widok = true;
2062       std::string widget,adaptor;
2063       // try to find a widget adaptor
2064       if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2065                                d->GetDataInfo(),
2066                                adaptor))
2067         {
2068           // command to create the adaptor
2069           (*s) << "  new "<<adaptor<<" "<<i->first<<std::endl;
2070           // Sets the label of the widget adaptor to the name of the input
2071           (*s) << "  set "<<i->first<<".Label "<<i->first<<std::endl;
2072           // Sets the initial value of the widget to the value of the input
2073           (*s) << "  set "<<i->first<<".In \" "
2074                <<box->bbGetInputAsString(i->first)<<"\""
2075                << std::endl;
2076           // store the input name
2077           in.push_back(i->first);
2078           (*s) << "  connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2079             //<i->first<<"'"<<std::endl;
2080           (*s) << "  connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2081         }
2082       // try to find a two pieces adaptor
2083       else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2084                                      d->GetDataInfo(),
2085                                      widget,adaptor) )
2086         {
2087           // command to create the widget
2088           (*s) << "  new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2089           // command to create the adaptor
2090           (*s) << "  new "<<adaptor<<" "<<i->first<<std::endl;
2091           // connect the two
2092           (*s) << "  connect "<<i->first<<"Widget.Out "
2093                <<i->first<<".In"<<std::endl;
2094           // Sets the label of the widget adaptor to the name of the input
2095           (*s) << "  set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2096           // Sets the initial value of the widget to the value of the input
2097           (*s) << "  set "<<i->first<<"Widget.In \" "
2098                <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2099           // store the input name
2100           in.push_back(i->first);
2101           (*s) << "  connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2102             //<i->first<<"'"<<std::endl;
2103           (*s) << "  connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2104
2105         }
2106       // try to find an adaptor from string 
2107       // If found then can create a text input which 
2108       // will be automatically adapted 
2109       else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2110                                d->GetDataInfo(),
2111                                adaptor))
2112         {
2113           // command to create the adaptor
2114           (*s) << "  new InputText "<<i->first<<std::endl;
2115           // Sets the label of the widget adaptor to the name of the input
2116           (*s) << "  set "<<i->first<<".Title "<<i->first<<std::endl;
2117           // Sets the initial value of the widget to the value of the input
2118           (*s) << "  set "<<i->first<<".In \" "
2119                <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2120           // store the input name
2121           in.push_back(i->first);
2122           (*s) << "  connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2123             //<i->first<<"'"<<std::endl;
2124           (*s) << "  connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2125
2126         }
2127       else 
2128         {
2129           widok = false;
2130         }
2131       if (widok)
2132         {
2133           // command to create the output
2134           (*s) << "  output "<<i->first<<" "
2135                <<i->first<<".Out "<<i->first<<std::endl;
2136             //         <<" Output of the widget which allows to set "
2137           
2138         }
2139     }   
2140   // Inputs for window properties
2141   (*s) << "  input WinTitle layout.WinTitle Title"<<std::endl;
2142   (*s) << "  input WinWidth layout.WinWidth Width"<<std::endl;
2143   (*s) << "  input WinHeight layout.WinHeight Height"<<std::endl;
2144   (*s) << "  input WinDialog layout.WinDialog Dialog"<<std::endl;
2145   (*s) << "  input WinHide layout.WinHide Hide"<<std::endl;
2146
2147   
2148   
2149   // Execute the box executes the layout
2150   (*s) << "  exec layout" << std::endl;
2151   (*s) << "endefine" << std::endl;
2152   // (*s) << "help "<< typeName<< std::endl;
2153   // instanciate the box and connect it
2154   (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2155   // connections
2156   std::vector<std::string>::iterator j;
2157   for (j=in.begin();j!=in.end();++j)
2158     {
2159       // connect
2160       (*s) << "connect "<<instanceName<<"."<<*j<<" "
2161            << boxname<<"."<<*j<<std::endl;
2162     }
2163   // That's all folks ! now execute the commands :
2164   SwitchToStream(s);
2165 }
2166 //=======================================================================
2167
2168
2169
2170  //==========================================================================
2171   void Interpreter::Debug(const std::string& name)
2172   {
2173     if ((name.length()==2)&&(name[0]=='-'))
2174       {
2175         if (name[1]=='D')
2176           {
2177             bbtk::StaticInitTime::PrintObjectListInfo = true;
2178           }
2179         if (name[1]=='C')
2180           {
2181             //      int o = MessageManager::GetMessageLevel("debug");
2182             //      if (o<2) MessageManager::SetMessageLevel("debug",2);
2183             mVirtualExecuter->GetFactory()->CheckPackages();
2184             //      MessageManager::SetMessageLevel("debug",o);
2185           }
2186       }
2187     else 
2188       {
2189         Object:: PrintObjectListInfo(name);
2190       }
2191   }
2192  //==========================================================================
2193  //==========================================================================
2194   std::string Interpreter::GetObjectName() const
2195   {
2196     return std::string("Interpreter");
2197   }
2198   //==========================================================================
2199   
2200   //==========================================================================
2201   std::string  Interpreter::GetObjectInfo() const 
2202   {
2203     std::stringstream i;
2204     return i.str();
2205   }
2206   //==========================================================================
2207
2208   //==========================================================================
2209 size_t  Interpreter::GetObjectSize() const 
2210 {
2211   size_t s = Superclass::GetObjectSize();
2212   s += Interpreter::GetObjectInternalSize();
2213   return s;
2214   }
2215   //==========================================================================
2216   //==========================================================================
2217 size_t  Interpreter::GetObjectInternalSize() const 
2218 {
2219   size_t s = sizeof(Interpreter);
2220   return s;
2221   }
2222   //==========================================================================
2223   //==========================================================================
2224   size_t  Interpreter::GetObjectRecursiveSize() const 
2225   {
2226     size_t s = Superclass::GetObjectRecursiveSize();
2227     s += Interpreter::GetObjectInternalSize();
2228     s += mVirtualExecuter->GetObjectRecursiveSize();
2229     return s;
2230   }
2231   //==========================================================================
2232 }//namespace
2233
2234