]> Creatis software - bbtk.git/blob - kernel/src/bbtkInterpreterVirtual.cxx
no message
[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(std::string boxType, std::string boxName)
695     {
696     }
697         
698         void InterpreterVirtual::commandDelete(std::string boxName)
699     {
700     }
701
702         void InterpreterVirtual::commandConnection(std::string nodeFrom, std::string outputLabel, std::string nodeTo, std::string inputLabel)
703     {
704     }
705                 
706         void InterpreterVirtual::commandPackage(std::string packageName)
707     {
708     }
709         
710         void InterpreterVirtual::commandEndPackage()
711     {
712     }
713         
714         void InterpreterVirtual::commandDefine(std::string name, std::string pack, std::string scriptfilename)
715     {
716     }
717
718         void InterpreterVirtual::commandEndDefine()
719     {
720     }
721
722         void InterpreterVirtual::commandKind(std::string kind)
723     {
724     }
725         
726         void InterpreterVirtual::commandPrint(std::string value)
727     {
728     }
729         
730         
731         void InterpreterVirtual::commandExec(std::string word)
732     {
733     }
734         
735         
736         void InterpreterVirtual::commandInput(std::string name, std::string box, std::string input,std::string  help)
737     {
738     }
739         
740         void InterpreterVirtual::commandOutput(std::string name, std::string box, std::string output,std::string  help)
741     {
742     }
743         
744         void InterpreterVirtual::commandSet(std::string box, std::string input, std::string value)
745     {
746     }
747
748         void InterpreterVirtual::commandAuthor(std::string author)
749     {
750     }
751
752         void InterpreterVirtual::commandCategory(std::string categorytype)
753     {
754     }
755         
756         
757         
758         void InterpreterVirtual::commandDescription(std::string description)
759     {
760     }
761
762         
763         void InterpreterVirtual::commandClear()
764     {
765     }
766         
767         void InterpreterVirtual::commandInclude(std::string word, bool ok)
768     {
769     }
770         
771         
772         void InterpreterVirtual::commandLoad(std::string packageName)
773     {
774     }
775
776         void InterpreterVirtual::commandUnload(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 //ups2 EED Borrame      
793         void InterpreterVirtual::commandMessage(std::string kind, std::string levelstr)
794     {
795     }
796         
797         
798         
799   //=======================================================================  
800   void InterpreterVirtual::DoInterpretLine( const std::string& line )
801   {
802     bbtkDebugMessage("interpreter",6,"==> InterpreterVirtual::DoInterpretLine(\""
803                      <<line<<"\")"<<std::endl);
804     std::vector<std::string> words;
805     SplitLine(line,words);
806
807     // Empty line
808     if (words.size()<1) 
809     {
810        bbtkDebugDecTab("interpreter",9);
811        return;
812     }
813
814     // Single line comment : # or //
815     if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') ) 
816     {  
817        bbtkDebugDecTab("interpreter",9);
818        bbtkMessage("interpreter",9,"Comment"<<std::endl);
819        return;
820     }
821
822     // Multi line comment ( /* ... */ ) -delimiters on different lines !-
823     
824     if (words[0][0]=='/' && words[0][1]=='*') 
825     {  
826        bbtkDebugDecTab("interpreter",9);
827        bbtkMessage("interpreter",9,"In multiline comment"<<std::endl);
828        mInsideComment = true;
829        return;
830     }
831
832     if (words[0][0]=='*' && words[0][1]=='/') 
833     {  
834        bbtkDebugDecTab("interpreter",9);
835        bbtkMessage("interpreter",9,"Out multiline comment"<<std::endl);
836        if ( !mInsideComment ) {
837           bbtkDebugDecTab("interpreter",9);
838           bbtkMessage("interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);       
839        }
840        mInsideComment = false;
841        return;
842     }
843
844     if (mInsideComment) 
845     {  
846        bbtkDebugDecTab("interpreter",9);
847        bbtkMessage("interpreter",9,"Multiline Comment"<<std::endl);
848        return;
849     }
850
851     // Command 
852     CommandInfoType command;
853     InterpretCommand(words,command);
854 //std::cout<<"JCP bbtkInterpreter command.keyword ="<<command.keyword<<std::endl;
855     bbtkDebugMessage("interpreter",9,
856                      "Command='"<<command.keyword
857                       <<"' code="<<command.code<<std::endl); 
858           
859     std::string left,right,left2,right2;
860     std::string filename;
861
862 //ups1 EED borrame        
863     // message command
864     if (command.code==cMessage)
865       {
866         if (words.size()<3)
867           {
868                   commandMessage();
869 //EED Borrame       mVirtualExecuter->HelpMessages();
870           }
871         else
872           {
873                 commandMessage(words[1],words[2]);
874 //EED Borrame           sscanf(words[2].c_str(),"%d",&level);
875 //EED Borrame       mVirtualExecuter->SetMessageLevel(words[1],level);
876           }
877         return;
878       }
879     else 
880       {
881         bbtkMessage("echo",2,line<<std::endl);
882       }
883
884     // break and quit commands
885     if ((command.code==cBreak) || (command.code==cQuit))
886       {
887         bool in_script = false;
888         std::string file("");
889         int line = 0;
890
891         if (mFileName.size()) 
892           {
893             std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
894             if (fs!=0) in_script = true;          
895             file = mFileName.back();
896             line = mLine.back();
897           } 
898         if (command.code==cBreak)
899           {
900             /*
901             std::cout << "BreakException(" 
902                       <<in_script<<","
903                       <<file<<","
904                       <<line<<")"<<std::endl;
905             */
906                   commandBreak();
907 //EED Borrame       bbtkError("break");//,in_script,file,line);
908             //      throw BreakException(in_script,file,line);
909           }       
910         else 
911           {
912                   commandQuit();
913 //EED Borrame       bbtkError("quit");//,in_script,file,line);
914               //throw QuitException(in_script,file,line);
915           }
916         return;
917       }   
918 //std::cout<<" mVirtualExecuter->Create(words[1],words[2]); "<<line<<std::endl;
919     // other cammands
920
921     switch (command.code) 
922       {
923       case cNew :
924                 commandNew(words[1],words[2]);
925 //EED Borrame        mVirtualExecuter->Create(words[1],words[2]);
926         break;
927
928       case cDelete :
929                           commandDelete(words[1]);
930 //EED Borrame   mVirtualExecuter->Destroy(words[1]);
931         break;
932
933       case cConnect :
934         Utilities::SplitAroundFirstDot(words[1],left,right);
935         Utilities::SplitAroundFirstDot(words[2],left2,right2);      
936         commandConnection(left,right,left2,right2);
937 //EED Borrame        mVirtualExecuter->Connect(left,right,left2,right2);
938         break;
939
940       case cPackage :
941                           commandPackage(words[1]);
942 //EED Borrame                mVirtualExecuter->BeginPackage(words[1]);
943         break;
944
945       case cEndPackage :
946                           commandEndPackage();
947 //EED Borrame        mVirtualExecuter->EndPackage();
948         break;
949
950       case cDefine :
951         if (mFileName.size()>0) 
952         {
953 //???                   commandDefine(????);
954                    filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
955         }
956         if (words.size()==2) 
957         {
958                         commandDefine(words[1],"",filename);
959 //EED Borrame           mVirtualExecuter->Define(words[1],"",filename);
960         }
961         else
962         {
963                         commandDefine(words[1],words[2],filename);
964 //EED Borrame           mVirtualExecuter->Define(words[1],words[2],filename);
965         }
966         break;
967
968       case cEndDefine :
969                 commandEndDefine();
970 //EED Borrame        mVirtualExecuter->EndDefine();
971         break;
972
973       case cKind :
974                         commandKind(words[1]);
975 //EED Borrame        mVirtualExecuter->Kind(words[1]);
976         break;
977
978       case cPrint :
979                           commandPrint(words[1]);
980 //EED Borrame        mVirtualExecuter->Print(words[1]);
981         break;
982                           
983       case cExec :
984                           commandExec(words[1]);
985 //EED Borrame        if (words[1]=="freeze") 
986 //EED Borrame     {
987 //EED Borrame       mVirtualExecuter->SetNoExecMode(true);
988 //EED Borrame       mThrow = false;
989 //EED Borrame     }
990 //EED Borrame   else if (words[1]=="freeze_no_error") 
991 //EED Borrame     {
992 //EED Borrame       mVirtualExecuter->SetNoExecMode(true);
993 //EED Borrame       mVirtualExecuter->SetNoErrorMode(true);
994 //EED Borrame       mThrow = false;
995 //EED Borrame     }
996 //EED Borrame   else if (words[1]=="unfreeze") 
997 //EED Borrame     {
998 //EED Borrame       mVirtualExecuter->SetNoExecMode(false);
999 //EED Borrame       mVirtualExecuter->SetNoErrorMode(false);
1000 //EED Borrame     }
1001 //EED Borrame   else
1002 //EED Borrame     {
1003 //EED Borrame       mVirtualExecuter->Execute(words[1]);
1004 //EED Borrame     }
1005                           
1006         break;
1007
1008       case cInput :
1009         Utilities::SplitAroundFirstDot(words[2],left,right);
1010                           commandInput(words[1],left,right,words[3]);
1011 //EED Borrame        mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
1012         break;
1013
1014       case cOutput :
1015         Utilities::SplitAroundFirstDot(words[2],left,right);
1016                 commandOutput(words[1],left,right,words[3]);
1017 //EED Borrame         mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
1018         break;
1019
1020       case cSet :
1021         Utilities::SplitAroundFirstDot(words[1],left,right);
1022                 commandSet(left,right,words[2]);
1023 //EED Borrame        mVirtualExecuter->Set(left,right,words[2]);
1024         break;
1025
1026       case cAuthor :
1027                 commandAuthor(words[1]);
1028 //EED Borrame        mVirtualExecuter->Author(words[1]);
1029         break;
1030
1031       case cNewGUI :
1032                 commandNewGUI(words[1],words[2]);
1033         break;
1034
1035       case cCategory :
1036                 commandCategory(words[1]);
1037 //EED Borrame   mVirtualExecuter->Category(words[1]);
1038         break;
1039
1040       case cIndex :
1041         if (words.size()==1)
1042                         commandIndex("tmp_index.html");
1043         else if (words.size()==2)
1044                         commandIndex(words[1]);
1045         else if (words.size()==3)
1046                         commandIndex(words[1],words[2]);
1047         break;
1048
1049       case cDescription :
1050                 commandDescription(words[1]);
1051 //EED Borrame        mVirtualExecuter->Description(words[1]);
1052         break;
1053
1054       case cHelp :
1055         commandHelp(words);
1056         break;
1057
1058
1059       case cGraph :
1060         commandGraph(words);
1061         break;
1062
1063       case cConfig :
1064         commandConfig();
1065         break;
1066
1067       case cReset :  
1068         commandReset();
1069         break;
1070         
1071       case cClear :  
1072                 commandClear();
1073 //EED Borrame           mVirtualExecuter->Clear();
1074         break;
1075
1076       case cInclude :
1077                           commandInclude( words[1] , (words.size()==3) );
1078 //EED Borrame           // if 'source' was given (words.size()==3) then tell to set the 
1079 //EED Borrame           // source file name of the current complex box with the full file name included
1080 //EED Borrame           if (mCommandLine)
1081 //EED Borrame        {
1082 //EED Borrame           InterpretFile(words[1],(words.size()==3)); 
1083 //EED Borrame        } else{
1084 //EED Borrame            SwitchToFile(words[1],(words.size()==3) );
1085 //EED Borrame        }
1086                 break;
1087
1088       case cLoad:
1089                 commandLoad( words[1] );
1090 //EED Borrame        GetExecuter()->LoadPackage(words[1]);
1091         break;
1092
1093       case cUnload:
1094                 commandUnload( words[1] );
1095 //EED Borrame        GetExecuter()->UnLoadPackage(words[1]);
1096         break;
1097
1098       case cDebug :
1099                           if (words.size()==2) commandDebug(words[1]);
1100                                 else commandDebug("");
1101         break;
1102                           
1103         /* obsolete
1104       case cWorkspace :
1105         if (words.size() == 2) 
1106         {
1107            if (words[1]=="freeze")        mVirtualExecuter->SetNoExecMode(true);
1108            else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1109         }
1110         else
1111         {
1112            mVirtualExecuter->SetWorkspaceName(words[2]);
1113         }
1114         break;
1115         */
1116       default:
1117         bbtkInternalError("should not reach here !!!");
1118    }
1119
1120     bbtkDebugMessage("interpreter",6,"<== InterpreterVirtual::DoInterpretLine(\""
1121                      <<line<<"\")"<<std::endl);
1122     
1123   }
1124   //=======================================================================  
1125
1126
1127
1128
1129
1130   //=======================================================================
1131   void InterpreterVirtual::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1132 {
1133     bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1134
1135     std::string delimiters = "\"";
1136     std::vector<std::string> quote;
1137     Utilities::SplitString(str,delimiters,quote);
1138
1139     delimiters = " \t";
1140     std::vector<std::string>::iterator i;
1141     for (i=quote.begin(); i!=quote.end(); ) 
1142     {
1143        Utilities::SplitString(*i,delimiters,tokens);
1144        ++i;
1145        if (i!=quote.end()) 
1146        {
1147         //    bbtkDebugMessage("interpreter",0,"\""<<*i<<"\""<<std::endl);
1148           tokens.push_back(*i);
1149           ++i;
1150        }
1151     }
1152
1153     for (i=tokens.begin(); i!=tokens.end(); ++i) 
1154     {
1155       bbtkDebugMessage("interpreter",9,"--["<<*i<<"]"<<std::endl);
1156     }
1157     bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::SplitLine(\""<<str<<"\")"<<std::endl);
1158
1159  }
1160   //=======================================================================
1161
1162
1163   //=======================================================================
1164   void InterpreterVirtual::commandReset()
1165   {
1166   }
1167   //=======================================================================
1168
1169   //=======================================================================
1170   /**
1171    *
1172    */
1173   /*
1174   void InterpreterVirtual::Print( const std::string& str)
1175   {
1176     if (mVirtualExecuter->GetNoExecMode()) return;
1177
1178     bbtkDebugMessageInc("interpreter",9,"InterpreterVirtual::Print(\""<<str<<"\")"<<std::endl);
1179
1180  // TO DO :
1181  // InterpretLine ("load std")
1182  // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande 
1183  // InterpretLine("new Print _P_") 
1184  // InterpretLine("connect _C_.Out _P_.In")
1185  // int num = 1
1186  
1187
1188     std::vector<std::string> chains;
1189     std::string delimiters("$");
1190
1191     // Skip delimiters at beginning.
1192     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1193     bool is_text = true;
1194     if (lastPos>0) is_text = false;
1195
1196     // Find first delimiter.
1197     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
1198
1199     while (std::string::npos != pos || std::string::npos != lastPos)
1200     {
1201        if (is_text) 
1202        {
1203           // Found a text token, add it to the vector.
1204           chains.push_back(str.substr(lastPos, pos - lastPos));
1205  // std::string token = str.substr(lastPos, pos - lastPos)
1206  // InterpretLine("set _C_.In%num% %token%")
1207  
1208        }
1209        else 
1210        {
1211
1212        // is an output (between $$) : decode 
1213          std::string tok,box,output;
1214          tok = str.substr(lastPos, pos - lastPos);
1215          Utilities::SplitAroundFirstDot(tok,box,output);
1216          chains.push_back( mVirtualExecuter->Get(box,output) );
1217
1218 // InterpretLine("connect %tok% _C_.In%num%") 
1219
1220        }
1221         // Skip delimiters.  Note the "not_of"
1222        lastPos = str.find_first_not_of(delimiters, pos);
1223         // Find next delimiter
1224        pos = str.find_first_of(delimiters, lastPos);
1225     //
1226        is_text = !is_text;
1227 // num ++;
1228      }
1229 // InterpretLine("exec _P_")
1230 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1231
1232      std::vector<std::string>::iterator i;
1233      for (i= chains.begin(); i!=chains.end(); ++i) 
1234      {
1235
1236        Utilities::SubsBackslashN(*i);
1237        std::cout << *i;
1238      }
1239      std::cout << std::endl;
1240      bbtkDebugDecTab("interpreter",9);
1241  }
1242 */
1243
1244   //=======================================================================
1245   /**
1246    *
1247    */
1248
1249   // =========================================================================
1250   void InterpreterVirtual::SwitchToFile( const std::string& name , bool source )
1251   {
1252   // Note : in the following :
1253   // name : the user supplied name 
1254   //      - abreviated name    e.g.       scr   scr.bbs
1255   //      - relative full name e.g.       ./scr.bbs   ../../scr.bbs 
1256   //      - absolute full name e.g.       /home/usrname/proj/dir/scr.bbs
1257   //          same for Windows, with      c:, d: ...
1258   //
1259   // use ./directory/subdir/scrname.bbs
1260   //
1261
1262     bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToFile( \""
1263                      <<name<<"\")"<<std::endl);
1264
1265     std::vector<std::string> script_paths;
1266     std::string fullPathScriptName;  // full path script name
1267     std::string pkgname;             // e.g. <scriptname>.bbs
1268     std::vector<std::string> Filenames;
1269
1270     // The following is *NOT* a debug time message :
1271     // It's a user intended message.
1272     // Please don't remove it.
1273     bbtkMessage("interpreter",1,
1274         "look for : [" << name
1275         << "]" << std::endl);
1276
1277
1278     std::string upath;
1279     pkgname = Utilities::ExtractScriptName(name,upath);
1280
1281     bbtkMessage("interpreter",3,
1282                 "package name:[" << pkgname
1283                  << "] path:[" << upath << "]" << std::endl);
1284     bool fullnameGiven = false; 
1285     bool foundFile     = false;
1286
1287     // ==== "*" provided : load all scripts in given path 
1288     // relative (e.g. std/boxes/*) or absolute 
1289     if (pkgname == "*") 
1290       {
1291
1292         std::stringstream* stream = new std::stringstream;
1293         //if (upath.size()!=0) // avoid troubles for "*"
1294         
1295         // ==== no path provided : look in root bbs path
1296         if (upath.size()==0)
1297           {
1298             //      bbtkMessage("interpreter",1,
1299             // LG : add all bbs path
1300             //  script_paths.push_back(  ConfigurationFile::GetInstance().Get_root_bbs_path() );
1301             std::vector<std::string>::const_iterator i;
1302             for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1303                  i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1304                  i++)
1305               {
1306                 script_paths.push_back(*i);
1307               }
1308           }
1309         // ==== absolute path provided 
1310         else if (upath[0]=='/' || upath[1] == ':' ) 
1311           {
1312             if ( Utilities::IsDirectory( upath ) )
1313               {
1314                 script_paths.push_back(upath);
1315               }
1316             else 
1317               {
1318                 bbtkError("'"<<upath<<"' : directory does not exist"); 
1319               }
1320           }
1321         // ==== relative path provided : search all bbs path appended with 
1322         // the relative path provided
1323         else
1324           {    
1325             std::vector<std::string>::const_iterator i;
1326             for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1327                  i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1328                  i++)
1329               {
1330                 std::string full_path(*i);
1331                 // we *really* want '.' to be the current working directory
1332                 if (full_path == ".") 
1333                   {
1334                     char buf[2048]; // for getcwd
1335                     char * currentDir = getcwd(buf, 2048);
1336                     std::string cwd(currentDir);
1337                     full_path = currentDir;
1338                   } // if full_path
1339                 
1340                 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1341                 full_path += upath;
1342                 
1343                 if ( Utilities::IsDirectory( full_path ) )
1344                   {
1345                     script_paths.push_back(full_path);
1346                   }
1347               } 
1348             if (script_paths.empty())
1349               {
1350                 bbtkError("no '"<<upath<<"' subdir found in search paths" 
1351                           << std::endl);
1352               }
1353           }
1354         
1355         
1356         // === search paths list complete : now explore it
1357         int nbBssFiles = 0;     
1358         // ==== relative name, iterate + load all .bbs/.bbp files
1359         std::vector<std::string>::iterator i;
1360         for (i=script_paths.begin();i!=script_paths.end();i++)
1361           {
1362             bbtkMessage("interpreter",1,
1363                         "--> Looking in '" << *i << "'" << std::endl);
1364             
1365             Filenames.clear();
1366             //int nbFiles = 
1367             Utilities::Explore(*i, false, Filenames);
1368             
1369             for (std::vector<std::string>::iterator j = Filenames.begin(); 
1370                  j!= Filenames.end(); ++j)
1371               {
1372                 int lgr = (*j).size();
1373                 if (lgr < 5) continue;  
1374                 // ignore non .bbp file
1375                 if ( (*j).substr(lgr-4, 4) != ".bbp") continue; 
1376                 
1377                 (*stream) << "include \"" << *j << "\"\n";
1378                 bbtkMessage("interpreter",2,"  --> Found '" << *j << "'" << std::endl);
1379                 
1380                 nbBssFiles++;
1381               } // for (std::vector...
1382           } // for (i=script_...
1383
1384         // === Result ...
1385         if (nbBssFiles==0)
1386           {
1387             bbtkMessage("interpreter",1,
1388                         "  --> No .bbp found"<< std::endl);
1389           } 
1390         else 
1391           {
1392             bbtkMessage("interpreter",1,
1393                         "  --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1394             SwitchToStream(stream);
1395           }
1396         return;
1397       }  
1398     //=============== end pkgname=="*" ===========
1399     
1400     
1401     // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1402     // (not only a plain script name)
1403     // we trust him, and try to expland the directory name
1404     // WARNING : starting from current local directory :  ./whatYouWant  (./ mandatory!)
1405
1406     if (name[0]=='/' || name[1] == ':' || name[0]=='.')  // absolute path (linux/windows) or relative path
1407     { 
1408
1409       // ===========================================================check user supplied location
1410       fullnameGiven = true;
1411
1412       fullPathScriptName =  Utilities::ExpandLibName(name, false);
1413
1414       // allow user to always forget ".bbs"
1415       int l = fullPathScriptName.size();
1416
1417       if (l!=0) 
1418           {
1419          if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1420                          (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1421          {
1422                         std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1423                         if ( Utilities::FileExists(tfullPathScriptName) )
1424                         {
1425                                 fullPathScriptName = tfullPathScriptName;
1426                                 foundFile = true;
1427                         }
1428                         else 
1429                         {
1430                                 tfullPathScriptName = fullPathScriptName + ".bbp";
1431                                 if ( Utilities::FileExists(tfullPathScriptName) )
1432                                 {
1433                                         fullPathScriptName = tfullPathScriptName;
1434                                         foundFile = true;
1435                                 }
1436                         }
1437                  }
1438                  else 
1439                  {
1440                         if ( Utilities::FileExists(fullPathScriptName) )
1441                         {
1442                                 foundFile = true;
1443                         }
1444                  }
1445           } // endif l != 0
1446   }
1447   else
1448   // =============================== iterate on the paths
1449   {
1450       script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1451       std::string path;
1452       std::vector<std::string>::iterator i;
1453       for (i=script_paths.begin();i!=script_paths.end();++i)
1454           {
1455                 path = *i;
1456                 // we *really* want '.' to be the current working directory
1457                 if (path == ".") 
1458                 {
1459                         char buf[2048]; // for getcwd
1460                         char * currentDir = getcwd(buf, 2048);
1461                         std::string cwd(currentDir);
1462                         path = currentDir;
1463                 }
1464           
1465                 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1466 //Addition JCP tfullPathScriptName.size()>=4 
1467                 if(tfullPathScriptName.size()>=4){
1468                         if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1469                         {
1470                           fullPathScriptName = tfullPathScriptName;
1471                                 if ( ! Utilities::FileExists(fullPathScriptName) )
1472                                 {
1473                                         // The following is *NOT* a debug time message :
1474                                         // It's a user intended message.
1475                                         // Please don't remove it.
1476                                         bbtkMessage("interpreter",2,
1477                                   "   [" <<fullPathScriptName <<"] : does not exist" 
1478                                   <<std::endl);
1479                                         continue;  // try next path
1480                                 }
1481                                 bbtkMessage("interpreter",2,
1482                                           "   [" <<fullPathScriptName 
1483                                           <<"] : found" <<std::endl);
1484                                 foundFile = true;
1485                                 break; // a script was found; we stop iterating
1486                         }
1487                         else 
1488                         {
1489                                 fullPathScriptName = tfullPathScriptName + ".bbs";
1490                                 // Check if library exists
1491                                 if ( ! Utilities::FileExists(fullPathScriptName) )
1492                                 {
1493                                         fullPathScriptName = tfullPathScriptName + ".bbp";
1494                                         if ( ! Utilities::FileExists(fullPathScriptName) )
1495                                         {
1496                                                 // The following is *NOT* a debug time message :
1497                                                 // It's a user intended message.
1498                                                 // Please don't remove it.
1499                                                 bbtkMessage("interpreter",2,
1500                                                 "   [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist" 
1501                                                 <<std::endl);
1502                                                 continue;  // try next path
1503                                         }
1504                                 }
1505                                 bbtkMessage("interpreter",2,
1506                                   "   [" <<fullPathScriptName 
1507                                   <<"] : found" <<std::endl);
1508                                 foundFile = true;
1509                                 break; // a script was found; we stop iterating
1510                         }
1511                 }               
1512         } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1513   }
1514
1515     if (!foundFile)
1516       {
1517         if (fullnameGiven)
1518           if(fullPathScriptName == "")
1519             bbtkError("Path ["<<upath<<"] doesn't exist");
1520           else
1521             bbtkError("Script ["<<fullPathScriptName<<"] not found");
1522         else
1523           bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1524         return;
1525       } else {
1526                 LoadScript(fullPathScriptName,name);
1527 //EED Borrame     if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1528                 if (source) SetCurrentFileName(fullPathScriptName);
1529         }    
1530     return;
1531   }
1532   //=======================================================================
1533
1534         //=======================================================================
1535         void InterpreterVirtual::SetCurrentFileName(std::string fullPathScriptName)  // virtual 
1536         {
1537         }       
1538         //=======================================================================
1539         
1540   //=======================================================================
1541 void InterpreterVirtual::SwitchToStream( std::stringstream* stream )
1542 {
1543   bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::SwitchToStream()"
1544                    <<std::endl);
1545    mFile.push_back(stream);
1546     std::ostringstream buffer_name;
1547     bufferNb++;
1548     buffer_name << "buffer_" ;
1549
1550     if (mFileName.size()>0 )
1551     {
1552        buffer_name << mFileName.back() << "_" << mLine.back();
1553     }
1554     mFileName.push_back(buffer_name.str());
1555     mIncludeFileName.push_back(buffer_name.str());
1556     mLine.push_back(0);
1557 }
1558   //=======================================================================
1559
1560   //=======================================================================
1561
1562   void InterpreterVirtual::LoadScript( std::string fullPathScriptName,
1563                                 std::string includeScriptName)
1564   {
1565     bbtkDebugMessage("interpreter",4,"==> InterpreterVirtual::LoadScript("
1566                      <<fullPathScriptName<<")"
1567                      <<std::endl);
1568
1569     Utilities::replace( fullPathScriptName , 
1570                          INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1571    
1572      if (find(mFileNameHistory.begin(),
1573               mFileNameHistory.end(),
1574               fullPathScriptName)!=mFileNameHistory.end())
1575      {
1576         return;
1577      }
1578
1579     std::ifstream* s;
1580     s = new std::ifstream;
1581     s->open(fullPathScriptName.c_str());
1582     if (!s->good())
1583     {
1584         bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1585         return;
1586     }
1587
1588     bbtkMessage("interpreter",1,"   -->[" << fullPathScriptName 
1589                 << "] found" << std::endl);
1590
1591     mFile.push_back(s);
1592     mFileName.push_back(fullPathScriptName);
1593     mFileNameHistory.push_back(fullPathScriptName);
1594     mIncludeFileName.push_back(includeScriptName);
1595     mLine.push_back(0);
1596
1597     return;
1598   }
1599   //=======================================================================
1600
1601   //=======================================================================
1602   void InterpreterVirtual::CloseCurrentFile()
1603   {
1604     bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseCurrentFile()"
1605                       <<std::endl);
1606
1607     if (mFile.size()==0)
1608     {
1609       bbtkDebugMessage("interpreter",9," -> no file left open"<<std::endl);
1610       return;
1611     }
1612
1613     bbtkDebugMessage("interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1614
1615     std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1616     if (file!=0) file->close();
1617
1618     delete mFile.back();
1619     mFile.pop_back();
1620     mFileName.pop_back();
1621     mIncludeFileName.pop_back();
1622     mLine.pop_back();
1623
1624     bbtkDebugMessage("interpreter",9," Remains "
1625                      <<mFile.size()
1626                      <<" open"<<std::endl);
1627     bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseCurrentFile()"
1628                      <<std::endl);
1629   }
1630   //=======================================================================
1631
1632  //=======================================================================
1633   void InterpreterVirtual::CloseAllFiles()
1634   {
1635     bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::CloseAllFiles()"
1636                       <<std::endl);
1637
1638     while (mFile.size() != 0) 
1639     {
1640        CloseCurrentFile();
1641     }
1642     bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::CloseAllFiles()"
1643                       <<std::endl);
1644   }
1645   //=======================================================================
1646
1647
1648
1649   //=======================================================================
1650   void InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,
1651                                       CommandInfoType& info )
1652   {
1653     bbtkDebugMessage("interpreter",9,"==> InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1654
1655     // searches the command keyword
1656     CommandDictType::iterator c;
1657     c = mCommandDict.find(words[0]);
1658     if ( c == mCommandDict.end() ) {
1659       bbtkError(words[0]<<" : unknown command");
1660     }
1661
1662     // tests the number of args 
1663     if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1664          ( ((int)words.size())-1 > c->second.argmax ) )
1665     {
1666                 
1667 //EED       HelpCommand(words[0]);
1668                 commandHelp(words[0]);
1669                 
1670        bbtkError(words[0]<<" : wrong number of arguments");
1671     }
1672 //std::cout<<"InterpreterVirtual::InterpretCommand( const std::vector<std::string>& words,"<<std::endl;
1673     info = c->second;
1674
1675     bbtkDebugMessage("interpreter",9,"<== InterpreterVirtual::InterpretCommand(...)"<<std::endl);
1676
1677   }
1678   //=======================================================================
1679
1680
1681   //=======================================================================
1682   /// Displays help on all the commands
1683   void InterpreterVirtual::commandHelp(const std::vector<std::string>& words) 
1684   { 
1685   }
1686   //=======================================================================
1687   void InterpreterVirtual::commandHelp(const std::string words) 
1688   {  
1689   }
1690         //=======================================================================
1691         
1692    //===================================================================    
1693   /// Displays the Configuration
1694   void InterpreterVirtual::commandConfig() const
1695   {
1696   }  
1697    //===================================================================    
1698
1699
1700
1701   //=======================================================================
1702   /// Fills the vector commands with the commands which 
1703   /// have the first n chars of buf for prefix
1704   /// TODO : skip initial spaces in buf and also return the position of first
1705   /// non blank char in buf
1706   void InterpreterVirtual::FindCommandsWithPrefix( char* buf,
1707                                             int n,
1708                                             std::vector<std::string>& commands )
1709   {
1710     CommandDictType::const_iterator i;
1711     for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1712     {
1713       if ((i->first).find(buf,0,n) == 0) 
1714         commands.push_back(i->first);
1715     }
1716   }
1717   //=======================================================================
1718
1719
1720
1721   //=======================================================================
1722 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1723   
1724   inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1725   inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1726   
1727   // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1728   // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1729   // E.G. STORE THIS IN bbtk_config.xml
1730 #define BBTK_UP_ARROW_KBCODE    0x00415B1B
1731 #define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
1732 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1733 #define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
1734 #define BBTK_BACKSPACE_KBCODE   0x00000008
1735 #define BBTK_DEL_KBCODE         0x0000007F
1736 #define BBTK_SPACE_KBCODE       0x00000020 
1737
1738   //=======================================================================
1739   void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1740   {
1741     int c;
1742     unsigned int ind=0;
1743
1744     unsigned int MAX_LINE_SIZE = 160;
1745     unsigned int MAX_HISTORY_SIZE = 100;
1746
1747     char* newline = new char[MAX_LINE_SIZE];
1748     memset(newline,0,MAX_LINE_SIZE);
1749     char* histline = new char[MAX_LINE_SIZE];
1750     memset(histline,0,MAX_LINE_SIZE);
1751
1752     char* line = newline;
1753     unsigned int hist = mHistory.size();
1754
1755     write(1,"> ",2);
1756     while(1)
1757     {
1758        c=0;
1759        read ( STDIN_FILENO, &c, 4) ;
1760
1761        bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1762
1763        // Printable character
1764        if ( (ind<MAX_LINE_SIZE-1) &&
1765             ( c >= BBTK_SPACE_KBCODE ) && 
1766             ( c <  BBTK_DEL_KBCODE )) 
1767        {
1768           PrintChar(c);
1769           line[ind++]=c;
1770        }
1771       // CR
1772        else if (c=='\n')
1773        {
1774        // delete the unused line
1775           if (line==newline)
1776               delete histline;
1777           else
1778               delete newline;
1779    
1780     // empty lines are not stored in from history
1781           if (strlen(line)) 
1782           {
1783              // if history too long : delete oldest command
1784              if (mHistory.size()>MAX_HISTORY_SIZE) 
1785              {
1786                 delete mHistory.front();
1787                 mHistory.pop_front();
1788              }
1789              mHistory.push_back(line);
1790           }
1791           break;
1792         }
1793        // Backspace
1794         else if ( (ind>0) && 
1795                   ((c == BBTK_BACKSPACE_KBCODE) ||
1796                    (c == BBTK_DEL_KBCODE)) )
1797           {
1798             line[ind--]=' ';
1799             BackSpace();
1800           }
1801         // Tab 
1802         else if (c=='\t')
1803           {
1804             // TODO : Command completion  
1805             std::vector<std::string> commands;
1806             FindCommandsWithPrefix( line,ind,commands);
1807             if (commands.size()==1) 
1808               {
1809                 std::string com = *commands.begin();
1810                 for (; ind<com.size(); ++ind) 
1811                   {
1812                     PrintChar(com[ind]); 
1813                     line[ind]=com[ind];
1814                   }
1815                 PrintChar(' '); 
1816                 line[ind++]=' ';
1817               }
1818             else if (commands.size()>1) 
1819               {
1820                 std::vector<std::string>::iterator i;
1821                 write(1,"\n",1);
1822                 for (i=commands.begin();i!=commands.end();++i) 
1823                   {
1824                     write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1825                     PrintChar(' ');
1826                   }
1827                 write(STDOUT_FILENO,"\n> ",3);
1828                 //for (int j=0;j<ind;++j) 
1829                   //{
1830                     write(STDOUT_FILENO,line,ind); 
1831                     //  }
1832               }
1833           }
1834         // Arrow up : back in history
1835         else if (c==BBTK_UP_ARROW_KBCODE)
1836           {
1837             if (hist) 
1838               {
1839                 // erase current line
1840                 while (ind--) BackSpace();
1841                 // 
1842                 hist--;
1843                 // 
1844                 strcpy(histline,mHistory[hist]);
1845                 line = histline;
1846                 ind = strlen(line);
1847                 
1848                 write(STDOUT_FILENO,line,ind);
1849               }
1850           }
1851         // Arrow down : down in history
1852         else if (c==BBTK_DOWN_ARROW_KBCODE)
1853           {
1854             if (hist<mHistory.size()-1) 
1855               {
1856                 // erase current line
1857                 while (ind--) BackSpace();
1858                 // 
1859                 hist++;
1860                 // 
1861                 strcpy(histline,mHistory[hist]);
1862                 line = histline;
1863                 ind = strlen(line);
1864                 
1865                 write(STDOUT_FILENO,line,ind);
1866               }
1867             // end of history : switch back to newline
1868             else if (hist==mHistory.size()-1)
1869               {
1870                 // erase current line
1871                 while (ind--) BackSpace();
1872                 // 
1873                 hist++;
1874                 // 
1875                 line = newline;
1876                 ind = strlen(line);
1877                 
1878                 write(STDOUT_FILENO,line,ind);
1879               }
1880           }
1881         // Arrow right
1882         else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1883           {
1884             PrintChar(line[ind]);
1885             ind++;
1886           }
1887
1888         // Arrow left
1889         else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1890           {
1891             PrintChar('\b');
1892             ind--;
1893     
1894           }
1895
1896       }
1897     write(STDOUT_FILENO,"\n\r",2);
1898     
1899     
1900     s = line;
1901     
1902   }
1903 #else
1904
1905   //=======================================================================
1906   void InterpreterVirtual::GetLineFromPrompt(std::string& s)
1907   {  
1908     s.clear();
1909
1910     putchar('>');
1911     putchar(' ');
1912
1913     do 
1914     {
1915       char c = getchar();
1916       if (c=='\n') 
1917       {
1918         putchar('\n');
1919         break;
1920       }
1921       if (c=='\t') 
1922       {
1923         // putchar('T');
1924         continue;
1925       }
1926       // putchar(c);
1927       s += c;
1928     } 
1929     while (true);  
1930     
1931   }
1932   //=======================================================================  
1933
1934 #endif
1935
1936
1937
1938   //=======================================================================
1939   void InterpreterVirtual::CommandLineInterpreter()
1940   {
1941     bbtkDebugMessageInc("interpreter",9,
1942                         "InterpreterVirtual::CommandLineInterpreter()"<<std::endl);
1943
1944 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
1945     // Initialise the tty in non canonical mode with no echo
1946     // oter remembers the previous settings to restore them after 
1947     struct termios ter,oter;
1948     tcgetattr(0,&ter);
1949     oter=ter;
1950     ter.c_lflag &= ~ECHO;
1951     ter.c_lflag &= ~ICANON;
1952     ter.c_cc[VMIN]=1;
1953     ter.c_cc[VTIME]=0;
1954     tcsetattr(0,TCSANOW,&ter);
1955 #endif
1956     
1957     mCommandLine = true;
1958     bool again = true;
1959     // bool insideComment = false; // for multiline comment  
1960     mInsideComment = false;
1961     do 
1962     {
1963       try
1964       {
1965         std::string line;
1966         GetLineFromPrompt(line);
1967         DoInterpretLine(line); //, insideComment);
1968       }
1969       /*
1970       catch (QuitException e)
1971       {
1972         bbtkMessage("interpreter",1,"Interpreter : Quit"<<std::endl);
1973         again = false;
1974       }
1975       */
1976       catch (bbtk::Exception e) 
1977       {
1978         e.Print();
1979       }
1980         catch (std::exception& e) 
1981       {
1982         std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1983       }
1984       catch (...)
1985       {
1986         std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1987       }
1988     }
1989     while (again);
1990
1991 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1992     tcsetattr(0,TCSANOW,&oter);
1993 #endif
1994
1995     std::cout << "Good bye !" << std::endl;
1996
1997     bbtkDebugDecTab("interpreter",9);
1998   }
1999
2000 //=======================================================================
2001 void InterpreterVirtual::commandGraph(const std::vector<std::string>& words)
2002 {
2003 }
2004 //=======================================================================
2005
2006
2007 //=======================================================================
2008 void  InterpreterVirtual::commandIndex(const std::string& filename, const std::string& type)
2009 {
2010 }
2011 //=======================================================================
2012
2013
2014 //=======================================================================
2015 void  InterpreterVirtual::commandNewGUI(const std::string& boxname,const std::string& instanceName)
2016 {
2017 }
2018 //=======================================================================
2019
2020
2021
2022  //==========================================================================
2023   void InterpreterVirtual::commandDebug(const std::string& name)
2024   {
2025   }
2026  //==========================================================================
2027
2028   /*
2029   //==========================================================================
2030   // Adds a callback when 'break' command issued
2031   void InterpreterVirtual::AddBreakObserver( BreakCallbackType c )
2032   {
2033     mBreakSignal.connect(c);
2034   }
2035  //==========================================================================
2036  */
2037
2038  //==========================================================================
2039   std::string InterpreterVirtual::GetObjectName() const
2040   {
2041     return std::string("InterpreterVirtual");
2042   }
2043   //==========================================================================
2044   
2045   //==========================================================================
2046   std::string  InterpreterVirtual::GetObjectInfo() const 
2047   {
2048     std::stringstream i;
2049     return i.str();
2050   }
2051   //==========================================================================
2052
2053   //==========================================================================
2054 size_t  InterpreterVirtual::GetObjectSize() const 
2055 {
2056   size_t s = Superclass::GetObjectSize();
2057   s += InterpreterVirtual::GetObjectInternalSize();
2058   return s;
2059   }
2060   //==========================================================================
2061   //==========================================================================
2062 size_t  InterpreterVirtual::GetObjectInternalSize() const 
2063 {
2064   size_t s = sizeof(InterpreterVirtual);
2065   return s;
2066   }
2067   //==========================================================================
2068   //==========================================================================
2069   size_t  InterpreterVirtual::GetObjectRecursiveSize() const 
2070   {
2071     size_t s = Superclass::GetObjectRecursiveSize();
2072     s += InterpreterVirtual::GetObjectInternalSize();
2073     return s;
2074   }
2075   //==========================================================================
2076 }//namespace
2077
2078