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