1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2009/04/08 07:56:11 $
6 Version: $Revision: 1.83 $
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 "bbtkAtomicBlackBox.h"
43 #include "bbtkWxBlackBox.h"
46 #ifdef CMAKE_HAVE_TERMIOS_H
48 #define BBTK_USE_TERMIOS_BASED_PROMPT
56 //=======================================================================
57 Interpreter::Pointer Interpreter::New(const std::string& cpp_file)
59 bbtkDebugMessage("Kernel",9,"Interpreter::New('"<<cpp_file<<"')"<<std::endl);
60 return MakePointer(new Interpreter(cpp_file));
62 //=======================================================================
64 //=======================================================================
65 Interpreter::Pointer Interpreter::New(VirtualExec::Pointer e)
67 bbtkDebugMessage("Kernel",9,"Interpreter::New(VirtualExec)"<<std::endl);
68 return MakePointer(new Interpreter(e));
70 //=======================================================================
72 //=======================================================================
73 Interpreter::Interpreter(const std::string& cpp_file)
75 Init(VirtualExec::Pointer(), cpp_file);
77 //=======================================================================
79 //=======================================================================
80 Interpreter::Interpreter(VirtualExec::Pointer e)
84 //=======================================================================
86 //=======================================================================
87 void Interpreter::Init(VirtualExec::Pointer e, const std::string& cpp_file)
93 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);
94 bbtk::MessageManager::RegisterMessageType("Interpreter","Messages of the interpreter",0);
95 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Interpreter()" <<std::endl);
100 else if (cpp_file.size()!=0)
102 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(bbtk::Transcriptor::New(cpp_file));
106 bbtk::Executer::Pointer exe = bbtk::Executer::New();
108 mVirtualExecuter = boost::static_pointer_cast<VirtualExec>(exe);
111 // Lock this pointer or will auto-destruct !!
112 if (!e) mVirtualExecuter->SetInterpreter(MakePointer(this,true));
114 // For the time being, comment out previous line, and
115 // uncomment next line to check Transcriptor
117 //mVirtualExecuter = new bbtk::Transcriptor("GeneratedProgram.txt");
119 // Builds the commands dict
120 CommandInfoType info;
122 info.keyword = "new";
126 info.syntax = "new <type> <name>";
127 info.help = "Creates a new black box of type <type> with name <name>";
128 mCommandDict[info.keyword] = info;
130 info.keyword = "delete";
134 info.syntax = "delete <box>";
135 info.help = "Deletes the black box of name <box>";
136 mCommandDict[info.keyword] = info;
138 info.keyword = "clear";
142 info.syntax = "clear";
143 info.help = "Clears the currently defined complex box (deletes all its boxes and connections)";
144 mCommandDict[info.keyword] = info;
146 info.keyword = "break";
150 info.syntax = "break";
151 info.help = "Breaks the current execution";
152 mCommandDict[info.keyword] = info;
154 info.keyword = "newgui";
158 info.syntax = "newgui <box> <name>";
159 info.help = "Automatically creates a graphical user interface with name <name> for the black box <box> and connects it to the box inputs";
160 mCommandDict[info.keyword] = info;
162 info.keyword = "connect";
165 info.code = cConnect;
166 info.syntax = "connect <box1.output> <box2.input>";
167 info.help = "Connects the ouput <output> of black box <box1> to the input <input> of black box <box2>";
168 mCommandDict[info.keyword] = info;
170 info.keyword = "print";
174 info.syntax = "print <string>";
175 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').";
176 mCommandDict[info.keyword] = info;
178 info.keyword = "exec";
182 info.syntax = "exec <box | 'freeze' | 'unfreeze' | 'freeze_no_error' >";
183 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.";
184 mCommandDict[info.keyword] = info;
186 info.keyword = "package";
189 info.code = cPackage;
190 info.syntax = "package <name>";
191 info.help = "Begins the definition of a package.";
192 mCommandDict[info.keyword] = info;
194 info.keyword = "endpackage";
197 info.code = cEndPackage;
198 info.syntax = "endpackage";
199 info.help = "Ends the definition of a package.";
200 mCommandDict[info.keyword] = info;
202 info.keyword = "define";
206 info.syntax = "define <type> [<package>]";
207 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.";
208 mCommandDict[info.keyword] = info;
210 info.keyword = "endefine";
213 info.code = cEndDefine;
214 info.syntax = "endefine";
215 info.help = "Ends the definition of a new type of complex black box";
216 mCommandDict[info.keyword] = info;
218 info.keyword = "kind";
222 info.syntax = "kind <ADAPTOR|DEFAULT_ADAPTOR|WIDGET_ADAPTOR|DEFAULT_WIDGET_ADAPTOR>";
223 info.help = "Sets the kind of the currently defined complex black box";
224 mCommandDict[info.keyword] = info;
226 info.keyword = "input";
230 info.syntax = "input <name> <box.input> <help>";
231 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";
232 mCommandDict[info.keyword] = info;
234 info.keyword = "output";
238 info.syntax = "output <name> <box.output> <help>";
239 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";
240 mCommandDict[info.keyword] = info;
242 info.keyword = "set";
246 info.syntax = "set <box.input> <value>";
247 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";
248 mCommandDict[info.keyword] = info;
250 info.keyword = "config"; // JPR
254 info.syntax = "config";
255 info.help = "Prints the value of all configuration parameters";
256 mCommandDict[info.keyword] = info;
258 info.keyword = "index"; // LG
263 info.syntax = "index [<filename> ['Initials'(default)|'Packages'|'Categories'|'Adaptors']]";
264 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.";
265 mCommandDict[info.keyword] = info;
267 info.keyword = "reset";
271 info.syntax = "reset";
272 info.help = "Deletes all boxes and unloads all packages (reset to start state)";
273 mCommandDict[info.keyword] = info;
275 info.keyword = "author";
279 info.syntax = "author <string>";
280 info.help = "Adds the string <string> to the author information of the black box being defined";
281 mCommandDict[info.keyword] = info;
283 info.keyword = "category"; //JP
286 info.code = cCategory;
287 info.syntax = "category <list of items, separated by ;>";
288 info.help = "Adds the string <string> to the category information of the black box being defined";
289 mCommandDict[info.keyword] = info;
291 info.keyword = "description";
294 info.code = cDescription;
295 info.syntax = "description <string>";
296 info.help = "Adds the string <string> to the descriptive information of the black box being defined";
297 mCommandDict[info.keyword] = info;
299 info.keyword = "help";
303 info.syntax = "help";
304 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>";
305 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.";
306 mCommandDict[info.keyword] = info;
308 info.keyword = "message";
311 info.code = cMessage;
312 info.syntax = "message <kind> <level>";
313 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.";
314 mCommandDict[info.keyword] = info;
316 info.keyword = "include";
319 info.code = cInclude;
320 info.syntax = "include <filename> [source]";
321 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).";
322 mCommandDict[info.keyword] = info;
324 info.keyword = "quit";
328 info.syntax = "quit";
329 info.help = "Quits the program (during script execution it stops the complete execution)";
330 mCommandDict[info.keyword] = info;
332 info.keyword = "load";
336 info.syntax = "load <packagename>";
337 info.help = "Loads the black box package <packagename>";
338 mCommandDict[info.keyword] = info;
340 info.keyword = "unload";
344 info.syntax = "unload <packagename>";
345 info.help = "Unloads the black box package <packagename>";
346 mCommandDict[info.keyword] = info;
348 info.keyword = "graph";
352 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 ]]]]]]";
353 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')";
354 mCommandDict[info.keyword] = info;
356 info.keyword = "debug";
360 info.syntax = "debug [expr|-C|-D]";
361 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";
362 mCommandDict[info.keyword] = info;
365 info.keyword = "workspace";
368 info.code = cWorkspace;
369 info.syntax = "workspace < ( freeze | unfreeze ) | ( rename <newname> ) >";
370 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.";
371 mCommandDict[info.keyword] = info;
374 bbtkDebugDecTab("Interpreter",9);
377 //=======================================================================
381 //=======================================================================
385 Interpreter::~Interpreter()
387 bbtkDebugMessageInc("Interpreter",9,"==> Interpreter::~Interpreter()" <<std::endl);
388 mVirtualExecuter = VirtualExec::Pointer();
389 bbtkDebugMessageInc("Interpreter",9,"<== Interpreter::~Interpreter()" <<std::endl);
391 //=======================================================================
394 //=======================================================================
395 InterpreterException::InterpreterException( const std::string& message,
397 const std::string& script_file,
400 : Exception("Interpreter",0,message),
401 mInScriptFile(in_script_file),
402 mScriptFile(script_file),
403 mScriptLine(script_line)
406 //=======================================================================
407 //=======================================================================
408 InterpreterException::InterpreterException( const Exception& excep,
410 const std::string& script_file,
414 mInScriptFile(in_script_file),
415 mScriptFile(script_file),
416 mScriptLine(script_line)
419 //=======================================================================
422 //=======================================================================
423 void Interpreter::CatchInterpreterException( const InterpreterException& e )
425 if (GetExecuter()->GetNoErrorMode())
427 bbtkWarning("ERROR :"<<e.GetErrorMessage()
428 <<" ("<<e.GetScriptFile()<<":"<<e.GetScriptLine()
435 if (e.GetErrorMessage()!="break")
437 mStatus = Interpreter_ERROR;
440 throw InterpreterException(e);
444 std::stringstream mess;
445 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
446 if (e.IsInScriptFile())
448 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
449 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
452 std::cerr << mess.str();
455 //=======================================================================
457 //=======================================================================
458 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
460 if (GetExecuter()->GetNoErrorMode())
462 std::string file("?");
464 if (mFileName.size()) {
465 file = mFileName.back();
468 bbtkWarning("ERROR '"<<e.GetErrorMessage()
469 <<"' ("<<file<<":"<<line<<") skipped");
473 mStatus = Interpreter_ERROR;
476 bool in_script = false;
477 std::string file("");
479 if (mFileName.size()) {
480 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
481 if (fs!=0) in_script = true;
482 file = mFileName.back();
485 if (e.GetErrorMessage()!="break")
487 throw InterpreterException(e,in_script,file,line);
491 std::stringstream mess;
492 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
493 if (mFileName.size()) {
494 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
495 mess << "* LINE : "<<mLine.back()<<std::endl;
498 std::cerr << mess.str();
501 //=======================================================================
503 //=======================================================================
504 void Interpreter::CatchStdException( const std::exception& e )
506 if (GetExecuter()->GetNoErrorMode())
508 std::string file("?");
510 if (mFileName.size()) {
511 file = mFileName.back();
514 bbtkWarning("ERROR '"<<e.what()
515 <<"' ("<<file<<":"<<line<<") skipped");
519 mStatus = Interpreter_ERROR;
522 bool in_script = false;
523 std::string file("");
525 if (mFileName.size()) {
526 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
527 if (fs!=0) in_script = true;
528 file = mFileName.back();
532 throw InterpreterException(e.what(),in_script,file,line);
536 std::stringstream mess;
537 mess << "* ERROR : "<<e.what()<<std::endl;
538 if (mFileName.size()) {
539 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
540 mess << "* LINE : "<<mLine.back()<<std::endl;
543 std::cerr << mess.str();
546 //=======================================================================
548 //=======================================================================
549 void Interpreter::CatchUnknownException()
551 if (GetExecuter()->GetNoErrorMode())
553 std::string file("?");
555 if (mFileName.size()) {
556 file = mFileName.back();
559 bbtkWarning("UNDEFINED ERROR "
560 <<"("<<file<<":"<<line<<") skipped");
563 mStatus = Interpreter_ERROR;
566 bool in_script = false;
567 std::string file("");
569 if (mFileName.size()) {
570 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
571 if (fs!=0) in_script = true;
572 file = mFileName.back();
576 throw InterpreterException("Unknown exception caught",
577 in_script,file,line);
581 std::stringstream mess;
582 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
584 if (mFileName.size()) {
585 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
586 mess << "* LINE : "<<mLine.back()<<std::endl;
589 std::cerr << mess.str();
592 //=======================================================================
594 //=======================================================================
596 #define CATCH_MACRO \
597 catch (InterpreterException e) \
599 CatchInterpreterException(e); \
601 catch (bbtk::Exception e) \
603 CatchBbtkException(e); \
605 catch (std::exception& e) \
607 CatchStdException(e); \
611 CatchUnknownException(); \
613 //=======================================================================
616 //=======================================================================
617 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
619 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
621 bool exm = mCommandLine;
622 mCommandLine = false;
626 mStatus = Interpreter_OK;
627 SwitchToFile(filename,source);
628 mInsideComment = false;
629 InterpretCurrentStreams();
633 bbtkDebugMessage("Interpreter",9,
634 "EO Interpreter::InterpretFile(\""
635 <<filename<<"\")"<<std::endl);
636 bbtkDecTab("Interpreter",9);
642 //=======================================================================
645 //=======================================================================
646 Interpreter::ExitStatus
647 Interpreter::InterpretBuffer( std::stringstream* buffer )
649 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
651 bool exm = mCommandLine;
652 mCommandLine = false;
656 mStatus = Interpreter_OK;
657 SwitchToStream(buffer);
658 mInsideComment = false;
659 InterpretCurrentStreams();
664 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
665 bbtkDecTab("Interpreter",9);
670 //=======================================================================
672 //=======================================================================
673 /// Interprets the currently open streams
674 Interpreter::ExitStatus Interpreter::InterpretCurrentStreams()
676 bbtkDebugMessageInc("Interpreter",9,
677 "Interpreter::InterpretCurrentStreams()"<<std::endl);
679 while (mFile.size()>0)
681 while (!mFile.back()->eof()) {
684 mFile.back()->getline(buf,500);
685 std::string str(buf);
687 int size=str.length();
688 if ( str[ size-1 ]==13 )
694 DoInterpretLine(str);
702 //=======================================================================
704 //=======================================================================
705 /// Runs the interpretation of a command
706 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
708 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
712 mStatus = Interpreter_OK;
713 mInsideComment = false;
714 DoInterpretLine(line );
719 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
721 bbtkDecTab("Interpreter",9);
725 //=======================================================================
728 //=======================================================================
729 void Interpreter::DoInterpretLine( const std::string& line )
731 bbtkDebugMessageInc("Interpreter",9,"Interpreter::DoInterpretLine(\""<<line<<"\")"<<std::endl);
733 std::vector<std::string> words;
734 SplitLine(line,words);
739 bbtkDebugDecTab("Interpreter",9);
743 // Single line comment : # or //
744 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
746 bbtkDebugDecTab("Interpreter",9);
747 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
751 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
753 if (words[0][0]=='/' && words[0][1]=='*')
755 bbtkDebugDecTab("Interpreter",9);
756 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
757 mInsideComment = true;
761 if (words[0][0]=='*' && words[0][1]=='/')
763 bbtkDebugDecTab("Interpreter",9);
764 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
765 if ( !mInsideComment ) {
766 bbtkDebugDecTab("Interpreter",9);
767 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
769 mInsideComment = false;
775 bbtkDebugDecTab("Interpreter",9);
776 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
781 CommandInfoType command;
782 InterpretCommand(words,command);
784 bbtkDebugMessage("Interpreter",9,
785 "Command='"<<command.keyword
786 <<"' code="<<command.code<<std::endl);
788 std::string left,right,left2,right2;
789 std::string filename;
792 if (command.code==cMessage)
796 mVirtualExecuter->HelpMessages();
800 sscanf(words[2].c_str(),"%d",&level);
801 mVirtualExecuter->SetMessageLevel(words[1],level);
807 bbtkMessage("echo",2,line<<std::endl);
810 // break and quit commands
811 if ((command.code==cBreak) || (command.code==cQuit))
813 bool in_script = false;
814 std::string file("");
816 if (mFileName.size())
818 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
819 if (fs!=0) in_script = true;
820 file = mFileName.back();
823 if (command.code==cBreak)
826 std::cout << "BreakException("
829 <<line<<")"<<std::endl;
831 bbtkError("break");//,in_script,file,line);
832 // throw BreakException(in_script,file,line);
836 bbtkError("quit");//,in_script,file,line);
837 //throw QuitException(in_script,file,line);
843 switch (command.code)
846 mVirtualExecuter->Create(words[1],words[2]);
850 mVirtualExecuter->Destroy(words[1]);
854 Utilities::SplitAroundFirstDot(words[1],left,right);
855 Utilities::SplitAroundFirstDot(words[2],left2,right2);
856 mVirtualExecuter->Connect(left,right,left2,right2);
860 mVirtualExecuter->BeginPackage(words[1]);
864 mVirtualExecuter->EndPackage();
868 if (mFileName.size()>0)
870 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
874 mVirtualExecuter->Define(words[1],"",filename);
878 mVirtualExecuter->Define(words[1],words[2],filename);
883 mVirtualExecuter->EndDefine();
887 mVirtualExecuter->Kind(words[1]);
891 mVirtualExecuter->Print(words[1]);
895 if (words[1]=="freeze")
897 mVirtualExecuter->SetNoExecMode(true);
900 else if (words[1]=="freeze_no_error")
902 mVirtualExecuter->SetNoExecMode(true);
903 mVirtualExecuter->SetNoErrorMode(true);
906 else if (words[1]=="unfreeze")
908 mVirtualExecuter->SetNoExecMode(false);
909 mVirtualExecuter->SetNoErrorMode(false);
913 mVirtualExecuter->Execute(words[1]);
918 Utilities::SplitAroundFirstDot(words[2],left,right);
919 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
923 Utilities::SplitAroundFirstDot(words[2],left,right);
924 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
928 Utilities::SplitAroundFirstDot(words[1],left,right);
929 mVirtualExecuter->Set(left,right,words[2]);
933 mVirtualExecuter->Author(words[1]);
937 NewGUI(words[1],words[2]);
941 mVirtualExecuter->Category(words[1]);
946 Index("tmp_index.html");
947 else if (words.size()==2)
949 else if (words.size()==3)
950 Index(words[1],words[2]);
954 mVirtualExecuter->Description(words[1]);
975 mVirtualExecuter->Clear();
979 // if 'source' was given (words.size()==3) then tell to set the
980 // source file name of the current complex box with the full file name included
983 InterpretFile(words[1],(words.size()==3));
987 SwitchToFile(words[1],(words.size()==3) );
992 GetExecuter()->LoadPackage(words[1]);
996 GetExecuter()->UnLoadPackage(words[1]);
1000 if (words.size()==2) Debug(words[1]);
1005 if (words.size() == 2)
1007 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
1008 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
1012 mVirtualExecuter->SetWorkspaceName(words[2]);
1017 bbtkInternalError("should not reach here !!!");
1020 bbtkDecTab("Interpreter",9);
1022 //=======================================================================
1028 //=======================================================================
1029 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
1031 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
1033 std::string delimiters = "\"";
1034 std::vector<std::string> quote;
1035 Utilities::SplitString(str,delimiters,quote);
1038 std::vector<std::string>::iterator i;
1039 for (i=quote.begin(); i!=quote.end(); )
1041 Utilities::SplitString(*i,delimiters,tokens);
1045 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
1046 tokens.push_back(*i);
1051 for (i=tokens.begin(); i!=tokens.end(); ++i)
1053 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
1055 bbtkDebugMessageCont("Interpreter",9,std::endl);
1057 bbtkDebugDecTab("Interpreter",9);
1059 //=======================================================================
1062 //=======================================================================
1063 void Interpreter::Reset()
1065 // Cannot close all files if the reset command is read from a file !
1067 mFileNameHistory.clear();
1068 this->mVirtualExecuter->Reset();
1070 //=======================================================================
1072 //=======================================================================
1077 void Interpreter::Print( const std::string& str)
1079 if (mVirtualExecuter->GetNoExecMode()) return;
1081 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
1084 // InterpretLine ("load std")
1085 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1086 // InterpretLine("new Print _P_")
1087 // InterpretLine("connect _C_.Out _P_.In")
1091 std::vector<std::string> chains;
1092 std::string delimiters("$");
1094 // Skip delimiters at beginning.
1095 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1096 bool is_text = true;
1097 if (lastPos>0) is_text = false;
1099 // Find first delimiter.
1100 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1102 while (std::string::npos != pos || std::string::npos != lastPos)
1106 // Found a text token, add it to the vector.
1107 chains.push_back(str.substr(lastPos, pos - lastPos));
1108 // std::string token = str.substr(lastPos, pos - lastPos)
1109 // InterpretLine("set _C_.In%num% %token%")
1115 // is an output (between $$) : decode
1116 std::string tok,box,output;
1117 tok = str.substr(lastPos, pos - lastPos);
1118 Utilities::SplitAroundFirstDot(tok,box,output);
1119 chains.push_back( mVirtualExecuter->Get(box,output) );
1121 // InterpretLine("connect %tok% _C_.In%num%")
1124 // Skip delimiters. Note the "not_of"
1125 lastPos = str.find_first_not_of(delimiters, pos);
1126 // Find next delimiter
1127 pos = str.find_first_of(delimiters, lastPos);
1132 // InterpretLine("exec _P_")
1133 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1135 std::vector<std::string>::iterator i;
1136 for (i= chains.begin(); i!=chains.end(); ++i)
1139 Utilities::SubsBackslashN(*i);
1142 std::cout << std::endl;
1143 bbtkDebugDecTab("Interpreter",9);
1147 //=======================================================================
1152 // =========================================================================
1153 void Interpreter::SwitchToFile( const std::string& name , bool source )
1155 // Note : in the following :
1156 // name : the user supplied name
1157 // - abreviated name e.g. scr scr.bbs
1158 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1159 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1160 // same for Windows, with c:, d: ...
1162 // use ./directory/subdir/scrname.bbs
1165 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1166 <<name<<"\")"<<std::endl);
1168 std::vector<std::string> script_paths;
1169 std::string fullPathScriptName; // full path script name
1170 std::string pkgname; // e.g. <scriptname>.bbs
1171 std::vector<std::string> Filenames;
1173 // The following is *NOT* a debug time message :
1174 // It's a user intended message.
1175 // Please don't remove it.
1176 bbtkMessage("Interpreter",1,
1177 "look for : [" << name
1178 << "]" << std::endl);
1182 pkgname = Utilities::ExtractScriptName(name,upath);
1184 bbtkMessage("Interpreter",3,
1185 "package name:[" << pkgname
1186 << "] path:[" << upath << "]" << std::endl);
1187 bool fullnameGiven = false;
1188 bool foundFile = false;
1190 // ==== "*" provided : load all scripts in given path
1191 // relative (e.g. std/boxes/*) or absolute
1195 std::stringstream* stream = new std::stringstream;
1196 //if (upath.size()!=0) // avoid troubles for "*"
1198 // ==== no path provided : look in root bbs path
1199 if (upath.size()==0)
1201 // bbtkMessage("Interpreter",1,
1202 // LG : add all bbs path
1203 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1204 std::vector<std::string>::const_iterator i;
1205 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1206 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1209 script_paths.push_back(*i);
1212 // ==== absolute path provided
1213 else if (upath[0]=='/' || upath[1] == ':' )
1215 if ( Utilities::IsDirectory( upath ) )
1217 script_paths.push_back(upath);
1221 bbtkError("'"<<upath<<"' : directory does not exist");
1224 // ==== relative path provided : search all bbs path appended with
1225 // the relative path provided
1228 std::vector<std::string>::const_iterator i;
1229 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1230 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1233 std::string full_path(*i);
1234 // we *really* want '.' to be the current working directory
1235 if (full_path == ".")
1237 char buf[2048]; // for getcwd
1238 char * currentDir = getcwd(buf, 2048);
1239 std::string cwd(currentDir);
1240 full_path = currentDir;
1243 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1246 if ( Utilities::IsDirectory( full_path ) )
1248 script_paths.push_back(full_path);
1251 if (script_paths.empty())
1253 bbtkError("no '"<<upath<<"' subdir found in search paths"
1259 // === search paths list complete : now explore it
1261 // ==== relative name, iterate + load all .bbs/.bbp files
1262 std::vector<std::string>::iterator i;
1263 for (i=script_paths.begin();i!=script_paths.end();i++)
1265 bbtkMessage("Interpreter",1,
1266 "--> Looking in '" << *i << "'" << std::endl);
1270 Utilities::Explore(*i, false, Filenames);
1272 for (std::vector<std::string>::iterator j = Filenames.begin();
1273 j!= Filenames.end(); ++j)
1275 int lgr = (*j).size();
1276 if (lgr < 5) continue;
1277 // ignore non .bbp file
1278 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1280 (*stream) << "include \"" << *j << "\"\n";
1281 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1284 } // for (std::vector...
1285 } // for (i=script_...
1290 bbtkMessage("Interpreter",1,
1291 " --> No .bbp found"<< std::endl);
1295 bbtkMessage("Interpreter",1,
1296 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1297 SwitchToStream(stream);
1301 //=============== end pkgname=="*" ===========
1304 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1305 // (not only a plain script name)
1306 // we trust him, and try to expland the directory name
1307 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1309 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1312 // ===========================================================check user supplied location
1313 fullnameGiven = true;
1315 fullPathScriptName = Utilities::ExpandLibName(name, false);
1317 // allow user to always forget ".bbs"
1318 int l = fullPathScriptName.size();
1322 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1323 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1325 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1326 if ( Utilities::FileExists(tfullPathScriptName) )
1328 fullPathScriptName = tfullPathScriptName;
1333 tfullPathScriptName = fullPathScriptName + ".bbp";
1334 if ( Utilities::FileExists(tfullPathScriptName) )
1336 fullPathScriptName = tfullPathScriptName;
1343 if ( Utilities::FileExists(fullPathScriptName) )
1351 // =============================== iterate on the paths
1353 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1355 std::vector<std::string>::iterator i;
1356 for (i=script_paths.begin();i!=script_paths.end();++i)
1359 // we *really* want '.' to be the current working directory
1362 char buf[2048]; // for getcwd
1363 char * currentDir = getcwd(buf, 2048);
1364 std::string cwd(currentDir);
1368 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1369 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1371 fullPathScriptName = tfullPathScriptName;
1372 if ( ! Utilities::FileExists(fullPathScriptName) )
1374 // The following is *NOT* a debug time message :
1375 // It's a user intended message.
1376 // Please don't remove it.
1377 bbtkMessage("Interpreter",2,
1378 " [" <<fullPathScriptName <<"] : does not exist"
1380 continue; // try next path
1382 bbtkMessage("Interpreter",2,
1383 " [" <<fullPathScriptName
1384 <<"] : found" <<std::endl);
1386 break; // a script was found; we stop iterating
1390 fullPathScriptName = tfullPathScriptName + ".bbs";
1391 // Check if library exists
1392 if ( ! Utilities::FileExists(fullPathScriptName) )
1394 fullPathScriptName = tfullPathScriptName + ".bbp";
1395 if ( ! Utilities::FileExists(fullPathScriptName) )
1397 // The following is *NOT* a debug time message :
1398 // It's a user intended message.
1399 // Please don't remove it.
1400 bbtkMessage("Interpreter",2,
1401 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1403 continue; // try next path
1406 bbtkMessage("Interpreter",2,
1407 " [" <<fullPathScriptName
1408 <<"] : found" <<std::endl);
1410 break; // a script was found; we stop iterating
1412 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1418 if(fullPathScriptName == "")
1419 bbtkError("Path ["<<upath<<"] doesn't exist");
1421 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1423 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1428 LoadScript(fullPathScriptName,name);
1429 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1434 //=======================================================================
1437 //=======================================================================
1438 void Interpreter::SwitchToStream( std::stringstream* stream )
1440 mFile.push_back(stream);
1441 std::ostringstream buffer_name;
1443 buffer_name << "buffer_" ;
1445 if (mFileName.size()>0 )
1447 buffer_name << mFileName.back() << "_" << mLine.back();
1449 mFileName.push_back(buffer_name.str());
1450 mIncludeFileName.push_back(buffer_name.str());
1453 //=======================================================================
1455 //=======================================================================
1457 void Interpreter::LoadScript( std::string fullPathScriptName,
1458 std::string includeScriptName)
1460 Utilities::replace( fullPathScriptName ,
1461 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1463 if (find(mFileNameHistory.begin(),
1464 mFileNameHistory.end(),
1465 fullPathScriptName)!=mFileNameHistory.end())
1471 s = new std::ifstream;
1472 s->open(fullPathScriptName.c_str());
1475 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1479 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1480 << "] found" << std::endl);
1483 mFileName.push_back(fullPathScriptName);
1484 mFileNameHistory.push_back(fullPathScriptName);
1485 mIncludeFileName.push_back(includeScriptName);
1490 //=======================================================================
1492 //=======================================================================
1493 void Interpreter::CloseCurrentFile()
1495 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1498 if (mFile.size()==0)
1500 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1504 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1506 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1507 if (file!=0) file->close();
1509 delete mFile.back();
1511 mFileName.pop_back();
1512 mIncludeFileName.pop_back();
1515 bbtkDebugMessage("Interpreter",9," Remains "
1517 <<" open"<<std::endl);
1518 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1521 //=======================================================================
1523 //=======================================================================
1524 void Interpreter::CloseAllFiles()
1526 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1529 while (mFile.size() != 0)
1533 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1536 //=======================================================================
1540 //=======================================================================
1541 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1542 CommandInfoType& info )
1544 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1546 // searches the command keyword
1547 CommandDictType::iterator c;
1548 c = mCommandDict.find(words[0]);
1549 if ( c == mCommandDict.end() ) {
1550 bbtkError(words[0]<<" : unknown command");
1553 // tests the number of args
1554 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1555 ( ((int)words.size())-1 > c->second.argmax ) )
1557 HelpCommand(words[0]);
1558 bbtkError(words[0]<<" : wrong number of arguments");
1562 bbtkDecTab("Interpreter",9);
1564 //=======================================================================
1567 //=======================================================================
1568 /// Displays help on all the commands
1569 void Interpreter::Help(const std::vector<std::string>& words)
1571 unsigned int nbarg = words.size()-1;
1579 if (words[1]=="packages")
1581 GetExecuter()->GetFactory()->PrintPackages(true);
1586 HelpCommand(words[1]);
1588 catch (bbtk::Exception e)
1592 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1596 ConfigurationFile::GetInstance().Get_doc_path();
1597 url += "/bbdoc/" + words[1] + "/index.html";
1598 if (Utilities::FileExists(url))
1600 mUser->InterpreterUserViewHtmlPage(url);
1604 catch (bbtk::Exception f)
1608 std::string package;
1609 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1613 ConfigurationFile::GetInstance().Get_doc_path();
1614 url += "/bbdoc/" + package + "/index.html";
1615 if (Utilities::FileExists(url))
1617 url += "#" + words[1];
1618 mUser->InterpreterUserViewHtmlPage(url);
1622 catch (bbtk::Exception g)
1626 GetExecuter()->ShowRelations(words[1],"0","9999");
1628 catch (bbtk::Exception h){
1629 bbtkError("\""<<words[1].c_str()
1630 <<"\" is not a known command, package, black box type or black box name");
1638 if (words[2]=="all")
1640 if ( words[1]=="packages" )
1642 GetExecuter()->GetFactory()->PrintPackages(true,true);
1647 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1649 catch (bbtk::Exception f)
1655 HelpCommand(words[0]);
1656 bbtkError(words[0]<<" : syntax error");
1661 bbtkError("Should not reach here !!!");
1664 //=======================================================================
1666 //===================================================================
1667 /// Displays the Configuration
1668 void Interpreter::Config() const
1670 ConfigurationFile::GetInstance().GetHelp(1);
1672 //===================================================================
1674 //=======================================================================
1675 /// Displays help on all the commands
1676 void Interpreter::HelpCommands()
1678 std::cout << "Available commands :" << std::endl;
1679 CommandDictType::iterator i;
1680 for ( i = mCommandDict.begin();
1681 i != mCommandDict.end();
1683 std::cout << " " << i->first << std::endl;
1684 // std::cout << " usage : " << i->second.syntax << std::endl;
1685 // std::cout << " " << i->second.help << std::endl;
1689 //=======================================================================
1692 //=======================================================================
1693 /// Displays help on a particular commands
1694 void Interpreter::HelpCommand(const std::string& s)
1696 CommandDictType::iterator c;
1697 c = mCommandDict.find(s);
1698 if ( c == mCommandDict.end() ) {
1699 bbtkError(s<<" : Unknown command");
1701 // std::cout << " " << s << " : "<< std::endl;
1702 // CommandParamDictType::iterator i;
1703 // for ( i = c->second.begin();
1704 // i != c->second.end();
1706 std::cout << " usage : " << c->second.syntax << std::endl;
1707 std::cout << " " << c->second.help << std::endl;
1710 //=======================================================================
1713 //=======================================================================
1714 /// Fills the vector commands with the commands which
1715 /// have the first n chars of buf for prefix
1716 /// TODO : skip initial spaces in buf and also return the position of first
1717 /// non blank char in buf
1718 void Interpreter::FindCommandsWithPrefix( char* buf,
1720 std::vector<std::string>& commands )
1722 CommandDictType::const_iterator i;
1723 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1725 if ((i->first).find(buf,0,n) == 0)
1726 commands.push_back(i->first);
1729 //=======================================================================
1733 //=======================================================================
1734 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1736 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1737 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1739 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1740 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1741 // E.G. STORE THIS IN bbtk_config.xml
1742 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1743 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1744 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1745 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1746 #define BBTK_BACKSPACE_KBCODE 0x00000008
1747 #define BBTK_DEL_KBCODE 0x0000007F
1748 #define BBTK_SPACE_KBCODE 0x00000020
1750 //=======================================================================
1751 void Interpreter::GetLineFromPrompt(std::string& s)
1756 unsigned int MAX_LINE_SIZE = 160;
1757 unsigned int MAX_HISTORY_SIZE = 100;
1759 char* newline = new char[MAX_LINE_SIZE];
1760 memset(newline,0,MAX_LINE_SIZE);
1761 char* histline = new char[MAX_LINE_SIZE];
1762 memset(histline,0,MAX_LINE_SIZE);
1764 char* line = newline;
1765 unsigned int hist = mHistory.size();
1771 read ( STDIN_FILENO, &c, 4) ;
1773 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1775 // Printable character
1776 if ( (ind<MAX_LINE_SIZE-1) &&
1777 ( c >= BBTK_SPACE_KBCODE ) &&
1778 ( c < BBTK_DEL_KBCODE ))
1786 // delete the unused line
1792 // empty lines are not stored in from history
1795 // if history too long : delete oldest command
1796 if (mHistory.size()>MAX_HISTORY_SIZE)
1798 delete mHistory.front();
1799 mHistory.pop_front();
1801 mHistory.push_back(line);
1806 else if ( (ind>0) &&
1807 ((c == BBTK_BACKSPACE_KBCODE) ||
1808 (c == BBTK_DEL_KBCODE)) )
1816 // TODO : Command completion
1817 std::vector<std::string> commands;
1818 FindCommandsWithPrefix( line,ind,commands);
1819 if (commands.size()==1)
1821 std::string com = *commands.begin();
1822 for (; ind<com.size(); ++ind)
1824 PrintChar(com[ind]);
1830 else if (commands.size()>1)
1832 std::vector<std::string>::iterator i;
1834 for (i=commands.begin();i!=commands.end();++i)
1836 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1839 write(STDOUT_FILENO,"\n> ",3);
1840 //for (int j=0;j<ind;++j)
1842 write(STDOUT_FILENO,line,ind);
1846 // Arrow up : back in history
1847 else if (c==BBTK_UP_ARROW_KBCODE)
1851 // erase current line
1852 while (ind--) BackSpace();
1856 strcpy(histline,mHistory[hist]);
1860 write(STDOUT_FILENO,line,ind);
1863 // Arrow down : down in history
1864 else if (c==BBTK_DOWN_ARROW_KBCODE)
1866 if (hist<mHistory.size()-1)
1868 // erase current line
1869 while (ind--) BackSpace();
1873 strcpy(histline,mHistory[hist]);
1877 write(STDOUT_FILENO,line,ind);
1879 // end of history : switch back to newline
1880 else if (hist==mHistory.size()-1)
1882 // erase current line
1883 while (ind--) BackSpace();
1890 write(STDOUT_FILENO,line,ind);
1894 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1896 PrintChar(line[ind]);
1901 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1909 write(STDOUT_FILENO,"\n\r",2);
1917 //=======================================================================
1918 void Interpreter::GetLineFromPrompt(std::string& s)
1944 //=======================================================================
1950 //=======================================================================
1951 void Interpreter::CommandLineInterpreter()
1953 bbtkDebugMessageInc("Interpreter",9,
1954 "Interpreter::CommandLineInterpreter()"<<std::endl);
1956 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1957 // Initialise the tty in non canonical mode with no echo
1958 // oter remembers the previous settings to restore them after
1959 struct termios ter,oter;
1962 ter.c_lflag &= ~ECHO;
1963 ter.c_lflag &= ~ICANON;
1966 tcsetattr(0,TCSANOW,&ter);
1969 mCommandLine = true;
1971 // bool insideComment = false; // for multiline comment
1972 mInsideComment = false;
1978 GetLineFromPrompt(line);
1979 DoInterpretLine(line); //, insideComment);
1982 catch (QuitException e)
1984 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1988 catch (bbtk::Exception e)
1992 catch (std::exception& e)
1994 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1998 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
2003 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
2004 tcsetattr(0,TCSANOW,&oter);
2007 std::cout << "Good bye !" << std::endl;
2009 bbtkDebugDecTab("Interpreter",9);
2012 //=======================================================================
2013 void Interpreter::Graph(const std::vector<std::string>& words)
2016 bool system_display = true;
2018 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2019 system_display = false;
2021 if (words.size()==1)
2023 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
2025 else if (words.size()==2)
2027 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
2029 else if (words.size()==3)
2031 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
2033 else if (words.size()==4)
2035 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
2037 else if (words.size()==5)
2039 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
2041 else if (words.size()==6)
2043 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
2045 else if (words.size()==7)
2047 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
2050 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2051 mUser->InterpreterUserViewHtmlPage(page);
2054 //=======================================================================
2057 //=======================================================================
2058 void Interpreter::Index(const std::string& filename,
2059 const std::string& type)
2061 Factory::IndexEntryType t;
2062 if (type=="Initials") t = Factory::Initials;
2063 else if (type=="Categories") t = Factory::Categories;
2064 else if (type=="Packages") t = Factory::Packages;
2065 else if (type=="Adaptors") t = Factory::Adaptors;
2067 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
2069 //=======================================================================
2072 //=======================================================================
2073 void Interpreter::NewGUI(const std::string& boxname,
2074 const std::string& instanceName)
2076 if (mRealExecuter.expired())
2078 bbtkError("command 'newgui' cannot be compiled yet");
2081 std::string typeName = instanceName+"Type";
2082 std::stringstream* s = new std::stringstream;
2083 // create the complex box
2084 (*s) << "define "<<typeName<<std::endl;
2085 // (*s) << " description 'Automatically generated user interface for the box "
2086 // << boxname << "'" <<std::endl;
2087 // create the Layout box
2088 (*s) << " load wx"<<std::endl;
2089 (*s) << " new LayoutLine layout"<<std::endl;
2090 // create the output 'Widget'
2091 (*s) << " output Widget layout.Widget Widget"<<std::endl;
2092 // the box change output
2093 (*s) << " new MultipleInputs change"<<std::endl;
2094 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
2096 // Browse the inputs of the box in order to find which ones are not
2097 // connected and can be adapted from a widget adaptor
2098 // vector which stores the list of inputs of the box which must be connected
2099 std::vector<std::string> in;
2101 Factory::Pointer F = mVirtualExecuter->GetFactory();
2103 Package::Pointer user = F->GetPackage("user");
2105 ComplexBlackBoxDescriptor::Pointer workspace =
2106 mRealExecuter.lock()->GetCurrentDescriptor();
2111 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2116 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2119 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2120 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2122 BlackBox::InputConnectorMapType::iterator i;
2123 for (i=box->bbGetInputConnectorMap().begin();
2124 i!=box->bbGetInputConnectorMap().end();
2127 // If the input is connected : continue
2128 if (i->second->IsConnected()) continue;
2129 // Get the input descriptor
2130 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2131 // If it is a "system" input : skip it
2132 #ifdef USE_WXWIDGETS
2133 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2134 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2137 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) )
2141 std::string widget,adaptor;
2142 // try to find a widget adaptor
2143 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2147 // command to create the adaptor
2148 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2149 // Sets the label of the widget adaptor to the name of the input
2150 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2151 // Sets the initial value of the widget to the value of the input
2152 (*s) << " set "<<i->first<<".In \" "
2153 <<box->bbGetInputAsString(i->first)<<"\""
2155 // store the input name
2156 in.push_back(i->first);
2157 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2158 //<i->first<<"'"<<std::endl;
2159 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2161 // try to find a two pieces adaptor
2162 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2166 // command to create the widget
2167 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2168 // command to create the adaptor
2169 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2171 (*s) << " connect "<<i->first<<"Widget.Out "
2172 <<i->first<<".In"<<std::endl;
2173 // Sets the label of the widget adaptor to the name of the input
2174 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2175 // Sets the initial value of the widget to the value of the input
2176 (*s) << " set "<<i->first<<"Widget.In \" "
2177 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2178 // store the input name
2179 in.push_back(i->first);
2180 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2181 //<i->first<<"'"<<std::endl;
2182 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2185 // try to find an adaptor from string
2186 // If found then can create a text input which
2187 // will be automatically adapted
2188 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2192 // command to create the adaptor
2193 (*s) << " new InputText "<<i->first<<std::endl;
2194 // Sets the label of the widget adaptor to the name of the input
2195 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2196 // Sets the initial value of the widget to the value of the input
2197 (*s) << " set "<<i->first<<".In \" "
2198 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2199 // store the input name
2200 in.push_back(i->first);
2201 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2202 //<i->first<<"'"<<std::endl;
2203 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2212 // command to create the output
2213 (*s) << " output "<<i->first<<" "
2214 <<i->first<<".Out "<<i->first<<std::endl;
2215 // <<" Output of the widget which allows to set "
2219 // Inputs for window properties
2220 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2221 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2222 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2223 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2224 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2228 // Execute the box executes the layout
2229 (*s) << " exec layout" << std::endl;
2230 (*s) << "endefine" << std::endl;
2231 // (*s) << "help "<< typeName<< std::endl;
2232 // instanciate the box and connect it
2233 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2235 std::vector<std::string>::iterator j;
2236 for (j=in.begin();j!=in.end();++j)
2239 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2240 << boxname<<"."<<*j<<std::endl;
2242 // That's all folks ! now execute the commands :
2245 //=======================================================================
2249 //==========================================================================
2250 void Interpreter::Debug(const std::string& name)
2252 if ((name.length()==2)&&(name[0]=='-'))
2256 bbtk::StaticInitTime::PrintObjectListInfo = true;
2260 // int o = MessageManager::GetMessageLevel("debug");
2261 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2262 mVirtualExecuter->GetFactory()->CheckPackages();
2263 // MessageManager::SetMessageLevel("debug",o);
2268 Object:: PrintObjectListInfo(name);
2271 //==========================================================================
2274 //==========================================================================
2275 // Adds a callback when 'break' command issued
2276 void Interpreter::AddBreakObserver( BreakCallbackType c )
2278 mBreakSignal.connect(c);
2280 //==========================================================================
2283 //==========================================================================
2284 std::string Interpreter::GetObjectName() const
2286 return std::string("Interpreter");
2288 //==========================================================================
2290 //==========================================================================
2291 std::string Interpreter::GetObjectInfo() const
2293 std::stringstream i;
2296 //==========================================================================
2298 //==========================================================================
2299 size_t Interpreter::GetObjectSize() const
2301 size_t s = Superclass::GetObjectSize();
2302 s += Interpreter::GetObjectInternalSize();
2305 //==========================================================================
2306 //==========================================================================
2307 size_t Interpreter::GetObjectInternalSize() const
2309 size_t s = sizeof(Interpreter);
2312 //==========================================================================
2313 //==========================================================================
2314 size_t Interpreter::GetObjectRecursiveSize() const
2316 size_t s = Superclass::GetObjectRecursiveSize();
2317 s += Interpreter::GetObjectInternalSize();
2318 s += mVirtualExecuter->GetObjectRecursiveSize();
2321 //==========================================================================