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