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