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