1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2008/12/12 12:11:21 $
6 Version: $Revision: 1.79 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief class Interpreter :
36 #include "bbtkInterpreter.h"
37 #include "bbtkExecuter.h"
38 #include "bbtkTranscriptor.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkConfigurationFile.h"
41 #include "bbtkUtilities.h"
42 #include "bbtkWxBlackBox.h"
45 #ifdef CMAKE_HAVE_TERMIOS_H
47 #define BBTK_USE_TERMIOS_BASED_PROMPT
55 //=======================================================================
56 Interpreter::Pointer Interpreter::New(const std::string& cpp_file)
58 bbtkDebugMessage("Kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
59 return MakePointer(new Interpreter(cpp_file));
61 //=======================================================================
63 //=======================================================================
64 Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e)
66 bbtkDebugMessage("Kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
67 return MakePointer(new Interpreter(e));
69 //=======================================================================
71 //=======================================================================
72 Interpreter::Interpreter(const std::string& cpp_file)
74 Init(VirtualExec::Pointer(), cpp_file);
76 //=======================================================================
78 //=======================================================================
79 Interpreter::Interpreter(VirtualExec::Pointer e)
83 //=======================================================================
85 //=======================================================================
86 void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file)
92 bbtk::MessageManager::RegisterMessageType("echo","Level>0 : Prints the output of the 'print' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
93 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
94 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
99 else if (cpp_file.size()!=0)
101 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
105 bbtk::Executer::Pointer exe = bbtk::Executer::New();
107 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
110 // Lock this pointer or will auto-destruct !!
111 if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
113 // For the time being, comment out previous line, and
114 // uncomment next line to check Transcriptor
116 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
118 // Builds the commands dict
119 CommandInfoType info;
121 info.keyword = "new";
125 info.syntax = "new <type> <name>";
126 info.help = "Creates a new black box of type <type> with name <name>";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "delete";
133 info.syntax = "delete <box>";
134 info.help = "Deletes the black box of name <box>";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "clear";
141 info.syntax = "clear";
142 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "newgui";
149 info.syntax = "newgui <box> <name>";
150 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "connect";
156 info.code = cConnect;
157 info.syntax = "connect <box1.output> <box2.input>";
158 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "print";
165 info.syntax = "print <string>";
166 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').";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "exec";
173 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
174 info.help = "Executes the black box of name <box> (and connected boxes if needed). If the special keyword 'freeze' is given then freezes any further execution command. 'unfreeze' reverts to normal execution mode. 'freeze_no_error' is like freeze but also skips any error.";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "package";
180 info.code = cPackage;
181 info.syntax = "package <name>";
182 info.help = "Begins the definition of a package.";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "endpackage";
188 info.code = cEndPackage;
189 info.syntax = "endpackage";
190 info.help = "Ends the definition of a package.";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "define";
197 info.syntax = "define <type> [<package>]";
198 info.help = "Begins the definition of a new type of complex black box called <type>. If <package> is provided will create it in the given package.";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "endefine";
204 info.code = cEndDefine;
205 info.syntax = "endefine";
206 info.help = "Ends the definition of a new type of complex black box";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "kind";
213 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
214 info.help = "Sets the kind of the currently defined complex black box";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "input";
221 info.syntax = "input <name> <box.input> <help>";
222 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";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "output";
229 info.syntax = "output <name> <box.output> <help>";
230 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";
231 mCommandDict[info.keyword] = info;
233 info.keyword = "set";
237 info.syntax = "set <box.input> <value>";
238 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";
239 mCommandDict[info.keyword] = info;
241 info.keyword = "config"; // JPR
245 info.syntax = "config";
246 info.help = "Prints the value of all configuration parameters";
247 mCommandDict[info.keyword] = info;
249 info.keyword = "index"; // LG
254 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
255 info.help = "Creates an html index of known boxes. If filename is provided then save it to the file 'filename'. The default index entries are the initial letters of the names of the boxes. If 'Packages' or 'Categories' is provided then the entries are either the packages names or the categories. If 'Adaptors' is provided then an alphabetical index of all adaptors is created.";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "reset";
262 info.syntax = "reset";
263 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "author";
270 info.syntax = "author <string>";
271 info.help = "Adds the string <string> to the author information of the black box being defined";
272 mCommandDict[info.keyword] = info;
274 info.keyword = "category"; //JP
277 info.code = cCategory;
278 info.syntax = "category <list of items, separated by ;>";
279 info.help = "Adds the string <string> to the category information of the black box being defined";
280 mCommandDict[info.keyword] = info;
282 info.keyword = "description";
285 info.code = cDescription;
286 info.syntax = "description <string>";
287 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
288 mCommandDict[info.keyword] = info;
290 info.keyword = "help";
294 info.syntax = "help";
295 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>";
296 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.";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "message";
302 info.code = cMessage;
303 info.syntax = "message <kind> <level>";
304 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.";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "include";
310 info.code = cInclude;
311 info.syntax = "include <filename> [source]";
312 info.help = "Includes the file <filename>.\n 'source' : If the keyword 'source' is provided then informs the interpreter that the included file is the source of the current box definition (Advanced; used to get the right 'Include' field in html doc of packages 'appli' scripts).";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "quit";
319 info.syntax = "quit";
320 info.help = "Quits the program (during script execution it stops the complete execution)";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "load";
327 info.syntax = "load <packagename>";
328 info.help = "Loads the black box package <packagename>";
329 mCommandDict[info.keyword] = info;
331 info.keyword = "unload";
335 info.syntax = "unload <packagename>";
336 info.help = "Unloads the black box package <packagename>";
337 mCommandDict[info.keyword] = info;
339 info.keyword = "graph";
343 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 ]]]]]]";
344 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')";
345 mCommandDict[info.keyword] = info;
347 info.keyword = "debug";
351 info.syntax = "debug [expr|-C|-D]";
352 info.help = "Prints debug info on living bbtk objects containing the string 'expr' (default expr=''). -C checks the factory integrity. -D turns on objects debug info after main ends";
353 mCommandDict[info.keyword] = info;
356 info.keyword = "workspace";
359 info.code = cWorkspace;
360 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
361 info.help = "Configures the workspace.\n 'freeze' allows to block execution commands while keeping definition commands active. 'unfreeze' turns back the worspace in 'normal' mode.\n 'rename' allow to set a new name to the workspace.";
362 mCommandDict[info.keyword] = info;
365 bbtkDebugDecTab("Interpreter",9);
368 //=======================================================================
372 //=======================================================================
376 Interpreter::~Interpreter()
378 bbtkDebugMessageInc("Interpreter",9,"==> Interpreter::~Interpreter()" <<std::endl);
379 mVirtualExecuter = VirtualExec::Pointer();
380 bbtkDebugMessageInc("Interpreter",9,"<== Interpreter::~Interpreter()" <<std::endl);
382 //=======================================================================
385 InterpreterError::InterpreterError( const std::string& message,
387 const std::string& script_file,
390 : Exception("Interpreter",0,message),
391 mInScriptFile(in_script_file),
392 mScriptFile(script_file),
393 mScriptLine(script_line)
396 InterpreterError::InterpreterError( const Exception& excep,
398 const std::string& script_file,
402 mInScriptFile(in_script_file),
403 mScriptFile(script_file),
404 mScriptLine(script_line)
407 //=======================================================================
408 void Interpreter::CatchInterpreterException( const InterpreterError& e )
413 throw InterpreterError(e);
417 std::stringstream mess;
418 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
419 if (e.IsInScriptFile())
421 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
422 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
424 std::cerr << mess.str();
427 //=======================================================================
429 //=======================================================================
430 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
434 bool in_script = false;
435 std::string file("");
437 if (mFileName.size()) {
438 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
439 if (fs!=0) in_script = true;
440 file = mFileName.back();
444 throw InterpreterError(e,in_script,file,line);
448 std::stringstream mess;
449 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
450 if (mFileName.size()) {
451 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
452 mess << "* LINE : "<<mLine.back()<<std::endl;
454 std::cerr << mess.str();
457 //=======================================================================
459 //=======================================================================
460 void Interpreter::CatchStdException( const std::exception& e )
464 bool in_script = false;
465 std::string file("");
467 if (mFileName.size()) {
468 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
469 if (fs!=0) in_script = true;
470 file = mFileName.back();
474 throw InterpreterError(e.what(),in_script,file,line);
478 std::stringstream mess;
479 mess << "* ERROR : "<<e.what()<<std::endl;
480 if (mFileName.size()) {
481 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
482 mess << "* LINE : "<<mLine.back()<<std::endl;
484 std::cerr << mess.str();
487 //=======================================================================
489 //=======================================================================
490 void Interpreter::CatchUnknownException()
494 bool in_script = false;
495 std::string file("");
497 if (mFileName.size()) {
498 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
499 if (fs!=0) in_script = true;
500 file = mFileName.back();
504 throw InterpreterError("Unknown exception caught",
505 in_script,file,line);
509 std::stringstream mess;
510 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
512 if (mFileName.size()) {
513 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
514 mess << "* LINE : "<<mLine.back()<<std::endl;
516 std::cerr << mess.str();
519 //=======================================================================
521 //=======================================================================
523 #define CATCH_MACRO \
524 catch (QuitException e) \
526 status = Interpreter_QUIT; \
527 if (mThrow) throw QuitException(); \
529 catch (InterpreterError e) \
531 status = Interpreter_ERROR; \
532 CatchInterpreterException(e); \
534 catch (bbtk::Exception e) \
536 status = Interpreter_ERROR; \
537 CatchBbtkException(e); \
539 catch (std::exception& e) \
541 status = Interpreter_ERROR; \
542 CatchStdException(e); \
546 status = Interpreter_ERROR; \
547 CatchUnknownException(); \
549 //=======================================================================
552 //=======================================================================
556 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
558 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
560 bool exm = mCommandLine;
561 mCommandLine = false;
563 ExitStatus status = Interpreter_OK;
567 SwitchToFile(filename,source);
569 bool insideComment = false; // for multiline comment
570 while (mFile.size()>0)
572 while (!mFile.back()->eof()) {
575 mFile.back()->getline(buf,500);
576 std::string str(buf);
577 int size=str.length();
578 if ( str[ size-1 ]==13 )
584 InterpretLine(str, insideComment);
595 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
596 bbtkDecTab("Interpreter",9);
602 //=======================================================================
605 //=======================================================================
609 Interpreter::ExitStatus
610 Interpreter::InterpretBuffer( std::stringstream* buffer )
612 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
614 bool exm = mCommandLine;
615 mCommandLine = false;
617 ExitStatus status = Interpreter_OK;
621 SwitchToStream(buffer);
622 bool insideComment = false; // for multiline comment
623 while (mFile.size()>0)
625 while (!mFile.back()->eof()) {
628 mFile.back()->getline(buf,500);
629 std::string str(buf);
631 int size=str.length();
632 if ( str[ size-1 ]==13 )
638 InterpretLine(str, insideComment);
648 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
649 bbtkDecTab("Interpreter",9);
654 //=======================================================================
656 //=======================================================================
657 /// Runs the interpretation of a command
658 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
660 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
662 ExitStatus status = Interpreter_OK;
666 bool insideComment = false;
667 InterpretLine(line, insideComment);
672 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
674 bbtkDecTab("Interpreter",9);
680 //=======================================================================
684 void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
686 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
687 bbtkMessage("echo",2,line<<std::endl);
689 std::vector<std::string> words;
690 SplitLine(line,words);
695 bbtkDebugDecTab("Interpreter",9);
699 // Single line comment : # or //
700 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
702 bbtkDebugDecTab("Interpreter",9);
703 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
707 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
709 if (words[0][0]=='/' && words[0][1]=='*')
711 bbtkDebugDecTab("Interpreter",9);
712 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
713 insideComment = true;
717 if (words[0][0]=='*' && words[0][1]=='/')
719 bbtkDebugDecTab("Interpreter",9);
720 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
721 if ( !insideComment ) {
722 bbtkDebugDecTab("Interpreter",9);
723 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
725 insideComment = false;
731 bbtkDebugDecTab("Interpreter",9);
732 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
737 CommandInfoType command;
738 InterpretCommand(words,command);
740 bbtkDebugMessage("Interpreter",9,
741 "Command='"<<command.keyword
742 <<"' code="<<command.code<<std::endl);
744 std::string left,right,left2,right2;
745 std::string filename;
746 switch (command.code)
749 mVirtualExecuter->Create(words[1],words[2]);
753 mVirtualExecuter->Destroy(words[1]);
757 Utilities::SplitAroundFirstDot(words[1],left,right);
758 Utilities::SplitAroundFirstDot(words[2],left2,right2);
759 mVirtualExecuter->Connect(left,right,left2,right2);
763 mVirtualExecuter->BeginPackage(words[1]);
767 mVirtualExecuter->EndPackage();
771 if (mFileName.size()>0)
773 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
777 mVirtualExecuter->Define(words[1],"",filename);
781 mVirtualExecuter->Define(words[1],words[2],filename);
786 mVirtualExecuter->EndDefine();
790 mVirtualExecuter->Kind(words[1]);
794 mVirtualExecuter->Print(words[1]);
798 if (words[1]=="freeze")
800 mVirtualExecuter->SetNoExecMode(true);
803 else if (words[1]=="freeze_no_error ")
805 mVirtualExecuter->SetNoExecMode(true);
806 mVirtualExecuter->SetNoErrorMode(true);
809 else if (words[1]=="unfreeze")
811 mVirtualExecuter->SetNoExecMode(false);
812 mVirtualExecuter->SetNoErrorMode(false);
816 mVirtualExecuter->Execute(words[1]);
821 Utilities::SplitAroundFirstDot(words[2],left,right);
822 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
826 Utilities::SplitAroundFirstDot(words[2],left,right);
827 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
831 Utilities::SplitAroundFirstDot(words[1],left,right);
832 mVirtualExecuter->Set(left,right,words[2]);
836 mVirtualExecuter->Author(words[1]);
840 NewGUI(words[1],words[2]);
844 mVirtualExecuter->Category(words[1]);
849 Index("tmp_index.html");
850 else if (words.size()==2)
852 else if (words.size()==3)
853 Index(words[1],words[2]);
857 mVirtualExecuter->Description(words[1]);
867 mVirtualExecuter->HelpMessages();
871 sscanf(words[2].c_str(),"%d",&level);
872 mVirtualExecuter->SetMessageLevel(words[1],level);
889 mVirtualExecuter->Clear();
893 // if 'source' was given (words.size()==3) then tell to set the
894 // source file name of the current complex box with the full file name included
897 InterpretFile(words[1],(words.size()==3));
901 SwitchToFile(words[1],(words.size()==3) );
906 GetExecuter()->LoadPackage(words[1]);
910 GetExecuter()->UnLoadPackage(words[1]);
914 throw QuitException();
918 if (words.size()==2) Debug(words[1]);
923 if (words.size() == 2)
925 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
926 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
930 mVirtualExecuter->SetWorkspaceName(words[2]);
935 bbtkInternalError("should not reach here !!!");
938 bbtkDecTab("Interpreter",9);
940 //=======================================================================
946 //=======================================================================
950 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
952 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
954 std::string delimiters = "\"";
955 std::vector<std::string> quote;
956 Utilities::SplitString(str,delimiters,quote);
959 std::vector<std::string>::iterator i;
960 for (i=quote.begin(); i!=quote.end(); )
962 Utilities::SplitString(*i,delimiters,tokens);
966 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
967 tokens.push_back(*i);
972 for (i=tokens.begin(); i!=tokens.end(); ++i)
974 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
976 bbtkDebugMessageCont("Interpreter",9,std::endl);
978 bbtkDebugDecTab("Interpreter",9);
980 //=======================================================================
983 //=======================================================================
984 void Interpreter::Reset()
986 // Cannot close all files if the reset command is read from a file !
988 mFileNameHistory.clear();
989 this->mVirtualExecuter->Reset();
991 //=======================================================================
993 //=======================================================================
998 void Interpreter::Print( const std::string& str)
1000 if (mVirtualExecuter->GetNoExecMode()) return;
1002 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
1005 // InterpretLine ("load std")
1006 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1007 // InterpretLine("new Print _P_")
1008 // InterpretLine("connect _C_.Out _P_.In")
1012 std::vector<std::string> chains;
1013 std::string delimiters("$");
1015 // Skip delimiters at beginning.
1016 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1017 bool is_text = true;
1018 if (lastPos>0) is_text = false;
1020 // Find first delimiter.
1021 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1023 while (std::string::npos != pos || std::string::npos != lastPos)
1027 // Found a text token, add it to the vector.
1028 chains.push_back(str.substr(lastPos, pos - lastPos));
1029 // std::string token = str.substr(lastPos, pos - lastPos)
1030 // InterpretLine("set _C_.In%num% %token%")
1036 // is an output (between $$) : decode
1037 std::string tok,box,output;
1038 tok = str.substr(lastPos, pos - lastPos);
1039 Utilities::SplitAroundFirstDot(tok,box,output);
1040 chains.push_back( mVirtualExecuter->Get(box,output) );
1042 // InterpretLine("connect %tok% _C_.In%num%")
1045 // Skip delimiters. Note the "not_of"
1046 lastPos = str.find_first_not_of(delimiters, pos);
1047 // Find next delimiter
1048 pos = str.find_first_of(delimiters, lastPos);
1053 // InterpretLine("exec _P_")
1054 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1056 std::vector<std::string>::iterator i;
1057 for (i= chains.begin(); i!=chains.end(); ++i)
1060 Utilities::SubsBackslashN(*i);
1063 std::cout << std::endl;
1064 bbtkDebugDecTab("Interpreter",9);
1068 //=======================================================================
1073 // =========================================================================
1074 void Interpreter::SwitchToFile( const std::string& name , bool source )
1076 // Note : in the following :
1077 // name : the user supplied name
1078 // - abreviated name e.g. scr scr.bbs
1079 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1080 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1081 // same for Windows, with c:, d: ...
1083 // use ./directory/subdir/scrname.bbs
1086 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1087 <<name<<"\")"<<std::endl);
1089 std::vector<std::string> script_paths;
1090 std::string fullPathScriptName; // full path script name
1091 std::string pkgname; // e.g. <scriptname>.bbs
1092 std::vector<std::string> Filenames;
1094 // The following is *NOT* a debug time message :
1095 // It's a user intended message.
1096 // Please don't remove it.
1097 bbtkMessage("Interpreter",1,
1098 "look for : [" << name
1099 << "]" << std::endl);
1103 pkgname = Utilities::ExtractScriptName(name,upath);
1105 bbtkMessage("Interpreter",3,
1106 "package name:[" << pkgname
1107 << "] path:[" << upath << "]" << std::endl);
1108 bool fullnameGiven = false;
1109 bool foundFile = false;
1111 // ==== "*" provided : load all scripts in given path
1112 // relative (e.g. std/boxes/*) or absolute
1116 std::stringstream* stream = new std::stringstream;
1117 //if (upath.size()!=0) // avoid troubles for "*"
1119 // ==== no path provided : look in root bbs path
1120 if (upath.size()==0)
1122 // bbtkMessage("Interpreter",1,
1123 // LG : add all bbs path
1124 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1125 std::vector<std::string>::const_iterator i;
1126 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1127 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1130 script_paths.push_back(*i);
1133 // ==== absolute path provided
1134 else if (upath[0]=='/' || upath[1] == ':' )
1136 if ( Utilities::IsDirectory( upath ) )
1138 script_paths.push_back(upath);
1142 bbtkError("'"<<upath<<"' : directory does not exist");
1145 // ==== relative path provided : search all bbs path appended with
1146 // the relative path provided
1149 std::vector<std::string>::const_iterator i;
1150 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1151 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1154 std::string full_path(*i);
1155 // we *really* want '.' to be the current working directory
1156 if (full_path == ".")
1158 char buf[2048]; // for getcwd
1159 char * currentDir = getcwd(buf, 2048);
1160 std::string cwd(currentDir);
1161 full_path = currentDir;
1164 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1167 if ( Utilities::IsDirectory( full_path ) )
1169 script_paths.push_back(full_path);
1172 if (script_paths.empty())
1174 bbtkError("no '"<<upath<<"' subdir found in search paths"
1180 // === search paths list complete : now explore it
1182 // ==== relative name, iterate + load all .bbs/.bbp files
1183 std::vector<std::string>::iterator i;
1184 for (i=script_paths.begin();i!=script_paths.end();i++)
1186 bbtkMessage("Interpreter",1,
1187 "--> Looking in '" << *i << "'" << std::endl);
1191 Utilities::Explore(*i, false, Filenames);
1193 for (std::vector<std::string>::iterator j = Filenames.begin();
1194 j!= Filenames.end(); ++j)
1196 int lgr = (*j).size();
1197 if (lgr < 5) continue;
1198 // ignore non .bbp file
1199 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1201 (*stream) << "include \"" << *j << "\"\n";
1202 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1205 } // for (std::vector...
1206 } // for (i=script_...
1211 bbtkMessage("Interpreter",1,
1212 " --> No .bbp found"<< std::endl);
1216 bbtkMessage("Interpreter",1,
1217 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1218 SwitchToStream(stream);
1222 //=============== end pkgname=="*" ===========
1225 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1226 // (not only a plain script name)
1227 // we trust him, and try to expland the directory name
1228 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1230 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1233 // ===========================================================check user supplied location
1234 fullnameGiven = true;
1236 fullPathScriptName = Utilities::ExpandLibName(name, false);
1238 // allow user to always forget ".bbs"
1239 int l = fullPathScriptName.size();
1243 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1244 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1246 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1247 if ( Utilities::FileExists(tfullPathScriptName) )
1249 fullPathScriptName = tfullPathScriptName;
1254 tfullPathScriptName = fullPathScriptName + ".bbp";
1255 if ( Utilities::FileExists(tfullPathScriptName) )
1257 fullPathScriptName = tfullPathScriptName;
1264 if ( Utilities::FileExists(fullPathScriptName) )
1272 // =============================== iterate on the paths
1274 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1276 std::vector<std::string>::iterator i;
1277 for (i=script_paths.begin();i!=script_paths.end();++i)
1280 // we *really* want '.' to be the current working directory
1283 char buf[2048]; // for getcwd
1284 char * currentDir = getcwd(buf, 2048);
1285 std::string cwd(currentDir);
1289 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1290 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1292 fullPathScriptName = tfullPathScriptName;
1293 if ( ! Utilities::FileExists(fullPathScriptName) )
1295 // The following is *NOT* a debug time message :
1296 // It's a user intended message.
1297 // Please don't remove it.
1298 bbtkMessage("Interpreter",2,
1299 " [" <<fullPathScriptName <<"] : does not exist"
1301 continue; // try next path
1303 bbtkMessage("Interpreter",2,
1304 " [" <<fullPathScriptName
1305 <<"] : found" <<std::endl);
1307 break; // a script was found; we stop iterating
1311 fullPathScriptName = tfullPathScriptName + ".bbs";
1312 // Check if library exists
1313 if ( ! Utilities::FileExists(fullPathScriptName) )
1315 fullPathScriptName = tfullPathScriptName + ".bbp";
1316 if ( ! Utilities::FileExists(fullPathScriptName) )
1318 // The following is *NOT* a debug time message :
1319 // It's a user intended message.
1320 // Please don't remove it.
1321 bbtkMessage("Interpreter",2,
1322 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1324 continue; // try next path
1327 bbtkMessage("Interpreter",2,
1328 " [" <<fullPathScriptName
1329 <<"] : found" <<std::endl);
1331 break; // a script was found; we stop iterating
1333 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1339 if(fullPathScriptName == "")
1340 bbtkError("Path ["<<upath<<"] doesn't exist");
1342 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1344 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1349 LoadScript(fullPathScriptName,name);
1350 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1355 //=======================================================================
1358 //=======================================================================
1359 void Interpreter::SwitchToStream( std::stringstream* stream )
1361 mFile.push_back(stream);
1362 std::ostringstream buffer_name;
1364 buffer_name << "buffer_" ;
1366 if (mFileName.size()>0 )
1368 buffer_name << mFileName.back() << "_" << mLine.back();
1370 mFileName.push_back(buffer_name.str());
1371 mIncludeFileName.push_back(buffer_name.str());
1374 //=======================================================================
1376 //=======================================================================
1378 void Interpreter::LoadScript( std::string fullPathScriptName,
1379 std::string includeScriptName)
1381 Utilities::replace( fullPathScriptName ,
1382 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1384 if (find(mFileNameHistory.begin(),
1385 mFileNameHistory.end(),
1386 fullPathScriptName)!=mFileNameHistory.end())
1392 s = new std::ifstream;
1393 s->open(fullPathScriptName.c_str());
1396 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1400 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1401 << "] found" << std::endl);
1404 mFileName.push_back(fullPathScriptName);
1405 mFileNameHistory.push_back(fullPathScriptName);
1406 mIncludeFileName.push_back(includeScriptName);
1412 //=======================================================================
1416 void Interpreter::CloseCurrentFile()
1418 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1421 if (mFile.size()==0)
1423 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1427 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1429 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1430 if (file!=0) file->close();
1432 delete mFile.back();
1434 mFileName.pop_back();
1435 mIncludeFileName.pop_back();
1438 bbtkDebugMessage("Interpreter",9," Remains "
1440 <<" open"<<std::endl);
1441 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1444 //=======================================================================
1446 //=======================================================================
1450 void Interpreter::CloseAllFiles()
1452 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1455 while (mFile.size() != 0)
1459 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1462 //=======================================================================
1466 //=======================================================================
1470 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1471 CommandInfoType& info )
1473 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1475 // searches the command keyword
1476 CommandDictType::iterator c;
1477 c = mCommandDict.find(words[0]);
1478 if ( c == mCommandDict.end() ) {
1479 bbtkError(words[0]<<" : unknown command");
1482 // tests the number of args
1483 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1484 ( ((int)words.size())-1 > c->second.argmax ) )
1486 HelpCommand(words[0]);
1487 bbtkError(words[0]<<" : wrong number of arguments");
1491 bbtkDecTab("Interpreter",9);
1493 //=======================================================================
1496 //=======================================================================
1497 /// Displays help on all the commands
1498 void Interpreter::Help(const std::vector<std::string>& words)
1500 unsigned int nbarg = words.size()-1;
1508 if (words[1]=="packages")
1510 GetExecuter()->GetFactory()->PrintPackages(true);
1515 HelpCommand(words[1]);
1517 catch (bbtk::Exception e)
1521 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1525 ConfigurationFile::GetInstance().Get_doc_path();
1526 url += "/bbdoc/" + words[1] + "/index.html";
1527 if (Utilities::FileExists(url))
1529 mUser->InterpreterUserViewHtmlPage(url);
1533 catch (bbtk::Exception f)
1537 std::string package;
1538 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1542 ConfigurationFile::GetInstance().Get_doc_path();
1543 url += "/bbdoc/" + package + "/index.html";
1544 if (Utilities::FileExists(url))
1546 url += "#" + words[1];
1547 mUser->InterpreterUserViewHtmlPage(url);
1551 catch (bbtk::Exception g)
1555 GetExecuter()->ShowRelations(words[1],"0","9999");
1557 catch (bbtk::Exception h){
1558 bbtkError("\""<<words[1].c_str()
1559 <<"\" is not a known command, package, black box type or black box name");
1567 if (words[2]=="all")
1569 if ( words[1]=="packages" )
1571 GetExecuter()->GetFactory()->PrintPackages(true,true);
1576 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1578 catch (bbtk::Exception f)
1584 HelpCommand(words[0]);
1585 bbtkError(words[0]<<" : syntax error");
1590 bbtkError("Should not reach here !!!");
1593 //=======================================================================
1595 //===================================================================
1596 /// Displays the Configuration
1597 void Interpreter::Config() const
1599 ConfigurationFile::GetInstance().GetHelp(1);
1601 //===================================================================
1603 //=======================================================================
1604 /// Displays help on all the commands
1605 void Interpreter::HelpCommands()
1607 std::cout << "Available commands :" << std::endl;
1608 CommandDictType::iterator i;
1609 for ( i = mCommandDict.begin();
1610 i != mCommandDict.end();
1612 std::cout << " " << i->first << std::endl;
1613 // std::cout << " usage : " << i->second.syntax << std::endl;
1614 // std::cout << " " << i->second.help << std::endl;
1618 //=======================================================================
1621 //=======================================================================
1622 /// Displays help on a particular commands
1623 void Interpreter::HelpCommand(const std::string& s)
1625 CommandDictType::iterator c;
1626 c = mCommandDict.find(s);
1627 if ( c == mCommandDict.end() ) {
1628 bbtkError(s<<" : Unknown command");
1630 // std::cout << " " << s << " : "<< std::endl;
1631 // CommandParamDictType::iterator i;
1632 // for ( i = c->second.begin();
1633 // i != c->second.end();
1635 std::cout << " usage : " << c->second.syntax << std::endl;
1636 std::cout << " " << c->second.help << std::endl;
1639 //=======================================================================
1642 //=======================================================================
1643 /// Fills the vector commands with the commands which
1644 /// have the first n chars of buf for prefix
1645 /// TODO : skip initial spaces in buf and also return the position of first
1646 /// non blank char in buf
1647 void Interpreter::FindCommandsWithPrefix( char* buf,
1649 std::vector<std::string>& commands )
1651 CommandDictType::const_iterator i;
1652 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1654 if ((i->first).find(buf,0,n) == 0)
1655 commands.push_back(i->first);
1658 //=======================================================================
1662 //=======================================================================
1663 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1665 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1666 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1668 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1669 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1670 // E.G. STORE THIS IN bbtk_config.xml
1671 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1672 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1673 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1674 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1675 #define BBTK_BACKSPACE_KBCODE 0x00000008
1676 #define BBTK_DEL_KBCODE 0x0000007F
1677 #define BBTK_SPACE_KBCODE 0x00000020
1679 //=======================================================================
1680 void Interpreter::GetLineFromPrompt(std::string& s)
1685 unsigned int MAX_LINE_SIZE = 160;
1686 unsigned int MAX_HISTORY_SIZE = 100;
1688 char* newline = new char[MAX_LINE_SIZE];
1689 memset(newline,0,MAX_LINE_SIZE);
1690 char* histline = new char[MAX_LINE_SIZE];
1691 memset(histline,0,MAX_LINE_SIZE);
1693 char* line = newline;
1694 unsigned int hist = mHistory.size();
1700 read ( STDIN_FILENO, &c, 4) ;
1702 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1704 // Printable character
1705 if ( (ind<MAX_LINE_SIZE-1) &&
1706 ( c >= BBTK_SPACE_KBCODE ) &&
1707 ( c < BBTK_DEL_KBCODE ))
1715 // delete the unused line
1721 // empty lines are not stored in from history
1724 // if history too long : delete oldest command
1725 if (mHistory.size()>MAX_HISTORY_SIZE)
1727 delete mHistory.front();
1728 mHistory.pop_front();
1730 mHistory.push_back(line);
1735 else if ( (ind>0) &&
1736 ((c == BBTK_BACKSPACE_KBCODE) ||
1737 (c == BBTK_DEL_KBCODE)) )
1745 // TODO : Command completion
1746 std::vector<std::string> commands;
1747 FindCommandsWithPrefix( line,ind,commands);
1748 if (commands.size()==1)
1750 std::string com = *commands.begin();
1751 for (; ind<com.size(); ++ind)
1753 PrintChar(com[ind]);
1759 else if (commands.size()>1)
1761 std::vector<std::string>::iterator i;
1763 for (i=commands.begin();i!=commands.end();++i)
1765 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1768 write(STDOUT_FILENO,"\n> ",3);
1769 //for (int j=0;j<ind;++j)
1771 write(STDOUT_FILENO,line,ind);
1775 // Arrow up : back in history
1776 else if (c==BBTK_UP_ARROW_KBCODE)
1780 // erase current line
1781 while (ind--) BackSpace();
1785 strcpy(histline,mHistory[hist]);
1789 write(STDOUT_FILENO,line,ind);
1792 // Arrow down : down in history
1793 else if (c==BBTK_DOWN_ARROW_KBCODE)
1795 if (hist<mHistory.size()-1)
1797 // erase current line
1798 while (ind--) BackSpace();
1802 strcpy(histline,mHistory[hist]);
1806 write(STDOUT_FILENO,line,ind);
1808 // end of history : switch back to newline
1809 else if (hist==mHistory.size()-1)
1811 // erase current line
1812 while (ind--) BackSpace();
1819 write(STDOUT_FILENO,line,ind);
1823 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1825 PrintChar(line[ind]);
1830 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1838 write(STDOUT_FILENO,"\n\r",2);
1846 //=======================================================================
1847 void Interpreter::GetLineFromPrompt(std::string& s)
1873 //=======================================================================
1879 //=======================================================================
1880 void Interpreter::CommandLineInterpreter()
1882 bbtkDebugMessageInc("Interpreter",9,
1883 "Interpreter::CommandLineInterpreter()"<<std::endl);
1885 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1886 // Initialise the tty in non canonical mode with no echo
1887 // oter remembers the previous settings to restore them after
1888 struct termios ter,oter;
1891 ter.c_lflag &= ~ECHO;
1892 ter.c_lflag &= ~ICANON;
1895 tcsetattr(0,TCSANOW,&ter);
1898 mCommandLine = true;
1900 bool insideComment = false; // for multiline comment
1906 GetLineFromPrompt(line);
1907 InterpretLine(line, insideComment);
1909 catch (QuitException e)
1911 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1914 catch (bbtk::Exception e)
1918 catch (std::exception& e)
1920 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1924 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1929 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1930 tcsetattr(0,TCSANOW,&oter);
1933 std::cout << "Good bye !" << std::endl;
1935 bbtkDebugDecTab("Interpreter",9);
1938 //=======================================================================
1939 void Interpreter::Graph(const std::vector<std::string>& words)
1942 bool system_display = true;
1944 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1945 system_display = false;
1947 if (words.size()==1)
1949 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1951 else if (words.size()==2)
1953 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1955 else if (words.size()==3)
1957 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1959 else if (words.size()==4)
1961 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1963 else if (words.size()==5)
1965 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1967 else if (words.size()==6)
1969 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1971 else if (words.size()==7)
1973 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1976 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1977 mUser->InterpreterUserViewHtmlPage(page);
1980 //=======================================================================
1983 //=======================================================================
1984 void Interpreter::Index(const std::string& filename,
1985 const std::string& type)
1987 Factory::IndexEntryType t;
1988 if (type=="Initials") t = Factory::Initials;
1989 else if (type=="Categories") t = Factory::Categories;
1990 else if (type=="Packages") t = Factory::Packages;
1991 else if (type=="Adaptors") t = Factory::Adaptors;
1993 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1995 //=======================================================================
1998 //=======================================================================
1999 void Interpreter::NewGUI(const std::string& boxname,
2000 const std::string& instanceName)
2002 if (mRealExecuter.expired())
2004 bbtkError("command 'newgui' cannot be compiled yet");
2007 std::string typeName = instanceName+"Type";
2008 std::stringstream* s = new std::stringstream;
2009 // create the complex box
2010 (*s) << "define "<<typeName<<std::endl;
2011 // (*s) << " description 'Automatically generated user interface for the box "
2012 // << boxname << "'" <<std::endl;
2013 // create the Layout box
2014 (*s) << " load wx"<<std::endl;
2015 (*s) << " new LayoutLine layout"<<std::endl;
2016 // create the output 'Widget'
2017 (*s) << " output Widget layout.Widget Widget"<<std::endl;
2018 // the box change output
2019 (*s) << " new MultipleInputs change"<<std::endl;
2020 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
2022 // Browse the inputs of the box in order to find which ones are not
2023 // connected and can be adapted from a widget adaptor
2024 // vector which stores the list of inputs of the box which must be connected
2025 std::vector<std::string> in;
2027 Factory::Pointer F = mVirtualExecuter->GetFactory();
2029 Package::Pointer user = F->GetPackage("user");
2031 ComplexBlackBoxDescriptor::Pointer workspace =
2032 mRealExecuter.lock()->GetCurrentDescriptor();
2037 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2042 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2045 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2046 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2048 BlackBox::InputConnectorMapType::iterator i;
2049 for (i=box->bbGetInputConnectorMap().begin();
2050 i!=box->bbGetInputConnectorMap().end();
2053 // If the input is connected : continue
2054 if (i->second->IsConnected()) continue;
2055 // Get the input descriptor
2056 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2057 // If it is a "system" input : skip it
2058 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2059 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2062 std::string widget,adaptor;
2063 // try to find a widget adaptor
2064 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2068 // command to create the adaptor
2069 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2070 // Sets the label of the widget adaptor to the name of the input
2071 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2072 // Sets the initial value of the widget to the value of the input
2073 (*s) << " set "<<i->first<<".In \" "
2074 <<box->bbGetInputAsString(i->first)<<"\""
2076 // store the input name
2077 in.push_back(i->first);
2078 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2079 //<i->first<<"'"<<std::endl;
2080 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2082 // try to find a two pieces adaptor
2083 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2087 // command to create the widget
2088 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2089 // command to create the adaptor
2090 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2092 (*s) << " connect "<<i->first<<"Widget.Out "
2093 <<i->first<<".In"<<std::endl;
2094 // Sets the label of the widget adaptor to the name of the input
2095 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2096 // Sets the initial value of the widget to the value of the input
2097 (*s) << " set "<<i->first<<"Widget.In \" "
2098 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2099 // store the input name
2100 in.push_back(i->first);
2101 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2102 //<i->first<<"'"<<std::endl;
2103 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2106 // try to find an adaptor from string
2107 // If found then can create a text input which
2108 // will be automatically adapted
2109 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2113 // command to create the adaptor
2114 (*s) << " new InputText "<<i->first<<std::endl;
2115 // Sets the label of the widget adaptor to the name of the input
2116 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2117 // Sets the initial value of the widget to the value of the input
2118 (*s) << " set "<<i->first<<".In \" "
2119 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2120 // store the input name
2121 in.push_back(i->first);
2122 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2123 //<i->first<<"'"<<std::endl;
2124 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2133 // command to create the output
2134 (*s) << " output "<<i->first<<" "
2135 <<i->first<<".Out "<<i->first<<std::endl;
2136 // <<" Output of the widget which allows to set "
2140 // Inputs for window properties
2141 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2142 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2143 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2144 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2145 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2149 // Execute the box executes the layout
2150 (*s) << " exec layout" << std::endl;
2151 (*s) << "endefine" << std::endl;
2152 // (*s) << "help "<< typeName<< std::endl;
2153 // instanciate the box and connect it
2154 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2156 std::vector<std::string>::iterator j;
2157 for (j=in.begin();j!=in.end();++j)
2160 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2161 << boxname<<"."<<*j<<std::endl;
2163 // That's all folks ! now execute the commands :
2166 //=======================================================================
2170 //==========================================================================
2171 void Interpreter::Debug(const std::string& name)
2173 if ((name.length()==2)&&(name[0]=='-'))
2177 bbtk::StaticInitTime::PrintObjectListInfo = true;
2181 // int o = MessageManager::GetMessageLevel("debug");
2182 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2183 mVirtualExecuter->GetFactory()->CheckPackages();
2184 // MessageManager::SetMessageLevel("debug",o);
2189 Object:: PrintObjectListInfo(name);
2192 //==========================================================================
2193 //==========================================================================
2194 std::string Interpreter::GetObjectName() const
2196 return std::string("Interpreter");
2198 //==========================================================================
2200 //==========================================================================
2201 std::string Interpreter::GetObjectInfo() const
2203 std::stringstream i;
2206 //==========================================================================
2208 //==========================================================================
2209 size_t Interpreter::GetObjectSize() const
2211 size_t s = Superclass::GetObjectSize();
2212 s += Interpreter::GetObjectInternalSize();
2215 //==========================================================================
2216 //==========================================================================
2217 size_t Interpreter::GetObjectInternalSize() const
2219 size_t s = sizeof(Interpreter);
2222 //==========================================================================
2223 //==========================================================================
2224 size_t Interpreter::GetObjectRecursiveSize() const
2226 size_t s = Superclass::GetObjectRecursiveSize();
2227 s += Interpreter::GetObjectInternalSize();
2228 s += mVirtualExecuter->GetObjectRecursiveSize();
2231 //==========================================================================