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