]> Creatis software - bbtk.git/blob - kernel/src/bbtkInterpreter.cxx
BUG LayoutTSplit Widget2
[bbtk.git] / kernel / src / bbtkInterpreter.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkInterpreter.cxx,v $ $
5   Language:  C++
6   Date:      $Date: 2008/02/21 07:30:20 $
7   Version:   $Revision: 1.36 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18 /**
19  *  \file 
20  *  \brief class Interpreter :
21  */
22
23 #include "bbtkInterpreter.h"
24 #include "bbtkMessageManager.h"
25 #include "bbtkConfigurationFile.h"
26 #include "bbtkWxConsole.h"
27 #include "bbtkUtilities.h"
28 #include <sys/stat.h>
29 #include <algorithm>
30 #ifdef CMAKE_HAVE_TERMIOS_H
31 #include <termios.h>
32 #define BBTK_USE_TERMIOS_BASED_PROMPT
33 #endif
34
35 #include <string>
36
37 namespace bbtk
38 {
39
40 Interpreter* Interpreter::mGlobalInterpreter = NULL;
41
42  //=======================================================================
43  /**
44    *
45    */
46   Interpreter::Interpreter() 
47     :
48     mCommandLine(false)
49   {
50     bbtk::MessageManager::RegisterMessageType("Echo","Level>0 : Prints the 'echo' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
51     bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
52     bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
53  
54     mGlobalInterpreter = this;
55
56     mExecuter = new bbtk::Executer();
57     
58     // For the time being, comment out previous line, and
59     // uncomment next line to check Transcriptor
60
61    // mExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
62
63     // Builds the commands dict
64     CommandInfoType info;
65    
66     info.category = "new";
67     info.argmin = 2;
68     info.argmax = 2;
69     info.code = cNew;
70     info.syntax = "new <type> <name>";
71     info.help = "Creates a new black box of type <type> with name <name>";
72     mCommandDict[info.category] = info;
73     
74     info.category = "delete";
75     info.argmin = 1;
76     info.argmax = 1;
77     info.code = cDelete;
78     info.syntax = "delete <box>";
79     info.help = "Deletes the black box of name <box>";
80     mCommandDict[info.category] = info;
81
82     info.category = "connect";
83     info.argmin = 2;
84     info.argmax = 2;
85     info.code = cConnect;
86     info.syntax = "connect <box1.output> <box2.input>";
87     info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
88     mCommandDict[info.category] = info;
89
90     info.category = "print";
91     info.argmin = 1;
92     info.argmax = 1;
93     info.code = cPrint;
94     info.syntax = "print <string>";
95     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').";
96     mCommandDict[info.category] = info;
97
98     info.category = "exec";
99     info.argmin = 1;
100     info.argmax = 2;
101     info.code = cExec;
102     info.syntax = "exec <box | 'freeze' | 'unfreeze' >";
103     info.help = "Executes the black box of name <box> (and connected boxes if needed). If the special category 'freeze' is given then freezes any further execution command. 'unfreeze' reverts to normal execution mode.";
104     mCommandDict[info.category] = info;
105
106     info.category = "package";
107     info.argmin = 1;
108     info.argmax = 1;
109     info.code = cPackage;
110     info.syntax = "package <name>";
111     info.help = "Begins the definition of a package.";
112     mCommandDict[info.category] = info;
113     
114     info.category = "endpackage";
115     info.argmin = 0;
116     info.argmax = 0;
117     info.code = cEndPackage;
118     info.syntax = "endpackage";
119     info.help = "Ends the definition of a package.";
120     mCommandDict[info.category] = info;
121
122     info.category = "define";
123     info.argmin = 1;
124     info.argmax = 2;
125     info.code = cDefine;
126     info.syntax = "define <type> [<package>]";
127     info.help = "Begins the definition of a new type of complex black box called <type>. If <package> if provided will create it in the given package.";
128     mCommandDict[info.category] = info;
129     
130     info.category = "endefine";
131     info.argmin = 0;
132     info.argmax = 0;
133     info.code = cEndDefine;
134     info.syntax = "endefine";
135     info.help = "Ends the definition of a new type of complex black box";
136     mCommandDict[info.category] = info;
137
138     info.category = "input";
139     info.argmin = 3;
140     info.argmax = 3;
141     info.code = cInput;
142     info.syntax = "input <name> <box.input> <help>";
143     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";
144     mCommandDict[info.category] = info;
145
146     info.category = "output";
147     info.argmin = 3;
148     info.argmax = 3;
149     info.code = cOutput;
150     info.syntax = "output <name> <box.output> <help>";
151     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";
152     mCommandDict[info.category] = info;
153
154     info.category = "set";
155     info.argmin = 2;
156     info.argmax = 2;
157     info.code = cSet;
158     info.syntax = "set <box.input> <value>";
159     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";
160     mCommandDict[info.category] = info;
161    
162     info.category = "config";  // JPR
163     info.argmin = 0;
164     info.argmax = 0;
165     info.code = cConfig;
166     info.syntax = "config";
167     info.help = "Prints the value of all configuration parameters";
168     mCommandDict[info.category] = info;
169
170     info.category = "index";  // LG
171     info.argmin = 0;
172     info.argmax = 2;
173     info.code = cIndex;
174
175     info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories']]";
176     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";
177     mCommandDict[info.category] = info;
178
179     info.category = "reset";  //EED
180     info.argmin = 0;
181     info.argmax = 0;
182     info.code = cReset;
183     info.syntax = "reset";
184     info.help = "Deletes all boxes and unloads all packages (bbi is reset to its start state)";
185     mCommandDict[info.category] = info;
186
187     info.category = "author";
188     info.argmin = 1;
189     info.argmax = 1;
190     info.code = cAuthor;
191     info.syntax = "author <string>";
192     info.help = "Adds the string <string> to the author information of the black box being defined";
193     mCommandDict[info.category] = info;
194     
195     info.category = "category"; //JP
196     info.argmin = 1;
197     info.argmax = 1;
198     info.code = cCategory;
199     info.syntax = "category <list of items, separated by ;>";
200     info.help = "Adds the string <string> to the category information of the black box being defined";
201     mCommandDict[info.category] = info;
202
203     info.category = "description";
204     info.argmin = 1;
205     info.argmax = 1;
206     info.code = cDescription;
207     info.syntax = "description <string>";
208     info.help = "Adds the string <string> to the descriptive information of the black box being defined";
209     mCommandDict[info.category] = info;
210
211     info.category = "help";
212     info.argmin = 0;
213     info.argmax = 2;
214     info.code = cHelp;
215     info.syntax = "help";
216     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>";
217     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.";
218     mCommandDict[info.category] = info;
219
220     info.category = "message";
221     info.argmin = 0;
222     info.argmax = 2;
223     info.code = cMessage;
224     info.syntax = "message <kind> <level>";
225     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.";  mCommandDict[info.category] = info;
226
227     info.category = "include";
228     info.argmin = 1;
229     info.argmax = 2;
230     info.code = cInclude;
231     info.syntax = "include <filename> [source]";
232     info.help = "Includes the file <filename>.\n  'source' : If the keyword 'source' is provided then informs bbi 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).";
233     mCommandDict[info.category] = info;
234
235     info.category = "quit";
236     info.argmin = 0;
237     info.argmax = 0;
238     info.code = cQuit;
239     info.syntax = "quit";
240     info.help = "Quits the program (during script execution it stops the complete execution)";
241     mCommandDict[info.category] = info;
242
243     info.category = "load";
244     info.argmin = 1;
245     info.argmax = 1;
246     info.code = cLoad;
247     info.syntax = "load <packagename>";
248     info.help = "Loads the black box package <packagename>";
249     mCommandDict[info.category] = info;
250
251     info.category = "unload";
252     info.argmin = 1;
253     info.argmax = 1;
254     info.code = cUnload;
255     info.syntax = "unload <packagename>";
256     info.help = "Unloads the black box package <packagename>";
257     mCommandDict[info.category] = info;
258
259     info.category = "graph";
260     info.argmin = 0;
261     info.argmax = 6;
262     info.code = cGraph;
263     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 ]]]]]]";
264     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')";
265     mCommandDict[info.category] = info;
266
267     /*
268     info.category = "workspace";
269     info.argmin = 1;
270     info.argmax = 2;
271     info.code = cWorkspace;
272     info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
273     info.help = "Configures the workspace.\n        'freeze' allow 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.";
274     mCommandDict[info.category] = info;
275     */
276
277     bbtkDebugDecTab("Interpreter",9);
278
279   } 
280   //=======================================================================
281   
282   
283   
284   //=======================================================================  
285   /**
286    *  
287    */
288   Interpreter::~Interpreter()
289   {
290     bbtkDebugMessageInc("Interpreter",9,"Interpreter::~Interpreter()" <<std::endl);
291     delete mExecuter;
292     //delete mFactory;
293
294     bbtkDebugDecTab("Interpreter",9);
295   }
296   //=======================================================================
297
298
299   //=======================================================================
300   /**
301    *  
302    */
303   void Interpreter::InterpretFile( const std::string& filename,  
304                                    bool use_configuration_file)
305   {
306     bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
307
308     bool exm = mCommandLine;
309     mCommandLine = false;
310
311     try 
312     {
313       SwitchToFile(filename, use_configuration_file);
314       bool insideComment = false; // for multiline comment
315       while (mFile.size()>0) 
316       {
317          while ((mFile.size()>0) && 
318                 (!mFile.back()->eof()))
319          {
320             mLine.back()++;
321             char buf[500];
322             mFile.back()->getline(buf,500);
323       
324             std::string str(buf);
325             int size=str.length();
326             if ( str[ size-1 ]==13  )
327             {
328                str.erase(size-1,1);
329             }
330       
331             InterpretLine(str, insideComment);
332          }
333         //if (mFile.size()>0) 
334         CloseCurrentFile();
335       }
336     }
337     catch (QuitException e) 
338     {
339     }
340     catch (bbtk::Exception e) 
341     {
342       std::cerr << "* ERROR : "<<e.GetMessage()<<std::endl;
343       if (mFileName.size()) {
344          std::cerr << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
345          std::cerr << "* LINE  : "<<mLine.back()<<std::endl;
346       }    
347     }
348     catch (std::exception& e) 
349     {
350        std::cerr << "* ERROR : "<<e.what()<<" (not in bbtk)"<<std::endl;
351        if (mFileName.size()) {
352           std::cerr << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
353           std::cerr << "* LINE  : "<<mLine.back()<<std::endl;
354        }    
355     }  
356     catch (...)
357     {
358        std::cout << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
359        if (mFileName.size()) {
360           std::cout << "* FILE  : \""<<mFileName.back()<<"\""<<std::endl;
361           std::cout << "* LINE  : "<<mLine.back()<<std::endl;
362       }    
363     }
364
365     CloseAllFiles();
366     bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
367     bbtkDecTab("Interpreter",9);
368
369     mCommandLine = exm;
370   }
371   //=======================================================================
372
373
374
375   //=======================================================================  
376   /**
377    *
378    */
379 void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
380 {
381
382     bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
383     bbtkMessage("Echo",2,"\""<<line<<"\""<<std::endl);
384
385     std::vector<std::string> words;
386     SplitLine(line,words);
387
388     // Empty line
389     if (words.size()<1) 
390     {
391        bbtkDebugDecTab("Interpreter",9);
392        return;
393     }
394
395     // Single line comment : # or //
396     if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') ) 
397     {  
398        bbtkDebugDecTab("Interpreter",9);
399        bbtkMessage("Interpreter",9,"Comment"<<std::endl);
400        return;
401     }
402
403     // Multi line comment ( /* ... */ ) -delimiters on different lines !-
404     
405     if (words[0][0]=='/' && words[0][1]=='*') 
406     {  
407        bbtkDebugDecTab("Interpreter",9);
408        bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
409        insideComment = true;
410        return;
411     }
412
413     if (words[0][0]=='*' && words[0][1]=='/') 
414     {  
415        bbtkDebugDecTab("Interpreter",9);
416        bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
417        if ( !insideComment ) {
418           bbtkDebugDecTab("Interpreter",9);
419           bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);       
420        }
421        insideComment = false;
422        return;
423     }
424
425     if (insideComment) 
426     {  
427        bbtkDebugDecTab("Interpreter",9);
428        bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
429        return;
430     }
431
432     // Command 
433     CommandInfoType command;
434     InterpretCommand(words,command);
435
436     bbtkDebugMessage("Interpreter",9,
437                      "Command='"<<command.category
438                       <<"' code="<<command.code<<std::endl); 
439     int level=0;
440     std::string left,right,left2,right2;
441     std::string filename;
442     switch (command.code) 
443     {
444       case cNew :
445         mExecuter->Create(words[1],words[2]);
446         break;
447
448       case cDelete :
449         // TO DO !!
450         // mExecuter->Remove(words[1]);
451         break;
452
453       case cConnect :
454         Utilities::SplitAroundFirstDot(words[1],left,right);
455         Utilities::SplitAroundFirstDot(words[2],left2,right2);      
456         mExecuter->Connect(left,right,left2,right2);
457         break;
458
459       case cPackage :
460         mExecuter->BeginPackage(words[1]);
461         break;
462
463       case cEndPackage :
464         mExecuter->EndPackage();
465         break;
466
467       case cDefine :
468         if (mFileName.size()>0) 
469         {
470           filename = mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
471         }
472         if (words.size()==2) 
473         {
474            mExecuter->Define(words[1],"",filename);
475         }
476         else
477         {
478            mExecuter->Define(words[1],words[2],filename);
479         }
480         break;
481
482       case cEndDefine :
483         mExecuter->EndDefine();
484         break;
485
486       case cPrint :
487         Print(words[1]); /// \todo use mExecuter 
488         break;
489         
490       case cExec :
491         if (words[1]=="freeze") 
492           mExecuter->SetNoExecMode(true);
493         else if (words[1]=="unfreeze") 
494           mExecuter->SetNoExecMode(false);
495         else
496           mExecuter->Update(words[1]);
497         break;
498
499       case cInput :
500         Utilities::SplitAroundFirstDot(words[2],left,right);
501         mExecuter->DefineInput(words[1],left,right,words[3]);
502         break;
503
504       case cOutput :
505         Utilities::SplitAroundFirstDot(words[2],left,right);
506         mExecuter->DefineOutput(words[1],left,right,words[3]);
507         break;
508
509       case cSet :
510         Utilities::SplitAroundFirstDot(words[1],left,right);
511         mExecuter->Set(left,right,words[2]);
512         break;
513
514       case cAuthor :
515         mExecuter->Author(words[1]);
516         break;
517
518       case cCategory :
519         mExecuter->Category(words[1]);
520         break;
521
522       case cIndex :
523         if (words.size()==1)
524              Index("tmp_index.html");
525         else if (words.size()==2)
526              Index(words[1]);
527         else if (words.size()==3)
528              Index(words[1],words[2]);
529         break;
530
531       case cDescription :
532         mExecuter->Description(words[1]);
533         break;
534
535       case cHelp :
536         Help(words);
537         break;
538
539       case cMessage : 
540         if (words.size()<3)
541         {
542            bbtk::MessageManager::PrintInfo();
543         }
544         else
545         {
546            sscanf(words[2].c_str(),"%d",&level);
547            bbtk::MessageManager::SetMessageLevel(words[1],level);
548         }
549         break;
550
551       case cGraph :
552         Graph(words);
553         break;
554
555       case cConfig :
556         Config();
557         break;
558
559       case cReset :  // EED
560         this->mExecuter->Reset();
561         break;
562
563       case cInclude :
564         if (mCommandLine)
565         {
566            InterpretFile(words[1], true ); // true : better pass use_config_file
567         }
568         else
569         {
570             SwitchToFile(words[1], true ); // true : better pass use_config_file
571         }
572         // if 'source' was given
573         if (words.size()==3) 
574           {
575             this->mExecuter->SetCurrentFileName(words[1]);
576           }
577         break;
578
579       case cLoad:
580         LoadPackage(words[1], true ); // true : better pass use_config_file
581         break;
582
583       case cUnload:
584         UnLoadPackage(words[1]);
585         break;
586
587       case cQuit :
588         delete mExecuter;
589         throw QuitException();
590         break;
591
592       case cWorkspace :
593         if (words.size() == 2) 
594         {
595            if (words[1]=="freeze")        mExecuter->SetNoExecMode(true);
596            else if (words[1]=="unfreeze") mExecuter->SetNoExecMode(false);
597         }
598         else
599         {
600            mExecuter->SetWorkspaceName(words[2]);
601         }
602         break;
603         
604       default:
605         bbtkInternalError("should not reach here !!!");
606    }
607
608    bbtkDecTab("Interpreter",9);
609 }
610   //=======================================================================  
611
612
613
614
615
616   //=======================================================================
617   /**
618    *
619    */
620 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
621 {
622     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
623
624     std::string delimiters = "\"";
625     std::vector<std::string> quote;
626     Utilities::SplitString(str,delimiters,quote);
627
628     delimiters = " \t";
629     std::vector<std::string>::iterator i;
630     for (i=quote.begin(); i!=quote.end(); ) 
631     {
632        Utilities::SplitString(*i,delimiters,tokens);
633        ++i;
634        if (i!=quote.end()) 
635        {
636         //    bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
637           tokens.push_back(*i);
638           ++i;
639        }
640     }
641
642     for (i=tokens.begin(); i!=tokens.end(); ++i) 
643     {
644        bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
645     }
646     bbtkDebugMessageCont("Interpreter",9,std::endl);
647
648     bbtkDebugDecTab("Interpreter",9);
649  }
650   //=======================================================================
651
652
653   //=======================================================================
654   // Replaces substrings "\\n" by a real carriage return "\n"
655   void SubsBackslashN ( std::string& s )
656   {
657     std::string ss("\\n");
658     std::string::size_type pos = 0;
659     pos = s.find(ss,0);
660     char* cr = "\n";
661     while ( pos != std::string::npos )
662    {
663       s.replace(pos,2,cr,1);
664       pos = s.find(ss, pos-1);
665    }
666   }
667   //=======================================================================
668
669
670   //=======================================================================
671   /**
672    *
673    */
674   void Interpreter::Print( const std::string& str)
675   {
676     if (mExecuter->GetNoExecMode()) return;
677
678     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
679
680     std::vector<std::string> chains;
681     std::string delimiters("$");
682
683     // Skip delimiters at beginning.
684     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
685     bool is_text = true;
686     if (lastPos>0) is_text = false;
687
688     // Find first delimiter.
689     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
690
691     while (std::string::npos != pos || std::string::npos != lastPos)
692     {
693        if (is_text) 
694        {
695           // Found a text token, add it to the vector.
696           chains.push_back(str.substr(lastPos, pos - lastPos));
697        }
698        else 
699        {
700        // is an output (between $$) : decode 
701          std::string tok,box,output;
702          tok = str.substr(lastPos, pos - lastPos);
703          Utilities::SplitAroundFirstDot(tok,box,output);
704          chains.push_back( mExecuter->Get(box,output) );
705        }
706         // Skip delimiters.  Note the "not_of"
707        lastPos = str.find_first_not_of(delimiters, pos);
708         // Find next delimiter
709        pos = str.find_first_of(delimiters, lastPos);
710     //
711        is_text = !is_text;
712      }
713      std::vector<std::string>::iterator i;
714      for (i= chains.begin(); i!=chains.end(); ++i) 
715      {
716        //  bbtkMessage("Echo",1,*i);
717        SubsBackslashN(*i);
718        std::cout << *i;
719      }
720      std::cout << std::endl;
721      bbtkDebugDecTab("Interpreter",9);
722  }
723
724   //=======================================================================
725   /**
726    *
727    */
728
729 // ===================================================================================
730
731   void Interpreter::SwitchToFile( const std::string& name,
732                                   bool use_configuration_file )
733   {
734   // Note : in the following :
735   // name : the user supplied name 
736   //      - abreviated name    e.g.       scr   scr.bbs
737   //      - relative full name e.g.       ./scr.bbs   ../../scr.bbs 
738   //      - absolute full name e.g.       /home/usrname/proj/dir/scr.bbs
739   //          same for Windows, with      c:, d: ...
740   //
741   // use ./directory/subdir/scrname.bbs
742   //
743
744     bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
745                          <<name<<"\")"<<std::endl);
746
747     std::vector<std::string> script_paths;
748     std::string fullPathScriptName;  // full path script name
749     std::string pkgname;             // e.g. <scriptname>.bbs
750     std::vector<std::string> Filenames;
751
752     if (use_configuration_file)
753     {
754         // The following is *NOT* a debug time message :
755         // It's a user intended message.
756         // Please don't remove it.
757       bbtkMessage("Interpreter",1,
758                   "look for : [" << name
759                   << "] (use_configuration_file == TRUE)" << std::endl);
760       script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
761     }
762     std::string upath;
763     pkgname = Utilities::ExtractScriptName(name,upath);
764
765     bool fullnameGiven = false; 
766     bool foundFile     = false;
767
768     if(pkgname == "*") // =========================================== load all boxes (e.g. std/boxes/*)
769     {
770       int nbBssFiles;
771
772       if (upath[0]=='/' || upath[1] == ':' ) // ==== absolute name, load all .bbs files
773       {
774         int nbFiles = Utilities::Explore(upath, false, Filenames);
775         nbBssFiles = 0;
776         for (std::vector<std::string>::iterator i = Filenames.begin(); i!= Filenames.end(); ++i)
777         {
778            if ((*i).substr((*i).size()-4, 4) != ".bbs")
779               continue;      // ignore non .bbs files
780            LoadScript(*i,name);
781            nbBssFiles++;
782         }
783         if (nbBssFiles==0)
784            bbtkMessage("Interpreter",2,
785                        "WARNING : No '.bbs' file found in [" 
786                        << upath << "]" << std::endl);
787         return;
788       }
789
790       std::string path;
791       std::vector<std::string>::iterator i;
792       std::string fullDirectoryName;
793       for (i=script_paths.begin();i!=script_paths.end();i++)// ==== relative name, iterate + load all .bbs files
794       {
795         path = *i;
796
797        // we *really* want '.' to be the current working directory
798         if (path == ".") {
799           char buf[2048]; // for getcwd
800           char * currentDir = getcwd(buf, 2048);
801           std::string cwd(currentDir);
802           path = currentDir;
803         }
804
805         fullDirectoryName = Utilities::MakePkgnameFromPath(path, upath, false);
806
807         //EED 18 Fev 2008
808         // without last slash "\"
809         std::string fullDirectoryNameClean = fullDirectoryName.substr(0,fullDirectoryName.size()-1);
810
811       // Check if library exists
812         if ( ! Utilities::IsDirectory( fullDirectoryNameClean ) )
813         {
814         // The following is *NOT* a debug time message :
815         // It's a user intended message.
816         // Please don't remove it.
817           bbtkMessage("Interpreter",1,"   [" <<fullDirectoryName 
818                       <<"] : doesn't exist" <<std::endl);
819           continue;  // try next path
820         }
821         foundFile = true;
822
823
824         int nbFiles = Utilities::Explore(fullDirectoryName, false, Filenames);
825
826         nbBssFiles = 0;
827         for (std::vector<std::string>::iterator i = Filenames.begin(); i!= Filenames.end(); ++i)
828         {
829            if ((*i).substr((*i).size()-4, 4) != ".bbs")
830               continue;      // ignore non .bbs files
831            LoadScript(*i,name);
832            nbBssFiles++;
833         }
834         if (nbBssFiles==0)
835           bbtkMessage("Interpreter",1,
836                       "WARNING : No '.bbs' file found in [" 
837                       << fullDirectoryName << "]" << std::endl);
838
839         //break; // a directory was found; we stop iterating
840         // LG : No! We want all files included !
841        }
842        return;
843     }
844
845     //std::string::size_type slash_position = name.find_last_of("/\\");
846
847     // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
848     // (not only a plain script name)
849     // we trust him, and try to expland the directory name
850     // WARNING : starting from current local directory :  ./whatYouWant  (./ mandatory!)
851
852     if (name[0]=='/' || name[1] == ':' || name[0]=='.')  // absolute path (linux/windows) or relative path
853     { 
854
855       // ===========================================================check user supplied location
856       fullnameGiven = true;
857
858       fullPathScriptName =  Utilities::ExpandLibName(name, false);
859
860       // allow user to always forget ".bbs"
861       int l = fullPathScriptName.size();
862
863       if (l!=0) {
864       
865       if (l>4)
866       {
867          if (fullPathScriptName.substr(l-4, 4) != ".bbs")
868          {
869             fullPathScriptName = fullPathScriptName + ".bbs";
870          }
871       }
872       else
873       {
874          fullPathScriptName = fullPathScriptName + ".bbs";   
875       }
876
877         if ( Utilities::FileExists(fullPathScriptName))
878         {
879           foundFile = true;
880         }
881       } // endif l != 0
882     }
883     else 
884
885       // =============================================================== iterate on the paths
886       {
887       std::string path;
888       std::vector<std::string>::iterator i;
889       for (i=script_paths.begin();i!=script_paths.end();++i)
890       {
891
892         path = *i;
893        // we *really* want '.' to be the current working directory
894         if (path == ".") {
895           char buf[2048]; // for getcwd
896           char * currentDir = getcwd(buf, 2048);
897           std::string cwd(currentDir);
898           path = currentDir;
899         }
900
901        // fullPathScriptName = Utilities::MakePkgnameFromPath(path, name, true); //pkgname);
902
903             fullPathScriptName = Utilities::MakePkgnameFromPath(path, name, true);
904
905
906       // Check if library exists
907         if ( ! Utilities::FileExists(fullPathScriptName) )
908         {
909         // The following is *NOT* a debug time message :
910         // It's a user intended message.
911         // Please don't remove it.
912           bbtkMessage("Interpreter",2,
913                       "   [" <<fullPathScriptName <<"] : doesn't exist" 
914                       <<std::endl);
915           continue;  // try next path
916         }
917         bbtkMessage("Interpreter",2,
918                     "   [" <<fullPathScriptName 
919                     <<"] : found" <<std::endl);
920         foundFile = true;
921         break; // a script was found; we stop iterating
922
923       } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
924     }
925
926     if (!foundFile)
927     {
928        if (fullnameGiven)
929          if(fullPathScriptName == "")
930             bbtkError("Path ["<<upath<<"] doesn't exist");
931          else
932             bbtkError("Script ["<<fullPathScriptName<<"] not found");
933        else
934           bbtkError("No ["<<pkgname<<".bbs] script found");
935        return;
936     }
937     else
938       LoadScript(fullPathScriptName,name);
939
940     return;
941   }
942
943
944   //=======================================================================
945
946   void Interpreter::LoadScript( std::string fullPathScriptName,
947                                 std::string includeScriptName)
948   {
949     if (find(mFileName.begin(),mFileName.end(),fullPathScriptName)
950         !=mFileName.end()) 
951       {
952         bbtkMessage("Interpreter",1,"file '"<<fullPathScriptName
953                     <<"' already open : I do not open it once more to prevent recursive inclusion"<<std::endl);
954         return;
955       }
956
957     std::ifstream* s;
958     s = new std::ifstream;
959     s->open(fullPathScriptName.c_str());
960     if (!s->good()) 
961     {
962         bbtkError("Could not open file ["<<fullPathScriptName<<"]");
963         return;
964     }
965
966     bbtkMessage("Interpreter",1,"   -->[" << fullPathScriptName 
967                 << "] found" << std::endl);
968
969     mFile.push_back(s);
970     mFileName.push_back(fullPathScriptName);
971     mIncludeFileName.push_back(includeScriptName);
972     mLine.push_back(0);
973     return;
974   }
975
976   //=======================================================================
977   /**
978    *  
979    */
980   void Interpreter::CloseCurrentFile()
981   {
982     bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
983                       <<std::endl);
984
985     if (mFile.size()==0)
986     {
987       bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
988       return;
989     }
990
991     mFile.back()->close();
992     delete mFile.back();
993     mFile.pop_back();
994     bbtkDebugMessage("Interpreter",9,
995                      " Closing file '"<<mFileName.back()<<"'"<<std::endl);
996
997     mFileName.pop_back();
998     mIncludeFileName.pop_back();
999     mLine.pop_back();
1000     bbtkDebugMessage("Interpreter",9," Remains "
1001                      <<mFile.size()
1002                      <<" open"<<std::endl);
1003     bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1004                      <<std::endl);
1005   }
1006   //=======================================================================
1007
1008  //=======================================================================
1009   /**
1010    *  
1011    */
1012   void Interpreter::CloseAllFiles()
1013   {
1014     bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1015                       <<std::endl);
1016
1017     while (mFile.size() != 0) 
1018     {
1019       mFile.back()->close();
1020       delete mFile.back();
1021       mFile.pop_back();
1022       bbtkDebugMessage("Interpreter",9,
1023                       " Closing file '"<<mFileName.back()<<"'"<<std::endl);
1024       mFileName.pop_back();
1025       mIncludeFileName.pop_back();
1026       mLine.pop_back();
1027     }
1028     bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1029                       <<std::endl);
1030   }
1031   //=======================================================================
1032
1033
1034
1035   //=======================================================================
1036   /**
1037    *  
1038    */
1039   void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1040                                       CommandInfoType& info )
1041   {
1042     bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1043
1044     // searches the command category
1045     CommandDictType::iterator c;
1046     c = mCommandDict.find(words[0]);
1047     if ( c == mCommandDict.end() ) {
1048       bbtkError(words[0]<<" : unknown command");
1049     }
1050
1051     // tests the number of args 
1052     if ( ( words.size()-1 < c->second.argmin ) ||
1053          ( words.size()-1 > c->second.argmax ) )
1054     {
1055        HelpCommand(words[0]);
1056        bbtkError(words[0]<<" : wrong number of arguments");
1057     }
1058
1059     info = c->second;
1060     bbtkDecTab("Interpreter",9);
1061   }
1062   //=======================================================================
1063
1064
1065   //=======================================================================
1066   /// Displays help on all the commands
1067 void Interpreter::Help(const std::vector<std::string>& words)
1068 {
1069     unsigned int nbarg = words.size()-1;
1070
1071     if (nbarg==0) 
1072     {
1073        HelpCommands();
1074     }
1075     else if (nbarg==1) 
1076     {
1077       if (words[1]=="packages") 
1078       {
1079          PrintPackages(true);
1080          return;
1081       }
1082       try 
1083       {
1084           HelpCommand(words[1]);
1085       }
1086       catch (bbtk::Exception e) 
1087       {
1088          try 
1089          {
1090             HelpPackage(words[1]);
1091 #ifdef _USE_WXWIDGETS_
1092             if ( WxConsole::GetInstance() != 0 )
1093               {
1094                 std::string url = 
1095                   ConfigurationFile::GetInstance().Get_doc_path();
1096                 url += "/bbdoc/" + words[1] + "/index.html";
1097                 if (Utilities::FileExists(url)) 
1098                   {
1099                     WxConsole::GetInstance()->ShowHtmlPage(url);
1100                   }
1101               }
1102 #endif      
1103          }
1104          catch (bbtk::Exception f) 
1105          {
1106             try 
1107             {
1108               std::string package;
1109               HelpBlackBox(words[1],package);
1110 #ifdef _USE_WXWIDGETS_
1111                if ( WxConsole::GetInstance() != 0 )
1112                  {
1113                    std::string url = 
1114                      ConfigurationFile::GetInstance().Get_doc_path();
1115                    url += "/bbdoc/" + package + "/index.html";
1116                    if (Utilities::FileExists(url))
1117                      {
1118                        url += "#" + words[1];
1119                        WxConsole::GetInstance()->ShowHtmlPage(url);
1120                      }
1121                  }
1122 #endif
1123             }
1124             catch (bbtk::Exception g) 
1125               {
1126                 try
1127                   {
1128                     this->mExecuter->ShowRelations(words[1],"0","9999");
1129                   }
1130                 catch (bbtk::Exception h){
1131                   bbtkError("\""<<words[1].c_str()
1132                             <<"\" is not a known command, package, black box type or black box name");
1133                 }
1134               }
1135          }
1136       }
1137     }
1138     else if (nbarg==2) 
1139     {
1140       if (words[2]=="all")
1141       {
1142          if ( words[1]=="packages" )
1143          {
1144             PrintPackages(true,true);
1145             return;
1146           }
1147          try 
1148          {
1149             HelpPackage(words[1],true);
1150          }
1151          catch (bbtk::Exception f) 
1152          {
1153          }
1154      }
1155      else 
1156      {
1157         HelpCommand(words[0]);
1158         bbtkError(words[0]<<" : syntax error");
1159      }
1160   }
1161   else 
1162   {
1163      bbtkError("Should not reach here !!!");
1164   }
1165 }
1166   //=======================================================================
1167
1168    //===================================================================    
1169   /// Displays the Configuration
1170   void Interpreter::Config() const
1171   {
1172     ConfigurationFile::GetInstance().GetHelp(1);
1173   }  
1174    //===================================================================    
1175
1176   //=======================================================================
1177   /// Displays help on all the commands
1178   void Interpreter::HelpCommands()
1179   {
1180     std::cout << "Available commands :" << std::endl;
1181     CommandDictType::iterator i;
1182     for ( i =  mCommandDict.begin();
1183           i != mCommandDict.end();
1184         ++i) {
1185               std::cout << " " << i->first << std::endl;
1186       //      std::cout << "   usage : " << i->second.syntax << std::endl;
1187       //     std::cout << "    " << i->second.help << std::endl;
1188
1189     }
1190   }
1191   //=======================================================================
1192
1193
1194   //=======================================================================
1195   /// Displays help on a particular commands
1196   void Interpreter::HelpCommand(const std::string& s)
1197   {
1198     CommandDictType::iterator c;
1199     c = mCommandDict.find(s);
1200     if ( c == mCommandDict.end() ) {
1201       bbtkError(s<<" : Unknown command");
1202     }
1203     //    std::cout << " " << s << " : "<<  std::endl;
1204     //    CommandParamDictType::iterator i;
1205     //    for ( i =  c->second.begin();
1206     //      i != c->second.end();
1207     //      ++i) {
1208     std::cout << " usage : " << c->second.syntax << std::endl;
1209     std::cout << "  " << c->second.help << std::endl;
1210
1211   }
1212   //=======================================================================
1213
1214
1215   //=======================================================================
1216   /// Fills the vector commands with the commands which 
1217   /// have the first n chars of buf for prefix
1218   /// TODO : skip initial spaces in buf and also return the position of first
1219   /// non blank char in buf
1220   void Interpreter::FindCommandsWithPrefix( char* buf,
1221                                             int n,
1222                                             std::vector<std::string>& commands )
1223   {
1224     CommandDictType::const_iterator i;
1225     for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1226     {
1227       if ((i->first).find(buf,0,n) == 0) 
1228         commands.push_back(i->first);
1229     }
1230   }
1231   //=======================================================================
1232
1233
1234
1235   //=======================================================================
1236 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1237   
1238   inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1239   inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1240   
1241   // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1242   // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1243   // E.G. STORE THIS IN bbtk_config.xml
1244 #define BBTK_UP_ARROW_KBCODE    0x00415B1B
1245 #define BBTK_DOWN_ARROW_KBCODE  0x00425B1B
1246 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1247 #define BBTK_LEFT_ARROW_KBCODE  0x00445B1B
1248 #define BBTK_BACKSPACE_KBCODE   0x00000008
1249 #define BBTK_DEL_KBCODE         0x0000007F
1250 #define BBTK_SPACE_KBCODE       0x00000020 
1251
1252   //=======================================================================
1253   void Interpreter::GetLineFromPrompt(std::string& s)
1254   {
1255     int c;
1256     int ind=0;
1257
1258     int MAX_LINE_SIZE = 160;
1259     int MAX_HISTORY_SIZE = 100;
1260
1261     char* newline = new char[MAX_LINE_SIZE];
1262     memset(newline,0,MAX_LINE_SIZE);
1263     char* histline = new char[MAX_LINE_SIZE];
1264     memset(histline,0,MAX_LINE_SIZE);
1265
1266     char* line = newline;
1267     int hist = mHistory.size();
1268
1269     write(1,"> ",2);
1270     while(1)
1271     {
1272        c=0;
1273        read ( STDIN_FILENO, &c, 4) ;
1274
1275        bbtkDebugMessage("Debug",9,"[0x"<<std::hex<<c<<"]\n");
1276
1277        // Printable character
1278        if ( (ind<MAX_LINE_SIZE-1) &&
1279             ( c >= BBTK_SPACE_KBCODE ) && 
1280             ( c <  BBTK_DEL_KBCODE )) 
1281        {
1282           PrintChar(c);
1283           line[ind++]=c;
1284        }
1285       // CR
1286        else if (c=='\n')
1287        {
1288        // delete the unused line
1289           if (line==newline)
1290               delete histline;
1291           else
1292               delete newline;
1293    
1294     // empty lines are not stored in from history
1295           if (strlen(line)) 
1296           {
1297              // if history too long : delete oldest command
1298              if (mHistory.size()>MAX_HISTORY_SIZE) 
1299              {
1300                 delete mHistory.front();
1301                 mHistory.pop_front();
1302              }
1303              mHistory.push_back(line);
1304           }
1305           break;
1306         }
1307        // Backspace
1308         else if ( (ind>0) && 
1309                   ((c == BBTK_BACKSPACE_KBCODE) ||
1310                    (c == BBTK_DEL_KBCODE)) )
1311           {
1312             line[ind--]=' ';
1313             BackSpace();
1314           }
1315         // Tab 
1316         else if (c=='\t')
1317           {
1318             // TODO : Command completion  
1319             std::vector<std::string> commands;
1320             FindCommandsWithPrefix( line,ind,commands);
1321             if (commands.size()==1) 
1322               {
1323                 std::string com = *commands.begin();
1324                 for (; ind<com.size(); ++ind) 
1325                   {
1326                     PrintChar(com[ind]); 
1327                     line[ind]=com[ind];
1328                   }
1329                 PrintChar(' '); 
1330                 line[ind++]=' ';
1331               }
1332             else if (commands.size()>1) 
1333               {
1334                 std::vector<std::string>::iterator i;
1335                 write(1,"\n",1);
1336                 for (i=commands.begin();i!=commands.end();++i) 
1337                   {
1338                     write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1339                     PrintChar(' ');
1340                   }
1341                 write(STDOUT_FILENO,"\n> ",3);
1342                 //for (int j=0;j<ind;++j) 
1343                   //{
1344                     write(STDOUT_FILENO,line,ind); 
1345                     //  }
1346               }
1347           }
1348         // Arrow up : back in history
1349         else if (c==BBTK_UP_ARROW_KBCODE)
1350           {
1351             if (hist) 
1352               {
1353                 // erase current line
1354                 while (ind--) BackSpace();
1355                 // 
1356                 hist--;
1357                 // 
1358                 strcpy(histline,mHistory[hist]);
1359                 line = histline;
1360                 ind = strlen(line);
1361                 
1362                 write(STDOUT_FILENO,line,ind);
1363               }
1364           }
1365         // Arrow down : down in history
1366         else if (c==BBTK_DOWN_ARROW_KBCODE)
1367           {
1368             if (hist<mHistory.size()-1) 
1369               {
1370                 // erase current line
1371                 while (ind--) BackSpace();
1372                 // 
1373                 hist++;
1374                 // 
1375                 strcpy(histline,mHistory[hist]);
1376                 line = histline;
1377                 ind = strlen(line);
1378                 
1379                 write(STDOUT_FILENO,line,ind);
1380               }
1381             // end of history : switch back to newline
1382             else if (hist==mHistory.size()-1)
1383               {
1384                 // erase current line
1385                 while (ind--) BackSpace();
1386                 // 
1387                 hist++;
1388                 // 
1389                 line = newline;
1390                 ind = strlen(line);
1391                 
1392                 write(STDOUT_FILENO,line,ind);
1393               }
1394           }
1395         // Arrow right
1396         else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1397           {
1398             PrintChar(line[ind]);
1399             ind++;
1400           }
1401
1402         // Arrow left
1403         else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1404           {
1405             PrintChar('\b');
1406             ind--;
1407     
1408           }
1409
1410       }
1411     write(STDOUT_FILENO,"\n\r",2);
1412     
1413     
1414     s = line;
1415     
1416   }
1417 #else
1418
1419   //=======================================================================
1420   void Interpreter::GetLineFromPrompt(std::string& s)
1421   {  
1422     s.clear();
1423
1424     putchar('>');
1425     putchar(' ');
1426
1427     do 
1428     {
1429       char c = getchar();
1430       if (c=='\n') 
1431       {
1432         putchar('\n');
1433         break;
1434       }
1435       if (c=='\t') 
1436       {
1437         // putchar('T');
1438         continue;
1439       }
1440       // putchar(c);
1441       s += c;
1442     } 
1443     while (true);  
1444     
1445   }
1446   //=======================================================================  
1447
1448 #endif
1449
1450
1451
1452   //=======================================================================
1453   void Interpreter::CommandLineInterpreter()
1454   {
1455     bbtkDebugMessageInc("Interpreter",9,
1456                         "Interpreter::CommandLineInterpreter()"<<std::endl);
1457
1458 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT  
1459     // Initialise the tty in non canonical mode with no echo
1460     // oter remembers the previous settings to restore them after 
1461     struct termios ter,oter;
1462     tcgetattr(0,&ter);
1463     oter=ter;
1464     ter.c_lflag &= ~ECHO;
1465     ter.c_lflag &= ~ICANON;
1466     ter.c_cc[VMIN]=1;
1467     ter.c_cc[VTIME]=0;
1468     tcsetattr(0,TCSANOW,&ter);
1469 #endif
1470     
1471     mCommandLine = true;
1472     bool again = true;
1473     bool insideComment = false; // for multiline comment  
1474     do 
1475     {
1476       try
1477       {
1478         std::string line;
1479         GetLineFromPrompt(line);
1480         InterpretLine(line, insideComment);
1481       }
1482       catch (QuitException e)
1483       {
1484         again = false;
1485       }
1486       catch (bbtk::Exception e) 
1487       {
1488         e.Print();
1489       }
1490         catch (std::exception& e) 
1491       {
1492         std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1493       }
1494       catch (...)
1495       {
1496         std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1497       }
1498     }
1499     while (again);
1500
1501 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1502     tcsetattr(0,TCSANOW,&oter);
1503 #endif
1504
1505     std::cout << "Good bye !" << std::endl;
1506
1507     bbtkDebugDecTab("Interpreter",9);
1508   }
1509
1510 //=======================================================================
1511 void Interpreter::Graph(const std::vector<std::string>& words)
1512 {
1513   std::string page;
1514     bool system_display = true;
1515
1516 #ifdef _USE_WXWIDGETS_
1517     if ( WxConsole::GetInstance() != 0 ) system_display = false; 
1518 #endif
1519  
1520     if (words.size()==1) 
1521     {
1522       page = mExecuter->ShowGraph(".","0","0","","","",system_display);
1523     }
1524     else if (words.size()==2) 
1525     {
1526       page = mExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1527     }
1528     else if (words.size()==3) 
1529     {
1530       page = mExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1531     }
1532     else if (words.size()==4) 
1533     {
1534       page = mExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1535     } 
1536     else if (words.size()==5) 
1537     {
1538       page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1539     } 
1540     else if (words.size()==6) 
1541     {
1542       page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1543     } 
1544     else if (words.size()==7) 
1545       {
1546         page = mExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1547       } 
1548     
1549 #ifdef _USE_WXWIDGETS_
1550     if ( WxConsole::GetInstance() != 0 )
1551       WxConsole::GetInstance()->ShowHtmlPage(page);
1552 #endif
1553   }
1554 //=======================================================================
1555
1556
1557 //=======================================================================
1558 void  Interpreter::Index(const std::string& filename, 
1559                          const std::string& type)
1560 {
1561   Factory::IndexEntryType t;
1562   if (type=="Initials") t = Factory::Initials;
1563   else if (type=="Categories") t = Factory::Categories;
1564   else if (type=="Packages") t = Factory::Packages;
1565   
1566   GetGlobalFactory()->CreateHtmlIndex(t,filename);
1567 }
1568 //=======================================================================
1569
1570 }//namespace
1571
1572