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