1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2009/01/27 14:22:57 $
6 Version: $Revision: 1.82 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
33 * \brief class Interpreter :
36 #include "bbtkInterpreter.h"
37 #include "bbtkExecuter.h"
38 #include "bbtkTranscriptor.h"
39 #include "bbtkMessageManager.h"
40 #include "bbtkConfigurationFile.h"
41 #include "bbtkUtilities.h"
42 #include "bbtkWxBlackBox.h"
45 #ifdef CMAKE_HAVE_TERMIOS_H
47 #define BBTK_USE_TERMIOS_BASED_PROMPT
55 //=======================================================================
56 Interpreter::Pointer Interpreter::New(const std::string& cpp_file)
58 bbtkDebugMessage("Kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
59 return MakePointer(new Interpreter(cpp_file));
61 //=======================================================================
63 //=======================================================================
64 Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e)
66 bbtkDebugMessage("Kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
67 return MakePointer(new Interpreter(e));
69 //=======================================================================
71 //=======================================================================
72 Interpreter::Interpreter(const std::string& cpp_file)
74 Init(VirtualExec::Pointer(), cpp_file);
76 //=======================================================================
78 //=======================================================================
79 Interpreter::Interpreter(VirtualExec::Pointer e)
83 //=======================================================================
85 //=======================================================================
86 void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file)
92 bbtk::MessageManager::RegisterMessageType("echo","Level>0 : Prints the output of the 'print' commands of the user.\n\tLevel>1 : Prints the command being interpreted",1);
93 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
94 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
99 else if (cpp_file.size()!=0)
101 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
105 bbtk::Executer::Pointer exe = bbtk::Executer::New();
107 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
110 // Lock this pointer or will auto-destruct !!
111 if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
113 // For the time being, comment out previous line, and
114 // uncomment next line to check Transcriptor
116 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
118 // Builds the commands dict
119 CommandInfoType info;
121 info.keyword = "new";
125 info.syntax = "new <type> <name>";
126 info.help = "Creates a new black box of type <type> with name <name>";
127 mCommandDict[info.keyword] = info;
129 info.keyword = "delete";
133 info.syntax = "delete <box>";
134 info.help = "Deletes the black box of name <box>";
135 mCommandDict[info.keyword] = info;
137 info.keyword = "clear";
141 info.syntax = "clear";
142 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
143 mCommandDict[info.keyword] = info;
145 info.keyword = "break";
149 info.syntax = "break";
150 info.help = "Breaks the current execution";
151 mCommandDict[info.keyword] = info;
153 info.keyword = "newgui";
157 info.syntax = "newgui <box> <name>";
158 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
159 mCommandDict[info.keyword] = info;
161 info.keyword = "connect";
164 info.code = cConnect;
165 info.syntax = "connect <box1.output> <box2.input>";
166 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
167 mCommandDict[info.keyword] = info;
169 info.keyword = "print";
173 info.syntax = "print <string>";
174 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').";
175 mCommandDict[info.keyword] = info;
177 info.keyword = "exec";
181 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
182 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.";
183 mCommandDict[info.keyword] = info;
185 info.keyword = "package";
188 info.code = cPackage;
189 info.syntax = "package <name>";
190 info.help = "Begins the definition of a package.";
191 mCommandDict[info.keyword] = info;
193 info.keyword = "endpackage";
196 info.code = cEndPackage;
197 info.syntax = "endpackage";
198 info.help = "Ends the definition of a package.";
199 mCommandDict[info.keyword] = info;
201 info.keyword = "define";
205 info.syntax = "define <type> [<package>]";
206 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.";
207 mCommandDict[info.keyword] = info;
209 info.keyword = "endefine";
212 info.code = cEndDefine;
213 info.syntax = "endefine";
214 info.help = "Ends the definition of a new type of complex black box";
215 mCommandDict[info.keyword] = info;
217 info.keyword = "kind";
221 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
222 info.help = "Sets the kind of the currently defined complex black box";
223 mCommandDict[info.keyword] = info;
225 info.keyword = "input";
229 info.syntax = "input <name> <box.input> <help>";
230 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";
231 mCommandDict[info.keyword] = info;
233 info.keyword = "output";
237 info.syntax = "output <name> <box.output> <help>";
238 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";
239 mCommandDict[info.keyword] = info;
241 info.keyword = "set";
245 info.syntax = "set <box.input> <value>";
246 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";
247 mCommandDict[info.keyword] = info;
249 info.keyword = "config"; // JPR
253 info.syntax = "config";
254 info.help = "Prints the value of all configuration parameters";
255 mCommandDict[info.keyword] = info;
257 info.keyword = "index"; // LG
262 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
263 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.";
264 mCommandDict[info.keyword] = info;
266 info.keyword = "reset";
270 info.syntax = "reset";
271 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
272 mCommandDict[info.keyword] = info;
274 info.keyword = "author";
278 info.syntax = "author <string>";
279 info.help = "Adds the string <string> to the author information of the black box being defined";
280 mCommandDict[info.keyword] = info;
282 info.keyword = "category"; //JP
285 info.code = cCategory;
286 info.syntax = "category <list of items, separated by ;>";
287 info.help = "Adds the string <string> to the category information of the black box being defined";
288 mCommandDict[info.keyword] = info;
290 info.keyword = "description";
293 info.code = cDescription;
294 info.syntax = "description <string>";
295 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
296 mCommandDict[info.keyword] = info;
298 info.keyword = "help";
302 info.syntax = "help";
303 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>";
304 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.";
305 mCommandDict[info.keyword] = info;
307 info.keyword = "message";
310 info.code = cMessage;
311 info.syntax = "message <kind> <level>";
312 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.";
313 mCommandDict[info.keyword] = info;
315 info.keyword = "include";
318 info.code = cInclude;
319 info.syntax = "include <filename> [source]";
320 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).";
321 mCommandDict[info.keyword] = info;
323 info.keyword = "quit";
327 info.syntax = "quit";
328 info.help = "Quits the program (during script execution it stops the complete execution)";
329 mCommandDict[info.keyword] = info;
331 info.keyword = "load";
335 info.syntax = "load <packagename>";
336 info.help = "Loads the black box package <packagename>";
337 mCommandDict[info.keyword] = info;
339 info.keyword = "unload";
343 info.syntax = "unload <packagename>";
344 info.help = "Unloads the black box package <packagename>";
345 mCommandDict[info.keyword] = info;
347 info.keyword = "graph";
351 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 ]]]]]]";
352 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')";
353 mCommandDict[info.keyword] = info;
355 info.keyword = "debug";
359 info.syntax = "debug [expr|-C|-D]";
360 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";
361 mCommandDict[info.keyword] = info;
364 info.keyword = "workspace";
367 info.code = cWorkspace;
368 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
369 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.";
370 mCommandDict[info.keyword] = info;
373 bbtkDebugDecTab("Interpreter",9);
376 //=======================================================================
380 //=======================================================================
384 Interpreter::~Interpreter()
386 bbtkDebugMessageInc("Interpreter",9,"==> Interpreter::~Interpreter()" <<std::endl);
387 mVirtualExecuter = VirtualExec::Pointer();
388 bbtkDebugMessageInc("Interpreter",9,"<== Interpreter::~Interpreter()" <<std::endl);
390 //=======================================================================
393 //=======================================================================
394 InterpreterException::InterpreterException( const std::string& message,
396 const std::string& script_file,
399 : Exception("Interpreter",0,message),
400 mInScriptFile(in_script_file),
401 mScriptFile(script_file),
402 mScriptLine(script_line)
405 //=======================================================================
406 //=======================================================================
407 InterpreterException::InterpreterException( const Exception& excep,
409 const std::string& script_file,
413 mInScriptFile(in_script_file),
414 mScriptFile(script_file),
415 mScriptLine(script_line)
418 //=======================================================================
421 //=======================================================================
422 void Interpreter::CatchInterpreterException( const InterpreterException& e )
424 if (GetExecuter()->GetNoErrorMode())
426 bbtkWarning("ERROR :"<<e.GetErrorMessage()
427 <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
434 if (e.GetErrorMessage()!="break")
436 mStatus = Interpreter_ERROR;
439 throw InterpreterException(e);
443 std::stringstream mess;
444 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
445 if (e.IsInScriptFile())
447 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
448 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
451 std::cerr << mess.str();
454 //=======================================================================
456 //=======================================================================
457 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
459 if (GetExecuter()->GetNoErrorMode())
461 std::string file("?");
463 if (mFileName.size()) {
464 file = mFileName.back();
467 bbtkWarning("ERROR '"<<e.GetErrorMessage()
468 <<"' ("<<file<<":"<<line<<") skipped");
472 mStatus = Interpreter_ERROR;
475 bool in_script = false;
476 std::string file("");
478 if (mFileName.size()) {
479 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
480 if (fs!=0) in_script = true;
481 file = mFileName.back();
484 if (e.GetErrorMessage()!="break")
486 throw InterpreterException(e,in_script,file,line);
490 std::stringstream mess;
491 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
492 if (mFileName.size()) {
493 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
494 mess << "* LINE : "<<mLine.back()<<std::endl;
497 std::cerr << mess.str();
500 //=======================================================================
502 //=======================================================================
503 void Interpreter::CatchStdException( const std::exception& e )
505 if (GetExecuter()->GetNoErrorMode())
507 std::string file("?");
509 if (mFileName.size()) {
510 file = mFileName.back();
513 bbtkWarning("ERROR '"<<e.what()
514 <<"' ("<<file<<":"<<line<<") skipped");
518 mStatus = Interpreter_ERROR;
521 bool in_script = false;
522 std::string file("");
524 if (mFileName.size()) {
525 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
526 if (fs!=0) in_script = true;
527 file = mFileName.back();
531 throw InterpreterException(e.what(),in_script,file,line);
535 std::stringstream mess;
536 mess << "* ERROR : "<<e.what()<<std::endl;
537 if (mFileName.size()) {
538 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
539 mess << "* LINE : "<<mLine.back()<<std::endl;
542 std::cerr << mess.str();
545 //=======================================================================
547 //=======================================================================
548 void Interpreter::CatchUnknownException()
550 if (GetExecuter()->GetNoErrorMode())
552 std::string file("?");
554 if (mFileName.size()) {
555 file = mFileName.back();
558 bbtkWarning("UNDEFINED ERROR "
559 <<"("<<file<<":"<<line<<") skipped");
562 mStatus = Interpreter_ERROR;
565 bool in_script = false;
566 std::string file("");
568 if (mFileName.size()) {
569 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
570 if (fs!=0) in_script = true;
571 file = mFileName.back();
575 throw InterpreterException("Unknown exception caught",
576 in_script,file,line);
580 std::stringstream mess;
581 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
583 if (mFileName.size()) {
584 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
585 mess << "* LINE : "<<mLine.back()<<std::endl;
588 std::cerr << mess.str();
591 //=======================================================================
593 //=======================================================================
595 #define CATCH_MACRO \
596 catch (InterpreterException e) \
598 CatchInterpreterException(e); \
600 catch (bbtk::Exception e) \
602 CatchBbtkException(e); \
604 catch (std::exception& e) \
606 CatchStdException(e); \
610 CatchUnknownException(); \
612 //=======================================================================
615 //=======================================================================
616 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
618 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
620 bool exm = mCommandLine;
621 mCommandLine = false;
625 mStatus = Interpreter_OK;
626 SwitchToFile(filename,source);
627 mInsideComment = false;
628 InterpretCurrentStreams();
632 bbtkDebugMessage("Interpreter",9,
633 "EO Interpreter::InterpretFile(\""
634 <<filename<<"\")"<<std::endl);
635 bbtkDecTab("Interpreter",9);
641 //=======================================================================
644 //=======================================================================
645 Interpreter::ExitStatus
646 Interpreter::InterpretBuffer( std::stringstream* buffer )
648 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
650 bool exm = mCommandLine;
651 mCommandLine = false;
655 mStatus = Interpreter_OK;
656 SwitchToStream(buffer);
657 mInsideComment = false;
658 InterpretCurrentStreams();
663 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
664 bbtkDecTab("Interpreter",9);
669 //=======================================================================
671 //=======================================================================
672 /// Interprets the currently open streams
673 Interpreter::ExitStatus Interpreter::InterpretCurrentStreams()
675 bbtkDebugMessageInc("Interpreter",9,
676 "Interpreter::InterpretCurrentStreams()"<<std::endl);
678 while (mFile.size()>0)
680 while (!mFile.back()->eof()) {
683 mFile.back()->getline(buf,500);
684 std::string str(buf);
686 int size=str.length();
687 if ( str[ size-1 ]==13 )
693 DoInterpretLine(str);
701 //=======================================================================
703 //=======================================================================
704 /// Runs the interpretation of a command
705 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
707 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
711 mStatus = Interpreter_OK;
712 mInsideComment = false;
713 DoInterpretLine(line );
718 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
720 bbtkDecTab("Interpreter",9);
724 //=======================================================================
727 //=======================================================================
728 void Interpreter::DoInterpretLine( const std::string& line )
730 bbtkDebugMessageInc("Interpreter",9,"Interpreter::DoInterpretLine(\""<<line<<"\")"<<std::endl);
732 std::vector<std::string> words;
733 SplitLine(line,words);
738 bbtkDebugDecTab("Interpreter",9);
742 // Single line comment : # or //
743 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
745 bbtkDebugDecTab("Interpreter",9);
746 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
750 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
752 if (words[0][0]=='/' && words[0][1]=='*')
754 bbtkDebugDecTab("Interpreter",9);
755 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
756 mInsideComment = true;
760 if (words[0][0]=='*' && words[0][1]=='/')
762 bbtkDebugDecTab("Interpreter",9);
763 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
764 if ( !mInsideComment ) {
765 bbtkDebugDecTab("Interpreter",9);
766 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
768 mInsideComment = false;
774 bbtkDebugDecTab("Interpreter",9);
775 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
780 CommandInfoType command;
781 InterpretCommand(words,command);
783 bbtkDebugMessage("Interpreter",9,
784 "Command='"<<command.keyword
785 <<"' code="<<command.code<<std::endl);
787 std::string left,right,left2,right2;
788 std::string filename;
791 if (command.code==cMessage)
795 mVirtualExecuter->HelpMessages();
799 sscanf(words[2].c_str(),"%d",&level);
800 mVirtualExecuter->SetMessageLevel(words[1],level);
806 bbtkMessage("echo",2,line<<std::endl);
809 // break and quit commands
810 if ((command.code==cBreak) || (command.code==cQuit))
812 bool in_script = false;
813 std::string file("");
815 if (mFileName.size())
817 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
818 if (fs!=0) in_script = true;
819 file = mFileName.back();
822 if (command.code==cBreak)
825 std::cout << "BreakException("
828 <<line<<")"<<std::endl;
830 bbtkError("break");//,in_script,file,line);
831 // throw BreakException(in_script,file,line);
835 bbtkError("quit");//,in_script,file,line);
836 //throw QuitException(in_script,file,line);
842 switch (command.code)
845 mVirtualExecuter->Create(words[1],words[2]);
849 mVirtualExecuter->Destroy(words[1]);
853 Utilities::SplitAroundFirstDot(words[1],left,right);
854 Utilities::SplitAroundFirstDot(words[2],left2,right2);
855 mVirtualExecuter->Connect(left,right,left2,right2);
859 mVirtualExecuter->BeginPackage(words[1]);
863 mVirtualExecuter->EndPackage();
867 if (mFileName.size()>0)
869 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
873 mVirtualExecuter->Define(words[1],"",filename);
877 mVirtualExecuter->Define(words[1],words[2],filename);
882 mVirtualExecuter->EndDefine();
886 mVirtualExecuter->Kind(words[1]);
890 mVirtualExecuter->Print(words[1]);
894 if (words[1]=="freeze")
896 mVirtualExecuter->SetNoExecMode(true);
899 else if (words[1]=="freeze_no_error")
901 mVirtualExecuter->SetNoExecMode(true);
902 mVirtualExecuter->SetNoErrorMode(true);
905 else if (words[1]=="unfreeze")
907 mVirtualExecuter->SetNoExecMode(false);
908 mVirtualExecuter->SetNoErrorMode(false);
912 mVirtualExecuter->Execute(words[1]);
917 Utilities::SplitAroundFirstDot(words[2],left,right);
918 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
922 Utilities::SplitAroundFirstDot(words[2],left,right);
923 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
927 Utilities::SplitAroundFirstDot(words[1],left,right);
928 mVirtualExecuter->Set(left,right,words[2]);
932 mVirtualExecuter->Author(words[1]);
936 NewGUI(words[1],words[2]);
940 mVirtualExecuter->Category(words[1]);
945 Index("tmp_index.html");
946 else if (words.size()==2)
948 else if (words.size()==3)
949 Index(words[1],words[2]);
953 mVirtualExecuter->Description(words[1]);
974 mVirtualExecuter->Clear();
978 // if 'source' was given (words.size()==3) then tell to set the
979 // source file name of the current complex box with the full file name included
982 InterpretFile(words[1],(words.size()==3));
986 SwitchToFile(words[1],(words.size()==3) );
991 GetExecuter()->LoadPackage(words[1]);
995 GetExecuter()->UnLoadPackage(words[1]);
999 if (words.size()==2) Debug(words[1]);
1004 if (words.size() == 2)
1006 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1007 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1011 mVirtualExecuter->SetWorkspaceName(words[2]);
1016 bbtkInternalError("should not reach here !!!");
1019 bbtkDecTab("Interpreter",9);
1021 //=======================================================================
1027 //=======================================================================
1028 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1030 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
1032 std::string delimiters = "\"";
1033 std::vector<std::string> quote;
1034 Utilities::SplitString(str,delimiters,quote);
1037 std::vector<std::string>::iterator i;
1038 for (i=quote.begin(); i!=quote.end(); )
1040 Utilities::SplitString(*i,delimiters,tokens);
1044 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
1045 tokens.push_back(*i);
1050 for (i=tokens.begin(); i!=tokens.end(); ++i)
1052 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
1054 bbtkDebugMessageCont("Interpreter",9,std::endl);
1056 bbtkDebugDecTab("Interpreter",9);
1058 //=======================================================================
1061 //=======================================================================
1062 void Interpreter::Reset()
1064 // Cannot close all files if the reset command is read from a file !
1066 mFileNameHistory.clear();
1067 this->mVirtualExecuter->Reset();
1069 //=======================================================================
1071 //=======================================================================
1076 void Interpreter::Print( const std::string& str)
1078 if (mVirtualExecuter->GetNoExecMode()) return;
1080 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
1083 // InterpretLine ("load std")
1084 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1085 // InterpretLine("new Print _P_")
1086 // InterpretLine("connect _C_.Out _P_.In")
1090 std::vector<std::string> chains;
1091 std::string delimiters("$");
1093 // Skip delimiters at beginning.
1094 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1095 bool is_text = true;
1096 if (lastPos>0) is_text = false;
1098 // Find first delimiter.
1099 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1101 while (std::string::npos != pos || std::string::npos != lastPos)
1105 // Found a text token, add it to the vector.
1106 chains.push_back(str.substr(lastPos, pos - lastPos));
1107 // std::string token = str.substr(lastPos, pos - lastPos)
1108 // InterpretLine("set _C_.In%num% %token%")
1114 // is an output (between $$) : decode
1115 std::string tok,box,output;
1116 tok = str.substr(lastPos, pos - lastPos);
1117 Utilities::SplitAroundFirstDot(tok,box,output);
1118 chains.push_back( mVirtualExecuter->Get(box,output) );
1120 // InterpretLine("connect %tok% _C_.In%num%")
1123 // Skip delimiters. Note the "not_of"
1124 lastPos = str.find_first_not_of(delimiters, pos);
1125 // Find next delimiter
1126 pos = str.find_first_of(delimiters, lastPos);
1131 // InterpretLine("exec _P_")
1132 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1134 std::vector<std::string>::iterator i;
1135 for (i= chains.begin(); i!=chains.end(); ++i)
1138 Utilities::SubsBackslashN(*i);
1141 std::cout << std::endl;
1142 bbtkDebugDecTab("Interpreter",9);
1146 //=======================================================================
1151 // =========================================================================
1152 void Interpreter::SwitchToFile( const std::string& name , bool source )
1154 // Note : in the following :
1155 // name : the user supplied name
1156 // - abreviated name e.g. scr scr.bbs
1157 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1158 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1159 // same for Windows, with c:, d: ...
1161 // use ./directory/subdir/scrname.bbs
1164 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1165 <<name<<"\")"<<std::endl);
1167 std::vector<std::string> script_paths;
1168 std::string fullPathScriptName; // full path script name
1169 std::string pkgname; // e.g. <scriptname>.bbs
1170 std::vector<std::string> Filenames;
1172 // The following is *NOT* a debug time message :
1173 // It's a user intended message.
1174 // Please don't remove it.
1175 bbtkMessage("Interpreter",1,
1176 "look for : [" << name
1177 << "]" << std::endl);
1181 pkgname = Utilities::ExtractScriptName(name,upath);
1183 bbtkMessage("Interpreter",3,
1184 "package name:[" << pkgname
1185 << "] path:[" << upath << "]" << std::endl);
1186 bool fullnameGiven = false;
1187 bool foundFile = false;
1189 // ==== "*" provided : load all scripts in given path
1190 // relative (e.g. std/boxes/*) or absolute
1194 std::stringstream* stream = new std::stringstream;
1195 //if (upath.size()!=0) // avoid troubles for "*"
1197 // ==== no path provided : look in root bbs path
1198 if (upath.size()==0)
1200 // bbtkMessage("Interpreter",1,
1201 // LG : add all bbs path
1202 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1203 std::vector<std::string>::const_iterator i;
1204 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1205 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1208 script_paths.push_back(*i);
1211 // ==== absolute path provided
1212 else if (upath[0]=='/' || upath[1] == ':' )
1214 if ( Utilities::IsDirectory( upath ) )
1216 script_paths.push_back(upath);
1220 bbtkError("'"<<upath<<"' : directory does not exist");
1223 // ==== relative path provided : search all bbs path appended with
1224 // the relative path provided
1227 std::vector<std::string>::const_iterator i;
1228 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1229 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1232 std::string full_path(*i);
1233 // we *really* want '.' to be the current working directory
1234 if (full_path == ".")
1236 char buf[2048]; // for getcwd
1237 char * currentDir = getcwd(buf, 2048);
1238 std::string cwd(currentDir);
1239 full_path = currentDir;
1242 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1245 if ( Utilities::IsDirectory( full_path ) )
1247 script_paths.push_back(full_path);
1250 if (script_paths.empty())
1252 bbtkError("no '"<<upath<<"' subdir found in search paths"
1258 // === search paths list complete : now explore it
1260 // ==== relative name, iterate + load all .bbs/.bbp files
1261 std::vector<std::string>::iterator i;
1262 for (i=script_paths.begin();i!=script_paths.end();i++)
1264 bbtkMessage("Interpreter",1,
1265 "--> Looking in '" << *i << "'" << std::endl);
1269 Utilities::Explore(*i, false, Filenames);
1271 for (std::vector<std::string>::iterator j = Filenames.begin();
1272 j!= Filenames.end(); ++j)
1274 int lgr = (*j).size();
1275 if (lgr < 5) continue;
1276 // ignore non .bbp file
1277 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1279 (*stream) << "include \"" << *j << "\"\n";
1280 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1283 } // for (std::vector...
1284 } // for (i=script_...
1289 bbtkMessage("Interpreter",1,
1290 " --> No .bbp found"<< std::endl);
1294 bbtkMessage("Interpreter",1,
1295 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1296 SwitchToStream(stream);
1300 //=============== end pkgname=="*" ===========
1303 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1304 // (not only a plain script name)
1305 // we trust him, and try to expland the directory name
1306 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1308 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1311 // ===========================================================check user supplied location
1312 fullnameGiven = true;
1314 fullPathScriptName = Utilities::ExpandLibName(name, false);
1316 // allow user to always forget ".bbs"
1317 int l = fullPathScriptName.size();
1321 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1322 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1324 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1325 if ( Utilities::FileExists(tfullPathScriptName) )
1327 fullPathScriptName = tfullPathScriptName;
1332 tfullPathScriptName = fullPathScriptName + ".bbp";
1333 if ( Utilities::FileExists(tfullPathScriptName) )
1335 fullPathScriptName = tfullPathScriptName;
1342 if ( Utilities::FileExists(fullPathScriptName) )
1350 // =============================== iterate on the paths
1352 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1354 std::vector<std::string>::iterator i;
1355 for (i=script_paths.begin();i!=script_paths.end();++i)
1358 // we *really* want '.' to be the current working directory
1361 char buf[2048]; // for getcwd
1362 char * currentDir = getcwd(buf, 2048);
1363 std::string cwd(currentDir);
1367 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1368 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1370 fullPathScriptName = tfullPathScriptName;
1371 if ( ! Utilities::FileExists(fullPathScriptName) )
1373 // The following is *NOT* a debug time message :
1374 // It's a user intended message.
1375 // Please don't remove it.
1376 bbtkMessage("Interpreter",2,
1377 " [" <<fullPathScriptName <<"] : does not exist"
1379 continue; // try next path
1381 bbtkMessage("Interpreter",2,
1382 " [" <<fullPathScriptName
1383 <<"] : found" <<std::endl);
1385 break; // a script was found; we stop iterating
1389 fullPathScriptName = tfullPathScriptName + ".bbs";
1390 // Check if library exists
1391 if ( ! Utilities::FileExists(fullPathScriptName) )
1393 fullPathScriptName = tfullPathScriptName + ".bbp";
1394 if ( ! Utilities::FileExists(fullPathScriptName) )
1396 // The following is *NOT* a debug time message :
1397 // It's a user intended message.
1398 // Please don't remove it.
1399 bbtkMessage("Interpreter",2,
1400 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1402 continue; // try next path
1405 bbtkMessage("Interpreter",2,
1406 " [" <<fullPathScriptName
1407 <<"] : found" <<std::endl);
1409 break; // a script was found; we stop iterating
1411 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1417 if(fullPathScriptName == "")
1418 bbtkError("Path ["<<upath<<"] doesn't exist");
1420 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1422 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1427 LoadScript(fullPathScriptName,name);
1428 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1433 //=======================================================================
1436 //=======================================================================
1437 void Interpreter::SwitchToStream( std::stringstream* stream )
1439 mFile.push_back(stream);
1440 std::ostringstream buffer_name;
1442 buffer_name << "buffer_" ;
1444 if (mFileName.size()>0 )
1446 buffer_name << mFileName.back() << "_" << mLine.back();
1448 mFileName.push_back(buffer_name.str());
1449 mIncludeFileName.push_back(buffer_name.str());
1452 //=======================================================================
1454 //=======================================================================
1456 void Interpreter::LoadScript( std::string fullPathScriptName,
1457 std::string includeScriptName)
1459 Utilities::replace( fullPathScriptName ,
1460 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1462 if (find(mFileNameHistory.begin(),
1463 mFileNameHistory.end(),
1464 fullPathScriptName)!=mFileNameHistory.end())
1470 s = new std::ifstream;
1471 s->open(fullPathScriptName.c_str());
1474 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1478 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1479 << "] found" << std::endl);
1482 mFileName.push_back(fullPathScriptName);
1483 mFileNameHistory.push_back(fullPathScriptName);
1484 mIncludeFileName.push_back(includeScriptName);
1489 //=======================================================================
1491 //=======================================================================
1492 void Interpreter::CloseCurrentFile()
1494 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1497 if (mFile.size()==0)
1499 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1503 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1505 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1506 if (file!=0) file->close();
1508 delete mFile.back();
1510 mFileName.pop_back();
1511 mIncludeFileName.pop_back();
1514 bbtkDebugMessage("Interpreter",9," Remains "
1516 <<" open"<<std::endl);
1517 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1520 //=======================================================================
1522 //=======================================================================
1523 void Interpreter::CloseAllFiles()
1525 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1528 while (mFile.size() != 0)
1532 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1535 //=======================================================================
1539 //=======================================================================
1540 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1541 CommandInfoType& info )
1543 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1545 // searches the command keyword
1546 CommandDictType::iterator c;
1547 c = mCommandDict.find(words[0]);
1548 if ( c == mCommandDict.end() ) {
1549 bbtkError(words[0]<<" : unknown command");
1552 // tests the number of args
1553 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1554 ( ((int)words.size())-1 > c->second.argmax ) )
1556 HelpCommand(words[0]);
1557 bbtkError(words[0]<<" : wrong number of arguments");
1561 bbtkDecTab("Interpreter",9);
1563 //=======================================================================
1566 //=======================================================================
1567 /// Displays help on all the commands
1568 void Interpreter::Help(const std::vector<std::string>& words)
1570 unsigned int nbarg = words.size()-1;
1578 if (words[1]=="packages")
1580 GetExecuter()->GetFactory()->PrintPackages(true);
1585 HelpCommand(words[1]);
1587 catch (bbtk::Exception e)
1591 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1595 ConfigurationFile::GetInstance().Get_doc_path();
1596 url += "/bbdoc/" + words[1] + "/index.html";
1597 if (Utilities::FileExists(url))
1599 mUser->InterpreterUserViewHtmlPage(url);
1603 catch (bbtk::Exception f)
1607 std::string package;
1608 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1612 ConfigurationFile::GetInstance().Get_doc_path();
1613 url += "/bbdoc/" + package + "/index.html";
1614 if (Utilities::FileExists(url))
1616 url += "#" + words[1];
1617 mUser->InterpreterUserViewHtmlPage(url);
1621 catch (bbtk::Exception g)
1625 GetExecuter()->ShowRelations(words[1],"0","9999");
1627 catch (bbtk::Exception h){
1628 bbtkError("\""<<words[1].c_str()
1629 <<"\" is not a known command, package, black box type or black box name");
1637 if (words[2]=="all")
1639 if ( words[1]=="packages" )
1641 GetExecuter()->GetFactory()->PrintPackages(true,true);
1646 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1648 catch (bbtk::Exception f)
1654 HelpCommand(words[0]);
1655 bbtkError(words[0]<<" : syntax error");
1660 bbtkError("Should not reach here !!!");
1663 //=======================================================================
1665 //===================================================================
1666 /// Displays the Configuration
1667 void Interpreter::Config() const
1669 ConfigurationFile::GetInstance().GetHelp(1);
1671 //===================================================================
1673 //=======================================================================
1674 /// Displays help on all the commands
1675 void Interpreter::HelpCommands()
1677 std::cout << "Available commands :" << std::endl;
1678 CommandDictType::iterator i;
1679 for ( i = mCommandDict.begin();
1680 i != mCommandDict.end();
1682 std::cout << " " << i->first << std::endl;
1683 // std::cout << " usage : " << i->second.syntax << std::endl;
1684 // std::cout << " " << i->second.help << std::endl;
1688 //=======================================================================
1691 //=======================================================================
1692 /// Displays help on a particular commands
1693 void Interpreter::HelpCommand(const std::string& s)
1695 CommandDictType::iterator c;
1696 c = mCommandDict.find(s);
1697 if ( c == mCommandDict.end() ) {
1698 bbtkError(s<<" : Unknown command");
1700 // std::cout << " " << s << " : "<< std::endl;
1701 // CommandParamDictType::iterator i;
1702 // for ( i = c->second.begin();
1703 // i != c->second.end();
1705 std::cout << " usage : " << c->second.syntax << std::endl;
1706 std::cout << " " << c->second.help << std::endl;
1709 //=======================================================================
1712 //=======================================================================
1713 /// Fills the vector commands with the commands which
1714 /// have the first n chars of buf for prefix
1715 /// TODO : skip initial spaces in buf and also return the position of first
1716 /// non blank char in buf
1717 void Interpreter::FindCommandsWithPrefix( char* buf,
1719 std::vector<std::string>& commands )
1721 CommandDictType::const_iterator i;
1722 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1724 if ((i->first).find(buf,0,n) == 0)
1725 commands.push_back(i->first);
1728 //=======================================================================
1732 //=======================================================================
1733 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1735 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1736 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1738 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1739 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1740 // E.G. STORE THIS IN bbtk_config.xml
1741 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1742 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1743 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1744 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1745 #define BBTK_BACKSPACE_KBCODE 0x00000008
1746 #define BBTK_DEL_KBCODE 0x0000007F
1747 #define BBTK_SPACE_KBCODE 0x00000020
1749 //=======================================================================
1750 void Interpreter::GetLineFromPrompt(std::string& s)
1755 unsigned int MAX_LINE_SIZE = 160;
1756 unsigned int MAX_HISTORY_SIZE = 100;
1758 char* newline = new char[MAX_LINE_SIZE];
1759 memset(newline,0,MAX_LINE_SIZE);
1760 char* histline = new char[MAX_LINE_SIZE];
1761 memset(histline,0,MAX_LINE_SIZE);
1763 char* line = newline;
1764 unsigned int hist = mHistory.size();
1770 read ( STDIN_FILENO, &c, 4) ;
1772 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1774 // Printable character
1775 if ( (ind<MAX_LINE_SIZE-1) &&
1776 ( c >= BBTK_SPACE_KBCODE ) &&
1777 ( c < BBTK_DEL_KBCODE ))
1785 // delete the unused line
1791 // empty lines are not stored in from history
1794 // if history too long : delete oldest command
1795 if (mHistory.size()>MAX_HISTORY_SIZE)
1797 delete mHistory.front();
1798 mHistory.pop_front();
1800 mHistory.push_back(line);
1805 else if ( (ind>0) &&
1806 ((c == BBTK_BACKSPACE_KBCODE) ||
1807 (c == BBTK_DEL_KBCODE)) )
1815 // TODO : Command completion
1816 std::vector<std::string> commands;
1817 FindCommandsWithPrefix( line,ind,commands);
1818 if (commands.size()==1)
1820 std::string com = *commands.begin();
1821 for (; ind<com.size(); ++ind)
1823 PrintChar(com[ind]);
1829 else if (commands.size()>1)
1831 std::vector<std::string>::iterator i;
1833 for (i=commands.begin();i!=commands.end();++i)
1835 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1838 write(STDOUT_FILENO,"\n> ",3);
1839 //for (int j=0;j<ind;++j)
1841 write(STDOUT_FILENO,line,ind);
1845 // Arrow up : back in history
1846 else if (c==BBTK_UP_ARROW_KBCODE)
1850 // erase current line
1851 while (ind--) BackSpace();
1855 strcpy(histline,mHistory[hist]);
1859 write(STDOUT_FILENO,line,ind);
1862 // Arrow down : down in history
1863 else if (c==BBTK_DOWN_ARROW_KBCODE)
1865 if (hist<mHistory.size()-1)
1867 // erase current line
1868 while (ind--) BackSpace();
1872 strcpy(histline,mHistory[hist]);
1876 write(STDOUT_FILENO,line,ind);
1878 // end of history : switch back to newline
1879 else if (hist==mHistory.size()-1)
1881 // erase current line
1882 while (ind--) BackSpace();
1889 write(STDOUT_FILENO,line,ind);
1893 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1895 PrintChar(line[ind]);
1900 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1908 write(STDOUT_FILENO,"\n\r",2);
1916 //=======================================================================
1917 void Interpreter::GetLineFromPrompt(std::string& s)
1943 //=======================================================================
1949 //=======================================================================
1950 void Interpreter::CommandLineInterpreter()
1952 bbtkDebugMessageInc("Interpreter",9,
1953 "Interpreter::CommandLineInterpreter()"<<std::endl);
1955 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1956 // Initialise the tty in non canonical mode with no echo
1957 // oter remembers the previous settings to restore them after
1958 struct termios ter,oter;
1961 ter.c_lflag &= ~ECHO;
1962 ter.c_lflag &= ~ICANON;
1965 tcsetattr(0,TCSANOW,&ter);
1968 mCommandLine = true;
1970 // bool insideComment = false; // for multiline comment
1971 mInsideComment = false;
1977 GetLineFromPrompt(line);
1978 DoInterpretLine(line); //, insideComment);
1981 catch (QuitException e)
1983 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1987 catch (bbtk::Exception e)
1991 catch (std::exception& e)
1993 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1997 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2002 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2003 tcsetattr(0,TCSANOW,&oter);
2006 std::cout << "Good bye !" << std::endl;
2008 bbtkDebugDecTab("Interpreter",9);
2011 //=======================================================================
2012 void Interpreter::Graph(const std::vector<std::string>& words)
2015 bool system_display = true;
2017 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2018 system_display = false;
2020 if (words.size()==1)
2022 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
2024 else if (words.size()==2)
2026 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
2028 else if (words.size()==3)
2030 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
2032 else if (words.size()==4)
2034 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
2036 else if (words.size()==5)
2038 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
2040 else if (words.size()==6)
2042 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
2044 else if (words.size()==7)
2046 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
2049 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2050 mUser->InterpreterUserViewHtmlPage(page);
2053 //=======================================================================
2056 //=======================================================================
2057 void Interpreter::Index(const std::string& filename,
2058 const std::string& type)
2060 Factory::IndexEntryType t;
2061 if (type=="Initials") t = Factory::Initials;
2062 else if (type=="Categories") t = Factory::Categories;
2063 else if (type=="Packages") t = Factory::Packages;
2064 else if (type=="Adaptors") t = Factory::Adaptors;
2066 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
2068 //=======================================================================
2071 //=======================================================================
2072 void Interpreter::NewGUI(const std::string& boxname,
2073 const std::string& instanceName)
2075 if (mRealExecuter.expired())
2077 bbtkError("command 'newgui' cannot be compiled yet");
2080 std::string typeName = instanceName+"Type";
2081 std::stringstream* s = new std::stringstream;
2082 // create the complex box
2083 (*s) << "define "<<typeName<<std::endl;
2084 // (*s) << " description 'Automatically generated user interface for the box "
2085 // << boxname << "'" <<std::endl;
2086 // create the Layout box
2087 (*s) << " load wx"<<std::endl;
2088 (*s) << " new LayoutLine layout"<<std::endl;
2089 // create the output 'Widget'
2090 (*s) << " output Widget layout.Widget Widget"<<std::endl;
2091 // the box change output
2092 (*s) << " new MultipleInputs change"<<std::endl;
2093 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
2095 // Browse the inputs of the box in order to find which ones are not
2096 // connected and can be adapted from a widget adaptor
2097 // vector which stores the list of inputs of the box which must be connected
2098 std::vector<std::string> in;
2100 Factory::Pointer F = mVirtualExecuter->GetFactory();
2102 Package::Pointer user = F->GetPackage("user");
2104 ComplexBlackBoxDescriptor::Pointer workspace =
2105 mRealExecuter.lock()->GetCurrentDescriptor();
2110 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2115 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2118 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2119 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2121 BlackBox::InputConnectorMapType::iterator i;
2122 for (i=box->bbGetInputConnectorMap().begin();
2123 i!=box->bbGetInputConnectorMap().end();
2126 // If the input is connected : continue
2127 if (i->second->IsConnected()) continue;
2128 // Get the input descriptor
2129 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2130 // If it is a "system" input : skip it
2131 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2132 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2135 std::string widget,adaptor;
2136 // try to find a widget adaptor
2137 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2141 // command to create the adaptor
2142 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2143 // Sets the label of the widget adaptor to the name of the input
2144 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2145 // Sets the initial value of the widget to the value of the input
2146 (*s) << " set "<<i->first<<".In \" "
2147 <<box->bbGetInputAsString(i->first)<<"\""
2149 // store the input name
2150 in.push_back(i->first);
2151 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2152 //<i->first<<"'"<<std::endl;
2153 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2155 // try to find a two pieces adaptor
2156 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2160 // command to create the widget
2161 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2162 // command to create the adaptor
2163 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2165 (*s) << " connect "<<i->first<<"Widget.Out "
2166 <<i->first<<".In"<<std::endl;
2167 // Sets the label of the widget adaptor to the name of the input
2168 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2169 // Sets the initial value of the widget to the value of the input
2170 (*s) << " set "<<i->first<<"Widget.In \" "
2171 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2172 // store the input name
2173 in.push_back(i->first);
2174 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2175 //<i->first<<"'"<<std::endl;
2176 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2179 // try to find an adaptor from string
2180 // If found then can create a text input which
2181 // will be automatically adapted
2182 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2186 // command to create the adaptor
2187 (*s) << " new InputText "<<i->first<<std::endl;
2188 // Sets the label of the widget adaptor to the name of the input
2189 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2190 // Sets the initial value of the widget to the value of the input
2191 (*s) << " set "<<i->first<<".In \" "
2192 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2193 // store the input name
2194 in.push_back(i->first);
2195 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2196 //<i->first<<"'"<<std::endl;
2197 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2206 // command to create the output
2207 (*s) << " output "<<i->first<<" "
2208 <<i->first<<".Out "<<i->first<<std::endl;
2209 // <<" Output of the widget which allows to set "
2213 // Inputs for window properties
2214 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2215 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2216 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2217 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2218 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2222 // Execute the box executes the layout
2223 (*s) << " exec layout" << std::endl;
2224 (*s) << "endefine" << std::endl;
2225 // (*s) << "help "<< typeName<< std::endl;
2226 // instanciate the box and connect it
2227 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2229 std::vector<std::string>::iterator j;
2230 for (j=in.begin();j!=in.end();++j)
2233 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2234 << boxname<<"."<<*j<<std::endl;
2236 // That's all folks ! now execute the commands :
2239 //=======================================================================
2243 //==========================================================================
2244 void Interpreter::Debug(const std::string& name)
2246 if ((name.length()==2)&&(name[0]=='-'))
2250 bbtk::StaticInitTime::PrintObjectListInfo = true;
2254 // int o = MessageManager::GetMessageLevel("debug");
2255 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2256 mVirtualExecuter->GetFactory()->CheckPackages();
2257 // MessageManager::SetMessageLevel("debug",o);
2262 Object:: PrintObjectListInfo(name);
2265 //==========================================================================
2268 //==========================================================================
2269 // Adds a callback when 'break' command issued
2270 void Interpreter::AddBreakObserver( BreakCallbackType c )
2272 mBreakSignal.connect(c);
2274 //==========================================================================
2277 //==========================================================================
2278 std::string Interpreter::GetObjectName() const
2280 return std::string("Interpreter");
2282 //==========================================================================
2284 //==========================================================================
2285 std::string Interpreter::GetObjectInfo() const
2287 std::stringstream i;
2290 //==========================================================================
2292 //==========================================================================
2293 size_t Interpreter::GetObjectSize() const
2295 size_t s = Superclass::GetObjectSize();
2296 s += Interpreter::GetObjectInternalSize();
2299 //==========================================================================
2300 //==========================================================================
2301 size_t Interpreter::GetObjectInternalSize() const
2303 size_t s = sizeof(Interpreter);
2306 //==========================================================================
2307 //==========================================================================
2308 size_t Interpreter::GetObjectRecursiveSize() const
2310 size_t s = Superclass::GetObjectRecursiveSize();
2311 s += Interpreter::GetObjectInternalSize();
2312 s += mVirtualExecuter->GetObjectRecursiveSize();
2315 //==========================================================================