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