1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2008/10/17 08:18:13 $
6 Version: $Revision: 1.77 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief class Interpreter :
36 #include "bbtkInterpreter.h"
37 #include "bbtkExecuter.h"
38 #include "bbtkTranscriptor.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkConfigurationFile.h"
41 #include "bbtkUtilities.h"
42 #include "bbtkWxBlackBox.h"
45 #ifdef CMAKE_HAVE_TERMIOS_H
47 #define BBTK_USE_TERMIOS_BASED_PROMPT
55 //=======================================================================
56 Interpreter::Pointer Interpreter::New(const std::string& cpp_file)
58 bbtkDebugMessage("Kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
59 return MakePointer(new Interpreter(cpp_file));
61 //=======================================================================
63 //=======================================================================
64 Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e)
66 bbtkDebugMessage("Kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
67 return MakePointer(new Interpreter(e));
69 //=======================================================================
71 //=======================================================================
72 Interpreter::Interpreter(const std::string& cpp_file)
74 Init(VirtualExec::Pointer(), cpp_file);
76 //=======================================================================
78 //=======================================================================
79 Interpreter::Interpreter(VirtualExec::Pointer e)
83 //=======================================================================
85 //=======================================================================
86 void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file)
92 bbtk::MessageManager::RegisterMessageType("echo","Level>0 : Prints the output of the 'print' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
93 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
94 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
99 else if (cpp_file.size()!=0)
101 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
105 bbtk::Executer::Pointer exe = bbtk::Executer::New();
107 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
110 // Lock this pointer or will auto-destruct !!
111 if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
113 // For the time being, comment out previous line, and
114 // uncomment next line to check Transcriptor
116 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
118 // Builds the commands dict
119 CommandInfoType info;
121 info.keyword = "new";
125 info.syntax = "new <type> <name>";
126 info.help = "Creates a new black box of type <type> with name <name>";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "delete";
133 info.syntax = "delete <box>";
134 info.help = "Deletes the black box of name <box>";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "newgui";
141 info.syntax = "newgui <box> <name>";
142 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "connect";
148 info.code = cConnect;
149 info.syntax = "connect <box1.output> <box2.input>";
150 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "print";
157 info.syntax = "print <string>";
158 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').";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "exec";
165 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
166 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.";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "package";
172 info.code = cPackage;
173 info.syntax = "package <name>";
174 info.help = "Begins the definition of a package.";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "endpackage";
180 info.code = cEndPackage;
181 info.syntax = "endpackage";
182 info.help = "Ends the definition of a package.";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "define";
189 info.syntax = "define <type> [<package>]";
190 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.";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "endefine";
196 info.code = cEndDefine;
197 info.syntax = "endefine";
198 info.help = "Ends the definition of a new type of complex black box";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "kind";
205 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
206 info.help = "Sets the kind of the currently defined complex black box";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "input";
213 info.syntax = "input <name> <box.input> <help>";
214 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";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "output";
221 info.syntax = "output <name> <box.output> <help>";
222 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";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "set";
229 info.syntax = "set <box.input> <value>";
230 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";
231 mCommandDict[info.keyword] = info;
233 info.keyword = "config"; // JPR
237 info.syntax = "config";
238 info.help = "Prints the value of all configuration parameters";
239 mCommandDict[info.keyword] = info;
241 info.keyword = "index"; // LG
246 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
247 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.";
248 mCommandDict[info.keyword] = info;
250 info.keyword = "reset";
254 info.syntax = "reset";
255 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "author";
262 info.syntax = "author <string>";
263 info.help = "Adds the string <string> to the author information of the black box being defined";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "category"; //JP
269 info.code = cCategory;
270 info.syntax = "category <list of items, separated by ;>";
271 info.help = "Adds the string <string> to the category information of the black box being defined";
272 mCommandDict[info.keyword] = info;
274 info.keyword = "description";
277 info.code = cDescription;
278 info.syntax = "description <string>";
279 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
280 mCommandDict[info.keyword] = info;
282 info.keyword = "help";
286 info.syntax = "help";
287 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>";
288 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.";
289 mCommandDict[info.keyword] = info;
291 info.keyword = "message";
294 info.code = cMessage;
295 info.syntax = "message <kind> <level>";
296 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.";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "include";
302 info.code = cInclude;
303 info.syntax = "include <filename> [source]";
304 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).";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "quit";
311 info.syntax = "quit";
312 info.help = "Quits the program (during script execution it stops the complete execution)";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "load";
319 info.syntax = "load <packagename>";
320 info.help = "Loads the black box package <packagename>";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "unload";
327 info.syntax = "unload <packagename>";
328 info.help = "Unloads the black box package <packagename>";
329 mCommandDict[info.keyword] = info;
331 info.keyword = "graph";
335 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 ]]]]]]";
336 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')";
337 mCommandDict[info.keyword] = info;
339 info.keyword = "debug";
343 info.syntax = "debug [expr|-C|-D]";
344 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";
345 mCommandDict[info.keyword] = info;
348 info.keyword = "workspace";
351 info.code = cWorkspace;
352 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
353 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.";
354 mCommandDict[info.keyword] = info;
357 bbtkDebugDecTab("Interpreter",9);
360 //=======================================================================
364 //=======================================================================
368 Interpreter::~Interpreter()
370 bbtkDebugMessageInc("Interpreter",9,"==> Interpreter::~Interpreter()" <<std::endl);
371 mVirtualExecuter = VirtualExec::Pointer();
372 bbtkDebugMessageInc("Interpreter",9,"<== Interpreter::~Interpreter()" <<std::endl);
374 //=======================================================================
377 InterpreterError::InterpreterError( const std::string& message,
379 const std::string& script_file,
382 : Exception("Interpreter",0,message),
383 mInScriptFile(in_script_file),
384 mScriptFile(script_file),
385 mScriptLine(script_line)
388 InterpreterError::InterpreterError( const Exception& excep,
390 const std::string& script_file,
394 mInScriptFile(in_script_file),
395 mScriptFile(script_file),
396 mScriptLine(script_line)
399 //=======================================================================
400 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
404 bool in_script = false;
405 std::string file("");
407 if (mFileName.size()) {
408 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
409 if (fs!=0) in_script = true;
410 file = mFileName.back();
414 throw InterpreterError(e,in_script,file,line);
418 std::stringstream mess;
419 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
420 if (mFileName.size()) {
421 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
422 mess << "* LINE : "<<mLine.back()<<std::endl;
424 std::cerr << mess.str();
427 //=======================================================================
429 //=======================================================================
430 void Interpreter::CatchStdException( const std::exception& e )
434 bool in_script = false;
435 std::string file("");
437 if (mFileName.size()) {
438 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
439 if (fs!=0) in_script = true;
440 file = mFileName.back();
444 throw InterpreterError(e.what(),in_script,file,line);
448 std::stringstream mess;
449 mess << "* ERROR : "<<e.what()<<std::endl;
450 if (mFileName.size()) {
451 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
452 mess << "* LINE : "<<mLine.back()<<std::endl;
454 std::cerr << mess.str();
457 //=======================================================================
459 //=======================================================================
460 void Interpreter::CatchUnknownException()
464 bool in_script = false;
465 std::string file("");
467 if (mFileName.size()) {
468 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
469 if (fs!=0) in_script = true;
470 file = mFileName.back();
474 throw InterpreterError("Unknown exception caught",
475 in_script,file,line);
479 std::stringstream mess;
480 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
482 if (mFileName.size()) {
483 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
484 mess << "* LINE : "<<mLine.back()<<std::endl;
486 std::cerr << mess.str();
489 //=======================================================================
491 //=======================================================================
493 #define CATCH_MACRO \
494 catch (QuitException e) \
496 status = Interpreter_QUIT; \
497 if (mThrow) throw QuitException(); \
499 catch (bbtk::Exception e) \
501 status = Interpreter_ERROR; \
502 CatchBbtkException(e); \
504 catch (std::exception& e) \
506 status = Interpreter_ERROR; \
507 CatchStdException(e); \
511 status = Interpreter_ERROR; \
512 CatchUnknownException(); \
514 //=======================================================================
517 //=======================================================================
521 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
523 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
525 bool exm = mCommandLine;
526 mCommandLine = false;
528 ExitStatus status = Interpreter_OK;
532 SwitchToFile(filename,source);
534 bool insideComment = false; // for multiline comment
535 while (mFile.size()>0)
537 while (!mFile.back()->eof()) {
540 mFile.back()->getline(buf,500);
541 std::string str(buf);
542 int size=str.length();
543 if ( str[ size-1 ]==13 )
549 InterpretLine(str, insideComment);
560 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
561 bbtkDecTab("Interpreter",9);
567 //=======================================================================
570 //=======================================================================
574 Interpreter::ExitStatus
575 Interpreter::InterpretBuffer( std::stringstream* buffer )
577 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
579 bool exm = mCommandLine;
580 mCommandLine = false;
582 ExitStatus status = Interpreter_OK;
586 SwitchToStream(buffer);
587 bool insideComment = false; // for multiline comment
588 while (mFile.size()>0)
590 while (!mFile.back()->eof()) {
593 mFile.back()->getline(buf,500);
594 std::string str(buf);
596 int size=str.length();
597 if ( str[ size-1 ]==13 )
603 InterpretLine(str, insideComment);
613 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
614 bbtkDecTab("Interpreter",9);
619 //=======================================================================
621 //=======================================================================
622 /// Runs the interpretation of a command
623 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
625 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
627 ExitStatus status = Interpreter_OK;
631 bool insideComment = false;
632 InterpretLine(line, insideComment);
637 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
639 bbtkDecTab("Interpreter",9);
645 //=======================================================================
649 void Interpreter::InterpretLine( const std::string& line, bool &insideComment )
651 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine(\""<<line<<"\")"<<std::endl);
652 bbtkMessage("echo",2,line<<std::endl);
654 std::vector<std::string> words;
655 SplitLine(line,words);
660 bbtkDebugDecTab("Interpreter",9);
664 // Single line comment : # or //
665 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
667 bbtkDebugDecTab("Interpreter",9);
668 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
672 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
674 if (words[0][0]=='/' && words[0][1]=='*')
676 bbtkDebugDecTab("Interpreter",9);
677 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
678 insideComment = true;
682 if (words[0][0]=='*' && words[0][1]=='/')
684 bbtkDebugDecTab("Interpreter",9);
685 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
686 if ( !insideComment ) {
687 bbtkDebugDecTab("Interpreter",9);
688 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
690 insideComment = false;
696 bbtkDebugDecTab("Interpreter",9);
697 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
702 CommandInfoType command;
703 InterpretCommand(words,command);
705 bbtkDebugMessage("Interpreter",9,
706 "Command='"<<command.keyword
707 <<"' code="<<command.code<<std::endl);
709 std::string left,right,left2,right2;
710 std::string filename;
711 switch (command.code)
714 mVirtualExecuter->Create(words[1],words[2]);
718 mVirtualExecuter->Destroy(words[1]);
722 Utilities::SplitAroundFirstDot(words[1],left,right);
723 Utilities::SplitAroundFirstDot(words[2],left2,right2);
724 mVirtualExecuter->Connect(left,right,left2,right2);
728 mVirtualExecuter->BeginPackage(words[1]);
732 mVirtualExecuter->EndPackage();
736 if (mFileName.size()>0)
738 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
742 mVirtualExecuter->Define(words[1],"",filename);
746 mVirtualExecuter->Define(words[1],words[2],filename);
751 mVirtualExecuter->EndDefine();
755 mVirtualExecuter->Kind(words[1]);
759 mVirtualExecuter->Print(words[1]);
763 if (words[1]=="freeze")
765 mVirtualExecuter->SetNoExecMode(true);
768 else if (words[1]=="freeze_no_error ")
770 mVirtualExecuter->SetNoExecMode(true);
771 mVirtualExecuter->SetNoErrorMode(true);
774 else if (words[1]=="unfreeze")
776 mVirtualExecuter->SetNoExecMode(false);
777 mVirtualExecuter->SetNoErrorMode(false);
781 mVirtualExecuter->Execute(words[1]);
786 Utilities::SplitAroundFirstDot(words[2],left,right);
787 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
791 Utilities::SplitAroundFirstDot(words[2],left,right);
792 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
796 Utilities::SplitAroundFirstDot(words[1],left,right);
797 mVirtualExecuter->Set(left,right,words[2]);
801 mVirtualExecuter->Author(words[1]);
805 NewGUI(words[1],words[2]);
809 mVirtualExecuter->Category(words[1]);
814 Index("tmp_index.html");
815 else if (words.size()==2)
817 else if (words.size()==3)
818 Index(words[1],words[2]);
822 mVirtualExecuter->Description(words[1]);
832 mVirtualExecuter->HelpMessages();
836 sscanf(words[2].c_str(),"%d",&level);
837 mVirtualExecuter->SetMessageLevel(words[1],level);
854 // if 'source' was given (words.size()==3) then tell to set the
855 // source file name of the current complex box with the full file name included
858 InterpretFile(words[1],(words.size()==3));
862 SwitchToFile(words[1],(words.size()==3) );
867 GetExecuter()->LoadPackage(words[1]);
871 GetExecuter()->UnLoadPackage(words[1]);
875 throw QuitException();
879 if (words.size()==2) Debug(words[1]);
884 if (words.size() == 2)
886 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
887 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
891 mVirtualExecuter->SetWorkspaceName(words[2]);
896 bbtkInternalError("should not reach here !!!");
899 bbtkDecTab("Interpreter",9);
901 //=======================================================================
907 //=======================================================================
911 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
913 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
915 std::string delimiters = "\"";
916 std::vector<std::string> quote;
917 Utilities::SplitString(str,delimiters,quote);
920 std::vector<std::string>::iterator i;
921 for (i=quote.begin(); i!=quote.end(); )
923 Utilities::SplitString(*i,delimiters,tokens);
927 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
928 tokens.push_back(*i);
933 for (i=tokens.begin(); i!=tokens.end(); ++i)
935 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
937 bbtkDebugMessageCont("Interpreter",9,std::endl);
939 bbtkDebugDecTab("Interpreter",9);
941 //=======================================================================
944 //=======================================================================
945 void Interpreter::Reset()
947 // Cannot close all files if the reset command is read from a file !
949 mFileNameHistory.clear();
950 this->mVirtualExecuter->Reset();
952 //=======================================================================
954 //=======================================================================
959 void Interpreter::Print( const std::string& str)
961 if (mVirtualExecuter->GetNoExecMode()) return;
963 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
966 // InterpretLine ("load std")
967 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
968 // InterpretLine("new Print _P_")
969 // InterpretLine("connect _C_.Out _P_.In")
973 std::vector<std::string> chains;
974 std::string delimiters("$");
976 // Skip delimiters at beginning.
977 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
979 if (lastPos>0) is_text = false;
981 // Find first delimiter.
982 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
984 while (std::string::npos != pos || std::string::npos != lastPos)
988 // Found a text token, add it to the vector.
989 chains.push_back(str.substr(lastPos, pos - lastPos));
990 // std::string token = str.substr(lastPos, pos - lastPos)
991 // InterpretLine("set _C_.In%num% %token%")
997 // is an output (between $$) : decode
998 std::string tok,box,output;
999 tok = str.substr(lastPos, pos - lastPos);
1000 Utilities::SplitAroundFirstDot(tok,box,output);
1001 chains.push_back( mVirtualExecuter->Get(box,output) );
1003 // InterpretLine("connect %tok% _C_.In%num%")
1006 // Skip delimiters. Note the "not_of"
1007 lastPos = str.find_first_not_of(delimiters, pos);
1008 // Find next delimiter
1009 pos = str.find_first_of(delimiters, lastPos);
1014 // InterpretLine("exec _P_")
1015 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1017 std::vector<std::string>::iterator i;
1018 for (i= chains.begin(); i!=chains.end(); ++i)
1021 Utilities::SubsBackslashN(*i);
1024 std::cout << std::endl;
1025 bbtkDebugDecTab("Interpreter",9);
1029 //=======================================================================
1034 // =========================================================================
1035 void Interpreter::SwitchToFile( const std::string& name , bool source )
1037 // Note : in the following :
1038 // name : the user supplied name
1039 // - abreviated name e.g. scr scr.bbs
1040 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1041 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1042 // same for Windows, with c:, d: ...
1044 // use ./directory/subdir/scrname.bbs
1047 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1048 <<name<<"\")"<<std::endl);
1050 std::vector<std::string> script_paths;
1051 std::string fullPathScriptName; // full path script name
1052 std::string pkgname; // e.g. <scriptname>.bbs
1053 std::vector<std::string> Filenames;
1055 // The following is *NOT* a debug time message :
1056 // It's a user intended message.
1057 // Please don't remove it.
1058 bbtkMessage("Interpreter",1,
1059 "look for : [" << name
1060 << "]" << std::endl);
1064 pkgname = Utilities::ExtractScriptName(name,upath);
1066 bbtkMessage("Interpreter",3,
1067 "package name:[" << pkgname
1068 << "] path:[" << upath << "]" << std::endl);
1069 bool fullnameGiven = false;
1070 bool foundFile = false;
1072 // ==== "*" provided : load all scripts in given path
1073 // relative (e.g. std/boxes/*) or absolute
1077 std::stringstream* stream = new std::stringstream;
1078 //if (upath.size()!=0) // avoid troubles for "*"
1080 // ==== no path provided : look in root bbs path
1081 if (upath.size()==0)
1083 // bbtkMessage("Interpreter",1,
1084 // LG : add all bbs path
1085 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1086 std::vector<std::string>::const_iterator i;
1087 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1088 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1091 script_paths.push_back(*i);
1094 // ==== absolute path provided
1095 else if (upath[0]=='/' || upath[1] == ':' )
1097 if ( Utilities::IsDirectory( upath ) )
1099 script_paths.push_back(upath);
1103 bbtkError("'"<<upath<<"' : directory does not exist");
1106 // ==== relative path provided : search all bbs path appended with
1107 // the relative path provided
1110 std::vector<std::string>::const_iterator i;
1111 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1112 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1115 std::string full_path(*i);
1116 // we *really* want '.' to be the current working directory
1117 if (full_path == ".")
1119 char buf[2048]; // for getcwd
1120 char * currentDir = getcwd(buf, 2048);
1121 std::string cwd(currentDir);
1122 full_path = currentDir;
1125 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1128 if ( Utilities::IsDirectory( full_path ) )
1130 script_paths.push_back(full_path);
1133 if (script_paths.empty())
1135 bbtkError("no '"<<upath<<"' subdir found in search paths"
1141 // === search paths list complete : now explore it
1143 // ==== relative name, iterate + load all .bbs/.bbp files
1144 std::vector<std::string>::iterator i;
1145 for (i=script_paths.begin();i!=script_paths.end();i++)
1147 bbtkMessage("Interpreter",1,
1148 "--> Looking in '" << *i << "'" << std::endl);
1152 Utilities::Explore(*i, false, Filenames);
1154 for (std::vector<std::string>::iterator j = Filenames.begin();
1155 j!= Filenames.end(); ++j)
1157 int lgr = (*j).size();
1158 if (lgr < 5) continue;
1159 // ignore non .bbp file
1160 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1162 (*stream) << "include \"" << *j << "\"\n";
1163 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1166 } // for (std::vector...
1167 } // for (i=script_...
1172 bbtkMessage("Interpreter",1,
1173 " --> No .bbp found"<< std::endl);
1177 bbtkMessage("Interpreter",1,
1178 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1179 SwitchToStream(stream);
1183 //=============== end pkgname=="*" ===========
1186 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1187 // (not only a plain script name)
1188 // we trust him, and try to expland the directory name
1189 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1191 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1194 // ===========================================================check user supplied location
1195 fullnameGiven = true;
1197 fullPathScriptName = Utilities::ExpandLibName(name, false);
1199 // allow user to always forget ".bbs"
1200 int l = fullPathScriptName.size();
1204 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1205 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1207 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1208 if ( Utilities::FileExists(tfullPathScriptName) )
1210 fullPathScriptName = tfullPathScriptName;
1215 tfullPathScriptName = fullPathScriptName + ".bbp";
1216 if ( Utilities::FileExists(tfullPathScriptName) )
1218 fullPathScriptName = tfullPathScriptName;
1225 if ( Utilities::FileExists(fullPathScriptName) )
1233 // =============================== iterate on the paths
1235 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1237 std::vector<std::string>::iterator i;
1238 for (i=script_paths.begin();i!=script_paths.end();++i)
1241 // we *really* want '.' to be the current working directory
1244 char buf[2048]; // for getcwd
1245 char * currentDir = getcwd(buf, 2048);
1246 std::string cwd(currentDir);
1250 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1251 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1253 fullPathScriptName = tfullPathScriptName;
1254 if ( ! Utilities::FileExists(fullPathScriptName) )
1256 // The following is *NOT* a debug time message :
1257 // It's a user intended message.
1258 // Please don't remove it.
1259 bbtkMessage("Interpreter",2,
1260 " [" <<fullPathScriptName <<"] : does not exist"
1262 continue; // try next path
1264 bbtkMessage("Interpreter",2,
1265 " [" <<fullPathScriptName
1266 <<"] : found" <<std::endl);
1268 break; // a script was found; we stop iterating
1272 fullPathScriptName = tfullPathScriptName + ".bbs";
1273 // Check if library exists
1274 if ( ! Utilities::FileExists(fullPathScriptName) )
1276 fullPathScriptName = tfullPathScriptName + ".bbp";
1277 if ( ! Utilities::FileExists(fullPathScriptName) )
1279 // The following is *NOT* a debug time message :
1280 // It's a user intended message.
1281 // Please don't remove it.
1282 bbtkMessage("Interpreter",2,
1283 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1285 continue; // try next path
1288 bbtkMessage("Interpreter",2,
1289 " [" <<fullPathScriptName
1290 <<"] : found" <<std::endl);
1292 break; // a script was found; we stop iterating
1294 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1300 if(fullPathScriptName == "")
1301 bbtkError("Path ["<<upath<<"] doesn't exist");
1303 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1305 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1310 LoadScript(fullPathScriptName,name);
1311 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1316 //=======================================================================
1319 //=======================================================================
1320 void Interpreter::SwitchToStream( std::stringstream* stream )
1322 mFile.push_back(stream);
1323 std::ostringstream buffer_name;
1325 buffer_name << "buffer_" ;
1327 if (mFileName.size()>0 )
1329 buffer_name << mFileName.back() << "_" << mLine.back();
1331 mFileName.push_back(buffer_name.str());
1332 mIncludeFileName.push_back(buffer_name.str());
1335 //=======================================================================
1337 //=======================================================================
1339 void Interpreter::LoadScript( std::string fullPathScriptName,
1340 std::string includeScriptName)
1342 Utilities::replace( fullPathScriptName ,
1343 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1345 if (find(mFileNameHistory.begin(),
1346 mFileNameHistory.end(),
1347 fullPathScriptName)!=mFileNameHistory.end())
1353 s = new std::ifstream;
1354 s->open(fullPathScriptName.c_str());
1357 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1361 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1362 << "] found" << std::endl);
1365 mFileName.push_back(fullPathScriptName);
1366 mFileNameHistory.push_back(fullPathScriptName);
1367 mIncludeFileName.push_back(includeScriptName);
1373 //=======================================================================
1377 void Interpreter::CloseCurrentFile()
1379 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1382 if (mFile.size()==0)
1384 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1388 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1390 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1391 if (file!=0) file->close();
1393 delete mFile.back();
1395 mFileName.pop_back();
1396 mIncludeFileName.pop_back();
1399 bbtkDebugMessage("Interpreter",9," Remains "
1401 <<" open"<<std::endl);
1402 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1405 //=======================================================================
1407 //=======================================================================
1411 void Interpreter::CloseAllFiles()
1413 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1416 while (mFile.size() != 0)
1420 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1423 //=======================================================================
1427 //=======================================================================
1431 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1432 CommandInfoType& info )
1434 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1436 // searches the command keyword
1437 CommandDictType::iterator c;
1438 c = mCommandDict.find(words[0]);
1439 if ( c == mCommandDict.end() ) {
1440 bbtkError(words[0]<<" : unknown command");
1443 // tests the number of args
1444 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1445 ( ((int)words.size())-1 > c->second.argmax ) )
1447 HelpCommand(words[0]);
1448 bbtkError(words[0]<<" : wrong number of arguments");
1452 bbtkDecTab("Interpreter",9);
1454 //=======================================================================
1457 //=======================================================================
1458 /// Displays help on all the commands
1459 void Interpreter::Help(const std::vector<std::string>& words)
1461 unsigned int nbarg = words.size()-1;
1469 if (words[1]=="packages")
1471 GetExecuter()->GetFactory()->PrintPackages(true);
1476 HelpCommand(words[1]);
1478 catch (bbtk::Exception e)
1482 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1486 ConfigurationFile::GetInstance().Get_doc_path();
1487 url += "/bbdoc/" + words[1] + "/index.html";
1488 if (Utilities::FileExists(url))
1490 mUser->InterpreterUserViewHtmlPage(url);
1494 catch (bbtk::Exception f)
1498 std::string package;
1499 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1503 ConfigurationFile::GetInstance().Get_doc_path();
1504 url += "/bbdoc/" + package + "/index.html";
1505 if (Utilities::FileExists(url))
1507 url += "#" + words[1];
1508 mUser->InterpreterUserViewHtmlPage(url);
1512 catch (bbtk::Exception g)
1516 GetExecuter()->ShowRelations(words[1],"0","9999");
1518 catch (bbtk::Exception h){
1519 bbtkError("\""<<words[1].c_str()
1520 <<"\" is not a known command, package, black box type or black box name");
1528 if (words[2]=="all")
1530 if ( words[1]=="packages" )
1532 GetExecuter()->GetFactory()->PrintPackages(true,true);
1537 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1539 catch (bbtk::Exception f)
1545 HelpCommand(words[0]);
1546 bbtkError(words[0]<<" : syntax error");
1551 bbtkError("Should not reach here !!!");
1554 //=======================================================================
1556 //===================================================================
1557 /// Displays the Configuration
1558 void Interpreter::Config() const
1560 ConfigurationFile::GetInstance().GetHelp(1);
1562 //===================================================================
1564 //=======================================================================
1565 /// Displays help on all the commands
1566 void Interpreter::HelpCommands()
1568 std::cout << "Available commands :" << std::endl;
1569 CommandDictType::iterator i;
1570 for ( i = mCommandDict.begin();
1571 i != mCommandDict.end();
1573 std::cout << " " << i->first << std::endl;
1574 // std::cout << " usage : " << i->second.syntax << std::endl;
1575 // std::cout << " " << i->second.help << std::endl;
1579 //=======================================================================
1582 //=======================================================================
1583 /// Displays help on a particular commands
1584 void Interpreter::HelpCommand(const std::string& s)
1586 CommandDictType::iterator c;
1587 c = mCommandDict.find(s);
1588 if ( c == mCommandDict.end() ) {
1589 bbtkError(s<<" : Unknown command");
1591 // std::cout << " " << s << " : "<< std::endl;
1592 // CommandParamDictType::iterator i;
1593 // for ( i = c->second.begin();
1594 // i != c->second.end();
1596 std::cout << " usage : " << c->second.syntax << std::endl;
1597 std::cout << " " << c->second.help << std::endl;
1600 //=======================================================================
1603 //=======================================================================
1604 /// Fills the vector commands with the commands which
1605 /// have the first n chars of buf for prefix
1606 /// TODO : skip initial spaces in buf and also return the position of first
1607 /// non blank char in buf
1608 void Interpreter::FindCommandsWithPrefix( char* buf,
1610 std::vector<std::string>& commands )
1612 CommandDictType::const_iterator i;
1613 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1615 if ((i->first).find(buf,0,n) == 0)
1616 commands.push_back(i->first);
1619 //=======================================================================
1623 //=======================================================================
1624 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1626 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1627 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1629 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1630 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1631 // E.G. STORE THIS IN bbtk_config.xml
1632 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1633 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1634 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1635 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1636 #define BBTK_BACKSPACE_KBCODE 0x00000008
1637 #define BBTK_DEL_KBCODE 0x0000007F
1638 #define BBTK_SPACE_KBCODE 0x00000020
1640 //=======================================================================
1641 void Interpreter::GetLineFromPrompt(std::string& s)
1646 unsigned int MAX_LINE_SIZE = 160;
1647 unsigned int MAX_HISTORY_SIZE = 100;
1649 char* newline = new char[MAX_LINE_SIZE];
1650 memset(newline,0,MAX_LINE_SIZE);
1651 char* histline = new char[MAX_LINE_SIZE];
1652 memset(histline,0,MAX_LINE_SIZE);
1654 char* line = newline;
1655 unsigned int hist = mHistory.size();
1661 read ( STDIN_FILENO, &c, 4) ;
1663 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1665 // Printable character
1666 if ( (ind<MAX_LINE_SIZE-1) &&
1667 ( c >= BBTK_SPACE_KBCODE ) &&
1668 ( c < BBTK_DEL_KBCODE ))
1676 // delete the unused line
1682 // empty lines are not stored in from history
1685 // if history too long : delete oldest command
1686 if (mHistory.size()>MAX_HISTORY_SIZE)
1688 delete mHistory.front();
1689 mHistory.pop_front();
1691 mHistory.push_back(line);
1696 else if ( (ind>0) &&
1697 ((c == BBTK_BACKSPACE_KBCODE) ||
1698 (c == BBTK_DEL_KBCODE)) )
1706 // TODO : Command completion
1707 std::vector<std::string> commands;
1708 FindCommandsWithPrefix( line,ind,commands);
1709 if (commands.size()==1)
1711 std::string com = *commands.begin();
1712 for (; ind<com.size(); ++ind)
1714 PrintChar(com[ind]);
1720 else if (commands.size()>1)
1722 std::vector<std::string>::iterator i;
1724 for (i=commands.begin();i!=commands.end();++i)
1726 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1729 write(STDOUT_FILENO,"\n> ",3);
1730 //for (int j=0;j<ind;++j)
1732 write(STDOUT_FILENO,line,ind);
1736 // Arrow up : back in history
1737 else if (c==BBTK_UP_ARROW_KBCODE)
1741 // erase current line
1742 while (ind--) BackSpace();
1746 strcpy(histline,mHistory[hist]);
1750 write(STDOUT_FILENO,line,ind);
1753 // Arrow down : down in history
1754 else if (c==BBTK_DOWN_ARROW_KBCODE)
1756 if (hist<mHistory.size()-1)
1758 // erase current line
1759 while (ind--) BackSpace();
1763 strcpy(histline,mHistory[hist]);
1767 write(STDOUT_FILENO,line,ind);
1769 // end of history : switch back to newline
1770 else if (hist==mHistory.size()-1)
1772 // erase current line
1773 while (ind--) BackSpace();
1780 write(STDOUT_FILENO,line,ind);
1784 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1786 PrintChar(line[ind]);
1791 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1799 write(STDOUT_FILENO,"\n\r",2);
1807 //=======================================================================
1808 void Interpreter::GetLineFromPrompt(std::string& s)
1834 //=======================================================================
1840 //=======================================================================
1841 void Interpreter::CommandLineInterpreter()
1843 bbtkDebugMessageInc("Interpreter",9,
1844 "Interpreter::CommandLineInterpreter()"<<std::endl);
1846 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1847 // Initialise the tty in non canonical mode with no echo
1848 // oter remembers the previous settings to restore them after
1849 struct termios ter,oter;
1852 ter.c_lflag &= ~ECHO;
1853 ter.c_lflag &= ~ICANON;
1856 tcsetattr(0,TCSANOW,&ter);
1859 mCommandLine = true;
1861 bool insideComment = false; // for multiline comment
1867 GetLineFromPrompt(line);
1868 InterpretLine(line, insideComment);
1870 catch (QuitException e)
1872 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1875 catch (bbtk::Exception e)
1879 catch (std::exception& e)
1881 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1885 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1890 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1891 tcsetattr(0,TCSANOW,&oter);
1894 std::cout << "Good bye !" << std::endl;
1896 bbtkDebugDecTab("Interpreter",9);
1899 //=======================================================================
1900 void Interpreter::Graph(const std::vector<std::string>& words)
1903 bool system_display = true;
1905 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1906 system_display = false;
1908 if (words.size()==1)
1910 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1912 else if (words.size()==2)
1914 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1916 else if (words.size()==3)
1918 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1920 else if (words.size()==4)
1922 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1924 else if (words.size()==5)
1926 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1928 else if (words.size()==6)
1930 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1932 else if (words.size()==7)
1934 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
1937 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1938 mUser->InterpreterUserViewHtmlPage(page);
1941 //=======================================================================
1944 //=======================================================================
1945 void Interpreter::Index(const std::string& filename,
1946 const std::string& type)
1948 Factory::IndexEntryType t;
1949 if (type=="Initials") t = Factory::Initials;
1950 else if (type=="Categories") t = Factory::Categories;
1951 else if (type=="Packages") t = Factory::Packages;
1952 else if (type=="Adaptors") t = Factory::Adaptors;
1954 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
1956 //=======================================================================
1959 //=======================================================================
1960 void Interpreter::NewGUI(const std::string& boxname,
1961 const std::string& instanceName)
1963 if (mRealExecuter.expired())
1965 bbtkError("command 'newgui' cannot be compiled yet");
1968 std::string typeName = instanceName+"Type";
1969 std::stringstream* s = new std::stringstream;
1970 // create the complex box
1971 (*s) << "define "<<typeName<<std::endl;
1972 // (*s) << " description 'Automatically generated user interface for the box "
1973 // << boxname << "'" <<std::endl;
1974 // create the Layout box
1975 (*s) << " load wx"<<std::endl;
1976 (*s) << " new LayoutLine layout"<<std::endl;
1977 // create the output 'Widget'
1978 (*s) << " output Widget layout.Widget Widget"<<std::endl;
1979 // the box change output
1980 (*s) << " new MultipleInputs change"<<std::endl;
1981 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
1983 // Browse the inputs of the box in order to find which ones are not
1984 // connected and can be adapted from a widget adaptor
1985 // vector which stores the list of inputs of the box which must be connected
1986 std::vector<std::string> in;
1988 Factory::Pointer F = mVirtualExecuter->GetFactory();
1990 Package::Pointer user = F->GetPackage("user");
1992 ComplexBlackBoxDescriptor::Pointer workspace =
1993 mRealExecuter.lock()->GetCurrentDescriptor();
1998 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2003 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2006 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2007 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2009 BlackBox::InputConnectorMapType::iterator i;
2010 for (i=box->bbGetInputConnectorMap().begin();
2011 i!=box->bbGetInputConnectorMap().end();
2014 // If the input is connected : continue
2015 if (i->second->IsConnected()) continue;
2016 // Get the input descriptor
2017 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2018 // If it is a "system" input : skip it
2019 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2020 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2023 std::string widget,adaptor;
2024 // try to find a widget adaptor
2025 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2029 // command to create the adaptor
2030 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2031 // Sets the label of the widget adaptor to the name of the input
2032 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2033 // Sets the initial value of the widget to the value of the input
2034 (*s) << " set "<<i->first<<".In \" "
2035 <<box->bbGetInputAsString(i->first)<<"\""
2037 // store the input name
2038 in.push_back(i->first);
2039 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2040 //<i->first<<"'"<<std::endl;
2041 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2043 // try to find a two pieces adaptor
2044 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2048 // command to create the widget
2049 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2050 // command to create the adaptor
2051 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2053 (*s) << " connect "<<i->first<<"Widget.Out "
2054 <<i->first<<".In"<<std::endl;
2055 // Sets the label of the widget adaptor to the name of the input
2056 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2057 // Sets the initial value of the widget to the value of the input
2058 (*s) << " set "<<i->first<<"Widget.In \" "
2059 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2060 // store the input name
2061 in.push_back(i->first);
2062 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2063 //<i->first<<"'"<<std::endl;
2064 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2067 // try to find an adaptor from string
2068 // If found then can create a text input which
2069 // will be automatically adapted
2070 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2074 // command to create the adaptor
2075 (*s) << " new InputText "<<i->first<<std::endl;
2076 // Sets the label of the widget adaptor to the name of the input
2077 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2078 // Sets the initial value of the widget to the value of the input
2079 (*s) << " set "<<i->first<<".In \" "
2080 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2081 // store the input name
2082 in.push_back(i->first);
2083 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2084 //<i->first<<"'"<<std::endl;
2085 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2094 // command to create the output
2095 (*s) << " output "<<i->first<<" "
2096 <<i->first<<".Out "<<i->first<<std::endl;
2097 // <<" Output of the widget which allows to set "
2101 // Inputs for window properties
2102 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2103 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2104 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2105 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2106 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2110 // Execute the box executes the layout
2111 (*s) << " exec layout" << std::endl;
2112 (*s) << "endefine" << std::endl;
2113 // (*s) << "help "<< typeName<< std::endl;
2114 // instanciate the box and connect it
2115 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2117 std::vector<std::string>::iterator j;
2118 for (j=in.begin();j!=in.end();++j)
2121 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2122 << boxname<<"."<<*j<<std::endl;
2124 // That's all folks ! now execute the commands :
2127 //=======================================================================
2131 //==========================================================================
2132 void Interpreter::Debug(const std::string& name)
2134 if ((name.length()==2)&&(name[0]=='-'))
2138 bbtk::StaticInitTime::PrintObjectListInfo = true;
2142 // int o = MessageManager::GetMessageLevel("debug");
2143 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2144 mVirtualExecuter->GetFactory()->CheckPackages();
2145 // MessageManager::SetMessageLevel("debug",o);
2150 Object:: PrintObjectListInfo(name);
2153 //==========================================================================
2154 //==========================================================================
2155 std::string Interpreter::GetObjectName() const
2157 return std::string("Interpreter");
2159 //==========================================================================
2161 //==========================================================================
2162 std::string Interpreter::GetObjectInfo() const
2164 std::stringstream i;
2167 //==========================================================================
2169 //==========================================================================
2170 size_t Interpreter::GetObjectSize() const
2172 size_t s = Superclass::GetObjectSize();
2173 s += Interpreter::GetObjectInternalSize();
2176 //==========================================================================
2177 //==========================================================================
2178 size_t Interpreter::GetObjectInternalSize() const
2180 size_t s = sizeof(Interpreter);
2183 //==========================================================================
2184 //==========================================================================
2185 size_t Interpreter::GetObjectRecursiveSize() const
2187 size_t s = Superclass::GetObjectRecursiveSize();
2188 s += Interpreter::GetObjectInternalSize();
2189 s += mVirtualExecuter->GetObjectRecursiveSize();
2192 //==========================================================================