]> Creatis software - bbtk.git/blob - kernel/src/bbtkInterpreter.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkInterpreter.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbtkInterpreter.cxx,v $
4   Language:  C++
5   Date:      $Date: 2009/06/08 14:50:03 $
6   Version:   $Revision: 1.86 $
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()->PrintHelpListPackages(true);
1597          return;
1598       }
1599       try 
1600       {
1601           HelpCommand(words[1]);
1602       }
1603       catch (bbtk::Exception e) 
1604       {
1605          try 
1606          {
1607             GetExecuter()->GetFactory()->PrintHelpPackage(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()->PrintHelpDescriptor(words[1],
1625                                                                 package);
1626                if ( mUser != 0 )
1627                  {
1628                    std::string url = 
1629                      ConfigurationFile::GetInstance().Get_doc_path();
1630                    url += "/bbdoc/" + package + "/index.html";
1631                    if (Utilities::FileExists(url)) 
1632                      {
1633                        url += "#" + words[1];
1634                        mUser->InterpreterUserViewHtmlPage(url);
1635                      }
1636                  }
1637              }
1638            catch (bbtk::Exception g) 
1639              {
1640                try
1641                  {
1642                    GetExecuter()->PrintHelpBlackBox(words[1],"0","9999");
1643                  }
1644                catch (bbtk::Exception h){
1645                  bbtkError("\""<<words[1].c_str()
1646                            <<"\" is not a known command, package, black box type or black box name");
1647                }
1648              }
1649          }
1650       }
1651     }
1652     else if (nbarg==2) 
1653     {
1654       if (words[2]=="all")
1655       {
1656          if ( words[1]=="packages" )
1657          {
1658             GetExecuter()->GetFactory()->PrintHelpListPackages(true,true);
1659             return;
1660           }
1661          try 
1662          {
1663             GetExecuter()->GetFactory()->PrintHelpPackage(words[1],true);
1664          }
1665          catch (bbtk::Exception f) 
1666          {
1667          }
1668      }
1669      else 
1670      {
1671         HelpCommand(words[0]);
1672         bbtkError(words[0]<<" : syntax error");
1673      }
1674   }
1675   else 
1676   {
1677      bbtkError("Should not reach here !!!");
1678   }
1679 }
1680   //=======================================================================
1681
1682    //===================================================================    
1683   /// Displays the Configuration
1684   void Interpreter::Config() const
1685   {
1686     ConfigurationFile::GetInstance().GetHelp(1);
1687   }  
1688    //===================================================================    
1689
1690   //=======================================================================
1691   /// Displays help on all the commands
1692   void Interpreter::HelpCommands()
1693   {
1694     std::cout << "Available commands :" << std::endl;
1695     CommandDictType::iterator i;
1696     for ( i =  mCommandDict.begin();
1697           i != mCommandDict.end();
1698         ++i) {
1699               std::cout << " " << i->first << std::endl;
1700       //      std::cout << "   usage : " << i->second.syntax << std::endl;
1701       //     std::cout << "    " << i->second.help << std::endl;
1702
1703     }
1704   }
1705   //=======================================================================
1706
1707
1708   //=======================================================================
1709   /// Displays help on a particular commands
1710   void Interpreter::HelpCommand(const std::string& s)
1711   {
1712     CommandDictType::iterator c;
1713     c = mCommandDict.find(s);
1714     if ( c == mCommandDict.end() ) {
1715       bbtkError(s<<" : Unknown command");
1716     }   
1717     //    std::cout << " " << s << " : "<<  std::endl;
1718     //    CommandParamDictType::iterator i;
1719     //    for ( i =  c->second.begin();
1720     //      i != c->second.end();
1721     //      ++i) {
1722     std::cout << " usage : " << c->second.syntax << std::endl;
1723     std::cout << "  " << c->second.help << std::endl;
1724
1725   }
1726   //=======================================================================
1727
1728
1729   //=======================================================================
1730   /// Fills the vector commands with the commands which 
1731   /// have the first n chars of buf for prefix
1732   /// TODO : skip initial spaces in buf and also return the position of first
1733   /// non blank char in buf
1734   void Interpreter::FindCommandsWithPrefix( char* buf,
1735                                             int n,
1736                                             std::vector<std::string>& commands )
1737   {
1738     CommandDictType::const_iterator i;
1739     for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1740     {
1741       if ((i->first).find(buf,0,n) == 0) 
1742         commands.push_back(i->first);
1743     }
1744   }
1745   //=======================================================================
1746
1747
1748
1749   //=======================================================================
1750 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1751   
1752   inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1753   inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1754   
1755   // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1756   // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1757   // E.G. STORE THIS IN bbtk_config.xml
1758 #define BBTK_UP_ARROW_KBCODE    0x00415B1B
1759 #define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
1760 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1761 #define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
1762 #define BBTK_BACKSPACE_KBCODE   0x00000008
1763 #define BBTK_DEL_KBCODE         0x0000007F
1764 #define BBTK_SPACE_KBCODE       0x00000020 
1765
1766   //=======================================================================
1767   void Interpreter::GetLineFromPrompt(std::string& s)
1768   {
1769     int c;
1770     unsigned int ind=0;
1771
1772     unsigned int MAX_LINE_SIZE = 160;
1773     unsigned int MAX_HISTORY_SIZE = 100;
1774
1775     char* newline = new char[MAX_LINE_SIZE];
1776     memset(newline,0,MAX_LINE_SIZE);
1777     char* histline = new char[MAX_LINE_SIZE];
1778     memset(histline,0,MAX_LINE_SIZE);
1779
1780     char* line = newline;
1781     unsigned int hist = mHistory.size();
1782
1783     write(1,"> ",2);
1784     while(1)
1785     {
1786        c=0;
1787        read ( STDIN_FILENO, &c, 4) ;
1788
1789        bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1790
1791        // Printable character
1792        if ( (ind<MAX_LINE_SIZE-1) &&
1793             ( c >= BBTK_SPACE_KBCODE ) && 
1794             ( c <  BBTK_DEL_KBCODE )) 
1795        {
1796           PrintChar(c);
1797           line[ind++]=c;
1798        }
1799       // CR
1800        else if (c=='\n')
1801        {
1802        // delete the unused line
1803           if (line==newline)
1804               delete histline;
1805           else
1806               delete newline;
1807    
1808     // empty lines are not stored in from history
1809           if (strlen(line)) 
1810           {
1811              // if history too long : delete oldest command
1812              if (mHistory.size()>MAX_HISTORY_SIZE) 
1813              {
1814                 delete mHistory.front();
1815                 mHistory.pop_front();
1816              }
1817              mHistory.push_back(line);
1818           }
1819           break;
1820         }
1821        // Backspace
1822         else if ( (ind>0) && 
1823                   ((c == BBTK_BACKSPACE_KBCODE) ||
1824                    (c == BBTK_DEL_KBCODE)) )
1825           {
1826             line[ind--]=' ';
1827             BackSpace();
1828           }
1829         // Tab 
1830         else if (c=='\t')
1831           {
1832             // TODO : Command completion  
1833             std::vector<std::string> commands;
1834             FindCommandsWithPrefix( line,ind,commands);
1835             if (commands.size()==1) 
1836               {
1837                 std::string com = *commands.begin();
1838                 for (; ind<com.size(); ++ind) 
1839                   {
1840                     PrintChar(com[ind]); 
1841                     line[ind]=com[ind];
1842                   }
1843                 PrintChar(' '); 
1844                 line[ind++]=' ';
1845               }
1846             else if (commands.size()>1) 
1847               {
1848                 std::vector<std::string>::iterator i;
1849                 write(1,"\n",1);
1850                 for (i=commands.begin();i!=commands.end();++i) 
1851                   {
1852                     write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1853                     PrintChar(' ');
1854                   }
1855                 write(STDOUT_FILENO,"\n> ",3);
1856                 //for (int j=0;j<ind;++j) 
1857                   //{
1858                     write(STDOUT_FILENO,line,ind); 
1859                     //  }
1860               }
1861           }
1862         // Arrow up : back in history
1863         else if (c==BBTK_UP_ARROW_KBCODE)
1864           {
1865             if (hist) 
1866               {
1867                 // erase current line
1868                 while (ind--) BackSpace();
1869                 // 
1870                 hist--;
1871                 // 
1872                 strcpy(histline,mHistory[hist]);
1873                 line = histline;
1874                 ind = strlen(line);
1875                 
1876                 write(STDOUT_FILENO,line,ind);
1877               }
1878           }
1879         // Arrow down : down in history
1880         else if (c==BBTK_DOWN_ARROW_KBCODE)
1881           {
1882             if (hist<mHistory.size()-1) 
1883               {
1884                 // erase current line
1885                 while (ind--) BackSpace();
1886                 // 
1887                 hist++;
1888                 // 
1889                 strcpy(histline,mHistory[hist]);
1890                 line = histline;
1891                 ind = strlen(line);
1892                 
1893                 write(STDOUT_FILENO,line,ind);
1894               }
1895             // end of history : switch back to newline
1896             else if (hist==mHistory.size()-1)
1897               {
1898                 // erase current line
1899                 while (ind--) BackSpace();
1900                 // 
1901                 hist++;
1902                 // 
1903                 line = newline;
1904                 ind = strlen(line);
1905                 
1906                 write(STDOUT_FILENO,line,ind);
1907               }
1908           }
1909         // Arrow right
1910         else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1911           {
1912             PrintChar(line[ind]);
1913             ind++;
1914           }
1915
1916         // Arrow left
1917         else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1918           {
1919             PrintChar('\b');
1920             ind--;
1921     
1922           }
1923
1924       }
1925     write(STDOUT_FILENO,"\n\r",2);
1926     
1927     
1928     s = line;
1929     
1930   }
1931 #else
1932
1933   //=======================================================================
1934   void Interpreter::GetLineFromPrompt(std::string& s)
1935   {  
1936     s.clear();
1937
1938     putchar('>');
1939     putchar(' ');
1940
1941     do 
1942     {
1943       char c = getchar();
1944       if (c=='\n') 
1945       {
1946         putchar('\n');
1947         break;
1948       }
1949       if (c=='\t') 
1950       {
1951         // putchar('T');
1952         continue;
1953       }
1954       // putchar(c);
1955       s += c;
1956     } 
1957     while (true);  
1958     
1959   }
1960   //=======================================================================  
1961
1962 #endif
1963
1964
1965
1966   //=======================================================================
1967   void Interpreter::CommandLineInterpreter()
1968   {
1969     bbtkDebugMessageInc("interpreter",9,
1970                         "Interpreter::CommandLineInterpreter()"<<std::endl);
1971
1972 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
1973     // Initialise the tty in non canonical mode with no echo
1974     // oter remembers the previous settings to restore them after 
1975     struct termios ter,oter;
1976     tcgetattr(0,&ter);
1977     oter=ter;
1978     ter.c_lflag &= ~ECHO;
1979     ter.c_lflag &= ~ICANON;
1980     ter.c_cc[VMIN]=1;
1981     ter.c_cc[VTIME]=0;
1982     tcsetattr(0,TCSANOW,&ter);
1983 #endif
1984     
1985     mCommandLine = true;
1986     bool again = true;
1987     // bool insideComment = false; // for multiline comment  
1988     mInsideComment = false;
1989     do 
1990     {
1991       try
1992       {
1993         std::string line;
1994         GetLineFromPrompt(line);
1995         DoInterpretLine(line); //, insideComment);
1996       }
1997       /*
1998       catch (QuitException e)
1999       {
2000         bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
2001         again = false;
2002       }
2003       */
2004       catch (bbtk::Exception e) 
2005       {
2006         e.Print();
2007       }
2008         catch (std::exception& e) 
2009       {
2010         std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
2011       }
2012       catch (...)
2013       {
2014         std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2015       }
2016     }
2017     while (again);
2018
2019 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2020     tcsetattr(0,TCSANOW,&oter);
2021 #endif
2022
2023     std::cout << "Good bye !" << std::endl;
2024
2025     bbtkDebugDecTab("interpreter",9);
2026   }
2027
2028 //=======================================================================
2029 void Interpreter::Graph(const std::vector<std::string>& words)
2030 {
2031   std::string page;
2032     bool system_display = true;
2033
2034     if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2035       system_display = false; 
2036  
2037     if (words.size()==1) 
2038     {
2039       page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
2040     }
2041     else if (words.size()==2) 
2042     {
2043       page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
2044     }
2045     else if (words.size()==3) 
2046     {
2047       page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
2048     }
2049     else if (words.size()==4) 
2050     {
2051       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
2052     } 
2053     else if (words.size()==5) 
2054     {
2055       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
2056     } 
2057     else if (words.size()==6) 
2058     {
2059       page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
2060     } 
2061     else if (words.size()==7) 
2062       {
2063         page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
2064       } 
2065     
2066     if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2067       mUser->InterpreterUserViewHtmlPage(page);
2068
2069   }
2070 //=======================================================================
2071
2072
2073 //=======================================================================
2074 void  Interpreter::Index(const std::string& filename, 
2075                          const std::string& type)
2076 {
2077   Factory::IndexEntryType t;
2078   if (type=="Initials") t = Factory::Initials;
2079   else if (type=="Categories") t = Factory::Categories;
2080   else if (type=="Packages") t = Factory::Packages;
2081   else if (type=="Adaptors") t = Factory::Adaptors;
2082   
2083   GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
2084 }
2085 //=======================================================================
2086
2087
2088 //=======================================================================
2089 void  Interpreter::NewGUI(const std::string& boxname,
2090                              const std::string& instanceName)
2091 {
2092   if (mRealExecuter.expired())
2093     {
2094       bbtkError("command 'newgui' cannot be compiled yet");
2095     }
2096
2097   std::string typeName = instanceName+"Type";
2098   std::stringstream* s = new std::stringstream;
2099   // create the complex box
2100   (*s) << "define "<<typeName<<std::endl;
2101   //  (*s) << "  description 'Automatically generated user interface for the box "
2102   //       << boxname << "'" <<std::endl;
2103   // create the Layout box
2104   (*s) << "  load wx"<<std::endl;
2105   (*s) << "  new LayoutLine layout"<<std::endl;
2106   // create the output 'Widget'
2107   (*s) << "  output Widget layout.Widget Widget"<<std::endl;
2108   // the box change output 
2109   (*s) << "  new MultipleInputs change"<<std::endl;
2110   (*s) << "  output BoxChange change.Out BoxChange"<<std::endl;
2111
2112   // Browse the inputs of the box in order to find which ones are not 
2113   // connected and can be adapted from a widget adaptor
2114   // vector which stores the list of inputs of the box which must be connected
2115   std::vector<std::string> in;
2116  
2117   Factory::Pointer F = mVirtualExecuter->GetFactory();
2118   /*
2119   Package::Pointer user = F->GetPackage("user");
2120   */
2121   ComplexBlackBoxDescriptor::Pointer workspace = 
2122     mRealExecuter.lock()->GetCurrentDescriptor();
2123
2124   if (workspace==0)
2125     {
2126       delete s;
2127       bbtkError("interpreter::CreateGUI : could not access the executer currently defined complex box");
2128     }
2129  
2130
2131   /*
2132     (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2133   */
2134
2135   BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2136   //  BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2137   // int nb = 0;
2138   BlackBox::InputConnectorMapType::iterator i;
2139   for (i=box->bbGetInputConnectorMap().begin();
2140        i!=box->bbGetInputConnectorMap().end();
2141        ++i)
2142     {
2143       // If the input is connected : continue
2144       if (i->second->IsConnected()) continue;
2145       // Get the input descriptor 
2146       const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2147       // If it is a "system" input : skip it
2148 #ifdef USE_WXWIDGETS
2149       if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2150            ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2151         continue;
2152 #else
2153       if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) )
2154         continue;
2155 #endif
2156       bool widok = true;
2157       std::string widget,adaptor;
2158       // try to find a widget adaptor
2159       if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2160                                d->GetDataInfo(),
2161                                adaptor))
2162         {
2163           // command to create the adaptor
2164           (*s) << "  new "<<adaptor<<" "<<i->first<<std::endl;
2165           // Sets the label of the widget adaptor to the name of the input
2166           (*s) << "  set "<<i->first<<".Label "<<i->first<<std::endl;
2167           // Sets the initial value of the widget to the value of the input
2168           (*s) << "  set "<<i->first<<".In \" "
2169                <<box->bbGetInputAsString(i->first)<<"\""
2170                << std::endl;
2171           // store the input name
2172           in.push_back(i->first);
2173           (*s) << "  connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2174             //<i->first<<"'"<<std::endl;
2175           (*s) << "  connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2176         }
2177       // try to find a two pieces adaptor
2178       else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2179                                      d->GetDataInfo(),
2180                                      widget,adaptor) )
2181         {
2182           // command to create the widget
2183           (*s) << "  new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2184           // command to create the adaptor
2185           (*s) << "  new "<<adaptor<<" "<<i->first<<std::endl;
2186           // connect the two
2187           (*s) << "  connect "<<i->first<<"Widget.Out "
2188                <<i->first<<".In"<<std::endl;
2189           // Sets the label of the widget adaptor to the name of the input
2190           (*s) << "  set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2191           // Sets the initial value of the widget to the value of the input
2192           (*s) << "  set "<<i->first<<"Widget.In \" "
2193                <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2194           // store the input name
2195           in.push_back(i->first);
2196           (*s) << "  connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2197             //<i->first<<"'"<<std::endl;
2198           (*s) << "  connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2199
2200         }
2201       // try to find an adaptor from string 
2202       // If found then can create a text input which 
2203       // will be automatically adapted 
2204       else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2205                                d->GetDataInfo(),
2206                                adaptor))
2207         {
2208           // command to create the adaptor
2209           (*s) << "  new InputText "<<i->first<<std::endl;
2210           // Sets the label of the widget adaptor to the name of the input
2211           (*s) << "  set "<<i->first<<".Title "<<i->first<<std::endl;
2212           // Sets the initial value of the widget to the value of the input
2213           (*s) << "  set "<<i->first<<".In \" "
2214                <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2215           // store the input name
2216           in.push_back(i->first);
2217           (*s) << "  connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2218             //<i->first<<"'"<<std::endl;
2219           (*s) << "  connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2220
2221         }
2222       else 
2223         {
2224           widok = false;
2225         }
2226       if (widok)
2227         {
2228           // command to create the output
2229           (*s) << "  output "<<i->first<<" "
2230                <<i->first<<".Out "<<i->first<<std::endl;
2231             //         <<" Output of the widget which allows to set "
2232           
2233         }
2234     }   
2235   // Inputs for window properties
2236   (*s) << "  input WinTitle layout.WinTitle Title"<<std::endl;
2237   (*s) << "  input WinWidth layout.WinWidth Width"<<std::endl;
2238   (*s) << "  input WinHeight layout.WinHeight Height"<<std::endl;
2239   (*s) << "  input WinDialog layout.WinDialog Dialog"<<std::endl;
2240   (*s) << "  input WinHide layout.WinHide Hide"<<std::endl;
2241
2242   
2243   
2244   // Execute the box executes the layout
2245   (*s) << "  exec layout" << std::endl;
2246   (*s) << "endefine" << std::endl;
2247   // (*s) << "help "<< typeName<< std::endl;
2248   // instanciate the box and connect it
2249   (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2250   // connections
2251   std::vector<std::string>::iterator j;
2252   for (j=in.begin();j!=in.end();++j)
2253     {
2254       // connect
2255       (*s) << "connect "<<instanceName<<"."<<*j<<" "
2256            << boxname<<"."<<*j<<std::endl;
2257     }
2258   // That's all folks ! now execute the commands :
2259   SwitchToStream(s);
2260 }
2261 //=======================================================================
2262
2263
2264
2265  //==========================================================================
2266   void Interpreter::Debug(const std::string& name)
2267   {
2268     if ((name.length()==2)&&(name[0]=='-'))
2269       {
2270         if (name[1]=='D')
2271           {
2272             bbtk::StaticInitTime::PrintObjectListInfo = true;
2273           }
2274         if (name[1]=='C')
2275           {
2276             //      int o = MessageManager::GetMessageLevel("debug");
2277             //      if (o<2) MessageManager::SetMessageLevel("debug",2);
2278             mVirtualExecuter->GetFactory()->Check();
2279             //      MessageManager::SetMessageLevel("debug",o);
2280           }
2281       }
2282     else 
2283       {
2284         Object:: PrintObjectListInfo(name);
2285       }
2286   }
2287  //==========================================================================
2288
2289   /*
2290   //==========================================================================
2291   // Adds a callback when 'break' command issued
2292   void Interpreter::AddBreakObserver( BreakCallbackType c )
2293   {
2294     mBreakSignal.connect(c);
2295   }
2296  //==========================================================================
2297  */
2298
2299  //==========================================================================
2300   std::string Interpreter::GetObjectName() const
2301   {
2302     return std::string("Interpreter");
2303   }
2304   //==========================================================================
2305   
2306   //==========================================================================
2307   std::string  Interpreter::GetObjectInfo() const 
2308   {
2309     std::stringstream i;
2310     return i.str();
2311   }
2312   //==========================================================================
2313
2314   //==========================================================================
2315 size_t  Interpreter::GetObjectSize() const 
2316 {
2317   size_t s = Superclass::GetObjectSize();
2318   s += Interpreter::GetObjectInternalSize();
2319   return s;
2320   }
2321   //==========================================================================
2322   //==========================================================================
2323 size_t  Interpreter::GetObjectInternalSize() const 
2324 {
2325   size_t s = sizeof(Interpreter);
2326   return s;
2327   }
2328   //==========================================================================
2329   //==========================================================================
2330   size_t  Interpreter::GetObjectRecursiveSize() const 
2331   {
2332     size_t s = Superclass::GetObjectRecursiveSize();
2333     s += Interpreter::GetObjectInternalSize();
2334     s += mVirtualExecuter->GetObjectRecursiveSize();
2335     return s;
2336   }
2337   //==========================================================================
2338 }//namespace
2339
2340