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