1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2008/12/12 12:56:28 $
6 Version: $Revision: 1.80 $
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);
688 std::vector<std::string> words;
689 SplitLine(line,words);
694 bbtkDebugDecTab("Interpreter",9);
698 // Single line comment : # or //
699 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
701 bbtkDebugDecTab("Interpreter",9);
702 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
706 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
708 if (words[0][0]=='/' && words[0][1]=='*')
710 bbtkDebugDecTab("Interpreter",9);
711 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
712 insideComment = true;
716 if (words[0][0]=='*' && words[0][1]=='/')
718 bbtkDebugDecTab("Interpreter",9);
719 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
720 if ( !insideComment ) {
721 bbtkDebugDecTab("Interpreter",9);
722 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
724 insideComment = false;
730 bbtkDebugDecTab("Interpreter",9);
731 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
736 CommandInfoType command;
737 InterpretCommand(words,command);
739 bbtkDebugMessage("Interpreter",9,
740 "Command='"<<command.keyword
741 <<"' code="<<command.code<<std::endl);
743 std::string left,right,left2,right2;
744 std::string filename;
745 if (command.code==cMessage)
749 mVirtualExecuter->HelpMessages();
753 sscanf(words[2].c_str(),"%d",&level);
754 mVirtualExecuter->SetMessageLevel(words[1],level);
759 bbtkMessage("echo",2,line<<std::endl);
762 switch (command.code)
768 mVirtualExecuter->Create(words[1],words[2]);
772 mVirtualExecuter->Destroy(words[1]);
776 Utilities::SplitAroundFirstDot(words[1],left,right);
777 Utilities::SplitAroundFirstDot(words[2],left2,right2);
778 mVirtualExecuter->Connect(left,right,left2,right2);
782 mVirtualExecuter->BeginPackage(words[1]);
786 mVirtualExecuter->EndPackage();
790 if (mFileName.size()>0)
792 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
796 mVirtualExecuter->Define(words[1],"",filename);
800 mVirtualExecuter->Define(words[1],words[2],filename);
805 mVirtualExecuter->EndDefine();
809 mVirtualExecuter->Kind(words[1]);
813 mVirtualExecuter->Print(words[1]);
817 if (words[1]=="freeze")
819 mVirtualExecuter->SetNoExecMode(true);
822 else if (words[1]=="freeze_no_error ")
824 mVirtualExecuter->SetNoExecMode(true);
825 mVirtualExecuter->SetNoErrorMode(true);
828 else if (words[1]=="unfreeze")
830 mVirtualExecuter->SetNoExecMode(false);
831 mVirtualExecuter->SetNoErrorMode(false);
835 mVirtualExecuter->Execute(words[1]);
840 Utilities::SplitAroundFirstDot(words[2],left,right);
841 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
845 Utilities::SplitAroundFirstDot(words[2],left,right);
846 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
850 Utilities::SplitAroundFirstDot(words[1],left,right);
851 mVirtualExecuter->Set(left,right,words[2]);
855 mVirtualExecuter->Author(words[1]);
859 NewGUI(words[1],words[2]);
863 mVirtualExecuter->Category(words[1]);
868 Index("tmp_index.html");
869 else if (words.size()==2)
871 else if (words.size()==3)
872 Index(words[1],words[2]);
876 mVirtualExecuter->Description(words[1]);
897 mVirtualExecuter->Clear();
901 // if 'source' was given (words.size()==3) then tell to set the
902 // source file name of the current complex box with the full file name included
905 InterpretFile(words[1],(words.size()==3));
909 SwitchToFile(words[1],(words.size()==3) );
914 GetExecuter()->LoadPackage(words[1]);
918 GetExecuter()->UnLoadPackage(words[1]);
922 throw QuitException();
926 if (words.size()==2) Debug(words[1]);
931 if (words.size() == 2)
933 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
934 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
938 mVirtualExecuter->SetWorkspaceName(words[2]);
943 bbtkInternalError("should not reach here !!!");
946 bbtkDecTab("Interpreter",9);
948 //=======================================================================
954 //=======================================================================
958 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
960 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
962 std::string delimiters = "\"";
963 std::vector<std::string> quote;
964 Utilities::SplitString(str,delimiters,quote);
967 std::vector<std::string>::iterator i;
968 for (i=quote.begin(); i!=quote.end(); )
970 Utilities::SplitString(*i,delimiters,tokens);
974 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
975 tokens.push_back(*i);
980 for (i=tokens.begin(); i!=tokens.end(); ++i)
982 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
984 bbtkDebugMessageCont("Interpreter",9,std::endl);
986 bbtkDebugDecTab("Interpreter",9);
988 //=======================================================================
991 //=======================================================================
992 void Interpreter::Reset()
994 // Cannot close all files if the reset command is read from a file !
996 mFileNameHistory.clear();
997 this->mVirtualExecuter->Reset();
999 //=======================================================================
1001 //=======================================================================
1006 void Interpreter::Print( const std::string& str)
1008 if (mVirtualExecuter->GetNoExecMode()) return;
1010 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
1013 // InterpretLine ("load std")
1014 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1015 // InterpretLine("new Print _P_")
1016 // InterpretLine("connect _C_.Out _P_.In")
1020 std::vector<std::string> chains;
1021 std::string delimiters("$");
1023 // Skip delimiters at beginning.
1024 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1025 bool is_text = true;
1026 if (lastPos>0) is_text = false;
1028 // Find first delimiter.
1029 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1031 while (std::string::npos != pos || std::string::npos != lastPos)
1035 // Found a text token, add it to the vector.
1036 chains.push_back(str.substr(lastPos, pos - lastPos));
1037 // std::string token = str.substr(lastPos, pos - lastPos)
1038 // InterpretLine("set _C_.In%num% %token%")
1044 // is an output (between $$) : decode
1045 std::string tok,box,output;
1046 tok = str.substr(lastPos, pos - lastPos);
1047 Utilities::SplitAroundFirstDot(tok,box,output);
1048 chains.push_back( mVirtualExecuter->Get(box,output) );
1050 // InterpretLine("connect %tok% _C_.In%num%")
1053 // Skip delimiters. Note the "not_of"
1054 lastPos = str.find_first_not_of(delimiters, pos);
1055 // Find next delimiter
1056 pos = str.find_first_of(delimiters, lastPos);
1061 // InterpretLine("exec _P_")
1062 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1064 std::vector<std::string>::iterator i;
1065 for (i= chains.begin(); i!=chains.end(); ++i)
1068 Utilities::SubsBackslashN(*i);
1071 std::cout << std::endl;
1072 bbtkDebugDecTab("Interpreter",9);
1076 //=======================================================================
1081 // =========================================================================
1082 void Interpreter::SwitchToFile( const std::string& name , bool source )
1084 // Note : in the following :
1085 // name : the user supplied name
1086 // - abreviated name e.g. scr scr.bbs
1087 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1088 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1089 // same for Windows, with c:, d: ...
1091 // use ./directory/subdir/scrname.bbs
1094 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1095 <<name<<"\")"<<std::endl);
1097 std::vector<std::string> script_paths;
1098 std::string fullPathScriptName; // full path script name
1099 std::string pkgname; // e.g. <scriptname>.bbs
1100 std::vector<std::string> Filenames;
1102 // The following is *NOT* a debug time message :
1103 // It's a user intended message.
1104 // Please don't remove it.
1105 bbtkMessage("Interpreter",1,
1106 "look for : [" << name
1107 << "]" << std::endl);
1111 pkgname = Utilities::ExtractScriptName(name,upath);
1113 bbtkMessage("Interpreter",3,
1114 "package name:[" << pkgname
1115 << "] path:[" << upath << "]" << std::endl);
1116 bool fullnameGiven = false;
1117 bool foundFile = false;
1119 // ==== "*" provided : load all scripts in given path
1120 // relative (e.g. std/boxes/*) or absolute
1124 std::stringstream* stream = new std::stringstream;
1125 //if (upath.size()!=0) // avoid troubles for "*"
1127 // ==== no path provided : look in root bbs path
1128 if (upath.size()==0)
1130 // bbtkMessage("Interpreter",1,
1131 // LG : add all bbs path
1132 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1133 std::vector<std::string>::const_iterator i;
1134 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1135 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1138 script_paths.push_back(*i);
1141 // ==== absolute path provided
1142 else if (upath[0]=='/' || upath[1] == ':' )
1144 if ( Utilities::IsDirectory( upath ) )
1146 script_paths.push_back(upath);
1150 bbtkError("'"<<upath<<"' : directory does not exist");
1153 // ==== relative path provided : search all bbs path appended with
1154 // the relative path provided
1157 std::vector<std::string>::const_iterator i;
1158 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1159 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1162 std::string full_path(*i);
1163 // we *really* want '.' to be the current working directory
1164 if (full_path == ".")
1166 char buf[2048]; // for getcwd
1167 char * currentDir = getcwd(buf, 2048);
1168 std::string cwd(currentDir);
1169 full_path = currentDir;
1172 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1175 if ( Utilities::IsDirectory( full_path ) )
1177 script_paths.push_back(full_path);
1180 if (script_paths.empty())
1182 bbtkError("no '"<<upath<<"' subdir found in search paths"
1188 // === search paths list complete : now explore it
1190 // ==== relative name, iterate + load all .bbs/.bbp files
1191 std::vector<std::string>::iterator i;
1192 for (i=script_paths.begin();i!=script_paths.end();i++)
1194 bbtkMessage("Interpreter",1,
1195 "--> Looking in '" << *i << "'" << std::endl);
1199 Utilities::Explore(*i, false, Filenames);
1201 for (std::vector<std::string>::iterator j = Filenames.begin();
1202 j!= Filenames.end(); ++j)
1204 int lgr = (*j).size();
1205 if (lgr < 5) continue;
1206 // ignore non .bbp file
1207 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1209 (*stream) << "include \"" << *j << "\"\n";
1210 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1213 } // for (std::vector...
1214 } // for (i=script_...
1219 bbtkMessage("Interpreter",1,
1220 " --> No .bbp found"<< std::endl);
1224 bbtkMessage("Interpreter",1,
1225 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1226 SwitchToStream(stream);
1230 //=============== end pkgname=="*" ===========
1233 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1234 // (not only a plain script name)
1235 // we trust him, and try to expland the directory name
1236 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1238 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1241 // ===========================================================check user supplied location
1242 fullnameGiven = true;
1244 fullPathScriptName = Utilities::ExpandLibName(name, false);
1246 // allow user to always forget ".bbs"
1247 int l = fullPathScriptName.size();
1251 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1252 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1254 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1255 if ( Utilities::FileExists(tfullPathScriptName) )
1257 fullPathScriptName = tfullPathScriptName;
1262 tfullPathScriptName = fullPathScriptName + ".bbp";
1263 if ( Utilities::FileExists(tfullPathScriptName) )
1265 fullPathScriptName = tfullPathScriptName;
1272 if ( Utilities::FileExists(fullPathScriptName) )
1280 // =============================== iterate on the paths
1282 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1284 std::vector<std::string>::iterator i;
1285 for (i=script_paths.begin();i!=script_paths.end();++i)
1288 // we *really* want '.' to be the current working directory
1291 char buf[2048]; // for getcwd
1292 char * currentDir = getcwd(buf, 2048);
1293 std::string cwd(currentDir);
1297 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1298 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1300 fullPathScriptName = tfullPathScriptName;
1301 if ( ! Utilities::FileExists(fullPathScriptName) )
1303 // The following is *NOT* a debug time message :
1304 // It's a user intended message.
1305 // Please don't remove it.
1306 bbtkMessage("Interpreter",2,
1307 " [" <<fullPathScriptName <<"] : does not exist"
1309 continue; // try next path
1311 bbtkMessage("Interpreter",2,
1312 " [" <<fullPathScriptName
1313 <<"] : found" <<std::endl);
1315 break; // a script was found; we stop iterating
1319 fullPathScriptName = tfullPathScriptName + ".bbs";
1320 // Check if library exists
1321 if ( ! Utilities::FileExists(fullPathScriptName) )
1323 fullPathScriptName = tfullPathScriptName + ".bbp";
1324 if ( ! Utilities::FileExists(fullPathScriptName) )
1326 // The following is *NOT* a debug time message :
1327 // It's a user intended message.
1328 // Please don't remove it.
1329 bbtkMessage("Interpreter",2,
1330 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1332 continue; // try next path
1335 bbtkMessage("Interpreter",2,
1336 " [" <<fullPathScriptName
1337 <<"] : found" <<std::endl);
1339 break; // a script was found; we stop iterating
1341 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1347 if(fullPathScriptName == "")
1348 bbtkError("Path ["<<upath<<"] doesn't exist");
1350 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1352 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1357 LoadScript(fullPathScriptName,name);
1358 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1363 //=======================================================================
1366 //=======================================================================
1367 void Interpreter::SwitchToStream( std::stringstream* stream )
1369 mFile.push_back(stream);
1370 std::ostringstream buffer_name;
1372 buffer_name << "buffer_" ;
1374 if (mFileName.size()>0 )
1376 buffer_name << mFileName.back() << "_" << mLine.back();
1378 mFileName.push_back(buffer_name.str());
1379 mIncludeFileName.push_back(buffer_name.str());
1382 //=======================================================================
1384 //=======================================================================
1386 void Interpreter::LoadScript( std::string fullPathScriptName,
1387 std::string includeScriptName)
1389 Utilities::replace( fullPathScriptName ,
1390 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1392 if (find(mFileNameHistory.begin(),
1393 mFileNameHistory.end(),
1394 fullPathScriptName)!=mFileNameHistory.end())
1400 s = new std::ifstream;
1401 s->open(fullPathScriptName.c_str());
1404 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1408 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1409 << "] found" << std::endl);
1412 mFileName.push_back(fullPathScriptName);
1413 mFileNameHistory.push_back(fullPathScriptName);
1414 mIncludeFileName.push_back(includeScriptName);
1420 //=======================================================================
1424 void Interpreter::CloseCurrentFile()
1426 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1429 if (mFile.size()==0)
1431 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1435 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1437 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1438 if (file!=0) file->close();
1440 delete mFile.back();
1442 mFileName.pop_back();
1443 mIncludeFileName.pop_back();
1446 bbtkDebugMessage("Interpreter",9," Remains "
1448 <<" open"<<std::endl);
1449 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1452 //=======================================================================
1454 //=======================================================================
1458 void Interpreter::CloseAllFiles()
1460 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1463 while (mFile.size() != 0)
1467 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1470 //=======================================================================
1474 //=======================================================================
1478 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1479 CommandInfoType& info )
1481 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1483 // searches the command keyword
1484 CommandDictType::iterator c;
1485 c = mCommandDict.find(words[0]);
1486 if ( c == mCommandDict.end() ) {
1487 bbtkError(words[0]<<" : unknown command");
1490 // tests the number of args
1491 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1492 ( ((int)words.size())-1 > c->second.argmax ) )
1494 HelpCommand(words[0]);
1495 bbtkError(words[0]<<" : wrong number of arguments");
1499 bbtkDecTab("Interpreter",9);
1501 //=======================================================================
1504 //=======================================================================
1505 /// Displays help on all the commands
1506 void Interpreter::Help(const std::vector<std::string>& words)
1508 unsigned int nbarg = words.size()-1;
1516 if (words[1]=="packages")
1518 GetExecuter()->GetFactory()->PrintPackages(true);
1523 HelpCommand(words[1]);
1525 catch (bbtk::Exception e)
1529 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1533 ConfigurationFile::GetInstance().Get_doc_path();
1534 url += "/bbdoc/" + words[1] + "/index.html";
1535 if (Utilities::FileExists(url))
1537 mUser->InterpreterUserViewHtmlPage(url);
1541 catch (bbtk::Exception f)
1545 std::string package;
1546 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1550 ConfigurationFile::GetInstance().Get_doc_path();
1551 url += "/bbdoc/" + package + "/index.html";
1552 if (Utilities::FileExists(url))
1554 url += "#" + words[1];
1555 mUser->InterpreterUserViewHtmlPage(url);
1559 catch (bbtk::Exception g)
1563 GetExecuter()->ShowRelations(words[1],"0","9999");
1565 catch (bbtk::Exception h){
1566 bbtkError("\""<<words[1].c_str()
1567 <<"\" is not a known command, package, black box type or black box name");
1575 if (words[2]=="all")
1577 if ( words[1]=="packages" )
1579 GetExecuter()->GetFactory()->PrintPackages(true,true);
1584 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1586 catch (bbtk::Exception f)
1592 HelpCommand(words[0]);
1593 bbtkError(words[0]<<" : syntax error");
1598 bbtkError("Should not reach here !!!");
1601 //=======================================================================
1603 //===================================================================
1604 /// Displays the Configuration
1605 void Interpreter::Config() const
1607 ConfigurationFile::GetInstance().GetHelp(1);
1609 //===================================================================
1611 //=======================================================================
1612 /// Displays help on all the commands
1613 void Interpreter::HelpCommands()
1615 std::cout << "Available commands :" << std::endl;
1616 CommandDictType::iterator i;
1617 for ( i = mCommandDict.begin();
1618 i != mCommandDict.end();
1620 std::cout << " " << i->first << std::endl;
1621 // std::cout << " usage : " << i->second.syntax << std::endl;
1622 // std::cout << " " << i->second.help << std::endl;
1626 //=======================================================================
1629 //=======================================================================
1630 /// Displays help on a particular commands
1631 void Interpreter::HelpCommand(const std::string& s)
1633 CommandDictType::iterator c;
1634 c = mCommandDict.find(s);
1635 if ( c == mCommandDict.end() ) {
1636 bbtkError(s<<" : Unknown command");
1638 // std::cout << " " << s << " : "<< std::endl;
1639 // CommandParamDictType::iterator i;
1640 // for ( i = c->second.begin();
1641 // i != c->second.end();
1643 std::cout << " usage : " << c->second.syntax << std::endl;
1644 std::cout << " " << c->second.help << std::endl;
1647 //=======================================================================
1650 //=======================================================================
1651 /// Fills the vector commands with the commands which
1652 /// have the first n chars of buf for prefix
1653 /// TODO : skip initial spaces in buf and also return the position of first
1654 /// non blank char in buf
1655 void Interpreter::FindCommandsWithPrefix( char* buf,
1657 std::vector<std::string>& commands )
1659 CommandDictType::const_iterator i;
1660 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1662 if ((i->first).find(buf,0,n) == 0)
1663 commands.push_back(i->first);
1666 //=======================================================================
1670 //=======================================================================
1671 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1673 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1674 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1676 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1677 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1678 // E.G. STORE THIS IN bbtk_config.xml
1679 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1680 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1681 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1682 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1683 #define BBTK_BACKSPACE_KBCODE 0x00000008
1684 #define BBTK_DEL_KBCODE 0x0000007F
1685 #define BBTK_SPACE_KBCODE 0x00000020
1687 //=======================================================================
1688 void Interpreter::GetLineFromPrompt(std::string& s)
1693 unsigned int MAX_LINE_SIZE = 160;
1694 unsigned int MAX_HISTORY_SIZE = 100;
1696 char* newline = new char[MAX_LINE_SIZE];
1697 memset(newline,0,MAX_LINE_SIZE);
1698 char* histline = new char[MAX_LINE_SIZE];
1699 memset(histline,0,MAX_LINE_SIZE);
1701 char* line = newline;
1702 unsigned int hist = mHistory.size();
1708 read ( STDIN_FILENO, &c, 4) ;
1710 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1712 // Printable character
1713 if ( (ind<MAX_LINE_SIZE-1) &&
1714 ( c >= BBTK_SPACE_KBCODE ) &&
1715 ( c < BBTK_DEL_KBCODE ))
1723 // delete the unused line
1729 // empty lines are not stored in from history
1732 // if history too long : delete oldest command
1733 if (mHistory.size()>MAX_HISTORY_SIZE)
1735 delete mHistory.front();
1736 mHistory.pop_front();
1738 mHistory.push_back(line);
1743 else if ( (ind>0) &&
1744 ((c == BBTK_BACKSPACE_KBCODE) ||
1745 (c == BBTK_DEL_KBCODE)) )
1753 // TODO : Command completion
1754 std::vector<std::string> commands;
1755 FindCommandsWithPrefix( line,ind,commands);
1756 if (commands.size()==1)
1758 std::string com = *commands.begin();
1759 for (; ind<com.size(); ++ind)
1761 PrintChar(com[ind]);
1767 else if (commands.size()>1)
1769 std::vector<std::string>::iterator i;
1771 for (i=commands.begin();i!=commands.end();++i)
1773 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1776 write(STDOUT_FILENO,"\n> ",3);
1777 //for (int j=0;j<ind;++j)
1779 write(STDOUT_FILENO,line,ind);
1783 // Arrow up : back in history
1784 else if (c==BBTK_UP_ARROW_KBCODE)
1788 // erase current line
1789 while (ind--) BackSpace();
1793 strcpy(histline,mHistory[hist]);
1797 write(STDOUT_FILENO,line,ind);
1800 // Arrow down : down in history
1801 else if (c==BBTK_DOWN_ARROW_KBCODE)
1803 if (hist<mHistory.size()-1)
1805 // erase current line
1806 while (ind--) BackSpace();
1810 strcpy(histline,mHistory[hist]);
1814 write(STDOUT_FILENO,line,ind);
1816 // end of history : switch back to newline
1817 else if (hist==mHistory.size()-1)
1819 // erase current line
1820 while (ind--) BackSpace();
1827 write(STDOUT_FILENO,line,ind);
1831 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1833 PrintChar(line[ind]);
1838 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1846 write(STDOUT_FILENO,"\n\r",2);
1854 //=======================================================================
1855 void Interpreter::GetLineFromPrompt(std::string& s)
1881 //=======================================================================
1887 //=======================================================================
1888 void Interpreter::CommandLineInterpreter()
1890 bbtkDebugMessageInc("Interpreter",9,
1891 "Interpreter::CommandLineInterpreter()"<<std::endl);
1893 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1894 // Initialise the tty in non canonical mode with no echo
1895 // oter remembers the previous settings to restore them after
1896 struct termios ter,oter;
1899 ter.c_lflag &= ~ECHO;
1900 ter.c_lflag &= ~ICANON;
1903 tcsetattr(0,TCSANOW,&ter);
1906 mCommandLine = true;
1908 bool insideComment = false; // for multiline comment
1914 GetLineFromPrompt(line);
1915 InterpretLine(line, insideComment);
1917 catch (QuitException e)
1919 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1922 catch (bbtk::Exception e)
1926 catch (std::exception& e)
1928 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1932 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1937 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1938 tcsetattr(0,TCSANOW,&oter);
1941 std::cout << "Good bye !" << std::endl;
1943 bbtkDebugDecTab("Interpreter",9);
1946 //=======================================================================
1947 void Interpreter::Graph(const std::vector<std::string>& words)
1950 bool system_display = true;
1952 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1953 system_display = false;
1955 if (words.size()==1)
1957 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1959 else if (words.size()==2)
1961 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1963 else if (words.size()==3)
1965 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1967 else if (words.size()==4)
1969 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1971 else if (words.size()==5)
1973 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1975 else if (words.size()==6)
1977 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1979 else if (words.size()==7)
1981 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1984 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1985 mUser->InterpreterUserViewHtmlPage(page);
1988 //=======================================================================
1991 //=======================================================================
1992 void Interpreter::Index(const std::string& filename,
1993 const std::string& type)
1995 Factory::IndexEntryType t;
1996 if (type=="Initials") t = Factory::Initials;
1997 else if (type=="Categories") t = Factory::Categories;
1998 else if (type=="Packages") t = Factory::Packages;
1999 else if (type=="Adaptors") t = Factory::Adaptors;
2001 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
2003 //=======================================================================
2006 //=======================================================================
2007 void Interpreter::NewGUI(const std::string& boxname,
2008 const std::string& instanceName)
2010 if (mRealExecuter.expired())
2012 bbtkError("command 'newgui' cannot be compiled yet");
2015 std::string typeName = instanceName+"Type";
2016 std::stringstream* s = new std::stringstream;
2017 // create the complex box
2018 (*s) << "define "<<typeName<<std::endl;
2019 // (*s) << " description 'Automatically generated user interface for the box "
2020 // << boxname << "'" <<std::endl;
2021 // create the Layout box
2022 (*s) << " load wx"<<std::endl;
2023 (*s) << " new LayoutLine layout"<<std::endl;
2024 // create the output 'Widget'
2025 (*s) << " output Widget layout.Widget Widget"<<std::endl;
2026 // the box change output
2027 (*s) << " new MultipleInputs change"<<std::endl;
2028 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
2030 // Browse the inputs of the box in order to find which ones are not
2031 // connected and can be adapted from a widget adaptor
2032 // vector which stores the list of inputs of the box which must be connected
2033 std::vector<std::string> in;
2035 Factory::Pointer F = mVirtualExecuter->GetFactory();
2037 Package::Pointer user = F->GetPackage("user");
2039 ComplexBlackBoxDescriptor::Pointer workspace =
2040 mRealExecuter.lock()->GetCurrentDescriptor();
2045 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2050 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2053 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2054 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2056 BlackBox::InputConnectorMapType::iterator i;
2057 for (i=box->bbGetInputConnectorMap().begin();
2058 i!=box->bbGetInputConnectorMap().end();
2061 // If the input is connected : continue
2062 if (i->second->IsConnected()) continue;
2063 // Get the input descriptor
2064 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2065 // If it is a "system" input : skip it
2066 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2067 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2070 std::string widget,adaptor;
2071 // try to find a widget adaptor
2072 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2076 // command to create the adaptor
2077 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2078 // Sets the label of the widget adaptor to the name of the input
2079 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2080 // Sets the initial value of the widget to the value of the input
2081 (*s) << " set "<<i->first<<".In \" "
2082 <<box->bbGetInputAsString(i->first)<<"\""
2084 // store the input name
2085 in.push_back(i->first);
2086 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2087 //<i->first<<"'"<<std::endl;
2088 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2090 // try to find a two pieces adaptor
2091 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2095 // command to create the widget
2096 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2097 // command to create the adaptor
2098 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2100 (*s) << " connect "<<i->first<<"Widget.Out "
2101 <<i->first<<".In"<<std::endl;
2102 // Sets the label of the widget adaptor to the name of the input
2103 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2104 // Sets the initial value of the widget to the value of the input
2105 (*s) << " set "<<i->first<<"Widget.In \" "
2106 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2107 // store the input name
2108 in.push_back(i->first);
2109 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2110 //<i->first<<"'"<<std::endl;
2111 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2114 // try to find an adaptor from string
2115 // If found then can create a text input which
2116 // will be automatically adapted
2117 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2121 // command to create the adaptor
2122 (*s) << " new InputText "<<i->first<<std::endl;
2123 // Sets the label of the widget adaptor to the name of the input
2124 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2125 // Sets the initial value of the widget to the value of the input
2126 (*s) << " set "<<i->first<<".In \" "
2127 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2128 // store the input name
2129 in.push_back(i->first);
2130 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2131 //<i->first<<"'"<<std::endl;
2132 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2141 // command to create the output
2142 (*s) << " output "<<i->first<<" "
2143 <<i->first<<".Out "<<i->first<<std::endl;
2144 // <<" Output of the widget which allows to set "
2148 // Inputs for window properties
2149 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2150 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2151 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2152 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2153 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2157 // Execute the box executes the layout
2158 (*s) << " exec layout" << std::endl;
2159 (*s) << "endefine" << std::endl;
2160 // (*s) << "help "<< typeName<< std::endl;
2161 // instanciate the box and connect it
2162 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2164 std::vector<std::string>::iterator j;
2165 for (j=in.begin();j!=in.end();++j)
2168 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2169 << boxname<<"."<<*j<<std::endl;
2171 // That's all folks ! now execute the commands :
2174 //=======================================================================
2178 //==========================================================================
2179 void Interpreter::Debug(const std::string& name)
2181 if ((name.length()==2)&&(name[0]=='-'))
2185 bbtk::StaticInitTime::PrintObjectListInfo = true;
2189 // int o = MessageManager::GetMessageLevel("debug");
2190 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2191 mVirtualExecuter->GetFactory()->CheckPackages();
2192 // MessageManager::SetMessageLevel("debug",o);
2197 Object:: PrintObjectListInfo(name);
2200 //==========================================================================
2201 //==========================================================================
2202 std::string Interpreter::GetObjectName() const
2204 return std::string("Interpreter");
2206 //==========================================================================
2208 //==========================================================================
2209 std::string Interpreter::GetObjectInfo() const
2211 std::stringstream i;
2214 //==========================================================================
2216 //==========================================================================
2217 size_t Interpreter::GetObjectSize() const
2219 size_t s = Superclass::GetObjectSize();
2220 s += Interpreter::GetObjectInternalSize();
2223 //==========================================================================
2224 //==========================================================================
2225 size_t Interpreter::GetObjectInternalSize() const
2227 size_t s = sizeof(Interpreter);
2230 //==========================================================================
2231 //==========================================================================
2232 size_t Interpreter::GetObjectRecursiveSize() const
2234 size_t s = Superclass::GetObjectRecursiveSize();
2235 s += Interpreter::GetObjectInternalSize();
2236 s += mVirtualExecuter->GetObjectRecursiveSize();
2239 //==========================================================================