1 /*=========================================================================
3 Module: $RCSfile: bbtkInterpreter.cxx,v $
5 Date: $Date: 2008/12/15 09:04:47 $
6 Version: $Revision: 1.81 $
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 )
426 if (e.GetErrorMessage()!="break")
428 mStatus = Interpreter_ERROR;
431 throw InterpreterException(e);
435 std::stringstream mess;
436 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
437 if (e.IsInScriptFile())
439 mess << "* FILE : \""<<e.GetScriptFile()<<"\""<<std::endl;
440 mess << "* LINE : "<<e.GetScriptLine()<<std::endl;
443 std::cerr << mess.str();
446 //=======================================================================
448 //=======================================================================
449 void Interpreter::CatchBbtkException( const bbtk::Exception& e )
451 mStatus = Interpreter_ERROR;
454 bool in_script = false;
455 std::string file("");
457 if (mFileName.size()) {
458 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
459 if (fs!=0) in_script = true;
460 file = mFileName.back();
463 if (e.GetErrorMessage()!="break")
465 throw InterpreterException(e,in_script,file,line);
469 std::stringstream mess;
470 mess << "* ERROR : "<<e.GetErrorMessage()<<std::endl;
471 if (mFileName.size()) {
472 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
473 mess << "* LINE : "<<mLine.back()<<std::endl;
476 std::cerr << mess.str();
479 //=======================================================================
481 //=======================================================================
482 void Interpreter::CatchStdException( const std::exception& e )
484 mStatus = Interpreter_ERROR;
487 bool in_script = false;
488 std::string file("");
490 if (mFileName.size()) {
491 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
492 if (fs!=0) in_script = true;
493 file = mFileName.back();
497 throw InterpreterException(e.what(),in_script,file,line);
501 std::stringstream mess;
502 mess << "* ERROR : "<<e.what()<<std::endl;
503 if (mFileName.size()) {
504 mess << "* FILE : \""<<mFileName.back()<<"\""<<std::endl;
505 mess << "* LINE : "<<mLine.back()<<std::endl;
508 std::cerr << mess.str();
511 //=======================================================================
513 //=======================================================================
514 void Interpreter::CatchUnknownException()
516 mStatus = Interpreter_ERROR;
519 bool in_script = false;
520 std::string file("");
522 if (mFileName.size()) {
523 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
524 if (fs!=0) in_script = true;
525 file = mFileName.back();
529 throw InterpreterException("Unknown exception caught",
530 in_script,file,line);
534 std::stringstream mess;
535 mess << "* UNDEFINED ERROR (not a bbtk nor a std exception)"
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 //=======================================================================
549 #define CATCH_MACRO \
550 catch (InterpreterException e) \
552 CatchInterpreterException(e); \
554 catch (bbtk::Exception e) \
556 CatchBbtkException(e); \
558 catch (std::exception& e) \
560 CatchStdException(e); \
564 CatchUnknownException(); \
566 //=======================================================================
569 //=======================================================================
570 Interpreter::ExitStatus Interpreter::InterpretFile( const std::string& filename, bool source )
572 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretFile(\""<<filename<<"\")"<<std::endl);
574 bool exm = mCommandLine;
575 mCommandLine = false;
579 mStatus = Interpreter_OK;
580 SwitchToFile(filename,source);
581 mInsideComment = false;
582 InterpretCurrentStreams();
586 bbtkDebugMessage("Interpreter",9,
587 "EO Interpreter::InterpretFile(\""
588 <<filename<<"\")"<<std::endl);
589 bbtkDecTab("Interpreter",9);
595 //=======================================================================
598 //=======================================================================
599 Interpreter::ExitStatus
600 Interpreter::InterpretBuffer( std::stringstream* buffer )
602 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretBuffer()"<<std::endl);
604 bool exm = mCommandLine;
605 mCommandLine = false;
609 mStatus = Interpreter_OK;
610 SwitchToStream(buffer);
611 mInsideComment = false;
612 InterpretCurrentStreams();
617 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretBuffer()"<<std::endl);
618 bbtkDecTab("Interpreter",9);
623 //=======================================================================
625 //=======================================================================
626 /// Interprets the currently open streams
627 Interpreter::ExitStatus Interpreter::InterpretCurrentStreams()
629 bbtkDebugMessageInc("Interpreter",9,
630 "Interpreter::InterpretCurrentStreams()"<<std::endl);
632 while (mFile.size()>0)
634 while (!mFile.back()->eof()) {
637 mFile.back()->getline(buf,500);
638 std::string str(buf);
640 int size=str.length();
641 if ( str[ size-1 ]==13 )
647 DoInterpretLine(str);
655 //=======================================================================
657 //=======================================================================
658 /// Runs the interpretation of a command
659 Interpreter::ExitStatus Interpreter::InterpretLine( const std::string& line )
661 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretLine('"<<line<<"')"<<std::endl);
665 mStatus = Interpreter_OK;
666 mInsideComment = false;
667 DoInterpretLine(line );
672 bbtkDebugMessage("Interpreter",9,"EO Interpreter::InterpretLine()"
674 bbtkDecTab("Interpreter",9);
678 //=======================================================================
681 //=======================================================================
682 void Interpreter::DoInterpretLine( const std::string& line )
684 bbtkDebugMessageInc("Interpreter",9,"Interpreter::DoInterpretLine(\""<<line<<"\")"<<std::endl);
686 std::vector<std::string> words;
687 SplitLine(line,words);
692 bbtkDebugDecTab("Interpreter",9);
696 // Single line comment : # or //
697 if ( words[0][0]=='#' || (words[0][0]=='/' && words[0][1]=='/') )
699 bbtkDebugDecTab("Interpreter",9);
700 bbtkMessage("Interpreter",9,"Comment"<<std::endl);
704 // Multi line comment ( /* ... */ ) -delimiters on different lines !-
706 if (words[0][0]=='/' && words[0][1]=='*')
708 bbtkDebugDecTab("Interpreter",9);
709 bbtkMessage("Interpreter",9,"In multiline comment"<<std::endl);
710 mInsideComment = true;
714 if (words[0][0]=='*' && words[0][1]=='/')
716 bbtkDebugDecTab("Interpreter",9);
717 bbtkMessage("Interpreter",9,"Out multiline comment"<<std::endl);
718 if ( !mInsideComment ) {
719 bbtkDebugDecTab("Interpreter",9);
720 bbtkMessage("Interpreter",9,"Comment mismatch : '*/' with no matching '/*'"<<std::endl);
722 mInsideComment = false;
728 bbtkDebugDecTab("Interpreter",9);
729 bbtkMessage("Interpreter",9,"Multiline Comment"<<std::endl);
734 CommandInfoType command;
735 InterpretCommand(words,command);
737 bbtkDebugMessage("Interpreter",9,
738 "Command='"<<command.keyword
739 <<"' code="<<command.code<<std::endl);
741 std::string left,right,left2,right2;
742 std::string filename;
745 if (command.code==cMessage)
749 mVirtualExecuter->HelpMessages();
753 sscanf(words[2].c_str(),"%d",&level);
754 mVirtualExecuter->SetMessageLevel(words[1],level);
760 bbtkMessage("echo",2,line<<std::endl);
763 // break and quit commands
764 if ((command.code==cBreak) || (command.code==cQuit))
766 bool in_script = false;
767 std::string file("");
769 if (mFileName.size())
771 std::ifstream* fs = dynamic_cast<std::ifstream*>(mFile.back());
772 if (fs!=0) in_script = true;
773 file = mFileName.back();
776 if (command.code==cBreak)
779 std::cout << "BreakException("
782 <<line<<")"<<std::endl;
784 bbtkError("break");//,in_script,file,line);
785 // throw BreakException(in_script,file,line);
789 bbtkError("quit");//,in_script,file,line);
790 //throw QuitException(in_script,file,line);
796 switch (command.code)
799 mVirtualExecuter->Create(words[1],words[2]);
803 mVirtualExecuter->Destroy(words[1]);
807 Utilities::SplitAroundFirstDot(words[1],left,right);
808 Utilities::SplitAroundFirstDot(words[2],left2,right2);
809 mVirtualExecuter->Connect(left,right,left2,right2);
813 mVirtualExecuter->BeginPackage(words[1]);
817 mVirtualExecuter->EndPackage();
821 if (mFileName.size()>0)
823 filename = mFileName.back(); //mIncludeFileName.back(); //Utilities::get_file_name(mFileName.back());
827 mVirtualExecuter->Define(words[1],"",filename);
831 mVirtualExecuter->Define(words[1],words[2],filename);
836 mVirtualExecuter->EndDefine();
840 mVirtualExecuter->Kind(words[1]);
844 mVirtualExecuter->Print(words[1]);
848 if (words[1]=="freeze")
850 mVirtualExecuter->SetNoExecMode(true);
853 else if (words[1]=="freeze_no_error ")
855 mVirtualExecuter->SetNoExecMode(true);
856 mVirtualExecuter->SetNoErrorMode(true);
859 else if (words[1]=="unfreeze")
861 mVirtualExecuter->SetNoExecMode(false);
862 mVirtualExecuter->SetNoErrorMode(false);
866 mVirtualExecuter->Execute(words[1]);
871 Utilities::SplitAroundFirstDot(words[2],left,right);
872 mVirtualExecuter->DefineInput(words[1],left,right,words[3]);
876 Utilities::SplitAroundFirstDot(words[2],left,right);
877 mVirtualExecuter->DefineOutput(words[1],left,right,words[3]);
881 Utilities::SplitAroundFirstDot(words[1],left,right);
882 mVirtualExecuter->Set(left,right,words[2]);
886 mVirtualExecuter->Author(words[1]);
890 NewGUI(words[1],words[2]);
894 mVirtualExecuter->Category(words[1]);
899 Index("tmp_index.html");
900 else if (words.size()==2)
902 else if (words.size()==3)
903 Index(words[1],words[2]);
907 mVirtualExecuter->Description(words[1]);
928 mVirtualExecuter->Clear();
932 // if 'source' was given (words.size()==3) then tell to set the
933 // source file name of the current complex box with the full file name included
936 InterpretFile(words[1],(words.size()==3));
940 SwitchToFile(words[1],(words.size()==3) );
945 GetExecuter()->LoadPackage(words[1]);
949 GetExecuter()->UnLoadPackage(words[1]);
953 if (words.size()==2) Debug(words[1]);
958 if (words.size() == 2)
960 if (words[1]=="freeze") mVirtualExecuter->SetNoExecMode(true);
961 else if (words[1]=="unfreeze") mVirtualExecuter->SetNoExecMode(false);
965 mVirtualExecuter->SetWorkspaceName(words[2]);
970 bbtkInternalError("should not reach here !!!");
973 bbtkDecTab("Interpreter",9);
975 //=======================================================================
981 //=======================================================================
982 void Interpreter::SplitLine ( const std::string& str, std::vector<std::string>& tokens)
984 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SplitLine(\""<<str<<"\")"<<std::endl);
986 std::string delimiters = "\"";
987 std::vector<std::string> quote;
988 Utilities::SplitString(str,delimiters,quote);
991 std::vector<std::string>::iterator i;
992 for (i=quote.begin(); i!=quote.end(); )
994 Utilities::SplitString(*i,delimiters,tokens);
998 // bbtkDebugMessage("Interpreter",0,"\""<<*i<<"\""<<std::endl);
999 tokens.push_back(*i);
1004 for (i=tokens.begin(); i!=tokens.end(); ++i)
1006 bbtkDebugMessage("Interpreter",9,"["<<*i<<"] ");
1008 bbtkDebugMessageCont("Interpreter",9,std::endl);
1010 bbtkDebugDecTab("Interpreter",9);
1012 //=======================================================================
1015 //=======================================================================
1016 void Interpreter::Reset()
1018 // Cannot close all files if the reset command is read from a file !
1020 mFileNameHistory.clear();
1021 this->mVirtualExecuter->Reset();
1023 //=======================================================================
1025 //=======================================================================
1030 void Interpreter::Print( const std::string& str)
1032 if (mVirtualExecuter->GetNoExecMode()) return;
1034 bbtkDebugMessageInc("Interpreter",9,"Interpreter::Print(\""<<str<<"\")"<<std::endl);
1037 // InterpretLine ("load std")
1038 // InterpretLine("new ConcatStrings _C_ ") -> trouver un nom unique : # commande
1039 // InterpretLine("new Print _P_")
1040 // InterpretLine("connect _C_.Out _P_.In")
1044 std::vector<std::string> chains;
1045 std::string delimiters("$");
1047 // Skip delimiters at beginning.
1048 std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
1049 bool is_text = true;
1050 if (lastPos>0) is_text = false;
1052 // Find first delimiter.
1053 std::string::size_type pos = str.find_first_of(delimiters, lastPos);
1055 while (std::string::npos != pos || std::string::npos != lastPos)
1059 // Found a text token, add it to the vector.
1060 chains.push_back(str.substr(lastPos, pos - lastPos));
1061 // std::string token = str.substr(lastPos, pos - lastPos)
1062 // InterpretLine("set _C_.In%num% %token%")
1068 // is an output (between $$) : decode
1069 std::string tok,box,output;
1070 tok = str.substr(lastPos, pos - lastPos);
1071 Utilities::SplitAroundFirstDot(tok,box,output);
1072 chains.push_back( mVirtualExecuter->Get(box,output) );
1074 // InterpretLine("connect %tok% _C_.In%num%")
1077 // Skip delimiters. Note the "not_of"
1078 lastPos = str.find_first_not_of(delimiters, pos);
1079 // Find next delimiter
1080 pos = str.find_first_of(delimiters, lastPos);
1085 // InterpretLine("exec _P_")
1086 // if (IS_IN_WORKSPACE) InterpretLine("delete _C_; delete _P_");
1088 std::vector<std::string>::iterator i;
1089 for (i= chains.begin(); i!=chains.end(); ++i)
1092 Utilities::SubsBackslashN(*i);
1095 std::cout << std::endl;
1096 bbtkDebugDecTab("Interpreter",9);
1100 //=======================================================================
1105 // =========================================================================
1106 void Interpreter::SwitchToFile( const std::string& name , bool source )
1108 // Note : in the following :
1109 // name : the user supplied name
1110 // - abreviated name e.g. scr scr.bbs
1111 // - relative full name e.g. ./scr.bbs ../../scr.bbs
1112 // - absolute full name e.g. /home/usrname/proj/dir/scr.bbs
1113 // same for Windows, with c:, d: ...
1115 // use ./directory/subdir/scrname.bbs
1118 bbtkDebugMessageInc("Interpreter",9,"Interpreter::SwitchToFile( \""
1119 <<name<<"\")"<<std::endl);
1121 std::vector<std::string> script_paths;
1122 std::string fullPathScriptName; // full path script name
1123 std::string pkgname; // e.g. <scriptname>.bbs
1124 std::vector<std::string> Filenames;
1126 // The following is *NOT* a debug time message :
1127 // It's a user intended message.
1128 // Please don't remove it.
1129 bbtkMessage("Interpreter",1,
1130 "look for : [" << name
1131 << "]" << std::endl);
1135 pkgname = Utilities::ExtractScriptName(name,upath);
1137 bbtkMessage("Interpreter",3,
1138 "package name:[" << pkgname
1139 << "] path:[" << upath << "]" << std::endl);
1140 bool fullnameGiven = false;
1141 bool foundFile = false;
1143 // ==== "*" provided : load all scripts in given path
1144 // relative (e.g. std/boxes/*) or absolute
1148 std::stringstream* stream = new std::stringstream;
1149 //if (upath.size()!=0) // avoid troubles for "*"
1151 // ==== no path provided : look in root bbs path
1152 if (upath.size()==0)
1154 // bbtkMessage("Interpreter",1,
1155 // LG : add all bbs path
1156 // script_paths.push_back( ConfigurationFile::GetInstance().Get_root_bbs_path() );
1157 std::vector<std::string>::const_iterator i;
1158 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1159 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1162 script_paths.push_back(*i);
1165 // ==== absolute path provided
1166 else if (upath[0]=='/' || upath[1] == ':' )
1168 if ( Utilities::IsDirectory( upath ) )
1170 script_paths.push_back(upath);
1174 bbtkError("'"<<upath<<"' : directory does not exist");
1177 // ==== relative path provided : search all bbs path appended with
1178 // the relative path provided
1181 std::vector<std::string>::const_iterator i;
1182 for (i=ConfigurationFile::GetInstance().Get_bbs_paths().begin();
1183 i!=ConfigurationFile::GetInstance().Get_bbs_paths().end();
1186 std::string full_path(*i);
1187 // we *really* want '.' to be the current working directory
1188 if (full_path == ".")
1190 char buf[2048]; // for getcwd
1191 char * currentDir = getcwd(buf, 2048);
1192 std::string cwd(currentDir);
1193 full_path = currentDir;
1196 full_path += ConfigurationFile::GetInstance().Get_file_separator();
1199 if ( Utilities::IsDirectory( full_path ) )
1201 script_paths.push_back(full_path);
1204 if (script_paths.empty())
1206 bbtkError("no '"<<upath<<"' subdir found in search paths"
1212 // === search paths list complete : now explore it
1214 // ==== relative name, iterate + load all .bbs/.bbp files
1215 std::vector<std::string>::iterator i;
1216 for (i=script_paths.begin();i!=script_paths.end();i++)
1218 bbtkMessage("Interpreter",1,
1219 "--> Looking in '" << *i << "'" << std::endl);
1223 Utilities::Explore(*i, false, Filenames);
1225 for (std::vector<std::string>::iterator j = Filenames.begin();
1226 j!= Filenames.end(); ++j)
1228 int lgr = (*j).size();
1229 if (lgr < 5) continue;
1230 // ignore non .bbp file
1231 if ( (*j).substr(lgr-4, 4) != ".bbp") continue;
1233 (*stream) << "include \"" << *j << "\"\n";
1234 bbtkMessage("Interpreter",2," --> Found '" << *j << "'" << std::endl);
1237 } // for (std::vector...
1238 } // for (i=script_...
1243 bbtkMessage("Interpreter",1,
1244 " --> No .bbp found"<< std::endl);
1248 bbtkMessage("Interpreter",1,
1249 " --> "<<nbBssFiles<<" .bbp found"<< std::endl);
1250 SwitchToStream(stream);
1254 //=============== end pkgname=="*" ===========
1257 // if name starts with a / or a . or contains : user is assumed to have passed a relative/absolute name
1258 // (not only a plain script name)
1259 // we trust him, and try to expland the directory name
1260 // WARNING : starting from current local directory : ./whatYouWant (./ mandatory!)
1262 if (name[0]=='/' || name[1] == ':' || name[0]=='.') // absolute path (linux/windows) or relative path
1265 // ===========================================================check user supplied location
1266 fullnameGiven = true;
1268 fullPathScriptName = Utilities::ExpandLibName(name, false);
1270 // allow user to always forget ".bbs"
1271 int l = fullPathScriptName.size();
1275 if ((fullPathScriptName.substr(l-4, 4) != ".bbs")&&
1276 (fullPathScriptName.substr(l-4, 4) != ".bbp"))
1278 std::string tfullPathScriptName = fullPathScriptName + ".bbs";
1279 if ( Utilities::FileExists(tfullPathScriptName) )
1281 fullPathScriptName = tfullPathScriptName;
1286 tfullPathScriptName = fullPathScriptName + ".bbp";
1287 if ( Utilities::FileExists(tfullPathScriptName) )
1289 fullPathScriptName = tfullPathScriptName;
1296 if ( Utilities::FileExists(fullPathScriptName) )
1304 // =============================== iterate on the paths
1306 script_paths = ConfigurationFile::GetInstance().Get_bbs_paths();
1308 std::vector<std::string>::iterator i;
1309 for (i=script_paths.begin();i!=script_paths.end();++i)
1312 // we *really* want '.' to be the current working directory
1315 char buf[2048]; // for getcwd
1316 char * currentDir = getcwd(buf, 2048);
1317 std::string cwd(currentDir);
1321 std::string tfullPathScriptName = Utilities::MakePkgnameFromPath(path, name, false);
1322 if (tfullPathScriptName.substr(tfullPathScriptName.size()-4, 3)==".bb")
1324 fullPathScriptName = tfullPathScriptName;
1325 if ( ! Utilities::FileExists(fullPathScriptName) )
1327 // The following is *NOT* a debug time message :
1328 // It's a user intended message.
1329 // Please don't remove it.
1330 bbtkMessage("Interpreter",2,
1331 " [" <<fullPathScriptName <<"] : does not exist"
1333 continue; // try next path
1335 bbtkMessage("Interpreter",2,
1336 " [" <<fullPathScriptName
1337 <<"] : found" <<std::endl);
1339 break; // a script was found; we stop iterating
1343 fullPathScriptName = tfullPathScriptName + ".bbs";
1344 // Check if library exists
1345 if ( ! Utilities::FileExists(fullPathScriptName) )
1347 fullPathScriptName = tfullPathScriptName + ".bbp";
1348 if ( ! Utilities::FileExists(fullPathScriptName) )
1350 // The following is *NOT* a debug time message :
1351 // It's a user intended message.
1352 // Please don't remove it.
1353 bbtkMessage("Interpreter",2,
1354 " [" <<tfullPathScriptName <<".bbs/.bbp] : do not exist"
1356 continue; // try next path
1359 bbtkMessage("Interpreter",2,
1360 " [" <<fullPathScriptName
1361 <<"] : found" <<std::endl);
1363 break; // a script was found; we stop iterating
1365 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
1371 if(fullPathScriptName == "")
1372 bbtkError("Path ["<<upath<<"] doesn't exist");
1374 bbtkError("Script ["<<fullPathScriptName<<"] not found");
1376 bbtkError("No ["<<pkgname<<".bbs/.bbp] script found");
1381 LoadScript(fullPathScriptName,name);
1382 if (source) GetExecuter()->SetCurrentFileName(fullPathScriptName);
1387 //=======================================================================
1390 //=======================================================================
1391 void Interpreter::SwitchToStream( std::stringstream* stream )
1393 mFile.push_back(stream);
1394 std::ostringstream buffer_name;
1396 buffer_name << "buffer_" ;
1398 if (mFileName.size()>0 )
1400 buffer_name << mFileName.back() << "_" << mLine.back();
1402 mFileName.push_back(buffer_name.str());
1403 mIncludeFileName.push_back(buffer_name.str());
1406 //=======================================================================
1408 //=======================================================================
1410 void Interpreter::LoadScript( std::string fullPathScriptName,
1411 std::string includeScriptName)
1413 Utilities::replace( fullPathScriptName ,
1414 INVALID_FILE_SEPARATOR , VALID_FILE_SEPARATOR);
1416 if (find(mFileNameHistory.begin(),
1417 mFileNameHistory.end(),
1418 fullPathScriptName)!=mFileNameHistory.end())
1424 s = new std::ifstream;
1425 s->open(fullPathScriptName.c_str());
1428 bbtkError("Could not open file ["<<fullPathScriptName<<"]");
1432 bbtkMessage("Interpreter",1," -->[" << fullPathScriptName
1433 << "] found" << std::endl);
1436 mFileName.push_back(fullPathScriptName);
1437 mFileNameHistory.push_back(fullPathScriptName);
1438 mIncludeFileName.push_back(includeScriptName);
1443 //=======================================================================
1445 //=======================================================================
1446 void Interpreter::CloseCurrentFile()
1448 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseCurrentFile()"
1451 if (mFile.size()==0)
1453 bbtkDebugMessage("Interpreter",9," -> no file left open"<<std::endl);
1457 bbtkDebugMessage("Interpreter",9," Closing file '"<<mFileName.back()<<"'"<<std::endl);
1459 std::ifstream* file = dynamic_cast<std::ifstream*>(mFile.back());
1460 if (file!=0) file->close();
1462 delete mFile.back();
1464 mFileName.pop_back();
1465 mIncludeFileName.pop_back();
1468 bbtkDebugMessage("Interpreter",9," Remains "
1470 <<" open"<<std::endl);
1471 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseCurrentFile()"
1474 //=======================================================================
1476 //=======================================================================
1477 void Interpreter::CloseAllFiles()
1479 bbtkDebugMessage("Interpreter",9,"Interpreter::CloseAllFiles()"
1482 while (mFile.size() != 0)
1486 bbtkDebugMessage("Interpreter",9,"EO Interpreter::CloseAllFiles()"
1489 //=======================================================================
1493 //=======================================================================
1494 void Interpreter::InterpretCommand( const std::vector<std::string>& words,
1495 CommandInfoType& info )
1497 bbtkDebugMessageInc("Interpreter",9,"Interpreter::InterpretCommand(...)"<<std::endl);
1499 // searches the command keyword
1500 CommandDictType::iterator c;
1501 c = mCommandDict.find(words[0]);
1502 if ( c == mCommandDict.end() ) {
1503 bbtkError(words[0]<<" : unknown command");
1506 // tests the number of args
1507 if ( ( ((int)words.size())-1 < c->second.argmin ) ||
1508 ( ((int)words.size())-1 > c->second.argmax ) )
1510 HelpCommand(words[0]);
1511 bbtkError(words[0]<<" : wrong number of arguments");
1515 bbtkDecTab("Interpreter",9);
1517 //=======================================================================
1520 //=======================================================================
1521 /// Displays help on all the commands
1522 void Interpreter::Help(const std::vector<std::string>& words)
1524 unsigned int nbarg = words.size()-1;
1532 if (words[1]=="packages")
1534 GetExecuter()->GetFactory()->PrintPackages(true);
1539 HelpCommand(words[1]);
1541 catch (bbtk::Exception e)
1545 GetExecuter()->GetFactory()->HelpPackage(words[1]);
1549 ConfigurationFile::GetInstance().Get_doc_path();
1550 url += "/bbdoc/" + words[1] + "/index.html";
1551 if (Utilities::FileExists(url))
1553 mUser->InterpreterUserViewHtmlPage(url);
1557 catch (bbtk::Exception f)
1561 std::string package;
1562 GetExecuter()->GetFactory()->HelpBlackBox(words[1],package);
1566 ConfigurationFile::GetInstance().Get_doc_path();
1567 url += "/bbdoc/" + package + "/index.html";
1568 if (Utilities::FileExists(url))
1570 url += "#" + words[1];
1571 mUser->InterpreterUserViewHtmlPage(url);
1575 catch (bbtk::Exception g)
1579 GetExecuter()->ShowRelations(words[1],"0","9999");
1581 catch (bbtk::Exception h){
1582 bbtkError("\""<<words[1].c_str()
1583 <<"\" is not a known command, package, black box type or black box name");
1591 if (words[2]=="all")
1593 if ( words[1]=="packages" )
1595 GetExecuter()->GetFactory()->PrintPackages(true,true);
1600 GetExecuter()->GetFactory()->HelpPackage(words[1],true);
1602 catch (bbtk::Exception f)
1608 HelpCommand(words[0]);
1609 bbtkError(words[0]<<" : syntax error");
1614 bbtkError("Should not reach here !!!");
1617 //=======================================================================
1619 //===================================================================
1620 /// Displays the Configuration
1621 void Interpreter::Config() const
1623 ConfigurationFile::GetInstance().GetHelp(1);
1625 //===================================================================
1627 //=======================================================================
1628 /// Displays help on all the commands
1629 void Interpreter::HelpCommands()
1631 std::cout << "Available commands :" << std::endl;
1632 CommandDictType::iterator i;
1633 for ( i = mCommandDict.begin();
1634 i != mCommandDict.end();
1636 std::cout << " " << i->first << std::endl;
1637 // std::cout << " usage : " << i->second.syntax << std::endl;
1638 // std::cout << " " << i->second.help << std::endl;
1642 //=======================================================================
1645 //=======================================================================
1646 /// Displays help on a particular commands
1647 void Interpreter::HelpCommand(const std::string& s)
1649 CommandDictType::iterator c;
1650 c = mCommandDict.find(s);
1651 if ( c == mCommandDict.end() ) {
1652 bbtkError(s<<" : Unknown command");
1654 // std::cout << " " << s << " : "<< std::endl;
1655 // CommandParamDictType::iterator i;
1656 // for ( i = c->second.begin();
1657 // i != c->second.end();
1659 std::cout << " usage : " << c->second.syntax << std::endl;
1660 std::cout << " " << c->second.help << std::endl;
1663 //=======================================================================
1666 //=======================================================================
1667 /// Fills the vector commands with the commands which
1668 /// have the first n chars of buf for prefix
1669 /// TODO : skip initial spaces in buf and also return the position of first
1670 /// non blank char in buf
1671 void Interpreter::FindCommandsWithPrefix( char* buf,
1673 std::vector<std::string>& commands )
1675 CommandDictType::const_iterator i;
1676 for (i=mCommandDict.begin(); i!=mCommandDict.end(); ++i)
1678 if ((i->first).find(buf,0,n) == 0)
1679 commands.push_back(i->first);
1682 //=======================================================================
1686 //=======================================================================
1687 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1689 inline void PrintChar(char c) { write(STDOUT_FILENO,&c,1); }
1690 inline void BackSpace() { write(STDOUT_FILENO,"\b \b",3); }
1692 // LG : KEYBOARD CODES AS SCANNED ON MY TTY : UNIVERSAL ?
1693 // IF NOT THE USER SHOULD BE ABLE TO CONFIGURE IT
1694 // E.G. STORE THIS IN bbtk_config.xml
1695 #define BBTK_UP_ARROW_KBCODE 0x00415B1B
1696 #define BBTK_DOWN_ARROW_KBCODE 0x00425B1B
1697 #define BBTK_RIGHT_ARROW_KBCODE 0x00435B1B
1698 #define BBTK_LEFT_ARROW_KBCODE 0x00445B1B
1699 #define BBTK_BACKSPACE_KBCODE 0x00000008
1700 #define BBTK_DEL_KBCODE 0x0000007F
1701 #define BBTK_SPACE_KBCODE 0x00000020
1703 //=======================================================================
1704 void Interpreter::GetLineFromPrompt(std::string& s)
1709 unsigned int MAX_LINE_SIZE = 160;
1710 unsigned int MAX_HISTORY_SIZE = 100;
1712 char* newline = new char[MAX_LINE_SIZE];
1713 memset(newline,0,MAX_LINE_SIZE);
1714 char* histline = new char[MAX_LINE_SIZE];
1715 memset(histline,0,MAX_LINE_SIZE);
1717 char* line = newline;
1718 unsigned int hist = mHistory.size();
1724 read ( STDIN_FILENO, &c, 4) ;
1726 bbtkDebugMessage("debug",9,"[0x"<<std::hex<<c<<"]\n");
1728 // Printable character
1729 if ( (ind<MAX_LINE_SIZE-1) &&
1730 ( c >= BBTK_SPACE_KBCODE ) &&
1731 ( c < BBTK_DEL_KBCODE ))
1739 // delete the unused line
1745 // empty lines are not stored in from history
1748 // if history too long : delete oldest command
1749 if (mHistory.size()>MAX_HISTORY_SIZE)
1751 delete mHistory.front();
1752 mHistory.pop_front();
1754 mHistory.push_back(line);
1759 else if ( (ind>0) &&
1760 ((c == BBTK_BACKSPACE_KBCODE) ||
1761 (c == BBTK_DEL_KBCODE)) )
1769 // TODO : Command completion
1770 std::vector<std::string> commands;
1771 FindCommandsWithPrefix( line,ind,commands);
1772 if (commands.size()==1)
1774 std::string com = *commands.begin();
1775 for (; ind<com.size(); ++ind)
1777 PrintChar(com[ind]);
1783 else if (commands.size()>1)
1785 std::vector<std::string>::iterator i;
1787 for (i=commands.begin();i!=commands.end();++i)
1789 write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
1792 write(STDOUT_FILENO,"\n> ",3);
1793 //for (int j=0;j<ind;++j)
1795 write(STDOUT_FILENO,line,ind);
1799 // Arrow up : back in history
1800 else if (c==BBTK_UP_ARROW_KBCODE)
1804 // erase current line
1805 while (ind--) BackSpace();
1809 strcpy(histline,mHistory[hist]);
1813 write(STDOUT_FILENO,line,ind);
1816 // Arrow down : down in history
1817 else if (c==BBTK_DOWN_ARROW_KBCODE)
1819 if (hist<mHistory.size()-1)
1821 // erase current line
1822 while (ind--) BackSpace();
1826 strcpy(histline,mHistory[hist]);
1830 write(STDOUT_FILENO,line,ind);
1832 // end of history : switch back to newline
1833 else if (hist==mHistory.size()-1)
1835 // erase current line
1836 while (ind--) BackSpace();
1843 write(STDOUT_FILENO,line,ind);
1847 else if (line[ind]!=0 && c==BBTK_RIGHT_ARROW_KBCODE)
1849 PrintChar(line[ind]);
1854 else if (ind>0 && c==BBTK_LEFT_ARROW_KBCODE)
1862 write(STDOUT_FILENO,"\n\r",2);
1870 //=======================================================================
1871 void Interpreter::GetLineFromPrompt(std::string& s)
1897 //=======================================================================
1903 //=======================================================================
1904 void Interpreter::CommandLineInterpreter()
1906 bbtkDebugMessageInc("Interpreter",9,
1907 "Interpreter::CommandLineInterpreter()"<<std::endl);
1909 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1910 // Initialise the tty in non canonical mode with no echo
1911 // oter remembers the previous settings to restore them after
1912 struct termios ter,oter;
1915 ter.c_lflag &= ~ECHO;
1916 ter.c_lflag &= ~ICANON;
1919 tcsetattr(0,TCSANOW,&ter);
1922 mCommandLine = true;
1924 // bool insideComment = false; // for multiline comment
1925 mInsideComment = false;
1931 GetLineFromPrompt(line);
1932 DoInterpretLine(line); //, insideComment);
1935 catch (QuitException e)
1937 bbtkMessage("Interpreter",1,"Interpreter : Quit"<<std::endl);
1941 catch (bbtk::Exception e)
1945 catch (std::exception& e)
1947 std::cerr << "* ERROR :: "<<e.what()<<" (not in bbtk)"<<std::endl;
1951 std::cerr << "* UNDEFINED ERROR (not a bbtk nor a std exception)"<<std::endl;
1956 #ifdef BBTK_USE_TERMIOS_BASED_PROMPT
1957 tcsetattr(0,TCSANOW,&oter);
1960 std::cout << "Good bye !" << std::endl;
1962 bbtkDebugDecTab("Interpreter",9);
1965 //=======================================================================
1966 void Interpreter::Graph(const std::vector<std::string>& words)
1969 bool system_display = true;
1971 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
1972 system_display = false;
1974 if (words.size()==1)
1976 page = mVirtualExecuter->ShowGraph(".","0","0","","","",system_display);
1978 else if (words.size()==2)
1980 page = mVirtualExecuter->ShowGraph(words[1],"0","0","","","",system_display);
1982 else if (words.size()==3)
1984 page = mVirtualExecuter->ShowGraph(words[1],words[2],"0","","","",system_display);
1986 else if (words.size()==4)
1988 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],"","","",system_display);
1990 else if (words.size()==5)
1992 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],"","",system_display);
1994 else if (words.size()==6)
1996 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],"",system_display);
1998 else if (words.size()==7)
2000 page = mVirtualExecuter->ShowGraph(words[1],words[2],words[3],words[4],words[5],words[6],system_display);
2003 if ( ( mUser != 0 ) && ( mUser->InterpreterUserHasOwnHtmlPageViewer() ) )
2004 mUser->InterpreterUserViewHtmlPage(page);
2007 //=======================================================================
2010 //=======================================================================
2011 void Interpreter::Index(const std::string& filename,
2012 const std::string& type)
2014 Factory::IndexEntryType t;
2015 if (type=="Initials") t = Factory::Initials;
2016 else if (type=="Categories") t = Factory::Categories;
2017 else if (type=="Packages") t = Factory::Packages;
2018 else if (type=="Adaptors") t = Factory::Adaptors;
2020 GetExecuter()->GetFactory()->CreateHtmlIndex(t,filename);
2022 //=======================================================================
2025 //=======================================================================
2026 void Interpreter::NewGUI(const std::string& boxname,
2027 const std::string& instanceName)
2029 if (mRealExecuter.expired())
2031 bbtkError("command 'newgui' cannot be compiled yet");
2034 std::string typeName = instanceName+"Type";
2035 std::stringstream* s = new std::stringstream;
2036 // create the complex box
2037 (*s) << "define "<<typeName<<std::endl;
2038 // (*s) << " description 'Automatically generated user interface for the box "
2039 // << boxname << "'" <<std::endl;
2040 // create the Layout box
2041 (*s) << " load wx"<<std::endl;
2042 (*s) << " new LayoutLine layout"<<std::endl;
2043 // create the output 'Widget'
2044 (*s) << " output Widget layout.Widget Widget"<<std::endl;
2045 // the box change output
2046 (*s) << " new MultipleInputs change"<<std::endl;
2047 (*s) << " output BoxChange change.Out BoxChange"<<std::endl;
2049 // Browse the inputs of the box in order to find which ones are not
2050 // connected and can be adapted from a widget adaptor
2051 // vector which stores the list of inputs of the box which must be connected
2052 std::vector<std::string> in;
2054 Factory::Pointer F = mVirtualExecuter->GetFactory();
2056 Package::Pointer user = F->GetPackage("user");
2058 ComplexBlackBoxDescriptor::Pointer workspace =
2059 mRealExecuter.lock()->GetCurrentDescriptor();
2064 bbtkError("Interpreter::CreateGUI : could not access the executer currently defined complex box");
2069 (ComplexBlackBoxDescriptor::Pointer)(user->GetBlackBoxMap().find("workspace")->second.get());
2072 BlackBox::Pointer box = workspace->GetPrototype()->bbGetBlackBox(boxname);
2073 // BlackBox::InputConnectorMapType incm = box->bbGetInputConnectorMap();
2075 BlackBox::InputConnectorMapType::iterator i;
2076 for (i=box->bbGetInputConnectorMap().begin();
2077 i!=box->bbGetInputConnectorMap().end();
2080 // If the input is connected : continue
2081 if (i->second->IsConnected()) continue;
2082 // Get the input descriptor
2083 const BlackBoxInputDescriptor* d = box->bbGetDescriptor()->GetInputDescriptor(i->first);
2084 // If it is a "system" input : skip it
2085 if ( ( d->GetCreatorTypeInfo() == typeid(AtomicBlackBoxDescriptor)) ||
2086 ( d->GetCreatorTypeInfo() == typeid(WxBlackBoxDescriptor)) )
2089 std::string widget,adaptor;
2090 // try to find a widget adaptor
2091 if (F->FindWidgetAdaptor(DataInfo(d->GetTypeInfo(),""),
2095 // command to create the adaptor
2096 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2097 // Sets the label of the widget adaptor to the name of the input
2098 (*s) << " set "<<i->first<<".Label "<<i->first<<std::endl;
2099 // Sets the initial value of the widget to the value of the input
2100 (*s) << " set "<<i->first<<".In \" "
2101 <<box->bbGetInputAsString(i->first)<<"\""
2103 // store the input name
2104 in.push_back(i->first);
2105 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2106 //<i->first<<"'"<<std::endl;
2107 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2109 // try to find a two pieces adaptor
2110 else if (F->FindWidgetAdaptor2(DataInfo(d->GetTypeInfo(),""),
2114 // command to create the widget
2115 (*s) << " new "<<widget<<" "<<i->first<<"Widget"<<std::endl;
2116 // command to create the adaptor
2117 (*s) << " new "<<adaptor<<" "<<i->first<<std::endl;
2119 (*s) << " connect "<<i->first<<"Widget.Out "
2120 <<i->first<<".In"<<std::endl;
2121 // Sets the label of the widget adaptor to the name of the input
2122 (*s) << " set "<<i->first<<"Widget.Label "<<i->first<<std::endl;
2123 // Sets the initial value of the widget to the value of the input
2124 (*s) << " set "<<i->first<<"Widget.In \" "
2125 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2126 // store the input name
2127 in.push_back(i->first);
2128 (*s) << " connect "<<i->first<<"Widget.Widget layout.Widget"<<in.size()<<std::endl;
2129 //<i->first<<"'"<<std::endl;
2130 (*s) << " connect "<<i->first<<"Widget.BoxChange change.In"<<in.size()<<std::endl;
2133 // try to find an adaptor from string
2134 // If found then can create a text input which
2135 // will be automatically adapted
2136 else if (F->FindAdaptor(DataInfo(typeid(std::string),""),
2140 // command to create the adaptor
2141 (*s) << " new InputText "<<i->first<<std::endl;
2142 // Sets the label of the widget adaptor to the name of the input
2143 (*s) << " set "<<i->first<<".Title "<<i->first<<std::endl;
2144 // Sets the initial value of the widget to the value of the input
2145 (*s) << " set "<<i->first<<".In \" "
2146 <<box->bbGetInputAsString(i->first)<<"\""<< std::endl;
2147 // store the input name
2148 in.push_back(i->first);
2149 (*s) << " connect "<<i->first<<".Widget layout.Widget"<<in.size()<<std::endl;
2150 //<i->first<<"'"<<std::endl;
2151 (*s) << " connect "<<i->first<<".BoxChange change.In"<<in.size()<<std::endl;
2160 // command to create the output
2161 (*s) << " output "<<i->first<<" "
2162 <<i->first<<".Out "<<i->first<<std::endl;
2163 // <<" Output of the widget which allows to set "
2167 // Inputs for window properties
2168 (*s) << " input WinTitle layout.WinTitle Title"<<std::endl;
2169 (*s) << " input WinWidth layout.WinWidth Width"<<std::endl;
2170 (*s) << " input WinHeight layout.WinHeight Height"<<std::endl;
2171 (*s) << " input WinDialog layout.WinDialog Dialog"<<std::endl;
2172 (*s) << " input WinHide layout.WinHide Hide"<<std::endl;
2176 // Execute the box executes the layout
2177 (*s) << " exec layout" << std::endl;
2178 (*s) << "endefine" << std::endl;
2179 // (*s) << "help "<< typeName<< std::endl;
2180 // instanciate the box and connect it
2181 (*s) << "new "<<typeName<<" "<<instanceName<<std::endl;
2183 std::vector<std::string>::iterator j;
2184 for (j=in.begin();j!=in.end();++j)
2187 (*s) << "connect "<<instanceName<<"."<<*j<<" "
2188 << boxname<<"."<<*j<<std::endl;
2190 // That's all folks ! now execute the commands :
2193 //=======================================================================
2197 //==========================================================================
2198 void Interpreter::Debug(const std::string& name)
2200 if ((name.length()==2)&&(name[0]=='-'))
2204 bbtk::StaticInitTime::PrintObjectListInfo = true;
2208 // int o = MessageManager::GetMessageLevel("debug");
2209 // if (o<2) MessageManager::SetMessageLevel("debug",2);
2210 mVirtualExecuter->GetFactory()->CheckPackages();
2211 // MessageManager::SetMessageLevel("debug",o);
2216 Object:: PrintObjectListInfo(name);
2219 //==========================================================================
2222 //==========================================================================
2223 // Adds a callback when 'break' command issued
2224 void Interpreter::AddBreakObserver( BreakCallbackType c )
2226 mBreakSignal.connect(c);
2228 //==========================================================================
2231 //==========================================================================
2232 std::string Interpreter::GetObjectName() const
2234 return std::string("Interpreter");
2236 //==========================================================================
2238 //==========================================================================
2239 std::string Interpreter::GetObjectInfo() const
2241 std::stringstream i;
2244 //==========================================================================
2246 //==========================================================================
2247 size_t Interpreter::GetObjectSize() const
2249 size_t s = Superclass::GetObjectSize();
2250 s += Interpreter::GetObjectInternalSize();
2253 //==========================================================================
2254 //==========================================================================
2255 size_t Interpreter::GetObjectInternalSize() const
2257 size_t s = sizeof(Interpreter);
2260 //==========================================================================
2261 //==========================================================================
2262 size_t Interpreter::GetObjectRecursiveSize() const
2264 size_t s = Superclass::GetObjectRecursiveSize();
2265 s += Interpreter::GetObjectInternalSize();
2266 s += mVirtualExecuter->GetObjectRecursiveSize();
2269 //==========================================================================