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