1 /*=========================================================================
4 Module: $RCSfile: bbtkInterpreter.cxx,v $ $
6 Date: $Date: 2008/10/08 10:56:27 $
7 Version: $Revision: 1.74 $
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 )
510 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
512 bool exm = mCommandLine;
513 mCommandLine = false;
515 ExitStatus status = Interpreter_OK;
519 SwitchToFile(filename);
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 = 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);
843 InterpretFile(words[1]);
847 SwitchToFile(words[1]);
849 // if 'source' was given
852 GetExecuter()->SetCurrentFileName(words[1]);
857 GetExecuter()->LoadPackage(words[1]);
861 GetExecuter()->UnLoadPackage(words[1]);
865 throw QuitException();
869 if (words.size()==2) Debug(words[1]);
874 if (words.size() == 2)
876 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
877 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
881 mVirtualExecuter->SetWorkspaceName(words[2]);
886 bbtkInternalError("should not reach here !!!");
889 bbtkDecTab("Interpreter",9);
891 //=======================================================================
897 //=======================================================================
901 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
903 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
905 std::string delimiters = "\"";
906 std::vector<std::string> quote;
907 Utilities::SplitString(str,delimiters,quote);
910 std::vector<std::string>::iterator i;
911 for (i=quote.begin(); i!=quote.end(); )
913 Utilities::SplitString(*i,delimiters,tokens);
917 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
918 tokens.push_back(*i);
923 for (i=tokens.begin(); i!=tokens.end(); ++i)
925 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
927 bbtkDebugMessageCont("Interpreter",9,std::endl);
929 bbtkDebugDecTab("Interpreter",9);
931 //=======================================================================
934 //=======================================================================
935 void Interpreter::Reset()
937 // Cannot close all files if the reset command is read from a file !
939 mFileNameHistory.clear();
940 this->mVirtualExecuter->Reset();
942 //=======================================================================
944 //=======================================================================
949 void Interpreter::Print( const std::string& str)
951 if (mVirtualExecuter->GetNoExecMode()) return;
953 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
956 // InterpretLine ("load std")
957 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
958 // InterpretLine("new Print _P_")
959 // InterpretLine("connect _C_.Out _P_.In")
963 std::vector<std::string> chains;
964 std::string delimiters("$");
966 // Skip delimiters at beginning.
967 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
969 if (lastPos>0) is_text = false;
971 // Find first delimiter.
972 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
974 while (std::string::npos != pos || std::string::npos != lastPos)
978 // Found a text token, add it to the vector.
979 chains.push_back(str.substr(lastPos, pos - lastPos));
980 // std::string token = str.substr(lastPos, pos - lastPos)
981 // InterpretLine("set _C_.In%num% %token%")
987 // is an output (between $$) : decode
988 std::string tok,box,output;
989 tok = str.substr(lastPos, pos - lastPos);
990 Utilities::SplitAroundFirstDot(tok,box,output);
991 chains.push_back( mVirtualExecuter->Get(box,output) );
993 // InterpretLine("connect %tok% _C_.In%num%")
996 // Skip delimiters. Note the "not_of"
997 lastPos = str.find_first_not_of(delimiters, pos);
998 // Find next delimiter
999 pos = str.find_first_of(delimiters, lastPos);
1004 // InterpretLine("exec _P_")
1005 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1007 std::vector<std::string>::iterator i;
1008 for (i= chains.begin(); i!=chains.end(); ++i)
1011 Utilities::SubsBackslashN(*i);
1014 std::cout << std::endl;
1015 bbtkDebugDecTab("Interpreter",9);
1019 //=======================================================================
1024 // =========================================================================
1025 void Interpreter::SwitchToFile( const std::string& name )
1027 // Note : in the following :
1028 // name : the user supplied name
1029 // - abreviated name e.g. scr scr.bbs
1030 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1031 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1032 // same for Windows, with c:, d: ...
1034 // use ./directory/subdir/scrname.bbs
1037 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1038 <<name<<"\")"<<std::endl);
1040 std::vector<std::string> script_paths;
1041 std::string fullPathScriptName; // full path script name
1042 std::string pkgname; // e.g. <scriptname>.bbs
1043 std::vector<std::string> Filenames;
1045 // The following is *NOT* a debug time message :
1046 // It's a user intended message.
1047 // Please don't remove it.
1048 bbtkMessage("Interpreter",1,
1049 "look for : [" << name
1050 << "]" << std::endl);
1054 pkgname = Utilities::ExtractScriptName(name,upath);
1056 bbtkMessage("Interpreter",3,
1057 "extract : pkgname [" << pkgname
1058 << "] upath [" << upath << "]" << std::endl);
1059 bool fullnameGiven = false;
1060 bool foundFile = false;
1062 // ==== "*" provided : load all scripts in given path
1063 // relative (e.g. std/boxes/*) or absolute
1068 std::stringstream* stream = new std::stringstream;
1069 //if (upath.size()!=0) // avoid troubles for "*"
1071 // ==== no path provided : look in root bbs path
1072 if (upath.size()==0)
1074 // bbtkMessage("Interpreter",1,
1075 // LG : add all bbs path
1076 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1077 std::vector<std::string>::const_iterator i;
1078 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1079 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1082 script_paths.push_back(*i);
1085 // ==== absolute path provided
1086 else if (upath[0]=='/' || upath[1] == ':' )
1088 if ( Utilities::IsDirectory( upath ) )
1090 script_paths.push_back(upath);
1094 bbtkError("'"<<upath<<"' : directory does not exist");
1097 // ==== relative path provided : search all bbs path appended with
1098 // the relative path provided
1101 std::vector<std::string>::const_iterator i;
1102 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1103 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1106 std::string full_path(*i);
1107 // we *really* want '.' to be the current working directory
1108 if (full_path == ".")
1110 char buf[2048]; // for getcwd
1111 char * currentDir = getcwd(buf, 2048);
1112 std::string cwd(currentDir);
1113 full_path = currentDir;
1116 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1119 if ( Utilities::IsDirectory( full_path ) )
1121 script_paths.push_back(full_path);
1124 if (script_paths.empty())
1126 bbtkError("no '"<<upath<<"' subdir found in search paths"
1132 // === search paths list complete : now explore it
1134 // ==== relative name, iterate + load all .bbs/.bbp files
1135 std::vector<std::string>::iterator i;
1136 for (i=script_paths.begin();i!=script_paths.end();i++)
1138 bbtkMessage("Interpreter",1,
1139 "--> Looking in '" << *i << "'" << std::endl);
1143 Utilities::Explore(*i, false, Filenames);
1146 for (std::vector<std::string>::iterator j = Filenames.begin();
1147 j!= Filenames.end(); ++j)
1149 int lgr = (*j).size();
1150 if (lgr < 5) continue;
1151 // ignore non .bbp file
1152 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1154 (*stream) << "include \"" << *j << "\"\n";
1155 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1158 } // for (std::vector...
1159 } // for (i=script_...
1162 bbtkMessage("Interpreter",1,
1163 " --> No .bbp found"<< std::endl);
1167 bbtkMessage("Interpreter",1,
1168 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1169 SwitchToStream(stream);
1173 //=============== end pkgname=="*" ===========
1176 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1177 // (not only a plain script name)
1178 // we trust him, and try to expland the directory name
1179 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1181 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1184 // ===========================================================check user supplied location
1185 fullnameGiven = true;
1187 fullPathScriptName = Utilities::ExpandLibName(name, false);
1189 // allow user to always forget ".bbs"
1190 int l = fullPathScriptName.size();
1194 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1195 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1197 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1198 if ( Utilities::FileExists(tfullPathScriptName) )
1200 fullPathScriptName = tfullPathScriptName;
1205 tfullPathScriptName = fullPathScriptName + ".bbp";
1206 if ( Utilities::FileExists(tfullPathScriptName) )
1208 fullPathScriptName = tfullPathScriptName;
1215 if ( Utilities::FileExists(fullPathScriptName) )
1223 // =============================== iterate on the paths
1225 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1227 std::vector<std::string>::iterator i;
1228 for (i=script_paths.begin();i!=script_paths.end();++i)
1231 // we *really* want '.' to be the current working directory
1234 char buf[2048]; // for getcwd
1235 char * currentDir = getcwd(buf, 2048);
1236 std::string cwd(currentDir);
1240 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1241 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1243 fullPathScriptName = tfullPathScriptName;
1244 if ( ! Utilities::FileExists(fullPathScriptName) )
1246 // The following is *NOT* a debug time message :
1247 // It's a user intended message.
1248 // Please don't remove it.
1249 bbtkMessage("Interpreter",2,
1250 " [" <<fullPathScriptName <<"] : does not exist"
1252 continue; // try next path
1254 bbtkMessage("Interpreter",2,
1255 " [" <<fullPathScriptName
1256 <<"] : found" <<std::endl);
1258 break; // a script was found; we stop iterating
1262 fullPathScriptName = tfullPathScriptName + ".bbs";
1263 // Check if library exists
1264 if ( ! Utilities::FileExists(fullPathScriptName) )
1266 fullPathScriptName = tfullPathScriptName + ".bbp";
1267 if ( ! Utilities::FileExists(fullPathScriptName) )
1269 // The following is *NOT* a debug time message :
1270 // It's a user intended message.
1271 // Please don't remove it.
1272 bbtkMessage("Interpreter",2,
1273 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1275 continue; // try next path
1278 bbtkMessage("Interpreter",2,
1279 " [" <<fullPathScriptName
1280 <<"] : found" <<std::endl);
1282 break; // a script was found; we stop iterating
1284 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1290 if(fullPathScriptName == "")
1291 bbtkError("Path ["<<upath<<"] doesn't exist");
1293 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1295 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1299 LoadScript(fullPathScriptName,name);
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 //==========================================================================