1 /*=========================================================================
4 Module: $RCSfile: bbtkInterpreter.cxx,v $ $
6 Date: $Date: 2008/10/08 13:39:33 $
7 Version: $Revision: 1.75 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
20 * \brief class Interpreter :
23 #include "bbtkInterpreter.h"
24 #include "bbtkExecuter.h"
25 #include "bbtkTranscriptor.h"
26 #include "bbtkMessageManager.h"
27 #include "bbtkConfigurationFile.h"
28 #include "bbtkUtilities.h"
29 #include "bbtkWxBlackBox.h"
32 #ifdef CMAKE_HAVE_TERMIOS_H
34 #define BBTK_USE_TERMIOS_BASED_PROMPT
42 //=======================================================================
43 Interpreter::Pointer Interpreter::New(const std::string& cpp_file)
45 bbtkDebugMessage("Kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
46 return MakePointer(new Interpreter(cpp_file));
48 //=======================================================================
50 //=======================================================================
51 Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e)
53 bbtkDebugMessage("Kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
54 return MakePointer(new Interpreter(e));
56 //=======================================================================
58 //=======================================================================
59 Interpreter::Interpreter(const std::string& cpp_file)
61 Init(VirtualExec::Pointer(), cpp_file);
63 //=======================================================================
65 //=======================================================================
66 Interpreter::Interpreter(VirtualExec::Pointer e)
70 //=======================================================================
72 //=======================================================================
73 void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file)
79 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);
80 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
81 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
86 else if (cpp_file.size()!=0)
88 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
92 bbtk::Executer::Pointer exe = bbtk::Executer::New();
94 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
97 // Lock this pointer or will auto-destruct !!
98 if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
100 // For the time being, comment out previous line, and
101 // uncomment next line to check Transcriptor
103 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
105 // Builds the commands dict
106 CommandInfoType info;
108 info.keyword = "new";
112 info.syntax = "new <type> <name>";
113 info.help = "Creates a new black box of type <type> with name <name>";
114 mCommandDict[info.keyword] = info;
116 info.keyword = "delete";
120 info.syntax = "delete <box>";
121 info.help = "Deletes the black box of name <box>";
122 mCommandDict[info.keyword] = info;
124 info.keyword = "newgui";
128 info.syntax = "newgui <box> <name>";
129 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
130 mCommandDict[info.keyword] = info;
132 info.keyword = "connect";
135 info.code = cConnect;
136 info.syntax = "connect <box1.output> <box2.input>";
137 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
138 mCommandDict[info.keyword] = info;
140 info.keyword = "print";
144 info.syntax = "print <string>";
145 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').";
146 mCommandDict[info.keyword] = info;
148 info.keyword = "exec";
152 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
153 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.";
154 mCommandDict[info.keyword] = info;
156 info.keyword = "package";
159 info.code = cPackage;
160 info.syntax = "package <name>";
161 info.help = "Begins the definition of a package.";
162 mCommandDict[info.keyword] = info;
164 info.keyword = "endpackage";
167 info.code = cEndPackage;
168 info.syntax = "endpackage";
169 info.help = "Ends the definition of a package.";
170 mCommandDict[info.keyword] = info;
172 info.keyword = "define";
176 info.syntax = "define <type> [<package>]";
177 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.";
178 mCommandDict[info.keyword] = info;
180 info.keyword = "endefine";
183 info.code = cEndDefine;
184 info.syntax = "endefine";
185 info.help = "Ends the definition of a new type of complex black box";
186 mCommandDict[info.keyword] = info;
188 info.keyword = "kind";
192 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
193 info.help = "Sets the kind of the currently defined complex black box";
194 mCommandDict[info.keyword] = info;
196 info.keyword = "input";
200 info.syntax = "input <name> <box.input> <help>";
201 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";
202 mCommandDict[info.keyword] = info;
204 info.keyword = "output";
208 info.syntax = "output <name> <box.output> <help>";
209 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";
210 mCommandDict[info.keyword] = info;
212 info.keyword = "set";
216 info.syntax = "set <box.input> <value>";
217 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";
218 mCommandDict[info.keyword] = info;
220 info.keyword = "config"; // JPR
224 info.syntax = "config";
225 info.help = "Prints the value of all configuration parameters";
226 mCommandDict[info.keyword] = info;
228 info.keyword = "index"; // LG
233 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
234 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.";
235 mCommandDict[info.keyword] = info;
237 info.keyword = "reset";
241 info.syntax = "reset";
242 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
243 mCommandDict[info.keyword] = info;
245 info.keyword = "author";
249 info.syntax = "author <string>";
250 info.help = "Adds the string <string> to the author information of the black box being defined";
251 mCommandDict[info.keyword] = info;
253 info.keyword = "category"; //JP
256 info.code = cCategory;
257 info.syntax = "category <list of items, separated by ;>";
258 info.help = "Adds the string <string> to the category information of the black box being defined";
259 mCommandDict[info.keyword] = info;
261 info.keyword = "description";
264 info.code = cDescription;
265 info.syntax = "description <string>";
266 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
267 mCommandDict[info.keyword] = info;
269 info.keyword = "help";
273 info.syntax = "help";
274 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>";
275 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.";
276 mCommandDict[info.keyword] = info;
278 info.keyword = "message";
281 info.code = cMessage;
282 info.syntax = "message <kind> <level>";
283 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.";
284 mCommandDict[info.keyword] = info;
286 info.keyword = "include";
289 info.code = cInclude;
290 info.syntax = "include <filename> [source]";
291 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).";
292 mCommandDict[info.keyword] = info;
294 info.keyword = "quit";
298 info.syntax = "quit";
299 info.help = "Quits the program (during script execution it stops the complete execution)";
300 mCommandDict[info.keyword] = info;
302 info.keyword = "load";
306 info.syntax = "load <packagename>";
307 info.help = "Loads the black box package <packagename>";
308 mCommandDict[info.keyword] = info;
310 info.keyword = "unload";
314 info.syntax = "unload <packagename>";
315 info.help = "Unloads the black box package <packagename>";
316 mCommandDict[info.keyword] = info;
318 info.keyword = "graph";
322 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 ]]]]]]";
323 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')";
324 mCommandDict[info.keyword] = info;
326 info.keyword = "debug";
330 info.syntax = "debug [expr|-C|-D]";
331 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";
332 mCommandDict[info.keyword] = info;
335 info.keyword = "workspace";
338 info.code = cWorkspace;
339 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
340 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.";
341 mCommandDict[info.keyword] = info;
344 bbtkDebugDecTab("Interpreter",9);
347 //=======================================================================
351 //=======================================================================
355 Interpreter::~Interpreter()
357 bbtkDebugMessageInc("Interpreter",9,"==> Interpreter::~Interpreter()" <<std::endl);
358 mVirtualExecuter = VirtualExec::Pointer();
359 bbtkDebugMessageInc("Interpreter",9,"<== Interpreter::~Interpreter()" <<std::endl);
361 //=======================================================================
364 InterpreterError::InterpreterError( const std::string& message,
366 const std::string& script_file,
369 : Exception("Interpreter",0,message),
370 mInScriptFile(in_script_file),
371 mScriptFile(script_file),
372 mScriptLine(script_line)
375 InterpreterError::InterpreterError( const Exception& excep,
377 const std::string& script_file,
381 mInScriptFile(in_script_file),
382 mScriptFile(script_file),
383 mScriptLine(script_line)
386 //=======================================================================
387 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
391 bool in_script = false;
392 std::string file("");
394 if (mFileName.size()) {
395 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
396 if (fs!=0) in_script = true;
397 file = mFileName.back();
401 throw InterpreterError(e,in_script,file,line);
405 std::stringstream mess;
406 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
407 if (mFileName.size()) {
408 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
409 mess << "* LINE : "<<mLine.back()<<std::endl;
411 std::cerr << mess.str();
414 //=======================================================================
416 //=======================================================================
417 void Interpreter::CatchStdException( const std::exception& e )
421 bool in_script = false;
422 std::string file("");
424 if (mFileName.size()) {
425 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
426 if (fs!=0) in_script = true;
427 file = mFileName.back();
431 throw InterpreterError(e.what(),in_script,file,line);
435 std::stringstream mess;
436 mess << "* ERROR : "<<e.what()<<std::endl;
437 if (mFileName.size()) {
438 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
439 mess << "* LINE : "<<mLine.back()<<std::endl;
441 std::cerr << mess.str();
444 //=======================================================================
446 //=======================================================================
447 void Interpreter::CatchUnknownException()
451 bool in_script = false;
452 std::string file("");
454 if (mFileName.size()) {
455 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
456 if (fs!=0) in_script = true;
457 file = mFileName.back();
461 throw InterpreterError("Unknown exception caught",
462 in_script,file,line);
466 std::stringstream mess;
467 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
469 if (mFileName.size()) {
470 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
471 mess << "* LINE : "<<mLine.back()<<std::endl;
473 std::cerr << mess.str();
476 //=======================================================================
478 //=======================================================================
480 #define CATCH_MACRO \
481 catch (QuitException e) \
483 status = Interpreter_QUIT; \
484 if (mThrow) throw QuitException(); \
486 catch (bbtk::Exception e) \
488 status = Interpreter_ERROR; \
489 CatchBbtkException(e); \
491 catch (std::exception& e) \
493 status = Interpreter_ERROR; \
494 CatchStdException(e); \
498 status = Interpreter_ERROR; \
499 CatchUnknownException(); \
501 //=======================================================================
504 //=======================================================================
508 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
510 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
512 bool exm = mCommandLine;
513 mCommandLine = false;
515 ExitStatus status = Interpreter_OK;
519 SwitchToFile(filename,source);
521 bool insideComment = false; // for multiline comment
522 while (mFile.size()>0)
524 while (!mFile.back()->eof()) {
527 mFile.back()->getline(buf,500);
528 std::string str(buf);
529 int size=str.length();
530 if ( str[ size-1 ]==13 )
536 InterpretLine(str, insideComment);
547 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
548 bbtkDecTab("Interpreter",9);
554 //=======================================================================
557 //=======================================================================
561 Interpreter::ExitStatus
562 Interpreter::InterpretBuffer( std::stringstream* buffer )
564 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
566 bool exm = mCommandLine;
567 mCommandLine = false;
569 ExitStatus status = Interpreter_OK;
573 SwitchToStream(buffer);
574 bool insideComment = false; // for multiline comment
575 while (mFile.size()>0)
577 while (!mFile.back()->eof()) {
580 mFile.back()->getline(buf,500);
581 std::string str(buf);
583 int size=str.length();
584 if ( str[ size-1 ]==13 )
590 InterpretLine(str, insideComment);
600 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
601 bbtkDecTab("Interpreter",9);
606 //=======================================================================
608 //=======================================================================
609 /// Runs the interpretation of a command
610 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
612 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
614 ExitStatus status = Interpreter_OK;
618 bool insideComment = false;
619 InterpretLine(line, insideComment);
624 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
626 bbtkDecTab("Interpreter",9);
632 //=======================================================================
636 void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
638 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
639 bbtkMessage("echo",2,line<<std::endl);
641 std::vector<std::string> words;
642 SplitLine(line,words);
647 bbtkDebugDecTab("Interpreter",9);
651 // Single line comment : # or //
652 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
654 bbtkDebugDecTab("Interpreter",9);
655 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
659 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
661 if (words[0][0]=='/' && words[0][1]=='*')
663 bbtkDebugDecTab("Interpreter",9);
664 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
665 insideComment = true;
669 if (words[0][0]=='*' && words[0][1]=='/')
671 bbtkDebugDecTab("Interpreter",9);
672 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
673 if ( !insideComment ) {
674 bbtkDebugDecTab("Interpreter",9);
675 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
677 insideComment = false;
683 bbtkDebugDecTab("Interpreter",9);
684 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
689 CommandInfoType command;
690 InterpretCommand(words,command);
692 bbtkDebugMessage("Interpreter",9,
693 "Command='"<<command.keyword
694 <<"' code="<<command.code<<std::endl);
696 std::string left,right,left2,right2;
697 std::string filename;
698 switch (command.code)
701 mVirtualExecuter->Create(words[1],words[2]);
705 mVirtualExecuter->Destroy(words[1]);
709 Utilities::SplitAroundFirstDot(words[1],left,right);
710 Utilities::SplitAroundFirstDot(words[2],left2,right2);
711 mVirtualExecuter->Connect(left,right,left2,right2);
715 mVirtualExecuter->BeginPackage(words[1]);
719 mVirtualExecuter->EndPackage();
723 if (mFileName.size()>0)
725 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
729 mVirtualExecuter->Define(words[1],"",filename);
733 mVirtualExecuter->Define(words[1],words[2],filename);
738 mVirtualExecuter->EndDefine();
742 mVirtualExecuter->Kind(words[1]);
746 mVirtualExecuter->Print(words[1]);
750 if (words[1]=="freeze")
752 mVirtualExecuter->SetNoExecMode(true);
755 else if (words[1]=="freeze_no_error ")
757 mVirtualExecuter->SetNoExecMode(true);
758 mVirtualExecuter->SetNoErrorMode(true);
761 else if (words[1]=="unfreeze")
763 mVirtualExecuter->SetNoExecMode(false);
764 mVirtualExecuter->SetNoErrorMode(false);
768 mVirtualExecuter->Execute(words[1]);
773 Utilities::SplitAroundFirstDot(words[2],left,right);
774 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
778 Utilities::SplitAroundFirstDot(words[2],left,right);
779 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
783 Utilities::SplitAroundFirstDot(words[1],left,right);
784 mVirtualExecuter->Set(left,right,words[2]);
788 mVirtualExecuter->Author(words[1]);
792 NewGUI(words[1],words[2]);
796 mVirtualExecuter->Category(words[1]);
801 Index("tmp_index.html");
802 else if (words.size()==2)
804 else if (words.size()==3)
805 Index(words[1],words[2]);
809 mVirtualExecuter->Description(words[1]);
819 mVirtualExecuter->HelpMessages();
823 sscanf(words[2].c_str(),"%d",&level);
824 mVirtualExecuter->SetMessageLevel(words[1],level);
841 // if 'source' was given (words.size()==3) then tell to set the
842 // source file name of the current complex box with the full file name included
845 InterpretFile(words[1],(words.size()==3));
849 SwitchToFile(words[1],(words.size()==3) );
854 GetExecuter()->LoadPackage(words[1]);
858 GetExecuter()->UnLoadPackage(words[1]);
862 throw QuitException();
866 if (words.size()==2) Debug(words[1]);
871 if (words.size() == 2)
873 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
874 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
878 mVirtualExecuter->SetWorkspaceName(words[2]);
883 bbtkInternalError("should not reach here !!!");
886 bbtkDecTab("Interpreter",9);
888 //=======================================================================
894 //=======================================================================
898 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
900 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
902 std::string delimiters = "\"";
903 std::vector<std::string> quote;
904 Utilities::SplitString(str,delimiters,quote);
907 std::vector<std::string>::iterator i;
908 for (i=quote.begin(); i!=quote.end(); )
910 Utilities::SplitString(*i,delimiters,tokens);
914 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
915 tokens.push_back(*i);
920 for (i=tokens.begin(); i!=tokens.end(); ++i)
922 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
924 bbtkDebugMessageCont("Interpreter",9,std::endl);
926 bbtkDebugDecTab("Interpreter",9);
928 //=======================================================================
931 //=======================================================================
932 void Interpreter::Reset()
934 // Cannot close all files if the reset command is read from a file !
936 mFileNameHistory.clear();
937 this->mVirtualExecuter->Reset();
939 //=======================================================================
941 //=======================================================================
946 void Interpreter::Print( const std::string& str)
948 if (mVirtualExecuter->GetNoExecMode()) return;
950 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
953 // InterpretLine ("load std")
954 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
955 // InterpretLine("new Print _P_")
956 // InterpretLine("connect _C_.Out _P_.In")
960 std::vector<std::string> chains;
961 std::string delimiters("$");
963 // Skip delimiters at beginning.
964 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
966 if (lastPos>0) is_text = false;
968 // Find first delimiter.
969 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
971 while (std::string::npos != pos || std::string::npos != lastPos)
975 // Found a text token, add it to the vector.
976 chains.push_back(str.substr(lastPos, pos - lastPos));
977 // std::string token = str.substr(lastPos, pos - lastPos)
978 // InterpretLine("set _C_.In%num% %token%")
984 // is an output (between $$) : decode
985 std::string tok,box,output;
986 tok = str.substr(lastPos, pos - lastPos);
987 Utilities::SplitAroundFirstDot(tok,box,output);
988 chains.push_back( mVirtualExecuter->Get(box,output) );
990 // InterpretLine("connect %tok% _C_.In%num%")
993 // Skip delimiters. Note the "not_of"
994 lastPos = str.find_first_not_of(delimiters, pos);
995 // Find next delimiter
996 pos = str.find_first_of(delimiters, lastPos);
1001 // InterpretLine("exec _P_")
1002 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1004 std::vector<std::string>::iterator i;
1005 for (i= chains.begin(); i!=chains.end(); ++i)
1008 Utilities::SubsBackslashN(*i);
1011 std::cout << std::endl;
1012 bbtkDebugDecTab("Interpreter",9);
1016 //=======================================================================
1021 // =========================================================================
1022 void Interpreter::SwitchToFile( const std::string& name , bool source )
1024 // Note : in the following :
1025 // name : the user supplied name
1026 // - abreviated name e.g. scr scr.bbs
1027 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1028 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1029 // same for Windows, with c:, d: ...
1031 // use ./directory/subdir/scrname.bbs
1034 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1035 <<name<<"\")"<<std::endl);
1037 std::vector<std::string> script_paths;
1038 std::string fullPathScriptName; // full path script name
1039 std::string pkgname; // e.g. <scriptname>.bbs
1040 std::vector<std::string> Filenames;
1042 // The following is *NOT* a debug time message :
1043 // It's a user intended message.
1044 // Please don't remove it.
1045 bbtkMessage("Interpreter",1,
1046 "look for : [" << name
1047 << "]" << std::endl);
1051 pkgname = Utilities::ExtractScriptName(name,upath);
1053 bbtkMessage("Interpreter",3,
1054 "extract : pkgname [" << pkgname
1055 << "] upath [" << upath << "]" << std::endl);
1056 bool fullnameGiven = false;
1057 bool foundFile = false;
1059 // ==== "*" provided : load all scripts in given path
1060 // relative (e.g. std/boxes/*) or absolute
1065 std::stringstream* stream = new std::stringstream;
1066 //if (upath.size()!=0) // avoid troubles for "*"
1068 // ==== no path provided : look in root bbs path
1069 if (upath.size()==0)
1071 // bbtkMessage("Interpreter",1,
1072 // LG : add all bbs path
1073 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1074 std::vector<std::string>::const_iterator i;
1075 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1076 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1079 script_paths.push_back(*i);
1082 // ==== absolute path provided
1083 else if (upath[0]=='/' || upath[1] == ':' )
1085 if ( Utilities::IsDirectory( upath ) )
1087 script_paths.push_back(upath);
1091 bbtkError("'"<<upath<<"' : directory does not exist");
1094 // ==== relative path provided : search all bbs path appended with
1095 // the relative path provided
1098 std::vector<std::string>::const_iterator i;
1099 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1100 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1103 std::string full_path(*i);
1104 // we *really* want '.' to be the current working directory
1105 if (full_path == ".")
1107 char buf[2048]; // for getcwd
1108 char * currentDir = getcwd(buf, 2048);
1109 std::string cwd(currentDir);
1110 full_path = currentDir;
1113 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1116 if ( Utilities::IsDirectory( full_path ) )
1118 script_paths.push_back(full_path);
1121 if (script_paths.empty())
1123 bbtkError("no '"<<upath<<"' subdir found in search paths"
1129 // === search paths list complete : now explore it
1131 // ==== relative name, iterate + load all .bbs/.bbp files
1132 std::vector<std::string>::iterator i;
1133 for (i=script_paths.begin();i!=script_paths.end();i++)
1135 bbtkMessage("Interpreter",1,
1136 "--> Looking in '" << *i << "'" << std::endl);
1140 Utilities::Explore(*i, false, Filenames);
1143 for (std::vector<std::string>::iterator j = Filenames.begin();
1144 j!= Filenames.end(); ++j)
1146 int lgr = (*j).size();
1147 if (lgr < 5) continue;
1148 // ignore non .bbp file
1149 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1151 (*stream) << "include \"" << *j << "\"\n";
1152 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1155 } // for (std::vector...
1156 } // for (i=script_...
1159 bbtkMessage("Interpreter",1,
1160 " --> No .bbp found"<< std::endl);
1164 bbtkMessage("Interpreter",1,
1165 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1166 SwitchToStream(stream);
1170 //=============== end pkgname=="*" ===========
1173 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1174 // (not only a plain script name)
1175 // we trust him, and try to expland the directory name
1176 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1178 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1181 // ===========================================================check user supplied location
1182 fullnameGiven = true;
1184 fullPathScriptName = Utilities::ExpandLibName(name, false);
1186 // allow user to always forget ".bbs"
1187 int l = fullPathScriptName.size();
1191 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1192 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1194 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1195 if ( Utilities::FileExists(tfullPathScriptName) )
1197 fullPathScriptName = tfullPathScriptName;
1202 tfullPathScriptName = fullPathScriptName + ".bbp";
1203 if ( Utilities::FileExists(tfullPathScriptName) )
1205 fullPathScriptName = tfullPathScriptName;
1212 if ( Utilities::FileExists(fullPathScriptName) )
1220 // =============================== iterate on the paths
1222 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1224 std::vector<std::string>::iterator i;
1225 for (i=script_paths.begin();i!=script_paths.end();++i)
1228 // we *really* want '.' to be the current working directory
1231 char buf[2048]; // for getcwd
1232 char * currentDir = getcwd(buf, 2048);
1233 std::string cwd(currentDir);
1237 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1238 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1240 fullPathScriptName = tfullPathScriptName;
1241 if ( ! Utilities::FileExists(fullPathScriptName) )
1243 // The following is *NOT* a debug time message :
1244 // It's a user intended message.
1245 // Please don't remove it.
1246 bbtkMessage("Interpreter",2,
1247 " [" <<fullPathScriptName <<"] : does not exist"
1249 continue; // try next path
1251 bbtkMessage("Interpreter",2,
1252 " [" <<fullPathScriptName
1253 <<"] : found" <<std::endl);
1255 break; // a script was found; we stop iterating
1259 fullPathScriptName = tfullPathScriptName + ".bbs";
1260 // Check if library exists
1261 if ( ! Utilities::FileExists(fullPathScriptName) )
1263 fullPathScriptName = tfullPathScriptName + ".bbp";
1264 if ( ! Utilities::FileExists(fullPathScriptName) )
1266 // The following is *NOT* a debug time message :
1267 // It's a user intended message.
1268 // Please don't remove it.
1269 bbtkMessage("Interpreter",2,
1270 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1272 continue; // try next path
1275 bbtkMessage("Interpreter",2,
1276 " [" <<fullPathScriptName
1277 <<"] : found" <<std::endl);
1279 break; // a script was found; we stop iterating
1281 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1287 if(fullPathScriptName == "")
1288 bbtkError("Path ["<<upath<<"] doesn't exist");
1290 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1292 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1297 LoadScript(fullPathScriptName,name);
1298 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1303 //=======================================================================
1306 //=======================================================================
1307 void Interpreter::SwitchToStream( std::stringstream* stream )
1309 mFile.push_back(stream);
1310 std::ostringstream buffer_name;
1312 buffer_name << "buffer_" ;
1314 if (mFileName.size()>0 )
1316 buffer_name << mFileName.back() << "_" << mLine.back();
1318 mFileName.push_back(buffer_name.str());
1319 mIncludeFileName.push_back(buffer_name.str());
1322 //=======================================================================
1324 //=======================================================================
1326 void Interpreter::LoadScript( std::string fullPathScriptName,
1327 std::string includeScriptName)
1329 Utilities::replace( fullPathScriptName ,
1330 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1332 if (find(mFileNameHistory.begin(),
1333 mFileNameHistory.end(),
1334 fullPathScriptName)!=mFileNameHistory.end())
1340 s = new std::ifstream;
1341 s->open(fullPathScriptName.c_str());
1344 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1348 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1349 << "] found" << std::endl);
1352 mFileName.push_back(fullPathScriptName);
1353 mFileNameHistory.push_back(fullPathScriptName);
1354 mIncludeFileName.push_back(includeScriptName);
1360 //=======================================================================
1364 void Interpreter::CloseCurrentFile()
1366 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1369 if (mFile.size()==0)
1371 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1375 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1377 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1378 if (file!=0) file->close();
1380 delete mFile.back();
1382 mFileName.pop_back();
1383 mIncludeFileName.pop_back();
1386 bbtkDebugMessage("Interpreter",9," Remains "
1388 <<" open"<<std::endl);
1389 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1392 //=======================================================================
1394 //=======================================================================
1398 void Interpreter::CloseAllFiles()
1400 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1403 while (mFile.size() != 0)
1407 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1410 //=======================================================================
1414 //=======================================================================
1418 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1419 CommandInfoType& info )
1421 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1423 // searches the command keyword
1424 CommandDictType::iterator c;
1425 c = mCommandDict.find(words[0]);
1426 if ( c == mCommandDict.end() ) {
1427 bbtkError(words[0]<<" : unknown command");
1430 // tests the number of args
1431 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1432 ( ((int)words.size())-1 > c->second.argmax ) )
1434 HelpCommand(words[0]);
1435 bbtkError(words[0]<<" : wrong number of arguments");
1439 bbtkDecTab("Interpreter",9);
1441 //=======================================================================
1444 //=======================================================================
1445 /// Displays help on all the commands
1446 void Interpreter::Help(const std::vector<std::string>& words)
1448 unsigned int nbarg = words.size()-1;
1456 if (words[1]=="packages")
1458 GetExecuter()->GetFactory()->PrintPackages(true);
1463 HelpCommand(words[1]);
1465 catch (bbtk::Exception e)
1469 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1473 ConfigurationFile::GetInstance().Get_doc_path();
1474 url += "/bbdoc/" + words[1] + "/index.html";
1475 if (Utilities::FileExists(url))
1477 mUser->InterpreterUserViewHtmlPage(url);
1481 catch (bbtk::Exception f)
1485 std::string package;
1486 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1490 ConfigurationFile::GetInstance().Get_doc_path();
1491 url += "/bbdoc/" + package + "/index.html";
1492 if (Utilities::FileExists(url))
1494 url += "#" + words[1];
1495 mUser->InterpreterUserViewHtmlPage(url);
1499 catch (bbtk::Exception g)
1503 GetExecuter()->ShowRelations(words[1],"0","9999");
1505 catch (bbtk::Exception h){
1506 bbtkError("\""<<words[1].c_str()
1507 <<"\" is not a known command, package, black box type or black box name");
1515 if (words[2]=="all")
1517 if ( words[1]=="packages" )
1519 GetExecuter()->GetFactory()->PrintPackages(true,true);
1524 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1526 catch (bbtk::Exception f)
1532 HelpCommand(words[0]);
1533 bbtkError(words[0]<<" : syntax error");
1538 bbtkError("Should not reach here !!!");
1541 //=======================================================================
1543 //===================================================================
1544 /// Displays the Configuration
1545 void Interpreter::Config() const
1547 ConfigurationFile::GetInstance().GetHelp(1);
1549 //===================================================================
1551 //=======================================================================
1552 /// Displays help on all the commands
1553 void Interpreter::HelpCommands()
1555 std::cout << "Available commands :" << std::endl;
1556 CommandDictType::iterator i;
1557 for ( i = mCommandDict.begin();
1558 i != mCommandDict.end();
1560 std::cout << " " << i->first << std::endl;
1561 // std::cout << " usage : " << i->second.syntax << std::endl;
1562 // std::cout << " " << i->second.help << std::endl;
1566 //=======================================================================
1569 //=======================================================================
1570 /// Displays help on a particular commands
1571 void Interpreter::HelpCommand(const std::string& s)
1573 CommandDictType::iterator c;
1574 c = mCommandDict.find(s);
1575 if ( c == mCommandDict.end() ) {
1576 bbtkError(s<<" : Unknown command");
1578 // std::cout << " " << s << " : "<< std::endl;
1579 // CommandParamDictType::iterator i;
1580 // for ( i = c->second.begin();
1581 // i != c->second.end();
1583 std::cout << " usage : " << c->second.syntax << std::endl;
1584 std::cout << " " << c->second.help << std::endl;
1587 //=======================================================================
1590 //=======================================================================
1591 /// Fills the vector commands with the commands which
1592 /// have the first n chars of buf for prefix
1593 /// TODO : skip initial spaces in buf and also return the position of first
1594 /// non blank char in buf
1595 void Interpreter::FindCommandsWithPrefix( char* buf,
1597 std::vector<std::string>& commands )
1599 CommandDictType::const_iterator i;
1600 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1602 if ((i->first).find(buf,0,n) == 0)
1603 commands.push_back(i->first);
1606 //=======================================================================
1610 //=======================================================================
1611 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1613 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1614 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1616 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1617 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1618 // E.G. STORE THIS IN bbtk_config.xml
1619 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1620 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1621 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1622 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1623 #define BBTK_BACKSPACE_KBCODE 0x00000008
1624 #define BBTK_DEL_KBCODE 0x0000007F
1625 #define BBTK_SPACE_KBCODE 0x00000020
1627 //=======================================================================
1628 void Interpreter::GetLineFromPrompt(std::string& s)
1633 unsigned int MAX_LINE_SIZE = 160;
1634 unsigned int MAX_HISTORY_SIZE = 100;
1636 char* newline = new char[MAX_LINE_SIZE];
1637 memset(newline,0,MAX_LINE_SIZE);
1638 char* histline = new char[MAX_LINE_SIZE];
1639 memset(histline,0,MAX_LINE_SIZE);
1641 char* line = newline;
1642 unsigned int hist = mHistory.size();
1648 read ( STDIN_FILENO, &c, 4) ;
1650 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1652 // Printable character
1653 if ( (ind<MAX_LINE_SIZE-1) &&
1654 ( c >= BBTK_SPACE_KBCODE ) &&
1655 ( c < BBTK_DEL_KBCODE ))
1663 // delete the unused line
1669 // empty lines are not stored in from history
1672 // if history too long : delete oldest command
1673 if (mHistory.size()>MAX_HISTORY_SIZE)
1675 delete mHistory.front();
1676 mHistory.pop_front();
1678 mHistory.push_back(line);
1683 else if ( (ind>0) &&
1684 ((c == BBTK_BACKSPACE_KBCODE) ||
1685 (c == BBTK_DEL_KBCODE)) )
1693 // TODO : Command completion
1694 std::vector<std::string> commands;
1695 FindCommandsWithPrefix( line,ind,commands);
1696 if (commands.size()==1)
1698 std::string com = *commands.begin();
1699 for (; ind<com.size(); ++ind)
1701 PrintChar(com[ind]);
1707 else if (commands.size()>1)
1709 std::vector<std::string>::iterator i;
1711 for (i=commands.begin();i!=commands.end();++i)
1713 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1716 write(STDOUT_FILENO,"\n> ",3);
1717 //for (int j=0;j<ind;++j)
1719 write(STDOUT_FILENO,line,ind);
1723 // Arrow up : back in history
1724 else if (c==BBTK_UP_ARROW_KBCODE)
1728 // erase current line
1729 while (ind--) BackSpace();
1733 strcpy(histline,mHistory[hist]);
1737 write(STDOUT_FILENO,line,ind);
1740 // Arrow down : down in history
1741 else if (c==BBTK_DOWN_ARROW_KBCODE)
1743 if (hist<mHistory.size()-1)
1745 // erase current line
1746 while (ind--) BackSpace();
1750 strcpy(histline,mHistory[hist]);
1754 write(STDOUT_FILENO,line,ind);
1756 // end of history : switch back to newline
1757 else if (hist==mHistory.size()-1)
1759 // erase current line
1760 while (ind--) BackSpace();
1767 write(STDOUT_FILENO,line,ind);
1771 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1773 PrintChar(line[ind]);
1778 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1786 write(STDOUT_FILENO,"\n\r",2);
1794 //=======================================================================
1795 void Interpreter::GetLineFromPrompt(std::string& s)
1821 //=======================================================================
1827 //=======================================================================
1828 void Interpreter::CommandLineInterpreter()
1830 bbtkDebugMessageInc("Interpreter",9,
1831 "Interpreter::CommandLineInterpreter()"<<std::endl);
1833 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1834 // Initialise the tty in non canonical mode with no echo
1835 // oter remembers the previous settings to restore them after
1836 struct termios ter,oter;
1839 ter.c_lflag &= ~ECHO;
1840 ter.c_lflag &= ~ICANON;
1843 tcsetattr(0,TCSANOW,&ter);
1846 mCommandLine = true;
1848 bool insideComment = false; // for multiline comment
1854 GetLineFromPrompt(line);
1855 InterpretLine(line, insideComment);
1857 catch (QuitException e)
1859 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1862 catch (bbtk::Exception e)
1866 catch (std::exception& e)
1868 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1872 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1877 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1878 tcsetattr(0,TCSANOW,&oter);
1881 std::cout << "Good bye !" << std::endl;
1883 bbtkDebugDecTab("Interpreter",9);
1886 //=======================================================================
1887 void Interpreter::Graph(const std::vector<std::string>& words)
1890 bool system_display = true;
1892 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1893 system_display = false;
1895 if (words.size()==1)
1897 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1899 else if (words.size()==2)
1901 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1903 else if (words.size()==3)
1905 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1907 else if (words.size()==4)
1909 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1911 else if (words.size()==5)
1913 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1915 else if (words.size()==6)
1917 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1919 else if (words.size()==7)
1921 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1924 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1925 mUser->InterpreterUserViewHtmlPage(page);
1928 //=======================================================================
1931 //=======================================================================
1932 void Interpreter::Index(const std::string& filename,
1933 const std::string& type)
1935 Factory::IndexEntryType t;
1936 if (type=="Initials") t = Factory::Initials;
1937 else if (type=="Categories") t = Factory::Categories;
1938 else if (type=="Packages") t = Factory::Packages;
1939 else if (type=="Adaptors") t = Factory::Adaptors;
1941 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1943 //=======================================================================
1946 //=======================================================================
1947 void Interpreter::NewGUI(const std::string& boxname,
1948 const std::string& instanceName)
1950 if (mRealExecuter.expired())
1952 bbtkError("command 'newgui' cannot be compiled yet");
1955 std::string typeName = instanceName+"Type";
1956 std::stringstream* s = new std::stringstream;
1957 // create the complex box
1958 (*s) << "define "<<typeName<<std::endl;
1959 // (*s) << " description 'Automatically generated user interface for the box "
1960 // << boxname << "'" <<std::endl;
1961 // create the Layout box
1962 (*s) << " load wx"<<std::endl;
1963 (*s) << " new LayoutLine layout"<<std::endl;
1964 // create the output 'Widget'
1965 (*s) << " output Widget layout.Widget Widget"<<std::endl;
1966 // the box change output
1967 (*s) << " new MultipleInputs change"<<std::endl;
1968 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
1970 // Browse the inputs of the box in order to find which ones are not
1971 // connected and can be adapted from a widget adaptor
1972 // vector which stores the list of inputs of the box which must be connected
1973 std::vector<std::string> in;
1975 Factory::Pointer F = mVirtualExecuter->GetFactory();
1977 Package::Pointer user = F->GetPackage("user");
1979 ComplexBlackBoxDescriptor::Pointer workspace =
1980 mRealExecuter.lock()->GetCurrentDescriptor();
1985 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
1990 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
1993 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
1994 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
1996 BlackBox::InputConnectorMapType::iterator i;
1997 for (i=box->bbGetInputConnectorMap().begin();
1998 i!=box->bbGetInputConnectorMap().end();
2001 // If the input is connected : continue
2002 if (i->second->IsConnected()) continue;
2003 // Get the input descriptor
2004 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2005 // If it is a "system" input : skip it
2006 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2007 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2010 std::string widget,adaptor;
2011 // try to find a widget adaptor
2012 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2016 // command to create the adaptor
2017 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2018 // Sets the label of the widget adaptor to the name of the input
2019 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2020 // Sets the initial value of the widget to the value of the input
2021 (*s) << " set "<<i->first<<".In \" "
2022 <<box->bbGetInputAsString(i->first)<<"\""
2024 // store the input name
2025 in.push_back(i->first);
2026 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2027 //<i->first<<"'"<<std::endl;
2028 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2030 // try to find a two pieces adaptor
2031 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2035 // command to create the widget
2036 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2037 // command to create the adaptor
2038 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2040 (*s) << " connect "<<i->first<<"Widget.Out "
2041 <<i->first<<".In"<<std::endl;
2042 // Sets the label of the widget adaptor to the name of the input
2043 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2044 // Sets the initial value of the widget to the value of the input
2045 (*s) << " set "<<i->first<<"Widget.In \" "
2046 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2047 // store the input name
2048 in.push_back(i->first);
2049 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2050 //<i->first<<"'"<<std::endl;
2051 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2054 // try to find an adaptor from string
2055 // If found then can create a text input which
2056 // will be automatically adapted
2057 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2061 // command to create the adaptor
2062 (*s) << " new InputText "<<i->first<<std::endl;
2063 // Sets the label of the widget adaptor to the name of the input
2064 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2065 // Sets the initial value of the widget to the value of the input
2066 (*s) << " set "<<i->first<<".In \" "
2067 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2068 // store the input name
2069 in.push_back(i->first);
2070 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2071 //<i->first<<"'"<<std::endl;
2072 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2081 // command to create the output
2082 (*s) << " output "<<i->first<<" "
2083 <<i->first<<".Out "<<i->first<<std::endl;
2084 // <<" Output of the widget which allows to set "
2088 // Inputs for window properties
2089 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2090 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2091 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2092 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2093 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2097 // Execute the box executes the layout
2098 (*s) << " exec layout" << std::endl;
2099 (*s) << "endefine" << std::endl;
2100 // (*s) << "help "<< typeName<< std::endl;
2101 // instanciate the box and connect it
2102 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2104 std::vector<std::string>::iterator j;
2105 for (j=in.begin();j!=in.end();++j)
2108 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2109 << boxname<<"."<<*j<<std::endl;
2111 // That's all folks ! now execute the commands :
2114 //=======================================================================
2118 //==========================================================================
2119 void Interpreter::Debug(const std::string& name)
2121 if ((name.length()==2)&&(name[0]=='-'))
2125 bbtk::StaticInitTime::PrintObjectListInfo = true;
2129 // int o = MessageManager::GetMessageLevel("debug");
2130 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2131 mVirtualExecuter->GetFactory()->CheckPackages();
2132 // MessageManager::SetMessageLevel("debug",o);
2137 Object:: PrintObjectListInfo(name);
2140 //==========================================================================
2141 //==========================================================================
2142 std::string Interpreter::GetObjectName() const
2144 return std::string("Interpreter");
2146 //==========================================================================
2148 //==========================================================================
2149 std::string Interpreter::GetObjectInfo() const
2151 std::stringstream i;
2154 //==========================================================================
2156 //==========================================================================
2157 size_t Interpreter::GetObjectSize() const
2159 size_t s = Superclass::GetObjectSize();
2160 s += Interpreter::GetObjectInternalSize();
2163 //==========================================================================
2164 //==========================================================================
2165 size_t Interpreter::GetObjectInternalSize() const
2167 size_t s = sizeof(Interpreter);
2170 //==========================================================================
2171 //==========================================================================
2172 size_t Interpreter::GetObjectRecursiveSize() const
2174 size_t s = Superclass::GetObjectRecursiveSize();
2175 s += Interpreter::GetObjectInternalSize();
2176 s += mVirtualExecuter->GetObjectRecursiveSize();
2179 //==========================================================================